#!/bin/bash
set -eo pipefail

fetch_k8s() {
	git clone https://github.com/Azure/kubernetes ${GOPATH}/src/k8s.io/kubernetes || true
	cd $KUBEPATH
	git remote add upstream https://github.com/kubernetes/kubernetes || true
	git fetch upstream
}

set_git_config() {
	git config user.name "ACS CI"
	git config user.email "containers@microsoft.com"
}

create_version_branch() {
	git checkout -b ${ACS_BRANCH_NAME} ${KUBERNETES_TAG_BRANCH} || true
}

version_lt() {
        [ "$1" != $(printf "$1\n$2" | sort -V | head -n 2 | tail -n 1) ]
}

version_ge() {
        [ "$1" == $(printf "$1\n$2" | sort -V | head -n 2 | tail -n 1) ]
}

k8s_16_cherry_pick() {
	# 232fa6e5bc (HEAD -> release-1.6, origin/release-1.6) Fix the delay caused by network setup in POD Infra container
	# 02b1c2b9e2 Use dns policy to determine setting DNS servers on the correct NIC in Windows container
	# 4c2a2d79aa Fix getting host DNS for Windows node when dnsPolicy is Default
	# caa314ccdc Update docker version parsing to allow nonsemantic versions as they have changed how they do their versions
	# f18be40948 Fix the issue in unqualified name where DNS client such as ping or iwr validate name in response and original question. Switch to use miekg's DNS library
	# c862b583c9 Remove DNS server from NAT network adapter inside container
	# f6c27f9375 Merged libCNI-on-Windows changes from CNI release 0.5.0, PRs 359 and 361
	# 4f196c6cac Fix the issue that ping uses the incorrect NIC to resolve name sometimes
	# 2c9fd27449 Workaround for Outbound Internet traffic in Azure Kubernetes
	# 5fa0725025 Use adapter vEthernet (HNSTransparent) on Windows host network to find node IP

	git cherry-pick 5fa0725025^..232fa6e5bc
}

k8s_17_cherry_pick() {
	if version_ge "${version}" "1.7.10"; then
		echo "version 1.7.10 and after..."
		# In 1.7.10, the following commit is not needed and has conflict with 137f4cb16e
		# due to the out-of-order back porting into Azure 1.7. So removing it.
		# cee32e92f7 fix#50150: azure disk mount failure on coreos
		git revert --no-edit cee32e92f7 || true

		if version_ge "${version}" "1.7.12"; then
			echo "version 1.7.12 and after..."
			# In 1.7.12, the following commits are cherry-picked in upstream and has conflict
			# with 137f4cb16e. So removing them.
			git revert --no-edit 593653c384 || true #only for linux
			git revert --no-edit 7305738dd1 || true #add tests only
			git revert --no-edit e01bafcf80 || true #only for linux
			git revert --no-edit afd79db7a6 || true #only for linux
			git revert --no-edit 3a4abca2f7 || true #covered by commit 3aa179744f
			git revert --no-edit 6a2e2f47d3 || true #covered by commit 3aa179744f

			if version_ge "${version}" "1.7.13"; then
				echo "version 1.7.13 and after..."
				# In 1.7.13, the following commit is cherry-picked in upstream and has conflict
				# with 137f4cb16e. So removing it.
				git revert --no-edit 3aa179744f || true #only for linux

				if version_ge "${version}" "1.7.14"; then
					echo "version 1.7.14 and after..."
					if version_ge "${version}" "1.7.15"; then
						echo "version 1.7.15 and after..."
						if version_ge "${version}" "1.7.16"; then
							echo "version 1.7.16 and after..."
							# From 1.7.16, 3e530479ed conflict with reverting 975d0a4bb9. We use 5f9113ce9b in Azure repo instead of 3e530479ed
							git revert --no-edit 3e530479ed || true
							# From 1.7.16, 76017a002b conflict with reverting 975d0a4bb9. We use 3d97a43e41 in Azure repo instead of 76017a002b
							git revert --no-edit 76017a002b || true
						fi

						# From 1.7.15, 0d5df36f05 conflict with reverting 975d0a4bb9. We use 631e363b9d in Azure repo instead of 0d5df36f05
						git revert --no-edit 0d5df36f05 || true
						# From 1.7.15, 4d50500614 conflict with reverting 51584188ee. It is server side code so jsut revert it.
						git revert --no-edit 4d50500614 || true
					fi
					# From 1.7.14, 975d0a4bb9 conflict with 137f4cb16e. We use a36d59ddda in Azure repo instead of 975d0a4bb9
					git revert --no-edit 975d0a4bb9 || true
					# From 1.7.14, 51584188ee and 3a0db21dcb conflict with af3a93b07e. We use f5c45d3def in Azure repo instead of them
					git revert --no-edit 51584188ee || true
					git revert --no-edit 3a0db21dcb || true
					# From 1.7.14, 273411cc90 conflict with e9591ef03e. We use d18812a049 in Azure repo instead of 273411cc90
					git revert --no-edit 273411cc90 || true
					# From 1.7.14, a97f60fbf3 conflict with a36d59ddda. We use 69c56c6037 in Azure repo instead of a97f60fbf3
					git revert --no-edit a97f60fbf3 || true
				fi
			fi
		fi
	fi

	# 32ceaa7918 fix #60625: add remount logic for azure file plugin on Windows
	# ...
	# b8fe713754 Use adapter vEthernet (HNSTransparent) on Windows host network to find node IP
	# From 1.7.13, acbdec96da is not needed since 060111c603 supercedes it
	git cherry-pick --allow-empty --keep-redundant-commits b8fe713754^..e912889a7f
	if version_lt "${version}" "1.7.13"; then
		echo "before version 1.7.13..."
		git cherry-pick --allow-empty --keep-redundant-commits acbdec96da
	fi
	git cherry-pick --allow-empty --keep-redundant-commits 76d7c23f62^..32ceaa7918

	if version_ge "${version}" "1.7.14"; then
		echo "version 1.7.14 and after..."
		# From 1.7.14, 975d0a4bb9 conflict with 137f4cb16e. We use a36d59ddda in Azure repo instead of 975d0a4bb9
		git cherry-pick --allow-empty --keep-redundant-commits a36d59ddda
		# From 1.7.14, 51584188ee and 3a0db21dcb conflict with af3a93b07e. We use f5c45d3def in Azure repo instead of them
		git cherry-pick -X theirs --allow-empty --keep-redundant-commits f5c45d3def # git complains about a conflict and just take theirs
		# From 1.7.14, 273411cc90 conflict with e9591ef03e. We use d18812a049 in Azure repo instead of 273411cc90
		git cherry-pick --allow-empty --keep-redundant-commits d18812a049
		# From 1.7.14, a97f60fbf3 conflict with a36d59ddda. We use 69c56c6037 in Azure repo instead of a97f60fbf3
		git cherry-pick --allow-empty --keep-redundant-commits 69c56c6037

		git cherry-pick --allow-empty --keep-redundant-commits 3e930be6bc

		if version_ge "${version}" "1.7.15"; then
			echo "version 1.7.15 and after..."
			# From 1.7.15, 0d5df36f05 conflict with reverting 975d0a4bb9. We use 631e363b9d in Azure repo instead of 0d5df36f05
			git cherry-pick --allow-empty --keep-redundant-commits 631e363b9d

			if version_ge "${version}" "1.7.16"; then
				echo "version 1.7.16 and after..."
				# From 1.7.16, 76017a002b conflict with reverting 975d0a4bb9. We use 3d97a43e41 in Azure repo instead of 76017a002b
				git cherry-pick --allow-empty --keep-redundant-commits 3d97a43e41
				# From 1.7.16, 3e530479ed conflict with reverting 975d0a4bb9. We use 5f9113ce9b in Azure repo instead of 3e530479ed
				git cherry-pick --allow-empty --keep-redundant-commits 5f9113ce9b
			fi
		fi
	fi
}

k8s_18_cherry_pick() {
	# 4fd355d04a fix #60625: add remount logic for azure file plugin on Windows
	# ...
	# 4647f2f616 merge #52401: add windows implementation of GetMountRefs

	# d75ef50170 merge#54334: fix azure disk mount failure on coreos and some other distros

	# Only cherry pick before 1.8.6 due to merge conflict with 1.8.6 and up: b8594873f4 merge #50673: azure disk fix of SovereignCloud support

	# cb29df51c0 Fixing 'targetport' to service 'port' mapping
	# ...
	# b42981f90b merge#53629: fix azure file mount limit issue on windows due to using drive letter

	# We have to skip 8b3345114e due to merge conflict with 1.8.4 and up, 4647f2f616 has the change.

	# 8d477271f7 update bazel
	# ...
	# 69644018c8 Use adapter vEthernet (HNSTransparent) on Windows host network to find node IP

	if version_ge "${version}" "1.8.9"; then
		echo "version 1.8.9 and after..."
		if version_ge "${version}" "1.8.10"; then
			echo "version 1.8.10 and after..."
			if version_ge "${version}" "1.8.11"; then
				echo "version 1.8.11 and after..."
				# From 1.8.11, 6487f82b13 conflict with 86107edff5. We use 8e081d5da9 in Azure repo instead of 6487f82b13
				git revert --no-edit 6487f82b13 || true
				# From 1.8.11, 2704ef877b conflict with reverting a418057ddd. We skip it since it is test file
				git revert --no-edit 2704ef877b || true
				# From 1.8.11, dc21ebe936 conflict with reverting 63b4f60e43. We use 18589971f7 in Azure repo instead of dc21ebe936
				git revert --no-edit dc21ebe936 || true
				# From 1.8.11, a418057ddd conflict with reverting 63b4f60e43. We use 57038dce90 in Azure repo instead of a418057ddd
				git revert --no-edit a418057ddd || true
				# From 1.8.11, beaca32611 conflict with reverting 63b4f60e43. We use e6d8af84df in Azure repo instead of beaca32611
				git revert --no-edit beaca32611 || true
			fi
			# From 1.8.10, 5936faed37 conflict with reverting 63b4f60e43. We use 1f26b7a083 in Azure repo instead of 5936faed37
			git revert --no-edit 5936faed37 || true
		fi
		# From 1.8.9, 63b4f60e43 conflict with b42981f90b. We use 6a8305e419 in Azure repo instead of 63b4f60e43
		git revert --no-edit 63b4f60e43 || true
		# From 1.8.9, 40d5e0a34f conflict with 6a8305e419. We use b90d61a48c in Azure repo instead of 40d5e0a34f
		git revert --no-edit 40d5e0a34f || true
	fi

	git cherry-pick --allow-empty --keep-redundant-commits 69644018c8^..8d477271f7
	git cherry-pick --allow-empty --keep-redundant-commits b42981f90b^..cb29df51c0
	if version_lt "${version}" "1.8.6"; then
		echo "before version 1.8.6..."
		git cherry-pick --allow-empty --keep-redundant-commits b8594873f4
	fi
	git cherry-pick --allow-empty --keep-redundant-commits d75ef50170
	git cherry-pick --allow-empty --keep-redundant-commits 4647f2f616^..4fd355d04a

	if version_ge "${version}" "1.8.9"; then
		echo "version 1.8.9 and after..."
		# From 1.8.9, 63b4f60e43 conflict with b42981f90b. We use 6a8305e419 in Azure repo instead of 63b4f60e43
		git cherry-pick --allow-empty --keep-redundant-commits 6a8305e419
		# From 1.8.9, 40d5e0a34f conflict with 6a8305e419. We use b90d61a48c in Azure repo instead of 40d5e0a34f
		git cherry-pick --allow-empty --keep-redundant-commits b90d61a48c
		if version_ge "${version}" "1.8.10"; then
			echo "version 1.8.10 and after..."
			# From 1.8.10, 5936faed37 conflict with reverting 63b4f60e43. We use 1f26b7a083 in Azure repo instead of 5936faed37
			git cherry-pick --allow-empty --keep-redundant-commits 1f26b7a083
			if version_ge "${version}" "1.8.11"; then
				echo "version 1.8.11 and after..."
				# From 1.8.11, 6487f82b13 conflict with 86107edff5. We use 8e081d5da9 in Azure repo instead of 6487f82b13
				# From 1.8.11, dc21ebe936 conflict with reverting 63b4f60e43. We use 18589971f7 in Azure repo instead of dc21ebe936
				# From 1.8.11, a418057ddd conflict with reverting 63b4f60e43. We use 57038dce90 in Azure repo instead of a418057ddd
				# From 1.8.11, beaca32611 conflict with reverting 63b4f60e43. We use e6d8af84df in Azure repo instead of beaca32611
				git cherry-pick --allow-empty --keep-redundant-commits 8e081d5da9^..18589971f7
			fi
		fi
	fi
}

apply_acs_cherry_picks() {
	if [ "${KUBERNETES_RELEASE}" == "1.6" ]; then
		k8s_16_cherry_pick
	elif [ "${KUBERNETES_RELEASE}" == "1.7" ]; then
		k8s_17_cherry_pick
	elif [ "${KUBERNETES_RELEASE}" == "1.8" ]; then
		k8s_18_cherry_pick
	elif version_ge "${KUBERNETES_RELEASE}" "1.9"; then
		echo "No need to cherry-pick for version greater than or equal to 1.9!"
	else
		echo "Unable to apply cherry picks for ${KUBERNETES_RELEASE}."
		exit 1
	fi
}

create_dist_dir() {
	mkdir -p ${DIST_DIR}
}

build_kubelet() {
	echo "building kubelet.exe..."
	$KUBEPATH/build/run.sh make WHAT=cmd/kubelet KUBE_BUILD_PLATFORMS=windows/amd64
	cp ${GOPATH}/src/k8s.io/kubernetes/_output/dockerized/bin/windows/amd64/kubelet.exe ${DIST_DIR}
}

build_kubeproxy() {
	echo "building kube-proxy.exe..."
	$KUBEPATH/build/run.sh make WHAT=cmd/kube-proxy KUBE_BUILD_PLATFORMS=windows/amd64
	cp ${GOPATH}/src/k8s.io/kubernetes/_output/dockerized/bin/windows/amd64/kube-proxy.exe ${DIST_DIR}
}

build_kubectl() {
	echo "building kubectl.exe..."
    $KUBEPATH/build/run.sh make WHAT=cmd/kubectl KUBE_BUILD_PLATFORMS=windows/amd64
    cp ${GOPATH}/src/k8s.io/kubernetes/_output/dockerized/bin/windows/amd64/kubectl.exe ${DIST_DIR}
}

download_kubectl() {
	kubectl="https://storage.googleapis.com/kubernetes-release/release/v${version}/bin/windows/amd64/kubectl.exe"
	echo "dowloading ${kubectl} ..."
	curl -L ${kubectl} -o ${DIST_DIR}/kubectl.exe
	chmod 775 ${DIST_DIR}/kubectl.exe
}

get_kube_binaries() {
	if version_lt "${KUBERNETES_RELEASE}" "1.9"; then
		echo "building kubelet/kubeproxy from azure repo..."
		fetch_k8s
		set_git_config
		create_version_branch
		apply_acs_cherry_picks

		# Due to what appears to be a bug in the Kubernetes Windows build system, one
		# has to first build a linux binary to generate _output/bin/deepcopy-gen.
		# Building to Windows w/o doing this will generate an empty deepcopy-gen.
		build/run.sh make WHAT=cmd/kubelet KUBE_BUILD_PLATFORMS=linux/amd64

		build_kubelet
		build_kubeproxy

		echo "downloading kubectl..."
		download_kubectl
	else
		echo "downloading kubelet/kubeproxy/kubectl from upstream..."
		WIN_TAR=kubernetes-node-windows-amd64.tar.gz
		SUB_DIR=kubernetes/node/bin
		curl -L https://storage.googleapis.com/kubernetes-release/release/v${version}/${WIN_TAR} -o ${TOP_DIR}/${WIN_TAR}
		tar -xzvf ${TOP_DIR}/${WIN_TAR} -C ${TOP_DIR}
		cp ${TOP_DIR}/${SUB_DIR}/kubelet.exe ${DIST_DIR}
		cp ${TOP_DIR}/${SUB_DIR}/kube-proxy.exe ${DIST_DIR}
		cp ${TOP_DIR}/${SUB_DIR}/kubectl.exe ${DIST_DIR}
		chmod 775 ${DIST_DIR}/kubectl.exe
	fi
}

build_kube_binaries_for_upstream_e2e() {
		$KUBEPATH/build/run.sh make WHAT=cmd/kubelet KUBE_BUILD_PLATFORMS=linux/amd64

		build_kubelet
		build_kubeproxy
		build_kubectl
}

download_nssm() {
	NSSM_VERSION=2.24
	NSSM_URL=https://nssm.cc/release/nssm-${NSSM_VERSION}.zip
	echo "downloading nssm ..."
	curl ${NSSM_URL} -o /tmp/nssm-${NSSM_VERSION}.zip
	unzip -q -d /tmp /tmp/nssm-${NSSM_VERSION}.zip
	cp /tmp/nssm-${NSSM_VERSION}/win64/nssm.exe ${DIST_DIR}
	chmod 775 ${DIST_DIR}/nssm.exe
	rm -rf /tmp/nssm-${NSSM_VERSION}*
}

download_wincni() {
	mkdir -p ${DIST_DIR}/cni/config
	WINSDN_URL=https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/
	WINCNI_EXE=cni/wincni.exe
	HNS_PSM1=hns.psm1
	curl -L ${WINSDN_URL}${WINCNI_EXE} -o ${DIST_DIR}/${WINCNI_EXE}
	curl -L ${WINSDN_URL}${HNS_PSM1} -o ${DIST_DIR}/${HNS_PSM1}
}

copy_dockerfile() {
  cp ${ACS_ENGINE_HOME}/windows/Dockerfile ${DIST_DIR}
}

create_zip() {
	ZIP_NAME="${k8s_e2e_upstream_version:-"v${ACS_VERSION}int.zip"}"
	cd ${DIST_DIR}/..
	zip -r ../${ZIP_NAME} k/*
	cd -
}

upload_zip_to_blob_storage() {
	az storage blob upload -f ${TOP_DIR}/../v${ACS_VERSION}int.zip -c ${AZURE_STORAGE_CONTAINER_NAME} -n v${ACS_VERSION}int.zip
}

push_acs_branch() {
	if version_lt "${KUBERNETES_RELEASE}" "1.9"; then
		echo "push to azure repo..."
		cd ${GOPATH}/src/k8s.io/kubernetes
		git push origin ${ACS_BRANCH_NAME}
	else
		echo "no need to push to azure repo"
	fi
}

cleanup_output() {
	rm ${TOP_DIR}/../v${ACS_VERSION}int.zip
	rm -r ${TOP_DIR}
}

ACS_ENGINE_HOME=${GOPATH}/src/github.com/Azure/acs-engine

usage() {
	echo "$0 [-v version] [-p acs_patch_version]"
	echo " -v <version>: version"
	echo " -p <patched version>: acs_patch_version"
	echo " -u <version build for kubernetes upstream e2e tests>: k8s_e2e_upstream_version"
	echo " -z <zip path>: zip_path"
}

while getopts ":v:p:u:z:" opt; do
  case ${opt} in
    v)
      version=${OPTARG}
      ;;
    p)
      acs_patch_version=${OPTARG}
      ;;
	u)
	  k8s_e2e_upstream_version=${OPTARG}
	  ;;
	z)
	  zip_path=${OPTARG}
	  ;;
    *)
			usage
			exit
      ;;
  esac
done

KUBEPATH=${GOPATH}/src/k8s.io/kubernetes

if [ -z "${k8s_e2e_upstream_version}" ]; then

	if [ -z "${version}" ] || [ -z "${acs_patch_version}" ]; then
		usage
			exit 1
	fi

	if [ -z "${AZURE_STORAGE_CONNECTION_STRING}" ] || [ -z "${AZURE_STORAGE_CONTAINER_NAME}" ]; then
		echo '$AZURE_STORAGE_CONNECTION_STRING and $AZURE_STORAGE_CONTAINER_NAME need to be set for upload to Azure Blob Storage.'
			exit 1
	fi

	KUBERNETES_RELEASE=$(echo $version | cut -d'.' -f1,2)
	KUBERNETES_TAG_BRANCH=v${version}
	ACS_VERSION=${version}-${acs_patch_version}
	ACS_BRANCH_NAME=acs-v${ACS_VERSION}
	TOP_DIR=${ACS_ENGINE_HOME}/_dist/k8s-windows-v${ACS_VERSION}
	DIST_DIR=${TOP_DIR}/k

	create_dist_dir
	get_kube_binaries
	download_nssm
	download_wincni
	copy_dockerfile
	create_zip
	upload_zip_to_blob_storage
	push_acs_branch
	cleanup_output

else
	DIST_DIR=${zip_path}/k
	create_dist_dir
	build_kube_binaries_for_upstream_e2e
	download_nssm
	download_wincni
	create_zip
fi


#!/usr/bin/env bash

# DON'T RUN. This script requires PythonLocalizerTool which is not published yet.
# TODO: make PythonLocalizerTool public
set -eo pipefail

langdirs=loc/*

convert_lcl_to_po() {
  for dir in $langdirs
  do
    loc_lang=`basename "$dir"`
    translation_lang=`echo $loc_lang | tr - _`
    publish/PythonLocalizerTool lcltopo $dir translations/$translation_lang/LC_MESSAGES/ translations/en_US/LC_MESSAGES/en-US/metadata acsengine ""
    msgfmt -c -v -o translations/$translation_lang/LC_MESSAGES/acsengine.mo translations/$translation_lang/LC_MESSAGES/acsengine.po
  done
}

convert_po_to_lcg() {
  publish/PythonLocalizerTool potolcg translations/en_US/LC_MESSAGES acsengine
}

case "${1-}" in
  --potolcg)
    echo "converting po to lcg..."
    convert_po_to_lcg
    ;;
  --lcltopo)
    echo "converting lcl to po..."
    convert_lcl_to_po
    ;;
  *)
    echo $"Usage: $0 {--potolcg|--lcltopo}"
    exit 1
esac


#!/bin/bash

set -euo pipefail

for i in $(find .. -type f -iname '*.go' ! -path '../vendor/*') # do not run on the vendor dir
do
  if ! grep -q Copyright "$i"
  then
    cat copyright.txt "$i" > "$i".new && mv "$i".new "$i"
  fi
done


#!/usr/bin/env bash

# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eo pipefail

covermode=${COVERMODE:-atomic}
coverdir=$(mktemp -d /tmp/coverage.XXXXXXXXXX)
profile="${coverdir}/cover.out"

hash goveralls 2>/dev/null || go get github.com/mattn/goveralls
hash godir 2>/dev/null || go get github.com/Masterminds/godir

generate_cover_data() {
  for d in $(godir) ; do
    (
      local output="${coverdir}/${d//\//-}.cover"
      go test -coverprofile="${output}" -covermode="$covermode" "$d"
    )
  done

  echo "mode: $covermode" >"$profile"
  grep -h -v "^mode:" "$coverdir"/*.cover >>"$profile"
}

push_to_coveralls() {
  goveralls -coverprofile="${profile}" -repotoken $COVERALLS_TOKEN
}

generate_cover_data
go tool cover -func "${profile}"

case "${1-}" in
  --html)
    go tool cover -html "${profile}"
    ;;
  --coveralls)
		if [ -z $COVERALLS_TOKEN ]; then
			echo '$COVERALLS_TOKEN not set. Skipping pushing coverage report to coveralls.io'
			exit
		fi
    push_to_coveralls
    ;;
esac


#!/usr/bin/env bash

set -eu -o pipefail
set -x

docker build --pull -t acs-engine .

docker run -it \
	--privileged \
	--security-opt seccomp:unconfined \
	-v /var/run/docker.sock:/var/run/docker.sock \
	-v `pwd`:/gopath/src/github.com/Azure/acs-engine \
	-v ~/.azure:/root/.azure \
	-w /gopath/src/github.com/Azure/acs-engine \
		acs-engine /bin/bash

chown -R "$(logname):$(id -gn $(logname))" . ~/.azure


#!/usr/bin/env bash

# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -eo pipefail

covermode=${COVERMODE:-atomic}
coverdir=$(mktemp -d /tmp/coverage.XXXXXXXXXX)
profile="${coverdir}/cover.out"
coveragetxt="coverage.txt"

hash goveralls 2>/dev/null || go get github.com/mattn/goveralls
hash godir 2>/dev/null || go get github.com/Masterminds/godir

generate_cover_data() {
  ginkgo -skipPackage test/e2e/dcos,test/e2e/kubernetes,test/e2e/openshift -failFast -cover -r .
  echo "" > ${coveragetxt}
  find . -type f -name "*.coverprofile" | while read -r file;  do cat $file >> ${coveragetxt} && mv $file ${coverdir}; done
  echo "mode: $covermode" >"$profile"
  grep -h -v "^mode:" "$coverdir"/*.coverprofile >>"$profile"
}

push_to_coveralls() {
  goveralls -coverprofile="${profile}" -service=circle-ci -repotoken $COVERALLS_REPO_TOKEN || echo "push to coveralls failed"
}

push_to_codecov() {
  bash <(curl -s https://codecov.io/bash) || echo "push to codecov failed"
}

generate_cover_data
go tool cover -func "${profile}"

case "${1-}" in
  --html)
    go tool cover -html "${profile}"
    ;;
  --coveralls)
		if [ -z $COVERALLS_REPO_TOKEN ]; then
			echo '$COVERALLS_REPO_TOKEN not set. Skipping pushing coverage report to coveralls.io'
			exit
		fi
    push_to_coveralls
    ;;
  --codecov)
    push_to_codecov
    ;;
esac


#!/bin/bash

scripts/update-translation.sh -l en_US -p

mv acsengine.po translations/en_US/LC_MESSAGES/acsengine.po
rm acsengine.pot


#!/bin/bash

GO_SOURCE="pkg/acsengine/*.go pkg/acsengine/transform/*.go pkg/api/*.go pkg/operations/*.go pkg/operations/kubernetesupgrade/*.go"
LANGUAGE="en_US"
DOMAIN="acsengine"
generate_po="false"
generate_mo="false"

while getopts "hl:pm" opt; do
  case $opt in
    h)
      echo "$0 [-l language] [-p] [-m]"
      echo " -l <language>: Language to translate"
      echo " -p extract strings and generate PO file"
      echo " -m generate MO file"
      exit 0
      ;;
    l)
      LANGUAGE="${OPTARG}"
      ;;
    p)
      generate_po="true"
      ;;
    m)
      generate_mo="true"
      ;;
    \?)
      echo "$0 [-l language] [-p] [-m]"
      exit 1
      ;;
  esac
done

if ! which go-xgettext > /dev/null; then
  echo 'Can not find go-xgettext, install with:'
  echo 'go get github.com/JiangtianLi/gettext/go-xgettext'
  exit 1
fi

if ! which msginit > /dev/null; then
  echo 'Can not find msginit, install with:'
  echo 'apt-get install gettext'
  exit 1
fi

if [[ "${generate_po}" == "true" ]]; then
  echo "Extract strings and generate PO files..."
  go-xgettext -o ${DOMAIN}.pot --keyword=Translator.Errorf --keyword-plural=Translator.NErrorf --msgid-bugs-address="" --sort-output ${GO_SOURCE}
  msginit -l ${LANGUAGE} -o ${DOMAIN}.po -i ${DOMAIN}.pot
fi

if [[ "${generate_mo}" == "true" ]]; then
  echo "Generate MO file..."
  if [ ! -f ${DOMAIN}.po ]; then
    echo "${DOMAIN}.po not found!"
	exit 1
  fi
  msgfmt -c -v -o ${DOMAIN}.mo ${DOMAIN}.po
fi


#!/usr/bin/env bash

set -euo pipefail

echo "==> Checking copyright headers <=="

files=$(find . -type f -iname '*.go' ! -path './vendor/*')
licRes=$(for file in $files; do
           awk 'NR<=3' "$file" | grep -Eq "(Copyright|generated|GENERATED)" || echo "$file";
         done)

if [ -n "$licRes" ]; then
        echo "Copyright header check failed:";
        echo "${licRes}";
        exit 1;
fi


#!/usr/bin/env bash

exit_code=0

echo "==> Running dep check <=="

dep check || exit_code=1

if [ $exit_code -ne 0 ]; then
  echo "The dependency state is out of sync. Please run dep ensure."
else
  echo "dep check passed."
fi

exit $exit_code


#!/usr/bin/env bash

# Copyright 2016 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -euo pipefail

exit_code=0

if ! hash gometalinter 2>/dev/null ; then
  go get -u github.com/alecthomas/gometalinter
  gometalinter --install
fi

echo
echo "==> Running static validations <=="
# Run linters that should return errors
gometalinter \
  --disable-all \
  --enable deadcode \
  --enable gofmt \
  --enable goimports \
  --enable gosimple \
  --enable ineffassign \
  --enable misspell \
  --enable unused \
  --enable vet \
  --tests \
  --vendor \
  --deadline 120s \
  --skip test/i18n \
  --skip pkg/test \
  --exclude pkg/i18n/i18n.go \
  --exclude pkg/i18n/translations.go \
  --exclude pkg/acsengine/templates.go \
  --exclude pkg/openshift/certgen/release39/templates/bindata.go \
  --exclude pkg/openshift/certgen/unstable/templates/bindata.go \
  ./... || exit_code=1

echo
echo "==> Running linters <=="
# Run linters that should return warnings
gometalinter \
  --disable-all \
  --enable golint \
  --vendor \
  --skip proto \
  --skip pkg/test \
  --deadline 60s \
  --exclude pkg/i18n/translations.go \
  --exclude pkg/acsengine/templates.go \
  --exclude pkg/openshift/certgen/release39/templates/bindata.go \
  --exclude pkg/openshift/certgen/unstable/templates/bindata.go \
  ./... || exit_code=1

exit $exit_code


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

ROOT="${DIR}/.."

# see: https://github.com/stedolan/jq/issues/105 & https://github.com/stedolan/jq/wiki/FAQ#general-questions
function jqi() { filename="${1}"; jqexpr="${2}"; jq "${jqexpr}" "${filename}" > "${filename}.tmp" && mv "${filename}.tmp" "${filename}"; }

function generate_template() {
	# Check pre-requisites
	[[ ! -z "${INSTANCE_NAME:-}" ]] || (echo "Must specify INSTANCE_NAME" && exit -1)
	[[ ! -z "${CLUSTER_DEFINITION:-}" ]] || (echo "Must specify CLUSTER_DEFINITION" && exit -1)
	[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_ID:-}" ]] || [[ ! -z "${CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID:-}" ]] || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_ID" && exit -1)
	[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_SECRET:-}" ]] || [[ ! -z "${CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET:-}" ]] || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_SECRET" && exit -1)
	[[ ! -z "${OUTPUT:-}" ]] || (echo "Must specify OUTPUT" && exit -1)

	# Set output directory
	mkdir -p "${OUTPUT}"

	# Prep SSH Key
	ssh-keygen -b 2048 -t rsa -f "${OUTPUT}/id_rsa" -q -N ""
	ssh-keygen -y -f "${OUTPUT}/id_rsa" > "${OUTPUT}/id_rsa.pub"
	export SSH_KEY_DATA="$(cat "${OUTPUT}/id_rsa.pub")"

	# Allow different credentials for cluster vs the deployment
	export CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID="${CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID:-${SERVICE_PRINCIPAL_CLIENT_ID}}"
	export CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET="${CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET:-${SERVICE_PRINCIPAL_CLIENT_SECRET}}"

	# Form the final cluster_definition file
	export FINAL_CLUSTER_DEFINITION="${OUTPUT}/clusterdefinition.json"
	cp "${CLUSTER_DEFINITION}" "${FINAL_CLUSTER_DEFINITION}"
	jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.masterProfile.dnsPrefix = \"${INSTANCE_NAME}\""
	jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.agentPoolProfiles |= map(if .name==\"agentpublic\" then .dnsPrefix = \"${INSTANCE_NAME}0\" else . end)"
	jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.linuxProfile.ssh.publicKeys[0].keyData = \"${SSH_KEY_DATA}\""

	k8sServicePrincipal=$(jq 'getpath(["properties","servicePrincipalProfile"])' ${FINAL_CLUSTER_DEFINITION})
	if [[ "${k8sServicePrincipal}" != "null" ]]; then
		apiVersion=$(get_api_version)
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.servicePrincipalProfile.clientId = \"${CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID}\""
		if [[ ${CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET} =~ /subscription.* ]]; then
			vaultID=$(echo $CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET | awk -F"/secrets/" '{print $1}')
			secretName=$(echo $CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET | awk -F"/secrets/" '{print $2}')
			jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.servicePrincipalProfile.keyvaultSecretRef.vaultID = \"${vaultID}\""
			jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.servicePrincipalProfile.keyvaultSecretRef.secretName  = \"${secretName}\""
		else
			jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.servicePrincipalProfile.secret = \"${CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET}\""
		fi
	fi

	secrets=$(jq 'getpath(["properties","linuxProfile","secrets"])' ${FINAL_CLUSTER_DEFINITION})
	if [[ "${secrets}" != "null" ]]; then
		[[ ! -z "${CERT_KEYVAULT_ID:-}" ]] || (echo "Must specify CERT_KEYVAULT_ID" && exit -1)
		[[ ! -z "${CERT_SECRET_URL:-}" ]] || (echo "Must specify CERT_SECRET_URL" && exit -1)
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.linuxProfile.secrets[0].sourceVault.id = \"${CERT_KEYVAULT_ID}\""
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.linuxProfile.secrets[0].vaultCertificates[0].certificateUrl = \"${CERT_SECRET_URL}\""
	fi
	secrets=$(jq 'getpath(["properties","windowsProfile","secrets"])' ${FINAL_CLUSTER_DEFINITION})
	if [[ "${secrets}" != "null" ]]; then
		[[ ! -z "${CERT_KEYVAULT_ID:-}" ]] || (echo "Must specify CERT_KEYVAULT_ID" && exit -1)
		[[ ! -z "${CERT_SECRET_URL:-}" ]] || (echo "Must specify CERT_SECRET_URL" && exit -1)
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.windowsProfile.secrets[0].sourceVault.id = \"${CERT_KEYVAULT_ID}\""
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.windowsProfile.secrets[0].vaultCertificates[0].certificateUrl = \"${CERT_SECRET_URL}\""
		jqi "${FINAL_CLUSTER_DEFINITION}" ".properties.windowsProfile.secrets[0].vaultCertificates[0].certificateStore = \"My\""
	fi
	# Generate template
	"${DIR}/../bin/acs-engine" generate --output-directory "${OUTPUT}" "${FINAL_CLUSTER_DEFINITION}" --debug

	# Fill in custom hyperkube spec, if it was set
	if [[ ! -z "${CUSTOM_HYPERKUBE_SPEC:-}" ]]; then
		# TODO: plumb hyperkube into the apimodel
		jqi "${OUTPUT}/azuredeploy.parameters.json" ".parameters.kubernetesHyperkubeSpec.value = \"${CUSTOM_HYPERKUBE_SPEC}\""
	fi
}

function set_azure_account() {
	# Check pre-requisites
	[[ ! -z "${SUBSCRIPTION_ID:-}" ]] || (echo "Must specify SUBSCRIPTION_ID" && exit -1)
	[[ ! -z "${TENANT_ID:-}" ]] || (echo "Must specify TENANT_ID" && exit -1)
	[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_ID:-}" ]] || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_ID" && exit -1)
	[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_SECRET:-}" ]] || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_SECRET" && exit -1)
	which kubectl || (echo "kubectl must be on PATH" && exit -1)
	which az || (echo "az must be on PATH" && exit -1)

	# Login to Azure-Cli
	az login --service-principal \
		--username "${SERVICE_PRINCIPAL_CLIENT_ID}" \
		--password "${SERVICE_PRINCIPAL_CLIENT_SECRET}" \
		--tenant "${TENANT_ID}" &>/dev/null

	az account set --subscription "${SUBSCRIPTION_ID}"
}

function create_resource_group() {
	[[ ! -z "${LOCATION:-}" ]] || (echo "Must specify LOCATION" && exit -1)
	[[ ! -z "${RESOURCE_GROUP:-}" ]] || (echo "Must specify RESOURCE_GROUP" && exit -1)

	# Create resource group if doesn't exist
	az group show --name="${RESOURCE_GROUP}" || [ $? -eq 3  ] && echo "will create resource group ${RESOURCE_GROUP}" || exit -1
	az group create --name="${RESOURCE_GROUP}" --location="${LOCATION}" --tags "type=${RESOURCE_GROUP_TAG_TYPE:-}" "now=$(date +%s)" "job=${JOB_BASE_NAME:-}" "buildno=${BUILD_NUM:-}"
		sleep 3 # TODO: investigate why this is needed (eventual consistency in ARM)
}

function deploy_template() {
	# Check pre-requisites
	[[ ! -z "${DEPLOYMENT_NAME:-}" ]] || (echo "Must specify DEPLOYMENT_NAME" && exit -1)
	[[ ! -z "${LOCATION:-}" ]] || (echo "Must specify LOCATION" && exit -1)
	[[ ! -z "${RESOURCE_GROUP:-}" ]] || (echo "Must specify RESOURCE_GROUP" && exit -1)
	[[ ! -z "${OUTPUT:-}" ]] || (echo "Must specify OUTPUT" && exit -1)

	which kubectl || (echo "kubectl must be on PATH" && exit -1)
	which az || (echo "az must be on PATH" && exit -1)

	create_resource_group

	# Deploy the template
	az group deployment create \
		--name "${DEPLOYMENT_NAME}" \
		--resource-group "${RESOURCE_GROUP}" \
		--template-file "${OUTPUT}/azuredeploy.json" \
		--parameters "@${OUTPUT}/azuredeploy.parameters.json"
}

function scale_agent_pool() {
	# Check pre-requisites
	[[ ! -z "${AGENT_POOL_SIZE:-}" ]] || (echo "Must specify AGENT_POOL_SIZE" && exit -1)
	[[ ! -z "${DEPLOYMENT_NAME:-}" ]] || (echo "Must specify DEPLOYMENT_NAME" && exit -1)
	[[ ! -z "${LOCATION:-}" ]] || (echo "Must specify LOCATION" && exit -1)
	[[ ! -z "${RESOURCE_GROUP:-}" ]] || (echo "Must specify RESOURCE_GROUP" && exit -1)
	[[ ! -z "${OUTPUT:-}" ]] || (echo "Must specify OUTPUT" && exit -1)

	which az || (echo "az must be on PATH" && exit -1)

	APIMODEL="${OUTPUT}/apimodel.json"
	DEPLOYMENT_PARAMS="${OUTPUT}/azuredeploy.parameters.json"

	for poolname in `jq '.properties.agentPoolProfiles[].name' "${APIMODEL}" | tr -d '\"'`; do
	  offset=$(jq "getpath([\"parameters\", \"${poolname}Count\", \"value\"])" ${DEPLOYMENT_PARAMS})
	  echo "$poolname : offset=$offset count=$AGENT_POOL_SIZE"
	  jqi "${DEPLOYMENT_PARAMS}" ".${poolname}Count.value = $AGENT_POOL_SIZE"
	  jqi "${DEPLOYMENT_PARAMS}" ".${poolname}Offset.value = $offset"
	done

	az group deployment create \
		--name "${DEPLOYMENT_NAME}" \
		--resource-group "${RESOURCE_GROUP}" \
		--template-file "${OUTPUT}/azuredeploy.json" \
		--parameters "@${OUTPUT}/azuredeploy.parameters.json"
}

function get_node_count() {
	[[ ! -z "${CLUSTER_DEFINITION:-}" ]] || (echo "Must specify CLUSTER_DEFINITION" && exit -1)

	count=$(jq '.properties.masterProfile.count' ${CLUSTER_DEFINITION})
	linux_agents=0
	windows_agents=0

	nodes=$(jq -r '.properties.agentPoolProfiles[].count' ${CLUSTER_DEFINITION})
	osTypes=$(jq -r '.properties.agentPoolProfiles[].osType' ${CLUSTER_DEFINITION})

	nArr=( $nodes )
	oArr=( $osTypes )
	indx=0
	for n in "${nArr[@]}"; do
		count=$((count+n))
		if [ "${oArr[$indx]}" = "Windows" ]; then
			windows_agents=$((windows_agents+n))
		else
			linux_agents=$((linux_agents+n))
		fi
		indx=$((indx+1))
	done
	echo "${count}:${linux_agents}:${windows_agents}"
}

function get_orchestrator_type() {
	[[ ! -z "${CLUSTER_DEFINITION:-}" ]] || (echo "Must specify CLUSTER_DEFINITION" && exit -1)

	orchestratorType=$(jq -r 'getpath(["properties","orchestratorProfile","orchestratorType"])' ${CLUSTER_DEFINITION} | tr '[:upper:]' '[:lower:]')

	echo $orchestratorType
}

function get_orchestrator_version() {
	[[ ! -z "${CLUSTER_DEFINITION:-}" ]] || (echo "Must specify CLUSTER_DEFINITION" && exit -1)

	orchestratorVersion=$(jq -r 'getpath(["properties","orchestratorProfile","orchestratorVersion"])' ${CLUSTER_DEFINITION})
	if [[ "$orchestratorVersion" == "null" ]]; then
		orchestratorVersion=""
	fi

	echo $orchestratorVersion
}

function get_api_version() {
	[[ ! -z "${CLUSTER_DEFINITION:-}" ]] || (echo "Must specify CLUSTER_DEFINITION" && exit -1)

	apiVersion=$(jq -r 'getpath(["apiVersion"])' ${CLUSTER_DEFINITION})
	if [[ "$apiVersion" == "null" ]]; then
		apiVersion=""
	fi

	echo $apiVersion
}

function cleanup() {
	if [[ "${CLEANUP:-}" == "y" ]]; then
		az group delete --no-wait --name="${RESOURCE_GROUP}" --yes || true
	fi
}


#!/usr/bin/env bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

###############################################################################

set -e
set -u
set -o pipefail

ROOT="${DIR}/.."

# Usage:
#
# Manual user usage (Specific name):
#   export INSTANCE_NAME=official-jenkins-infra
#   ./scripts/deploy.sh ./examples/kubernetes.json
#
# Manual user usage (Lots of rapid fire):
# In this mode, the user can repeat the same deploy
# command blindly and get new clusters each time.
#   unset INSTANCE_NAME
#   vim ./test/user.env (add your stuff)
#   ./scripts/deploy.sh ./examples.kubernetes.json
#   sleep 1
#   ./scripts/deploy.sh ./examples.kubernetes.json
#
# Prow:
#   export PULL_NUMBER=...
#   export VALIDATE=<script path>
#   export CLUSTER_DEFIITION=examples/kubernetes.json
#   ./scripts/deploy.sh

# Load any user set environment
if [[ -f "${ROOT}/test/user.env" ]]; then
	source "${ROOT}/test/user.env"
fi

# Ensure Cluster Definition
if [[ -z "${CLUSTER_DEFINITION:-}" ]]; then
	if [[ -z "${1:-}" ]]; then echo "You must specify a parameterized apimodel.json clusterdefinition"; exit -1; fi
	CLUSTER_DEFINITION="${1}"
fi

# Set Instance Name for PR or random run
if [[ ! -z "${PULL_NUMBER:-}" ]]; then
	export INSTANCE_NAME="${JOB_NAME}-${PULL_NUMBER}-$(printf "%x" $(date '+%s'))"
	# if we're running a pull request, assume we want to cleanup unless the user specified otherwise
	if [[ -z "${CLEANUP:-}" ]]; then
		export CLEANUP="y"
	fi
else
	export INSTANCE_NAME_DEFAULT="${INSTANCE_NAME_PREFIX}-$(printf "%x" $(date '+%s'))"
	export INSTANCE_NAME="${INSTANCE_NAME:-${INSTANCE_NAME_DEFAULT}}"
fi

# Let the example json.env file set any env vars it may need ahead of time
# (For example, the `managed-identity/kubernetes.json.env` sets env vars for a
# custom MSI-compatible build of Kubernetes, as well as the SP cred values.)
ENV_FILE="${CLUSTER_DEFINITION}.env"
if [ -e "${ENV_FILE}" ]; then
  source "${ENV_FILE}"
fi

# Set extra parameters
export OUTPUT="${ROOT}/_output/${INSTANCE_NAME}"
export RESOURCE_GROUP="${INSTANCE_NAME}"
export DEPLOYMENT_NAME="${INSTANCE_NAME}"

source "${ROOT}/test/common.sh"

# Set custom dir so we don't clobber global 'az' config
export AZURE_CONFIG_DIR="$(mktemp -d)"
trap 'rm -rf ${AZURE_CONFIG_DIR}' EXIT

make -C "${ROOT}" ci
generate_template
set_azure_account
trap cleanup EXIT
deploy_template

if [[ -z "${VALIDATE:-}" ]]; then
	exit 0
fi

export SSH_KEY="${OUTPUT}/id_rsa"
export KUBECONFIG="${OUTPUT}/kubeconfig/kubeconfig.${LOCATION}.json"

"${ROOT}/${VALIDATE}"

echo "post-test..."


#!/bin/bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

###############################################################################

set -e
set -o pipefail

ROOT="${DIR}/.."

# Check pre-requisites
[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_ID:-}" ]]             || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_ID" && exit -1)
[[ ! -z "${SERVICE_PRINCIPAL_CLIENT_SECRET:-}" ]]         || (echo "Must specify SERVICE_PRINCIPAL_CLIENT_SECRET" && exit -1)
[[ ! -z "${TENANT_ID:-}" ]]                               || (echo "Must specify TENANT_ID" && exit -1)
[[ ! -z "${SUBSCRIPTION_ID:-}" ]]                         || (echo "Must specify SUBSCRIPTION_ID" && exit -1)
[[ ! -z "${CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID:-}" ]]     || (echo "Must specify CLUSTER_SERVICE_PRINCIPAL_CLIENT_ID" && exit -1)
[[ ! -z "${CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET:-}" ]] || (echo "Must specify CLUSTER_SERVICE_PRINCIPAL_CLIENT_SECRET" && exit -1)
[[ ! -z "${STAGE_TIMEOUT_MIN:-}" ]]                       || (echo "Must specify STAGE_TIMEOUT_MIN" && exit -1)
[[ ! -z "${TEST_CONFIG:-}" ]]                             || (echo "Must specify TEST_CONFIG" && exit -1)

make bootstrap build

${ROOT}/test/acs-engine-test/acs-engine-test -c ${TEST_CONFIG} -d ${ROOT} -e ${LOGERROR_CONFIG:-${ROOT}/test/acs-engine-test/acs-engine-errors.json} -j ${SA_NAME} -k ${SA_KEY}


#!/usr/bin/env bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

###############################################################################

set -e
set -u
set -o pipefail

ROOT="${DIR}/.."

source "${ROOT}/test/common.sh"

case $1 in

set_azure_account)
  set_azure_account
;;

create_resource_group)
  create_resource_group
;;

predeploy)
  ACSE_PREDEPLOY=${ACSE_PREDEPLOY:-}
  if [ ! -z "${ACSE_PREDEPLOY}" ] && [ -x "${ACSE_PREDEPLOY}" ]; then
      "${ACSE_PREDEPLOY}"
  fi
;;

postdeploy)
  ACSE_POSTDEPLOY=${ACSE_POSTDEPLOY:-}
  if [ ! -z "${ACSE_POSTDEPLOY}" ] && [ -x "${ACSE_POSTDEPLOY}" ]; then
      "${ACSE_POSTDEPLOY}"
  fi
;;

generate_template)
  export OUTPUT="${ROOT}/_output/${INSTANCE_NAME}"
  generate_template
;;

deploy_template)
  export OUTPUT="${ROOT}/_output/${INSTANCE_NAME}"
  deploy_template
;;

get_node_count)
  export OUTPUT="${ROOT}/_output/${INSTANCE_NAME}"
  get_node_count
;;

get_orchestrator_type)
  get_orchestrator_type
;;

get_orchestrator_release)
  get_orchestrator_release
;;

validate)
  export OUTPUT="${ROOT}/_output/${INSTANCE_NAME}"
  export SSH_KEY="${OUTPUT}/id_rsa"
  if [ ${ORCHESTRATOR} = "kubernetes" ]; then
    export KUBECONFIG="${OUTPUT}/kubeconfig/kubeconfig.${LOCATION}.json"
  fi
  "${ROOT}/test/cluster-tests/${ORCHESTRATOR}/test.sh"
;;

cleanup)
  export CLEANUP="${CLEANUP:-y}"
  cleanup
;;
esac


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

set -eu -o pipefail
set -x

git init .
git clean -dfx
git reset --hard
git config --local user.name 'ACS Bot'
git config --local user.email 'acs-bot@microsoft.com'
git fetch --tags https://github.com/${REPO_OWNER}/${REPO_NAME} master +refs/pull/${PULL_NUMBER}/head:refs/pr/${PULL_NUMBER}
git checkout -B test "${PULL_BASE_SHA}"
git merge --no-ff -m "Merge +refs/pull/${PULL_NUMBER}/head:refs/pr/${PULL_NUMBER}" "${PULL_PULL_SHA}"

echo "----------------------------------------------------------"
env
echo "----------------------------------------------------------"


function log {
  local message="$1"
  local caller="$(caller 0)"
  now=$(date +"%D %T %Z")

  if [[ ! -z "${LOGFILE:-}" ]]; then
    echo "[${now}] [${caller}] ${message}" | tee -a ${LOGFILE}
  else
    echo "[${now}] [${caller}] ${message}"
  fi
}


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

# do not use 'set -e'
# -o pipefail
set -x

source "$DIR/../utils.sh"

ENV_FILE="${CLUSTER_DEFINITION}.env"
if [ -e "${ENV_FILE}" ]; then
  source "${ENV_FILE}"
fi

MARATHON_JSON="${MARATHON_JSON:-marathon.json}"

remote_exec="ssh -i "${SSH_KEY}" -o ConnectTimeout=30 -o StrictHostKeyChecking=no azureuser@${INSTANCE_NAME}.${LOCATION}.cloudapp.azure.com -p2200"
agentFQDN="${INSTANCE_NAME}0.${LOCATION}.cloudapp.azure.com"
remote_cp="scp -i "${SSH_KEY}" -P 2200 -o StrictHostKeyChecking=no"

function teardown {
  ${remote_exec} ./dcos marathon app remove /web
}

###### Check node count
function check_node_count() {
  log "Checking node count"
  count=20
  while (( $count > 0 )); do
    log "  ... counting down $count"
    node_count=$(${remote_exec} curl -s http://localhost:1050/system/health/v1/nodes | jq '.nodes | length')
    [ $? -eq 0 ] && [ ! -z "$node_count" ] && [ $node_count -eq ${EXPECTED_NODE_COUNT} ] && log "Successfully got $EXPECTED_NODE_COUNT nodes" && break
    sleep 30; count=$((count-1))
  done
  if (( $node_count != ${EXPECTED_NODE_COUNT} )); then
    log "gave up waiting for DCOS nodes: $node_count available, ${EXPECTED_NODE_COUNT} expected"
    exit 1
  fi
}

check_node_count

log "Downloading dcos"
${remote_exec} curl -O https://dcos-mirror.azureedge.net/binaries/cli/linux/x86-64/dcos-1.10/dcos
if [[ "$?" != "0" ]]; then log "Failed to download dcos"; exit 1; fi
log "Setting dcos permissions"
${remote_exec} chmod a+x ./dcos
if [[ "$?" != "0" ]]; then log "Failed to chmod dcos"; exit 1; fi
log "Configuring dcos"
${remote_exec} ./dcos cluster setup http://localhost:80
if [[ "$?" != "0" ]]; then log "Failed to configure dcos"; exit 1; fi

log "Copying marathon.json"

${remote_cp} "${DIR}/${MARATHON_JSON}" azureuser@${INSTANCE_NAME}.${LOCATION}.cloudapp.azure.com:marathon.json
if [[ "$?" != "0" ]]; then log "Failed to copy marathon.json"; exit 1; fi

# feed agentFQDN to marathon.json
log "Configuring marathon.json"
${remote_exec} sed -i "s/{agentFQDN}/${agentFQDN}/g" marathon.json
if [[ "$?" != "0" ]]; then log "Failed to configure marathon.json"; exit 1; fi

log "Adding marathon app"
count=20
while (( $count > 0 )); do
  log "  ... counting down $count"
  ${remote_exec} ./dcos marathon app list | grep /web
  retval=$?
  if [[ $retval -eq 0 ]]; then log "Marathon App successfully installed" && break; fi
  ${remote_exec} ./dcos marathon app add marathon.json
  retval=$?
  if [[ "$retval" == "0" ]]; then break; fi
  sleep 15; count=$((count-1))
done
if [[ $retval -ne 0 ]]; then log "gave up waiting for marathon to be added"; exit 1; fi

# only need to teardown if app added successfully
trap teardown EXIT

log "Validating marathon app"
count=0
while [[ ${count} -lt 25 ]]; do
  count=$((count+1))
  log "  ... cycle $count"
  running=$(${remote_exec} ./dcos marathon app show /web | jq .tasksRunning)
  if [[ "${running}" == "3" ]]; then
    log "Found 3 running tasks"
    break
  fi
  sleep ${count}
done

if [[ "${running}" != "3" ]]; then
  log "marathon validation failed"
  ${remote_exec} ./dcos marathon app show /web
  ${remote_exec} ./dcos marathon app list
  exit 1
fi

# install marathon-lb
${remote_exec} ./dcos package install marathon-lb --yes
if [[ "$?" != "0" ]]; then log "Failed to install marathon-lb"; exit 1; fi

# curl simpleweb through external haproxy
log "Checking Service"
count=20
while true; do
  log "  ... counting down $count"
  rc=$(curl -sI --max-time 60 "http://${agentFQDN}" | head -n1 | cut -d$' ' -f2)
  [[ "$rc" -eq "200" ]] && log "Successfully hitting simpleweb through external haproxy http://${agentFQDN}" && break
  if [[ "${count}" -le 1 ]]; then
    log "failed to get expected response from nginx through the loadbalancer: Error $rc"
    exit 1
  fi
  sleep 15; count=$((count-1))
done


function test_linux_deployment() {
  ###### Testing an nginx deployment
  log "Testing deployments"
  kubectl create namespace ${namespace}

  NGINX="docker.io/library/nginx:latest"
  IMAGE="${NGINX}" # default to the library image unless we're in TEST_ACR mode
  if [[ "${TEST_ACR}" == "y" ]]; then
    # force it to pull from ACR
    IMAGE="${ACR_REGISTRY}/test/nginx:latest"
    # wait for acr
    wait
    # TODO: how to do this without polluting user home dir?
    docker login --username="${SERVICE_PRINCIPAL_CLIENT_ID}" --password="${SERVICE_PRINCIPAL_CLIENT_SECRET}" "${ACR_REGISTRY}"
    docker pull "${NGINX}"
    docker tag "${NGINX}" "${IMAGE}"
    docker push "${IMAGE}"
  fi

  kubectl run --image="${IMAGE}" nginx --namespace=${namespace} --overrides='{ "apiVersion": "extensions/v1beta1", "spec":{"template":{"spec": {"nodeSelector":{"beta.kubernetes.io/os":"linux"}}}}}'
  count=12
  while (( $count > 0 )); do
    log "  ... counting down $count"
    running=$(kubectl get pods --namespace=${namespace} | grep nginx | grep Running | wc | awk '{print $1}')
    if (( ${running} == 1 )); then break; fi
      sleep 5; count=$((count-1))
  done
  if (( ${running} != 1 )); then
    log "K8S-Linux: gave up waiting for deployment"
    kubectl get all --namespace=${namespace}
    exit 1
  fi

  kubectl expose deployments/nginx --type=LoadBalancer --namespace=${namespace} --port=80

  log "Checking Service External IP"
  count=60
  external_ip=""
  while (( $count > 0 )); do
    log "  ... counting down $count"
    external_ip=$(kubectl get svc --namespace ${namespace} nginx --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}" || echo "")
    [[ ! -z "${external_ip}" ]] && break
    sleep 10; count=$((count-1))
  done
  if [[ -z "${external_ip}" ]]; then
    log "K8S-Linux: gave up waiting for loadbalancer to get an ingress ip"
    exit 1
  fi

  log "Checking Service"
  count=5
  success="n"
  while (( $count > 0 )); do
    log "  ... counting down $count"
    ret=$(curl -f --max-time 60 "http://${external_ip}" | grep 'Welcome to nginx!' || echo "curl_error")
    if [[ $ret =~ .*'Welcome to nginx!'.* ]]; then
      success="y"
      break
    fi
    sleep 5; count=$((count-1))
  done
  if [[ "${success}" != "y" ]]; then
    log "K8S-Linux: failed to get expected response from nginx through the loadbalancer"
    exit 1
  fi
}

function test_windows_deployment() {
  ###### Testing a simpleweb windows deployment
  log "Testing Windows deployments"

  log "Creating simpleweb service"
  kubectl apply -f "$DIR/simpleweb-windows.yaml"
  count=90
  while (( $count > 0 )); do
    log "  ... counting down $count"
    running=$(kubectl get pods --namespace=default | grep win-webserver | grep Running | wc | awk '{print $1}')
    if (( ${running} == 1 )); then break; fi
    sleep 10; count=$((count-1))
  done
  if (( ${running} != 1 )); then
    log "K8S-Windows: gave up waiting for deployment"
    kubectl get all --namespace=default
    exit 1
  fi

  log "Checking Service External IP"
  count=60
  external_ip=""
  while (( $count > 0 )); do
    log "  ... counting down $count"
    external_ip=$(kubectl get svc --namespace default win-webserver --template="{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}" || echo "")
    [[ ! -z "${external_ip}" ]] && break
    sleep 10; count=$((count-1))
  done
  if [[ -z "${external_ip}" ]]; then
    log "K8S-Windows: gave up waiting for loadbalancer to get an ingress ip"
    exit 1
  fi

  log "Checking Service"
  count=5
  success="n"
  while (( $count > 0 )); do
    log "  ... counting down $count"
    ret=$(curl -f --max-time 60 "http://${external_ip}" | grep 'Windows Container Web Server' || echo "curl_error")
    if [[ $ret =~ .*'Windows Container Web Server'.* ]]; then
      success="y"
      break
    fi
    sleep 10; count=$((count-1))
  done
  if [[ "${success}" != "y" ]]; then
    log "K8S-Windows: failed to get expected response from simpleweb through the loadbalancer"
    exit 1
  fi

  log "Checking outbound connection"
  count=10
  while (( $count > 0 )); do
    log "  ... counting down $count"
    winpodname=$(kubectl get pods --namespace=default | grep win-webserver | awk '{print $1}')
    [[ ! -z "${winpodname}" ]] && break
    sleep 10; count=$((count-1))
  done
  if [[ -z "${winpodname}" ]]; then
    log "K8S-Windows: failed to get expected pod name for simpleweb"
    exit 1
  fi

  log "query DNS"
  count=0 # disabled while outbound connection bug is present
  success="y" # disabled while outbound connection bug is present
  while (( $count > 0 )); do
    log "  ... counting down $count"
    query=$(kubectl exec $winpodname -- powershell nslookup www.bing.com)
    if [[ $(echo ${query} | grep "DNS request timed out" | wc -l) == 0 ]] && [[ $(echo ${query} | grep "UnKnown" | wc -l) == 0 ]]; then
      success="y"
      break
    fi
    sleep 10; count=$((count-1))
  done

  # temporarily disable breaking on errors to allow the retry
  set +e
  log "curl external website"
  count=0 # disabled while outbound connection bug is present
  success="y" # disabled while outbound connection bug is present
  while (( $count > 0 )); do
    log "  ... counting down $count"
    # curl without getting status first and see the response. getting status sometimes has the problem to hang
    # and it doesn't repro when running kubectl from the node
    kubectl exec $winpodname -- powershell iwr -UseBasicParsing -TimeoutSec 60 www.bing.com
    statuscode=$(kubectl exec $winpodname -- powershell iwr -UseBasicParsing -TimeoutSec 60 www.bing.com | grep StatusCode)
    if [[ ${statuscode} != "" ]] && [[ $(echo ${statuscode} | grep 200 | awk '{print $3}' | tr -d '\r') -eq "200" ]]; then
      log "got 200 status code"
      log "${statuscode}"
      success="y"
      break
    fi
    log "curl failed, retrying..."
    ipconfig=$(kubectl exec $winpodname -- powershell ipconfig /all)
    log "$ipconfig"
    # TODO: reduce sleep time when outbound connection delay is fixed
    sleep 100; count=$((count-1))
  done
  set -e
  if [[ "${success}" != "y" ]]; then
    nslookup=$(kubectl exec $winpodname -- powershell nslookup www.bing.com)
    log "$nslookup"
    log "getting the last 50 events to check timeout failure"
    hdr=$(kubectl get events | head -n 1)
    log "$hdr"
    evt=$(kubectl get events | tail -n 50)
    log "$evt"
    log "K8S-Windows: failed to get outbound internet connection inside simpleweb container"
    exit 1
  else
    log "outbound connection succeeded!"
  fi
}


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

# exit on errors
set -e
# exit on unbound variables
set -u
# verbose logging
set -x

source "$DIR/../utils.sh"
source "$DIR/k8s-utils.sh"

ENV_FILE="${CLUSTER_DEFINITION}.env"
if [ -e "${ENV_FILE}" ]; then
  source "${ENV_FILE}"
fi

EXPECTED_NODE_COUNT="${EXPECTED_NODE_COUNT:-4}"
EXPECTED_LINUX_AGENTS="${EXPECTED_LINUX_AGENTS:-3}"
EXPECTED_WINDOWS_AGENTS="${EXPECTED_WINDOWS_AGENTS:-0}"
EXPECTED_DNS="${EXPECTED_DNS:-2}"
EXPECTED_DASHBOARD="${EXPECTED_DASHBOARD:-1}"
EXPECTED_RESCHEDULER="${EXPECTED_RESCHEDULER:-0}"
EXPECTED_ORCHESTRATOR_VERSION="${EXPECTED_ORCHESTRATOR_VERSION:-}"

KUBE_PROXY_COUNT=$((EXPECTED_NODE_COUNT-$EXPECTED_WINDOWS_AGENTS))

# set TEST_ACR to "y" for ACR testing
TEST_ACR="${TEST_ACR:-n}"

namespace="namespace-${RANDOM}"
log "Running test in namespace: ${namespace}"
trap teardown EXIT

function teardown {
  kubectl get all --all-namespaces || echo "teardown error"
  kubectl get nodes || echo "teardown error"
  kubectl get namespaces || echo "teardown error"
  kubectl delete namespaces ${namespace} || echo "teardown error"
}

# TODO: cleanup the loops more
# TODO: the wc|awk business can just be kubectl with an output format and wc -l

###### Deploy ACR
if [[ "${TEST_ACR}" == "y" ]]; then
	ACR_NAME="${INSTANCE_NAME//[-._]/}1"
	ACR_REGISTRY="${ACR_NAME}-microsoft.azurecr.io" # fix this for non-ms tenant users
	if ! az acr show --resource-group "${RESOURCE_GROUP}" --name "${ACR_NAME}" ; then
		az acr create --location "${LOCATION}" --resource-group "${RESOURCE_GROUP}" --name "${ACR_NAME}" &
	fi
fi

###### Check node count
function check_node_count() {
  log "Checking node count"
  count=120
  while (( $count > 0 )); do
    log "  ... counting down $count"
    node_count=$(kubectl get nodes --no-headers | grep -v NotReady | grep Ready | wc | awk '{print $1}')
    if (( ${node_count} == ${EXPECTED_NODE_COUNT} )); then break; fi
    sleep 5; count=$((count-1))
  done
  if (( $node_count != ${EXPECTED_NODE_COUNT} )); then
    log "K8S: gave up waiting for apiserver / node counts"; exit 1
  fi
}

check_node_count

###### Validate Kubernetes version
kubernetes_version=$(kubectl version --short)
DASHBOARD_PORT=80
if [[ ${kubernetes_version} == *"Server Version: v1.9."* ]]; then
  DASHBOARD_PORT=443
fi
log "Setting dashboard port to ${DASHBOARD_PORT}"

log "Checking Kubernetes version. Expected: ${EXPECTED_ORCHESTRATOR_VERSION}"
if [ ! -z "${EXPECTED_ORCHESTRATOR_VERSION}" ]; then
  if [[ ${kubernetes_version} != *"Server Version: v${EXPECTED_ORCHESTRATOR_VERSION}"* ]]; then
    log "K8S: unexpected kubernetes version:\n${kubernetes_version}"; exit 1
  fi
fi

###### Wait for no more container creating
log "Checking containers being created"
count=60
while (( $count > 0 )); do
  log "  ... counting down $count"
  creating_count=$(kubectl get nodes --no-headers | grep 'CreatingContainer' | wc | awk '{print $1}')
  if (( ${creating_count} == 0 )); then break; fi
  sleep 5; count=$((count-1))
done
if (( ${creating_count} != 0 )); then
  log "K8S: gave up waiting for containers"; exit 1
fi

###### Check existence and status of essential pods

# we test other essential pods (kube-dns, kube-proxy) separately
pods="heapster kube-addon-manager kube-apiserver kube-controller-manager kube-scheduler tiller"
if (( ${EXPECTED_RESCHEDULER} != 0 )); then
    pods="$pods rescheduler"
fi
log "Checking $pods"

count=60
while (( $count > 0 )); do
  for pod in $pods; do
    running=$(kubectl get pods --all-namespaces | grep $pod | grep Running | wc -l)
    if (( $running > 0 )); then
      log "... $pod is Running"
      pods=$(echo $pods | sed -e "s/ *$pod */ /")
    fi
  done
  if [ -z "$(echo $pods | tr -d '[:space:]')" ]; then
    break
  fi
  sleep 5; count=$((count-1))
done

if [ ! -z "$(echo $pods | tr -d '[:space:]')" ]; then
  log "K8S: gave up waiting for running pods [$pods]"; exit 1
fi

###### Check for Kube-DNS
log "Checking Kube-DNS"
count=60
while (( $count > 0 )); do
  log "  ... counting down $count"
  running=$(kubectl get pods --namespace=kube-system | grep kube-dns | grep Running | wc | awk '{print $1}')
  if (( ${running} == ${EXPECTED_DNS} )); then break; fi
  sleep 5; count=$((count-1))
done
if (( ${running} != ${EXPECTED_DNS} )); then
  log "K8S: gave up waiting for kube-dns"; exit 1
fi

###### Check for Kube-Dashboard
if (( ${EXPECTED_DASHBOARD} != 0 )); then
  log "Checking Kube-Dashboard"
  count=60
  while (( $count > 0 )); do
    log "  ... counting down $count"
    running=$(kubectl get pods --namespace=kube-system | grep kubernetes-dashboard | grep Running | wc | awk '{print $1}')
    if (( ${running} == ${EXPECTED_DASHBOARD} )); then break; fi
    sleep 5; count=$((count-1))
  done
  if (( ${running} != ${EXPECTED_DASHBOARD} )); then
    log "K8S: gave up waiting for kubernetes-dashboard"; exit 1
  fi
else
  log "Expecting no dashboard"
fi

###### Check for Kube-Proxys
log "Checking Kube-Proxys"
count=60
while (( $count > 0 )); do
  log "  ... counting down $count"
  running=$(kubectl get pods --namespace=kube-system | grep kube-proxy | grep Running | wc | awk '{print $1}')
  if (( ${running} == ${KUBE_PROXY_COUNT} )); then break; fi
  sleep 5; count=$((count-1))
done
if (( ${running} != ${KUBE_PROXY_COUNT} )); then
  log "K8S: gave up waiting for kube-proxy"; exit 1
fi

if ! [ $EXPECTED_WINDOWS_AGENTS -gt 0 ] ; then
  if (( ${EXPECTED_DASHBOARD} != 0 )); then
    # get master public hostname
    master=$(kubectl config view | grep server | cut -f 3- -d "/" | tr -d " ")
    # get dashboard port
    port=$(kubectl get svc --namespace=kube-system | grep dashboard | awk '{print $4}' | sed -n 's/^'${DASHBOARD_PORT}':\(.*\)\/TCP$/\1/p')
    # get internal IPs of the nodes
    ips=$(kubectl get nodes --all-namespaces -o yaml | grep -B 1 InternalIP | grep address | awk '{print $3}')

    for ip in $ips; do
      log "Probing IP address ${ip}"
      count=60
      success="n"
      while (( $count > 0 )); do
        log "  ... counting down $count"
        ret=$(ssh -i "${OUTPUT}/id_rsa" -o ConnectTimeout=30 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "azureuser@${master}" "curl --max-time 60 http://${ip}:${port}" || echo "curl_error")
        if [[ ! $ret =~ .*curl_error.* ]]; then
          success="y"
          break
        fi
        if (( $count < 2 )); then
            log $ret
        fi
        sleep 5; count=$((count-1))
      done
      if [[ "${success}" == "n" ]]; then
        log "K8S: gave up verifying proxy"; exit 1
      fi
    done
  fi
fi

if [ $EXPECTED_LINUX_AGENTS -gt 0 ] ; then
  test_linux_deployment
fi

if [ $EXPECTED_WINDOWS_AGENTS -gt 0 ] ; then
  test_windows_deployment
fi

check_node_count


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

# do not use 'set -e'
set -x
set -u

source "$DIR/../utils.sh"

SSH="ssh -i ${SSH_KEY} -o ConnectTimeout=30 -o StrictHostKeyChecking=no -p2200 azureuser@${INSTANCE_NAME}.${LOCATION}.cloudapp.azure.com"

deploy="docker -H :2375 run -d -p 80:80 yeasy/simple-web"
wait_duration=10
total_loops=30
while true; do
  # || true is used to suppress the failure like "Error response from daemon: No elected primary cluster manager"
  # it should be gone after a few retries
  containerId="$($SSH $deploy 2>/dev/null )" || true
  [[ ! -z $containerId ]] && [[ "$(echo $containerId | grep '[0-9a-z]\{64\}')" ]] && log "container deployed! containerId is $containerId" && break
  log "Validation: Expected to get containerId. $(($total_loops*$wait_duration)) seconds remain"
  sleep $wait_duration
  total_loops=$((total_loops-1))
  if [ $total_loops -eq 0 ]; then
      log "Swarm validation failed: timeout"; exit 1;
  fi
done

result=$($SSH curl localhost:2375/containers/json | jq "[.[].Id==\"$containerId\"] | any")

if [ "$result" != "true" ]; then
  log "Swarm validation failed: container not found"; exit 1;
fi

log "Swarm validation completed"


#!/bin/bash

####################################################
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
####################################################

# do not use 'set -e'
set -x
set -u

source "$DIR/../utils.sh"

ssh_args="-i ${SSH_KEY} -o ConnectTimeout=30 -o StrictHostKeyChecking=no -p2200 azureuser@${INSTANCE_NAME}.${LOCATION}.cloudapp.azure.com"

function teardown {
  ssh ${ssh_args} docker service rm nginx
  sleep 10
  ssh ${ssh_args} docker network rm network
}

trap teardown EXIT

log "Starting swarmmode deployment validation in ${LOCATION}"
sleep 30
log "Creating network"
wait=10
count=12
args="${ssh_args} docker network create --driver overlay --subnet 10.0.9.0/24 --opt encrypted network"
while (( $count > 0 )); do
  log "  ... counting down $count"
  timeout -k 60s -s KILL 60s ssh $args
  retval=$?
  if [[ "$retval" == "0" ]]; then break; fi
  sleep $wait
  count=$((count-1))
done
if [[ "$retval" != "0" ]]; then
  log "DockerCE: gave up waiting for network to be created"
  exit 1
fi

log "Creating service"
wait=5
count=12
args="${ssh_args} docker service create --replicas 3 --name nginx --network network --publish 80:80 nginx"
while (( $count > 0 )); do
  log "  ... counting down $count"
  ssh $args
  retval=$?
  if [[ "$retval" == "0" ]]; then break; fi
  sleep $wait
  count=$((count-1))
done
if [[ "$retval" != "0" ]]; then
  log "DockerCE: gave up waiting for service to be created"
  exit 1
fi

sleep 10
log "Testing service"
wait=5
count=12
while (( $count > 0 )); do
  log "  ... counting down $count"
  curl --fail "http://${INSTANCE_NAME}0.${LOCATION}.cloudapp.azure.com:80/"
  retval=$?
  if [[ "$retval" == "0" ]]; then break; fi
  sleep $wait
  count=$((count-1))
done
if [[ "$retval" != "0" ]]; then
  log "DockerCE: gave up waiting for service to be externally reachable"
  exit 1
fi


#!/bin/bash

####################################################

if [ -z "$SERVICE_PRINCIPAL_CLIENT_ID" ]; then
    echo "must provide a SERVICE_PRINCIPAL_CLIENT_ID env var"
    exit 1;
fi

if [ -z "$SERVICE_PRINCIPAL_CLIENT_SECRET" ]; then
    echo "must provide a SERVICE_PRINCIPAL_CLIENT_SECRET env var"
    exit 1;
fi

if [ -z "$TENANT_ID" ]; then
    echo "must provide a TENANT_ID env var"
    exit 1;
fi

if [ -z "$SUBSCRIPTION_ID_TO_CLEANUP" ]; then
    echo "must provide a SUBSCRIPTION_ID_TO_CLEANUP env var"
    exit 1;
fi

if [ -z "$EXPIRATION_IN_HOURS" ]; then
    EXPIRATION_IN_HOURS=2
fi

az login --service-principal \
		--username "${SERVICE_PRINCIPAL_CLIENT_ID}" \
		--password "${SERVICE_PRINCIPAL_CLIENT_SECRET}" \
		--tenant "${TENANT_ID}" &>/dev/null

# set to the sub id we want to cleanup
az account set -s $SUBSCRIPTION_ID_TO_CLEANUP

# convert to seconds so we can compare it against the "tags.now" property in the resource group metadata
(( expirationInSecs = ${EXPIRATION_IN_HOURS} * 60 * 60 ))
# deadline = the "date +%s" representation of the oldest age we're willing to keep
(( deadline=$(date +%s)-${expirationInSecs%.*} ))
# find resource groups created before our deadline
echo "Looking for resource groups created over ${EXPIRATION_IN_HOURS} hours ago..."
for resourceGroup in `az group list | jq --arg dl $deadline '.[] | select(.name | contains("acse-test") | not) | select(.tags.now < $dl).name' | tr -d '\"' || ""`; do
    for deployment in `az group deployment list -g $resourceGroup | jq '.[] | .name' | tr -d '\"' || ""`; do
        echo "Will delete deployment ${deployment} from resource group ${resourceGroup}..."
        az group deployment delete -n $deployment -g $resourceGroup || echo "unable to delete deployment ${deployment}, will continue..."
    done
    echo "Will delete resource group ${resourceGroup}..."
    # delete old resource groups
    az group delete -y -n $resourceGroup --no-wait >> delete.log || echo "unable to delete resource group ${resourceGroup}, will continue..."
done


#!/usr/bin/env bash

source "${HOME}/test/common.sh"

function shunittest_deploy_template {
  set -eux -o pipefail

  export OUTPUT="${HOME}/_output/${INSTANCE_NAME}"

  deploy_template
}


#!/usr/bin/env bash

source "${HOME}/test/common.sh"

function shunittest_generate_template {
  set -eux -o pipefail

  export OUTPUT="${HOME}/_output/${INSTANCE_NAME}"

  generate_template
}


#!/usr/bin/env bash

source "${HOME}/test/common.sh"

function shunittest_scale_agent_pool {
  set -eux -o pipefail

  export OUTPUT="${HOME}/_output/${INSTANCE_NAME}"

  scale_agent_pool
}


#!/usr/bin/env bash

function shunittest_validate_deployment {
  set -eux -o pipefail

  export OUTPUT="${HOME}/_output/${INSTANCE_NAME}"
  export SSH_KEY="${OUTPUT}/id_rsa"
  if [[ "${ORCHESTRATOR}" == "kubernetes" ]]; then
    export KUBECONFIG="${OUTPUT}/kubeconfig/kubeconfig.${LOCATION}.json"
    nodes=$(${HOME}/test/step.sh get_node_count)
    IFS=':' read -a narr <<< "${nodes}"
    export EXPECTED_NODE_COUNT=${narr[0]}
    export EXPECTED_LINUX_AGENTS=${narr[1]}
    export EXPECTED_WINDOWS_AGENTS=${narr[1]}
    export EXPECTED_ORCHESTRATOR_VERSION=$(${HOME}/test/step.sh get_orchestrator_release)
  fi

  script="${HOME}/test/cluster-tests/${ORCHESTRATOR}/test.sh"

  if [ -x "${script}" ]; then
    "${script}"
  else
    echo "${script}: not an executable or no such file"
    exit 1
  fi
}


# <copyright file="DownloadDeployerVMPackages.sh" company="Microsoft Corporation">
# Copyright (c) Microsoft Corporation. All rights reserved.
# </copyright>

#!/bin/bash

#Exit when any command fails
set -e

#download packages locally

workloadWorkdir=DeployerVMPackages

if [[ ! -d "$workloadWorkdir" ]]; then
        mkdir $workloadWorkdir
fi

if [[ ! -d "$workloadWorkdir/packages" ]]; then
        mkdir $workloadWorkdir/packages
fi

#download python3-pip
cd $workloadWorkdir/packages

if [[ ! -f "pip-21.3.1.tar.gz" ]]; then
        wget -nv -q https://files.pythonhosted.org/packages/da/f6/c83229dcc3635cdeb51874184241a9508ada15d8baa337a41093fab58011/pip-21.3.1.tar.gz
        tar -xvf pip-21.3.1.tar.gz
fi

cd pip-21.3.1/

#Check if pip3 is already installed
if [[ -z $(which pip3) ]]; then
        #Install pip
        echo "Installing pip3."
        sudo python3 setup.py install
fi

cd ../../..
#download wheel
pip3 download -d $workloadWorkdir/packages wheel==0.37.1

#download netaddr
pip3 download -d $workloadWorkdir/packages netaddr==0.8.0

#download jq 1.6
if [[ ! -d "$workloadWorkdir/jq_pkg" ]]; then
        mkdir $workloadWorkdir/jq_pkg
fi

cd $workloadWorkdir/jq_pkg
wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x jq

cd -
#download ansible
if [[ ! -d "$workloadWorkdir/ansible_pkg" ]]; then
        mkdir $workloadWorkdir/ansible_pkg
fi
pip3 download -d $workloadWorkdir/ansible_pkg "ansible==2.9.27"

#download azure cli libraries
if [[ ! -d "$workloadWorkdir/azure_cli_pkg" ]]; then
        mkdir $workloadWorkdir/azure_cli_pkg
fi

cd $workloadWorkdir/azure_cli_pkg
wget -nv -q https://raw.githubusercontent.com/Azure/azure-cli/azure-cli-2.30.0/src/azure-cli/requirements.py3.Linux.txt

cd -
if [[ ! -d "$workloadWorkdir/azure_cli_pkg/azure_cli_requirements" ]]; then
        mkdir $workloadWorkdir/azure_cli_pkg/azure_cli_requirements
fi

pip3 download -r $workloadWorkdir/azure_cli_pkg/requirements.py3.Linux.txt -d $workloadWorkdir/azure_cli_pkg/azure_cli_requirements

#Check if zip is already installed
if [[ -z $(which zip) ]]; then
        echo "Installing zip package."
        #Install zip
        sudo apt-get --assume-yes install zip
fi

zip -r $workloadWorkdir.zip $workloadWorkdir

#Check if user have an existing storage account
echo "Do you have an existing storage account?"
echo -n "y/n: "
read -r userInput

if [[ ${userInput^^} == "Y" ]]; then
        #sapbits_location_base_path
        echo "Enter the SAP storage account base path(sapbits-location-base-path) url copied from storage container properties. This is the storage container where SAP installation bits and deployer vm packages are stored/will be stored."
        read -r sapbits_location_base_path

        #check if customer entered an empty string
        while [ -z $sapbits_location_base_path ]
        do
            echo "Empty sapbits-location-base-path given, please re-enter the SAP storage account base path(sapbits-location-base-path) url else press 'Ctrl+C' or type 'exit' to end the process."
            read -r sapbits_location_base_path

            if [[ ${sapbits_location_base_path^^} == "EXIT" ]]; then
                    exit 1
            fi
        done
        IFS='//'
        read -ra arr <<< $sapbits_location_base_path
        container=${arr[3]}

        IFS='.'
        read -ra arr <<< ${arr[2]}
        storageAccountName=${arr[0]}

        #Fetch container name
        IFS='"'
        read -ra arr <<< $container
        containerName=${arr[0]}
else
        #Storage account name
        echo "Enter the new storage account name you want to create."
        read -r storageAccountName
        while [ -z $storageAccountName ]
        do
            echo "Empty storage account name given, please re-enter the storage account name else press 'Ctrl+C' or type 'exit' to end the process."
            read -r storageAccountName

            if [[ ${storageAccountName^^} == "EXIT" ]]; then
                    exit 2
            fi
        done

        #Check subscription
        subscription=$(az account show --query name)
        echo "Current subscription is $subscription, do you want to change the subscription? This is the subscription where storage account will be created."
        echo -n "y/n: "
        read -r userInput

        if [[ ${userInput^^} == "Y" ]]; then
                echo "Enter the new subscription name or id. (Use az account list to get a list of subscriptions for the logged in account)."
                read -r subscription
                az account set --subscription "$subscription"
        fi

        echo "Do you want to use an existing resource group? This is the resource group where storage account will be created."
        echo -n "y/n: "
        read -r userInput
        if [[ ${userInput^^} == "Y" ]]; then
                echo "Enter the resource group name."
                read -r resourceGroupName
                while [ -z $resourceGroupName ]
                do
                    echo "Empty resource group name given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupName

                    if [[ ${resourceGroupName^^} == "EXIT" ]]; then
                            exit 3
                    fi
                done
        else
                echo "Enter the new resource group name to create a new resource group."
                read -r resourceGroupName
                while [ -z $resourceGroupName ]
                do
                    echo "Empty resource group name given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupName

                    if [[ ${resourceGroupName^^} == "EXIT" ]]; then
                            exit 4
                    fi
                done

                echo "Enter the location where you want to create resource group."
                read -r resourceGroupLocation
                while [ -z $resourceGroupLocation ]
                do
                    echo "Empty resource group locaion given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupLocation

                    if [[ ${resourceGroupLocation^^} == "EXIT" ]]; then
                            exit 5
                    fi
                done
                az group create --location $resourceGroupLocation --name $resourceGroupName
        fi

        echo "Creating storage account $storageAccountName in resource group $resourceGroupName and subscription $subscription"
        az storage account create --name $storageAccountName --resource-group $resourceGroupName

        #Container name
        echo "Enter the new container name you want to create."
        read -r containerName
        while [ -z $containerName ]
        do
            echo "Empty container name given, please re-enter the container name else press 'Ctrl+C' or type 'exit' to end the process."
            read -r containerName

            if [[ ${containerName^^} == "EXIT" ]]; then
                    exit 6
            fi
        done

        echo "Create container $containerName in storage account $storageAccountName"
        az storage container create --name $containerName --account-name $storageAccountName
fi

#sapbits-access-key
echo "Enter the sapbits-access-key copied from storage account 'Access keys'."
read -r sapbits_access_key

#Repeat while loop until customer enters a non empty sapbits-access-key
while [ -z $sapbits_access_key ]
do
    read -r sapbits_access_key
    echo "No sapbits-access-key detected, please re-enter the sapbits-access-key else press 'Ctrl+C' or type 'exit' to end the process."

    if [[ ${sapbits_access_key^^} == "EXIT" ]]; then
            exit 7
    fi
done

echo "Storage account name where deployer vm packages are stored/will be stored: $storageAccountName."
echo "Container name where deployer vm packages are stored/will be stored: $containerName/deployervmpackages."

isBlobExists=$(az storage blob exists --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --query exists)

if [[ $isBlobExists == "false" ]]; then
        #upload to storage account
        az storage blob upload --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --file $workloadWorkdir.zip --if-none-match "*" --no-progress
else
        echo "Existing blob $workloadWorkdir.zip found in storage account, do you want to update the blob?"
        echo -n "y/n: "
        read -r userInput

        if [[ ${userInput^^} == "Y" ]]; then
                #delete existing blob
                az storage blob delete --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip
                az storage blob upload --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --file $workloadWorkdir.zip --if-none-match "*" --no-progress
        fi
fi


# <copyright file="DownloadDeployerVMPackages.sh" company="Microsoft Corporation">
# Copyright (c) Microsoft Corporation. All rights reserved.
# </copyright>

#!/bin/bash

#Exit when any command fails
set -e

#download packages locally

workloadWorkdir=DeployerVMPackages

if [[ ! -d "$workloadWorkdir" ]]; then
        mkdir $workloadWorkdir
fi

if [[ ! -d "$workloadWorkdir/packages" ]]; then
        mkdir $workloadWorkdir/packages
fi

#download python3-pip
cd $workloadWorkdir/packages

if [[ ! -f "pip-21.3.1.tar.gz" ]]; then
        wget -nv -q https://files.pythonhosted.org/packages/da/f6/c83229dcc3635cdeb51874184241a9508ada15d8baa337a41093fab58011/pip-21.3.1.tar.gz
        tar -xvf pip-21.3.1.tar.gz
fi

cd pip-21.3.1/

#Check if pip3 is already installed
if [[ -z $(which pip3) ]]; then
        #Install pip
        echo "Installing pip3."
        sudo python3 setup.py install
fi

cd ../../..
#download wheel
pip3 download -d $workloadWorkdir/packages wheel==0.37.1

#download jq 1.6
if [[ ! -d "$workloadWorkdir/jq_pkg" ]]; then
        mkdir $workloadWorkdir/jq_pkg
fi

cd $workloadWorkdir/jq_pkg
wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64
chmod +x jq

cd -
#download ansible
if [[ ! -d "$workloadWorkdir/ansible_pkg" ]]; then
        mkdir $workloadWorkdir/ansible_pkg
fi
pip3 download -d $workloadWorkdir/ansible_pkg "ansible==2.9.27"

#download azure cli libraries
if [[ ! -d "$workloadWorkdir/azure_cli_pkg" ]]; then
        mkdir $workloadWorkdir/azure_cli_pkg
fi

cd $workloadWorkdir/azure_cli_pkg
wget -nv -q https://raw.githubusercontent.com/Azure/azure-cli/azure-cli-2.30.0/src/azure-cli/requirements.py3.Linux.txt

cd -
if [[ ! -d "$workloadWorkdir/azure_cli_pkg/azure_cli_requirements" ]]; then
        mkdir $workloadWorkdir/azure_cli_pkg/azure_cli_requirements
fi

pip3 download -r $workloadWorkdir/azure_cli_pkg/requirements.py3.Linux.txt -d $workloadWorkdir/azure_cli_pkg/azure_cli_requirements

#Check if zip is already installed
if [[ -z $(which zip) ]]; then
        echo "Installing zip package."
        #Install zip
        sudo apt-get --assume-yes install zip
fi

zip -r $workloadWorkdir.zip $workloadWorkdir

#Check if user have an existing storage account
echo "Do you have an existing storage account?"
echo -n "y/n: "
read -r userInput

if [[ ${userInput^^} == "Y" ]]; then
        #sapbits_location_base_path
        echo "Enter the SAP storage account base path(sapbits-location-base-path) url copied from storage container properties. This is the storage container where SAP installation bits and deployer vm packages are stored/will be stored."
        read -r sapbits_location_base_path

        #check if customer entered an empty string
        while [ -z $sapbits_location_base_path ]
        do
            echo "Empty sapbits-location-base-path given, please re-enter the SAP storage account base path(sapbits-location-base-path) url else press 'Ctrl+C' or type 'exit' to end the process."
            read -r sapbits_location_base_path

            if [[ ${sapbits_location_base_path^^} == "EXIT" ]]; then
                    exit 1
            fi
        done
        IFS='//'
        read -ra arr <<< $sapbits_location_base_path
        container=${arr[3]}

        IFS='.'
        read -ra arr <<< ${arr[2]}
        storageAccountName=${arr[0]}

        #Fetch container name
        IFS='"'
        read -ra arr <<< $container
        containerName=${arr[0]}
else
        #Storage account name
        echo "Enter the new storage account name you want to create."
        read -r storageAccountName
        while [ -z $storageAccountName ]
        do
            echo "Empty storage account name given, please re-enter the storage account name else press 'Ctrl+C' or type 'exit' to end the process."
            read -r storageAccountName

            if [[ ${storageAccountName^^} == "EXIT" ]]; then
                    exit 2
            fi
        done

        #Check subscription
        subscription=$(az account show --query name)
        echo "Current subscription is $subscription, do you want to change the subscription? This is the subscription where storage account will be created."
        echo -n "y/n: "
        read -r userInput

        if [[ ${userInput^^} == "Y" ]]; then
                echo "Enter the new subscription name or id. (Use az account list to get a list of subscriptions for the logged in account)."
                read -r subscription
                az account set --subscription "$subscription"
        fi

        echo "Do you want to use an existing resource group? This is the resource group where storage account will be created."
        echo -n "y/n: "
        read -r userInput
        if [[ ${userInput^^} == "Y" ]]; then
                echo "Enter the resource group name."
                read -r resourceGroupName
                while [ -z $resourceGroupName ]
                do
                    echo "Empty resource group name given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupName

                    if [[ ${resourceGroupName^^} == "EXIT" ]]; then
                            exit 3
                    fi
                done
        else
                echo "Enter the new resource group name to create a new resource group."
                read -r resourceGroupName
                while [ -z $resourceGroupName ]
                do
                    echo "Empty resource group name given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupName

                    if [[ ${resourceGroupName^^} == "EXIT" ]]; then
                            exit 4
                    fi
                done

                echo "Enter the location where you want to create resource group."
                read -r resourceGroupLocation
                while [ -z $resourceGroupLocation ]
                do
                    echo "Empty resource group locaion given, please re-enter the resource group name else press 'Ctrl+C' or type 'exit' to end the process."
                    read -r resourceGroupLocation

                    if [[ ${resourceGroupLocation^^} == "EXIT" ]]; then
                            exit 5
                    fi
                done
                az group create --location $resourceGroupLocation --name $resourceGroupName
        fi

        echo "Creating storage account $storageAccountName in resource group $resourceGroupName and subscription $subscription"
        az storage account create --name $storageAccountName --resource-group $resourceGroupName

        #Container name
        echo "Enter the new container name you want to create."
        read -r containerName
        while [ -z $containerName ]
        do
            echo "Empty container name given, please re-enter the container name else press 'Ctrl+C' or type 'exit' to end the process."
            read -r containerName

            if [[ ${containerName^^} == "EXIT" ]]; then
                    exit 6
            fi
        done

        echo "Create container $containerName in storage account $storageAccountName"
        az storage container create --name $containerName --account-name $storageAccountName
fi

#sapbits-access-key
echo "Enter the sapbits-access-key copied from storage account 'Access keys'."
read -r sapbits_access_key

#Repeat while loop until customer enters a non empty sapbits-access-key
while [ -z $sapbits_access_key ]
do
    read -r sapbits_access_key
    echo "No sapbits-access-key detected, please re-enter the sapbits-access-key else press 'Ctrl+C' or type 'exit' to end the process."

    if [[ ${sapbits_access_key^^} == "EXIT" ]]; then
            exit 7
    fi
done

echo "Storage account name where deployer vm packages are stored/will be stored: $storageAccountName."
echo "Container name where deployer vm packages are stored/will be stored: $containerName/deployervmpackages."

isBlobExists=$(az storage blob exists --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --query exists)

if [[ $isBlobExists == "false" ]]; then
        #upload to storage account
        az storage blob upload --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --file $workloadWorkdir.zip --if-none-match "*" --no-progress
else
        echo "Existing blob $workloadWorkdir.zip found in storage account, do you want to update the blob?"
        echo -n "y/n: "
        read -r userInput

        if [[ ${userInput^^} == "Y" ]]; then
                #delete existing blob
                az storage blob delete --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip
                az storage blob upload --account-name $storageAccountName --account-key "$sapbits_access_key" --container-name $containerName/deployervmpackages --name $workloadWorkdir.zip --file $workloadWorkdir.zip --if-none-match "*" --no-progress
        fi
fi


# Add RServer libraries to the R session config, but only after all libs are installed
# sudo echo "r-libs-user=/data/mlserver/9.2.1/libraries/RServer" >>/etc/rstudio/rsession.conf

# Enable the RStudio Server service
sudo systemctl enable rstudio-server

# Start the RStudio Server service
sudo systemctl start rstudio-server

sudo mkdir /data/active-learning-data

# take ownership of /data/active-learning-data
sudo chown -R remoteuser:remoteuser /data/active-learning-data

# create conda environment
cd text_featurization/lm_finetune
/anaconda/bin/conda env create -f conda.yml
source /anaconda/bin/activate py35
pip install ipykernel
sudo /anaconda/envs/embeddings/bin/python -m ipykernel install --name embeddings --display-name "embeddings"


#!/bin/bash

if [ -z $TRAVIS_TAG ]; then
    echo "Skip publishing since it is not a build triggered by a tag." >&2
    exit 0
fi

cd dist
wheel_file=`ls adx_automation_cli-*-py3-none-any.whl`

version=${wheel_file/adx_automation_cli-/}
version=${version/-py3-none-any.whl/}
echo $version

az storage blob upload -c client -f $wheel_file -n archive/$wheel_file --validate-content --no-progress
az storage blob url -c client -n archive/$wheel_file -otsv | tee ./blob_path
az storage blob upload -c client -f ./blob_path -n latest --validate-content --no-progress