# Set Vars for env check
RHO_PROVIDER=$(az provider show --namespace Microsoft.RedHatOpenShift --query "[registrationState]" --output tsv)
COMP_PROVIDER=$(az provider show --namespace Microsoft.Compute --query "[registrationState]" --output tsv)
STOR_PROVIDER=$(az provider show --namespace Microsoft.Storage --query "[registrationState]" --output tsv)
AUTH_PROVIDER=$(az provider show --namespace Microsoft.Authorization --query "[registrationState]" --output tsv)

#Check if the resource Providers are Installed
if [ "$RHO_PROVIDER" != "Registered" ]; then
    echo "RedHat OpenShift Provider Is Not Installed"
    az provider register --namespace Microsoft.RedHatOpenShift --wait
    echo "RedHat OpenShift Provider has been Installed"
    else
    echo "RedHat Openshift Provider was already installed"
fi
if [ "$COMP_PROVIDER" != "Registered" ]; then
    echo "Microsoft Compute Provider Is Not Installed"
    az provider register --namespace Microsoft.Compute --wait
    echo "Microsoft Compute Provider has been Installed"
    else
    echo "Microsoft Compute Provider was already installed"
fi
if [ "$STOR_PROVIDER" != "Registered" ]; then
    echo "Microsoft Storage Provider Is Not Installed"
    az provider register --namespace Microsoft.Storage --wait
    echo "Microsoft Storage Provider has been Installed"
    else
    echo "Microsoft Storage Provider was already installed"
fi
if [ "$AUTH_PROVIDER" != "Registered" ]; then
    echo "Microsoft Authentication Provider Is Not Installed"
    az provider register --namespace Microsoft.Authorization --wait
    echo "Microsoft Authorization Provider has been Installed"
    else
    echo "Microsoft Authorization Provider was already installed"
fi

# Prompt user for an Service Principal Name and Subscription ID
echo "Enter the Name of the Service Principal for ARO to use:"
read -r SPNNAME
#echo "Enter the Subscription ID where you want ARO deployed:"
#read -r SUBSCRIPTIONID
SUB_ID=$(az account show | jq -r ".id")

# Create the Service Principal
# TODO: Add check to see if the SPN already exists
az ad sp create-for-rbac --name $SPNNAME --scopes /subscriptions/$SUB_ID --role Contributor --output json > /tmp/sp.json

# Set variables from the Service Principal
SP_CLIENT_ID=$(jq -r '.appId' /tmp/sp.json)
SP_CLIENT_SECRET=$(jq -r '.password' /tmp/sp.json)
SP_OBJECT_ID=$(az ad sp show --id $SP_CLIENT_ID | jq -r '.id')

# Set variable for ARO Provider SP Object ID
ARO_SP_OBJECT_ID=$(az ad sp list --display-name "Azure Red Hat OpenShift RP" --query "[0].id" -o tsv)

#get the value for the pull secret
RHPS=$(cat pullsecret.txt)

echo "The ARO RP SP Object ID is:" $ARO_SP_OBJECT_ID
echo "The APPSP client ID is:" $SP_CLIENT_ID
echo "The APPSP object ID is:" $SP_OBJECT_ID
echo "The APPSP password is:" $SP_CLIENT_SECRET
echo "The redhat pull secret is:" $RHPS
echo "  "
echo "MAKE SURE TO NOTE THESE NOW AS THE APPSP PASSWORD CAN NEVER BE RETRIEVED AGAIN!!!!"
echo "Now would be a good time to check / update your paramaters files with these"
echo " values before continuing this deployment."
echo "  "
echo "press return if ready to proceed.... press CTRL-C to cancel...."
read -r ready

#Deploy the hub Vnet/routes/etc
az deployment sub create -n "LZ-HUB-ARO" -l "eastus" \
-f 01-Network-Hub/main.bicep \
-p 01-Network-Hub/parameters-main.json

#deploy the bastion VM
az deployment sub create -n "LZ-HUB-ARO-VM" -l "eastus" \
-f 01-Network-Hub/deploy-vm.bicep \
-p 01-Network-Hub/parameters-deploy-vm.json

#Update the HUB UDR
az deployment sub create -n "LZ-HUB-ARO-UDR" -l "eastus" \
-f 01-Network-Hub/updateUDR.bicep \
-p 01-Network-Hub/parameters-updateUDR.json

#Deploy the Spoke Vnet/routes/etc
az deployment sub create -n "LZ-SPOKE-ARO" -l "eastus" \
-f 02-Network-Spoke/main.bicep \
-p 02-Network-Spoke/parameters-main.json

#sleep and wait for completion, else route update below will fail
sleep 300

#Update the Spoke Route Table

az deployment sub create -n "LZ-SPOKE-ARO-updateUDR" -l "eastus" \
-f 02-Network-Spoke/updateUDR.bicep \
-p 02-Network-Spoke/parameters-updateUDR.json

#Deploy the supporting services
az deployment sub create -n "LZ-SUPPORTING-ARO" -l "eastus" \
-f 03-Supporting/main.bicep \
-p 03-Supporting/parameters-main.json

#Deploy the ARO cluster
az deployment group create -n "LZ-ARO" -g "spoke-aro" \
-f 04-ARO/arocluster.bicep \
-p aadClientId=${SP_CLIENT_ID} \
-p rpObjectId=${ARO_SP_OBJECT_ID} \
-p aadObjectId=${SP_OBJECT_ID} \
-p aadClientSecret=${SP_CLIENT_SECRET} \
-p rhps=${RHPS} \
-p 04-ARO/params.json


#!/bin/bash
#############################
# Script Definition
#############################
logpath=/var/log/deploymentscriptlog

#TODO: update this script for RHEL usage

#############################
# Upgrading Linux Distribution
#############################
echo "#############################" >> $logpath
echo "Upgrading Linux Distribution" >> $logpath
echo "#############################" >> $logpath
sudo apt-get update >> $logpath
sudo apt-get -y upgrade >> $logpath
echo " " >> $logpath

#############################
#Install Azure CLI
#############################
echo "#############################" >> $logpath
echo "Installing Azure CLI" >> $logpath
echo "#############################" >> $logpath
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

#############################
#Install Docker
#############################
echo "#############################" >> $logpath
echo "Installing Docker" >> $logpath
echo "#############################" >> $logpath
wget -qO- https://get.docker.com/ | sh >> $logpath
sudo usermod -aG docker $1
echo " " >> $logpath

#############################
#Install Kubectl
#############################
echo "#############################" >> $logpath
echo "Installing Kubectl" >> $logpath
echo "#############################" >> $logpath
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl

#############################
#Install Helm
#############################
echo "#############################" >> $logpath
echo "Installing Helm" >> $logpath
echo "#############################" >> $logpath
curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
sudo apt-get install apt-transport-https --yes
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm


#!/bin/bash -e

function clean() {
  local API_VERSION=$1
  local FOLDER=$2

  rm -rf pkg/client/services/redhatopenshift/mgmt/"$API_VERSION"
  mkdir pkg/client/services/redhatopenshift/mgmt/"$API_VERSION"

  rm -rf python/client/azure/mgmt/redhatopenshift/v"${API_VERSION//-/_}"
  mkdir -p python/client/azure/mgmt/redhatopenshift/v"${API_VERSION//-/_}"
}

function checksum() {
  local API_VERSION=$1
  local FOLDER=$2

  sha256sum swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/"$FOLDER"/"$API_VERSION"/redhatopenshift.json >> .sha256sum
}

function generate_golang() {
  local AUTOREST_IMAGE=$1
  local API_VERSION=$2
  local FOLDER=$3

  # Generating Track 1 Golang SDK
  # Needs work to migrate to Track 2
  docker run \
    --platform=linux/amd64 \
    --rm \
    -v $PWD/pkg/client:/github.com/Azure/ARO-RP/pkg/client:z \
    -v $PWD/swagger:/swagger:z \
    "${AUTOREST_IMAGE}" \
    --go \
    --use=@microsoft.azure/autorest.go@~2.1.187 \
    --use=@microsoft.azure/autorest.modeler@~2.3.38 \
    --version=~2.0.4421 \
    --license-header=MICROSOFT_APACHE_NO_VERSION \
    --namespace=redhatopenshift \
    --input-file=/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/"$FOLDER"/"$API_VERSION"/redhatopenshift.json \
    --output-folder=/github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/"$API_VERSION"/redhatopenshift

  docker run \
    --platform=linux/amd64 \
    --rm \
    -v $PWD/pkg/client:/github.com/Azure/ARO-RP/pkg/client:z \
    --entrypoint sed \
    "${AUTOREST_IMAGE}" \
    --in-place \
    --expression='s|azure/aro-rp|Azure/ARO-RP|g' \
    "/github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/${API_VERSION}/redhatopenshift/models.go" \
    "/github.com/Azure/ARO-RP/pkg/client/services/redhatopenshift/mgmt/${API_VERSION}/redhatopenshift/redhatopenshiftapi/interfaces.go"

  go run ./vendor/golang.org/x/tools/cmd/goimports -w -local=github.com/Azure/ARO-RP pkg/client
}

function generate_python() {
  local AUTOREST_IMAGE=$1
  local API_VERSION=$2
  local FOLDER=$3

  # Generating Track 2 Python SDK
  docker run \
    --platform=linux/amd64 \
    --rm \
    -v $PWD/python/client:/python/client:z \
    -v $PWD/swagger:/swagger:z \
    "${AUTOREST_IMAGE}" \
    --use=@autorest/python@~5.12.0 \
    --use=@autorest/modelerfour@~4.20.0 \
    --version=~3.6.2 \
    --python \
    --azure-arm \
    --license-header=MICROSOFT_APACHE_NO_VERSION \
    --namespace=azure.mgmt.redhatopenshift.v"${API_VERSION//-/_}" \
    --input-file=/swagger/redhatopenshift/resource-manager/Microsoft.RedHatOpenShift/"$FOLDER"/"$API_VERSION"/redhatopenshift.json \
    --output-folder=/python/client

  rm -rf python/client/azure/mgmt/redhatopenshift/v"${API_VERSION//-/_}"/aio
  >python/client/__init__.py
}

if [ -f .sha256sum ]; then
  rm .sha256sum
fi

AUTOREST_IMAGE=$1

for API_VERSION in "${@: 2}"
do
  FOLDER=stable
  if [[ "$API_VERSION" =~ .*preview ]]; then
    FOLDER=preview
  fi

  printf "\nGENERATING API v$API_VERSION\n"
  printf "%*s\n" "${COLUMNS:-$(tput cols)}" "" | tr " " -

  printf "CLEANING OLD API GENERATED FILES...\n"
  clean "$API_VERSION" "$FOLDER"
  printf "[\u2714] SUCCESS\n\n"

  printf "GENERATING CHECKSUM...\n"
  checksum "$API_VERSION" "$FOLDER"
  printf "[\u2714] SUCCESS\n\n"

  printf "GENERATING GOLANG SDK...\n"
  generate_golang "$AUTOREST_IMAGE" "$API_VERSION" "$FOLDER"
  printf "[\u2714] SUCCESS\n\n"

  printf "GENERATING PYTHON SDK...\n"
  generate_python "$AUTOREST_IMAGE" "$API_VERSION" "$FOLDER"
  printf "[\u2714] SUCCESS\n\n"
  printf "%*s\n" "${COLUMNS:-$(tput cols)}" "" | tr " " -
  printf "\n"
done

printf "[\u2714] CLIENT GENERATION COMPLETED SUCCESSFULLY\n"


#!/bin/bash

if [ -z "$RESOURCEGROUP" ]; then
    echo "the environment variable RESOURCEGROUP is required" >&2
    exit 1
fi

[ -f aks.kubeconfig ] && rm -f aks.kubeconfig

if az aks get-credentials --admin -g "$RESOURCEGROUP" -n aro-aks-cluster-001 --public-fqdn -f aks.kubeconfig 2>/dev/null; then
    chmod 600 aks.kubeconfig
else
    echo "Error generating AKS kubeconfig"
    exit 1
fi


#!/bin/bash

if [[ "$#" -ne 1 ]]; then
    echo "usage: $0 resourceid" >&2
    exit 1
fi

if [[ $CI ]]; then
    ./db "$1" | jq -r .openShiftCluster.properties.adminKubeconfig | base64 -d | sed -e 's|https://api-int\.|https://api\.|'
else
    go run ./hack/db "$1" | jq -r .openShiftCluster.properties.adminKubeconfig | base64 -d | sed -e 's|https://api-int\.|https://api\.|'
fi


#!/bin/bash

HIVE_OPERATOR_NS="hive"
KUBECTL=$( which kubectl 2> /dev/null || which oc 2> /dev/null)

function cleanup {
	[ -f "$(pwd)/kubectl" ] && rm -f "$(pwd)/kubectl"
}

function download_tmp_kubectl {
	curl -sLO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
	if [ $? -ne 0 ]; then
		echo ": error downloading kubectl"
		exit 1
	fi
	chmod 755 kubectl
	KUBECTL="$(pwd)/kubectl"
}

function verify_tools {
	if [ ! -z "$KUBECTL" ]; then
		return
	fi
	echo -n "kubectl or oc not detected, downloading"
	download_tmp_kubectl
	echo ", done."

	if [ $( $KUBECTL get nodes 2>/dev/null | wc -l ) -eq 0 ]; then
		echo "unable to connect to the cluster"
		exit 1
	fi
}

set -e
trap cleanup EXIT

if [ ! -f go.mod ] || [ ! -d ".git" ]; then
	echo "this script must by run from the repo's root directory"
	exit 1
fi

if [ ! -f "./hack/hive-config/hive-deployment.yaml" ] || [ ! -d "./hack/hive-config/crds" ] ; then
	echo "hive config is missing, generating config, please rerun this script afterwards"
	./hack/hive-generate-config.sh
	if [ $? -ne 0 ]; then
		echo "error generating the hive configs"
		exit 1
	fi
fi

if [ -z "$PULL_SECRET" ]; then
	echo "global pull secret variable required, please source ./env"
	exit
fi

verify_tools

if [ $( $KUBECTL get namespace $HIVE_OPERATOR_NS -o yaml 2>/dev/null | wc -l ) -ne 0 ]; then
	echo "hive is already installed in the namespace"
	echo -n "would you like to reapply the configs? (y/N): "
	read answer
	if [[ "$answer" != "y" ]]; then
		exit
	fi
else
	$KUBECTL create namespace $HIVE_OPERATOR_NS
fi

$KUBECTL apply -f ./hack/hive-config/crds
$KUBECTL apply -f ./hack/hive-config/hive-deployment.yaml

echo "$PULL_SECRET" > /tmp/.tmp-secret
# Using dry-run allows updates to work seamlessly
$KUBECTL create secret generic hive-global-pull-secret --from-file=.dockerconfigjson=/tmp/.tmp-secret --type=kubernetes.io/dockerconfigjson --namespace $HIVE_OPERATOR_NS -o yaml --dry-run=client | $KUBECTL apply -f - 2>/dev/null
rm -f /tmp/.tmp-secret

sed "s/HIVE_OPERATOR_NS/$HIVE_OPERATOR_NS/g" hack/hive-config/hive-config.yaml | $KUBECTL apply -f -

echo -e "\nHive is installed."


#!/bin/bash

# This is the commit sha that the image was built from and ensures we use the correct configs for the release
HIVE_IMAGE_COMMIT_HASH="fec14dc"

# For now we'll use the quay hive image, but this will change to an ACR once the quay.io -> ACR mirroring is setup
# Note: semi-scientific way to get the latest image: `podman search --list-tags --limit 10000 quay.io/app-sre/hive | tail -n1`
HIVE_IMAGE="quay.io/app-sre/hive:${HIVE_IMAGE_COMMIT_HASH}"

HIVE_OPERATOR_NS="hive"

# This version is specified in the hive repo and is the only hard dependency for this script
# https://github.com/openshift/hive/blob/master/vendor/github.com/openshift/build-machinery-go/make/targets/openshift/kustomize.mk#L7
KUSTOMIZE_VERSION=4.1.3
KUSTOMIZE=$( which kustomize 2>/dev/null )
TMPDIR=$( mktemp -d )

function cleanup {
	popd >& /dev/null
	[ -d "$TMPDIR" ] && rm -fr "$TMPDIR"
}

function verify_kustomize {
	if [ ! -z "$KUSTOMIZE" ]; then
		return
	fi
	echo -n "kustomize not detected, downloading "
	curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/kustomize/v${KUSTOMIZE_VERSION}/hack/install_kustomize.sh" | bash -s "$KUSTOMIZE_VERSION" "$TMPDIR"
	if [ $? -ne 0 ]; then
		echo "error downloading kustomize"
		exit 1
	fi
	KUSTOMIZE="${TMPDIR}/kustomize"
}

function hive_repo_clone {
	echo -n "Cloning hive repo into tmp for config generation"
	CLONE_ERROR=$(git clone https://github.com/openshift/hive.git "$TMPDIR" 2>/dev/null )
	if [ $? -ne 0 ]; then
		echo ": error cloning the hive repo: ${CLONE_ERROR}"
		exit 1
	fi
	echo ", done."
}

function hive_repo_hash_checkout {
	# go into $TMPDIR and checkout the commit the image was built with
	pushd $TMPDIR >& /dev/null
	git reset --hard $HIVE_IMAGE_COMMIT_HASH
	if [ $? -ne 0 ] || [[ $( git rev-parse --short=${#HIVE_IMAGE_COMMIT_HASH} HEAD ) != ${HIVE_IMAGE_COMMIT_HASH} ]]; then
		echo "error resetting the hive repo to the correct git hash '${HIVE_IMAGE_COMMIT_HASH}'"
		exit 1
	fi
}

function generate_hive_config {
	# Create the hive operator install config using kustomize
	mkdir -p overlays/deploy
	cp overlays/template/kustomization.yaml overlays/deploy
	pushd overlays/deploy >& /dev/null
	$KUSTOMIZE edit set image registry.ci.openshift.org/openshift/hive-v4.0:hive=$HIVE_IMAGE
	$KUSTOMIZE edit set namespace $HIVE_OPERATOR_NS
	popd >& /dev/null

	$KUSTOMIZE build overlays/deploy > hive-deployment.yaml

	# return to the repo directory to copy the generated config from $TMPDIR
	popd >& /dev/null
	mv "$TMPDIR/hive-deployment.yaml" ./hack/hive-config/

	if [ -d ./hack/hive-config/crds ]; then
		rm -fr ./hack/hive-config/crds
	fi
	cp -R "$TMPDIR/config/crds" ./hack/hive-config/
}

set -e
trap cleanup EXIT

if [ ! -f go.mod ] || [ ! -d ".git" ]; then
	echo "this script must by run from the repo's root directory"
	exit 1
fi
if [[ ! "$TMPDIR" || ! -d "$TMPDIR" ]]; then
	echo "could not create temp working dir"
	exit 1
fi

hive_repo_clone
hive_repo_hash_checkout
verify_kustomize
generate_hive_config

echo -e "\nHive config generated."


#!/bin/bash -e

# lint-go.sh is used to run Go linting. This shell script is invoked by the Makefile.
# It is not used in our pipelines as we have a github action that does the Go linting, so this script
# is intended to be used locally when developing.

# What does this script?
# It will try to execute the golangci-lint binary to check if there are any linter errors.
# In case the binary that is trying to execute does not exist,
# the script will print a message with instructions to download the binary and will exit with a non-zero exit code.

if ! command -v golangci-lint &> /dev/null
then
    echo "ERROR: golangci-lint could not be found, Go linting aborted. To install it visit https://golangci-lint.run/usage/install/#local-installation"
    exit 1
else
    golangci-lint run
fi


#!/bin/bash

# shared-cluster.sh is used to provide a repeatable production cluster create script

LOCATION="westcentralus"
CLUSTER="shared-cluster"
RESOURCEGROUP="shared-cluster"
CLUSTERRESOURCEGROUP="aro-shared-cluster"

usage() {
	echo -e "usage: ${0} <create|delete>"
	exit 1
}

if [ "$#" -ne 1 ]; then
	usage

elif [[ $1 == create ]]; then
    echo "creating resource group and network"
    az group create --name $RESOURCEGROUP --location $LOCATION

    az network vnet create \
      --resource-group $RESOURCEGROUP \
      --name aro-vnet \
      --address-prefixes 10.0.0.0/22

    az network vnet subnet create \
      --resource-group $RESOURCEGROUP \
      --vnet-name aro-vnet \
      --name master-subnet \
      --address-prefixes 10.0.0.0/23 \
      --service-endpoints Microsoft.ContainerRegistry

    az network vnet subnet create \
      --resource-group $RESOURCEGROUP \
      --vnet-name aro-vnet \
      --name worker-subnet \
      --address-prefixes 10.0.2.0/23 \
      --service-endpoints Microsoft.ContainerRegistry

    az network vnet subnet update \
      --name master-subnet \
      --resource-group $RESOURCEGROUP \
      --vnet-name aro-vnet \
      --disable-private-link-service-network-policies true
    echo "resource group and vnet/subnets created..."

    echo "creating cluster..."
    az aro create \
      --resource-group $RESOURCEGROUP \
      --cluster-resource-group $CLUSTERRESOURCEGROUP \
      --name $CLUSTER \
      --vnet aro-vnet \
      --master-subnet master-subnet \
      --worker-subnet worker-subnet

elif [[ $1 == "delete" ]]; then
  az aro delete --name $CLUSTER -g $RESOURCEGROUP --yes
  az network vnet delete --name aro-vnet -g $RESOURCEGROUP
  az group delete --resource-group $RESOURCEGROUP --yes

else
  usage
fi


#!/bin/bash -e

# ssh-agent.sh is intended to behave very similarly to ssh: specify the master or
# worker hostname that you want to connect to, along with any other ssh options
# you want to pass in

usage() {
    echo "usage: CLUSTER=cluster $0 hostname_pattern" >&2
    echo "       Examples: CLUSTER=cluster $0 master1" >&2
    echo "                 CLUSTER=cluster $0 eastus1 # worker node 1" >&2
    echo "                 CLUSTER=cluster $0 bootstrap" >&2
    exit 1
}

if [[ "$#" -ne 1 ]]; then
   usage
fi

cleanup() {
    rm -rf id_rsa
}

trap cleanup EXIT

eval "$(ssh-agent | grep -v '^echo ')"

if [[ -z "$RESOURCEID" ]]; then
    if [[ -z "$CLUSTER" ]]; then
        echo "CLUSTER must be specified"
        usage
    fi

    RESOURCEID="/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${RESOURCEGROUP}/providers/Microsoft.RedHatOpenShift/openShiftClusters/${CLUSTER}"
fi

CLUSTER_RESOURCEGROUP=$(go run ./hack/db "$RESOURCEID" | jq -r .openShiftCluster.properties.clusterProfile.resourceGroupId | cut -d/ -f5)

go run ./hack/db "$RESOURCEID" | jq -r .openShiftCluster.properties.sshKey | base64 -d | openssl rsa -inform der -outform pem >id_rsa 2>/dev/null
chmod 0600 id_rsa

# seeing ARM cache issues with -g $CLUSTER_RESOURCEGROUP, so using --query
IP=$(az network nic list --query "[?resourceGroup == '$CLUSTER_RESOURCEGROUP' && contains(name, '$1')].ipConfigurations[0].privateIPAddress" -o tsv)

if [[ $(grep -c . <<<"$IP") -ne 1 ]]; then
     echo -e "VM with pattern $1 not found in resourceGroup $CLUSTER_RESOURCEGROUP\n"
     usage
fi

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa -l core "$IP"


#!/bin/bash -e

# ssh-aks.sh allows you to ssh into the specifed AKS clusters worker nodes

usage() {
	echo -e "usage: ${0} <cluster-name> <worker-node-index>\n" >&2
	echo "       Examples: ${0} aks-test 0        # the first VM node in 'aks-test'" >&2
	echo "                 ${0} aro-aks-cluster 1 # The second VM node in 'aro-aks-cluster'" >&2
	exit 1
}

if [ "$#" -ne 2 ]; then
	usage
fi

if [ -z "$RESOURCEGROUP" ]; then
	echo "RESOURCEGROUP env variable must be set"
	exit 1
fi

NODE_RESOURCEGROUP=$( az aks list -g "$RESOURCEGROUP" --query "[?contains(name, '$1')].nodeResourceGroup" -o tsv )
if [[ $(grep -c . <<<"$NODE_RESOURCEGROUP") -ne 1 ]]; then
	echo "Cluster with pattern "${1}" not found in resource group ${RESOURCEGROUP}"
	echo "The following AKS clusters are available:"
	az aks list -g $RESOURCEGROUP -otable
	exit 1
fi

echo "Node RG:   ${NODE_RESOURCEGROUP}"

NODE_VMSS=$( az vmss list -g "$NODE_RESOURCEGROUP" --query "[?contains(name, 'system')].name" -otsv )
if [[ $(grep -c . <<<"$NODE_VMSS") -ne 1 ]]; then
	echo "VMSS not found in the node resource group ${NODE_RESOURCEGROUP}"
	usage
fi

echo "Node VMSS: ${NODE_VMSS}"

IPs=$( az vmss nic list -g "$NODE_RESOURCEGROUP" --vmss-name "$NODE_VMSS" --query '[?items[].ipConfigurations[].primary == true].ipConfigurations[0].privateIpAddress' )
if [ -z "$IPs" ]; then
	echo "Primary IPs not found for VMs in ${NODE_VMSS}"
	usage
fi

IP_COUNT=$( echo ${IPs} | jq -r ". | length" )
echo "Found ${IP_COUNT} worker node IPs"

IP=$( echo "$IPs" | jq -r ".[${2}]" )
if [ -z "$IP" ]; then
	echo "IP not found for worker index ${2}"
	usage
fi

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i secrets/proxy_id_rsa -l cloud-user "$IP"


#!/bin/bash -e

set -o pipefail

while [[ $1 == -* ]]; do
  if [[ $1 == -- ]]; then
    shift
    break
  fi
  shift
done

if [[ "$#" -gt 0 ]]; then
  NODENAME=$1
  shift
fi

COMMAND='bash --login'
TTY=true
TTYOPT=-t
if [[ "$#" -gt 0 ]]; then
  COMMAND="bash -c $(printf ' %q' "$@" | sed -e "s/'/''/g")"
  TTY=false
  TTYOPT=
fi

cleanup() {
    [[ -n "$POD" ]] && oc delete pod -n default "$POD" >/dev/null
}

trap cleanup EXIT

POD=$(oc create -o json -f - <<EOF | jq -r .metadata.name
kind: Pod
apiVersion: v1
metadata:
  generateName: debug
  labels:
    openshift.io/run-level: "0"
  namespace: default
spec:
  containers:
  - command:
    - /sbin/chroot
    - /host
    - /bin/bash
    - -c
    - 'cd && exec $COMMAND'
    image: ubi8/ubi-minimal
    name: debug
    securityContext:
      capabilities:
        add:
        - CHOWN
        - DAC_OVERRIDE
        - DAC_READ_SEARCH
        - FOWNER
        - FSETID
        - KILL
        - SETGID
        - SETUID
        - SETPCAP
        - LINUX_IMMUTABLE
        - NET_BIND_SERVICE
        - NET_BROADCAST
        - NET_ADMIN
        - NET_RAW
        - IPC_LOCK
        - IPC_OWNER
        - SYS_MODULE
        - SYS_RAWIO
        - SYS_CHROOT
        - SYS_PTRACE
        - SYS_PACCT
        - SYS_ADMIN
        - SYS_BOOT
        - SYS_NICE
        - SYS_RESOURCE
        - SYS_TIME
        - SYS_TTY_CONFIG
        - MKNOD
        - LEASE
        - AUDIT_WRITE
        - AUDIT_CONTROL
        - SETFCAP
        - MAC_OVERRIDE
        - MAC_ADMIN
        - SYSLOG
        - WAKE_ALARM
        - BLOCK_SUSPEND
        - AUDIT_READ
    stdin: true
    tty: $TTY
    volumeMounts:
    - mountPath: /host
      name: host
  hostIPC: true
  hostNetwork: true
  hostPID: true
  nodeName: "$NODENAME"
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
  volumes:
  - hostPath:
      path: /
    name: host
EOF
)

oc wait --timeout=300s --for=condition=Ready -n default "pod/$POD" >/dev/null
oc attach -i $TTYOPT -n default -c debug "pod/$POD"


#!/bin/bash

# This script executes Python unit tests. It first tries to activate the virtual environment,
# but if it does not exist it will be created and then activated.
# When executing "pytest" command, it ignores integration test folder as
# this script is intended to just execute unit tests.

. pyenv/bin/activate || python3 -m venv pyenv && . pyenv/bin/activate
pip install pytest
cd python
pytest --ignore=az/aro/azext_aro/tests/latest/integration


#!/bin/bash -ex

# Background: https://groups.google.com/forum/#!topic/golang-nuts/51-D_YFC78k
#
# TLDR: OCP consists of many repos where for each release a new release branch gets created (release-X.Y).
# When we update vendors we want to get latest changes from the release branch for all of the dependencies.
# With Go modules we can't easily do it, but there is a workaround which consists of multiple steps:
# 	1. Get the latest commit from the branch using `go list -mod=mod -m MODULE@release-x.y`.
# 	2. Using `sed`, transform output of the above command into format accepted by `go mod edit -replace`.
#	3. Modify `go.mod` by calling `go mod edit -replace`.
#
# This needs to happen for each module that uses this branching strategy: all these repos
# live under github.com/openshift organisation.
#
# There are however, some exceptions:
# 	* Some repos under github.com/openshift do not use this strategy.
#     We should skip them in this script and manage directly with `go mod`.
# 	* Some dependencies pin their own dependencies to older commits.
#     For example, dependency Foo from release-4.7 branch requires
#	  dependency Bar at older commit which is
#     not compatible with Bar@release-4.7.
#
# Note that github.com/openshift org also contains forks of K8s upstream repos and we
# use these forks (indirectly in most cases). This means that
# we also must take care of replacing modules such as sigs.k8s.io/cluster-api-provider-azure
# with github.com/openshift/cluster-api-provider-azure (just an example, there are more).

for x in vendor/github.com/openshift/*; do
	case $x in
		# Review the list of special cases on each release.

		# Do not update Hive: it is not part of OCP
		vendor/github.com/openshift/hive)
			;;

		# Replace the installer with our own fork below in this script.
		vendor/github.com/openshift/installer)
			;;

		# Inconsistent imports: some of our dependencies import it as github.com/metal3-io/cluster-api-provider-baremetal
		# but in some places directly from the openshift fork.
		# Replace github.com/metal3-io/cluster-api-provider-baremetal with an openshift fork in go.mod
		vendor/github.com/openshift/cluster-api-provider-baremetal)
			;;

		# It is only used indirectly and intermediate dependencies pin to different incompatible commits.
		# We force a specific commit here to make all dependencies happy.
		vendor/github.com/openshift/cloud-credential-operator)
			go mod edit -replace github.com/openshift/cloud-credential-operator=github.com/openshift/cloud-credential-operator@v0.0.0-20200316201045-d10080b52c9e
			;;

		# This repo doesn't follow release-x.y branching strategy
		# We skip it and let go mod resolve it
		vendor/github.com/openshift/custom-resource-status)
			;;

		*)
			go mod edit -replace ${x##vendor/}=$(go list -mod=mod -m ${x##vendor/}@release-4.10 | sed -e 's/ /@/')
			;;
	esac
done

for x in aws azure openstack; do
	go mod edit -replace sigs.k8s.io/cluster-api-provider-$x=$(go list -mod=mod -m github.com/openshift/cluster-api-provider-$x@release-4.10 | sed -e 's/ /@/')
done

go mod edit -replace github.com/openshift/installer=$(go list -mod=mod -m github.com/jewzaam/installer-aro@release-4.10-azure | sed -e 's/ /@/')

go get -u ./...

go mod tidy -compat=1.18
go mod vendor


#!/bin/bash

set -xe

go run hack/ci-utils/differenceChecker/main.go make generate
make build-all
make unit-test-go


#!/bin/bash

set -xe

DOCKERID=$(docker create $1)
docker export $DOCKERID > aro.tar
tar -xvf aro.tar --strip-components=3 usr/local/bin/
docker rm $DOCKERID


#!/bin/bash

set -xe
if [[ ! -z "$(git status -s)" ]]
then
    echo "there are some modified files"
    git status
    exit 1
fi


#!/bin/bash -e
######## Helper file to run E2e either locally or using Azure DevOps Pipelines ########

create_infra_rg() {
    echo "########## Creating RG $RESOURCEGROUP in $LOCATION ##########"
    az group create -g "$RESOURCEGROUP" -l "$LOCATION" --tags persist=true >/dev/null
}

deploy_rp_dev_predeploy() {
    echo "########## Deploying rp-development-predeploy in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n rp-development-predeploy \
        --template-file pkg/deploy/assets/rp-development-predeploy.json \
        --parameters \
            "adminObjectId=$ADMIN_OBJECT_ID" \
            "fpServicePrincipalId=$(az ad sp list --filter "appId eq '$AZURE_FP_CLIENT_ID'" --query '[].id' -o tsv)" \
            "keyvaultPrefix=$KEYVAULT_PREFIX" \
            "rpServicePrincipalId=$(az ad sp list --filter "appId eq '$AZURE_RP_CLIENT_ID'" --query '[].id' -o tsv)" >/dev/null
}

deploy_rp_dev() {
    echo "########## Deploying rp-development in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n rp-development \
        --template-file pkg/deploy/assets/rp-development.json \
        --parameters \
            "clusterParentDomainName=$PARENT_DOMAIN_NAME" \
            "databaseAccountName=$DATABASE_ACCOUNT_NAME" \
            "fpServicePrincipalId=$(az ad sp list --filter "appId eq '$AZURE_FP_CLIENT_ID'" --query '[].id' -o tsv)" \
            "rpServicePrincipalId=$(az ad sp list --filter "appId eq '$AZURE_RP_CLIENT_ID'" --query '[].id' -o tsv)" >/dev/null
}

deploy_env_dev() {
    echo "########## Deploying env-development in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n env-development \
        --template-file pkg/deploy/assets/env-development.json \
        --parameters \
            "proxyCert=$(base64 -w0 <secrets/proxy.crt)" \
            "proxyClientCert=$(base64 -w0 <secrets/proxy-client.crt)" \
            "proxyDomainNameLabel=$(cut -d. -f2 <<<$PROXY_HOSTNAME)" \
            "proxyImage=arointsvc.azurecr.io/proxy:latest" \
            "proxyImageAuth=$(jq -r '.auths["arointsvc.azurecr.io"].auth' <<<$PULL_SECRET)" \
            "proxyKey=$(base64 -w0 <secrets/proxy.key)" \
            "sshPublicKey=$(<secrets/proxy_id_rsa.pub)" \
            "vpnCACertificate=$(base64 -w0 <secrets/vpn-ca.crt)" >/dev/null
}

deploy_aks_dev() {
    echo "########## Deploying aks-development in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n aks-development \
        --template-file pkg/deploy/assets/aks-development.json \
        --parameters \
            "dnsZone=$DOMAIN_NAME" \
            "keyvaultPrefix=$KEYVAULT_PREFIX" \
            "sshRSAPublicKey=$(<secrets/proxy_id_rsa.pub)" >/dev/null
}

deploy_vpn_for_dedicated_rp() {
    echo "########## Deploying Dev VPN in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n dev-vpn \
        --template-file pkg/deploy/assets/vpn-development.json \
        --parameters \
             "vpnCACertificate=$(base64 -w0 <secrets/vpn-ca.crt)" >/dev/null
}

deploy_env_dev_override() {
    echo "########## Deploying env-development in RG $RESOURCEGROUP ##########"
    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n env-development \
        --template-file pkg/deploy/assets/env-development.json \
        --parameters \
            "proxyCert=$(base64 -w0 <secrets/proxy.crt)" \
            "proxyClientCert=$(base64 -w0 <secrets/proxy-client.crt)" \
            "proxyDomainNameLabel=$(cut -d. -f2 <<<$PROXY_HOSTNAME)" \
            "proxyImage=arointsvc.azurecr.io/proxy:latest" \
            "proxyImageAuth=$(jq -r '.auths["arointsvc.azurecr.io"].auth' <<<$PULL_SECRET)" \
            "proxyKey=$(base64 -w0 <secrets/proxy.key)" \
            "sshPublicKey=$(<secrets/proxy_id_rsa.pub)" \
            "vpnCACertificate=$(base64 -w0 <secrets/vpn-ca.crt)" \
            "publicIPAddressSkuName=Basic" \
            "publicIPAddressAllocationMethod=Dynamic" >/dev/null
}

import_certs_secrets() {
    echo "########## Import certificates to $KEYVAULT_PREFIX-svc KV ##########"
    az keyvault certificate import \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name rp-server \
        --file secrets/localhost.pem >/dev/null
    az keyvault certificate import \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name dev-arm \
        --file secrets/arm.pem >/dev/null
    az keyvault certificate import \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --name portal-server \
        --file secrets/localhost.pem >/dev/null
    az keyvault certificate import \
        --vault-name "$KEYVAULT_PREFIX-dbt" \
        --name dbtoken-server \
        --file secrets/localhost.pem >/dev/null
    az keyvault certificate import \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --name portal-client \
        --file secrets/portal-client.pem >/dev/null
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --query '[].name' \
        -o tsv | grep -q ^encryption-key$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name encryption-key \
        --value "$(openssl rand -base64 32)" >/dev/null
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --query '[].name' \
        -o tsv | grep -q ^encryption-key-v2$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name encryption-key-v2 \
        --value "$(openssl rand -base64 64)"
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --query '[].name' \
        -o tsv | grep -q ^fe-encryption-key$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name fe-encryption-key \
        --value "$(openssl rand -base64 32)" >/dev/null
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --query '[].name' \
        -o tsv | grep -q ^fe-encryption-key-v2$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-svc" \
        --name fe-encryption-key-v2 \
        --value "$(openssl rand -base64 64)"
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --query '[].name' \
        -o tsv | grep -q ^portal-session-key$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --name portal-session-key \
        --value "$(openssl rand -base64 32)" >/dev/null
    az keyvault secret list \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --query '[].name' \
        -o tsv | grep -q ^portal-sshkey$ || \
    az keyvault secret set \
        --vault-name "$KEYVAULT_PREFIX-por" \
        --name portal-sshkey \
        --value "$(openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -outform der | base64 -w0)" >/dev/null
}

update_parent_domain_dns_zone() {
    CHILD_DOMAIN_PREFIX="$(cut -d. -f1 <<<$DOMAIN_NAME)"
    echo "########## Creating NS record to DNS Zone $CHILD_DOMAIN_PREFIX ##########"
    az network dns record-set ns create \
        --resource-group "$PARENT_DOMAIN_RESOURCEGROUP" \
        --zone "$PARENT_DOMAIN_NAME" \
        --name "$CHILD_DOMAIN_PREFIX" >/dev/null
    for ns in $(az network dns zone show \
        --resource-group "$RESOURCEGROUP" \
        --name "$DOMAIN_NAME" \
        --query nameServers -o tsv); do
        az network dns record-set ns add-record \
          --resource-group "$PARENT_DOMAIN_RESOURCEGROUP" \
          --zone "$PARENT_DOMAIN_NAME" \
          --record-set-name "$CHILD_DOMAIN_PREFIX" \
          --nsdname "$ns" >/dev/null
      done
}

vpn_configuration() {
    echo "########## VPN Configuration ##########"
    curl -so vpnclientconfiguration.zip "$(az network vnet-gateway vpn-client generate \
        -g "$RESOURCEGROUP" \
        -n dev-vpn \
        -o tsv)"
    export CLIENTCERTIFICATE="$(openssl x509 -inform der -in secrets/vpn-client.crt)"
    export PRIVATEKEY="$(openssl rsa -inform der -in secrets/vpn-client.key)"
    unzip -qc vpnclientconfiguration.zip 'OpenVPN\\vpnconfig.ovpn' \
        | envsubst \
        | grep -v '^log ' >"secrets/vpn-$LOCATION.ovpn"
    rm vpnclientconfiguration.zip
}

validate_arm_template_state() {
    ARM_TEMPLATE_STATE=$(az deployment group show -n $1 -g $RESOURCEGROUP --query properties.provisioningState -o tsv)
    if [[ $ARM_TEMPLATE_STATE == "Failed" ]]; then
        echo "##[error] Error deploying $1 $(az deployment group show -n $1 -g $RESOURCEGROUP --query properties.error.details -o tsv)"
        exit 1
    fi
}

clean_env() {
    echo "########## Deleting RG $RESOURCEGROUP in $LOCATION ##########"
    az group delete -g "$RESOURCEGROUP" -y
    az network dns record-set ns delete \
        --resource-group "$PARENT_DOMAIN_RESOURCEGROUP" \
        --zone "$PARENT_DOMAIN_NAME" \
        --name "$RESOURCEGROUP"
    for ns in $(az network dns zone show \
        --resource-group "$RESOURCEGROUP" \
        --name "$DOMAIN_NAME" \
        --query nameServers -o tsv); do
        az network dns record-set ns remove-record \
          --resource-group "$PARENT_DOMAIN_RESOURCEGROUP" \
          --zone "$PARENT_DOMAIN_NAME" \
          --record-set-name "$RESOURCEGROUP" \
          --nsdname "$ns"
      done
}

echo "##########################################"
echo "##### ARO V4 Dev Env helper sourced ######"
echo "##########################################"
echo "########## Current settings : ############"
echo "RESOURCEGROUP=$RESOURCEGROUP"
echo "AZURE_SUBSCRIPTION_ID=$AZURE_SUBSCRIPTION_ID"
echo
echo "LOCATION=$LOCATION"
echo
echo "DATABASE_ACCOUNT_NAME=$DATABASE_ACCOUNT_NAME"
echo
echo "ADMIN_OBJECT_ID=$ADMIN_OBJECT_ID"
echo "AZURE_RP_CLIENT_ID=$AZURE_RP_CLIENT_ID"
echo "AZURE_FP_CLIENT_ID=$AZURE_FP_CLIENT_ID"
echo
echo "PARENT_DOMAIN_NAME=$PARENT_DOMAIN_NAME"
echo "PARENT_DOMAIN_RESOURCEGROUP=$PARENT_DOMAIN_RESOURCEGROUP"
echo
echo "KEYVAULT_PREFIX=$KEYVAULT_PREFIX"
echo
echo "PROXY_HOSTNAME=$PROXY_HOSTNAME"
echo "######################################"

[ "$LOCATION" ] || ( echo ">> LOCATION is not set please validate your ./secrets/env"; exit 128 )
[ "$RESOURCEGROUP" ] || ( echo ">> RESOURCEGROUP is not set please validate your ./secrets/env"; exit 128 )
[ "$PROXY_HOSTNAME" ] || ( echo ">> PROXY_HOSTNAME is not set please validate your ./secrets/env"; exit 128 )
[ "$DATABASE_ACCOUNT_NAME" ] || ( echo ">> DATABASE_ACCOUNT_NAME is not set please validate your ./secrets/env"; exit 128 )
[ "$ADMIN_OBJECT_ID" ] || ( echo ">> ADMIN_OBJECT_ID is not set please validate your ./secrets/env"; exit 128 )
[ "$PARENT_DOMAIN_NAME" ] || ( echo ">> PARENT_DOMAIN_NAME is not set please validate your ./secrets/env"; exit 128 )
[ "$AZURE_FP_CLIENT_ID" ] || ( echo ">> AZURE_FP_CLIENT_ID is not set please validate your ./secrets/env"; exit 128 )
[ "$KEYVAULT_PREFIX" ] || ( echo ">> KEYVAULT_PREFIX is not set please validate your ./secrets/env"; exit 128 )
[ "$AZURE_RP_CLIENT_ID" ] || ( echo ">> AZURE_RP_CLIENT_ID is not set please validate your ./secrets/env"; exit 128 )
[ "$PULL_SECRET" ] || ( echo ">> PULL_SECRET is not set please validate your ./secrets/env"; exit 128 )
[ "$PARENT_DOMAIN_RESOURCEGROUP" ] || ( echo ">> PARENT_DOMAIN_RESOURCEGROUP is not set please validate your ./secrets/env"; exit 128 )


#!/bin/bash

# Local development environment script.
# Execute this script from the root folder of the repo (ARO-RP).
# This script is aimed to provide an automatic and easy way to prepare
# the environment and execute the ARO RP locally.
# The steps here are the ones defined in docs/deploy-development-rp.md
# We recommend to use this script after you understand the steps of the process, not before.

build_development_az_aro_extension() {
    echo "INFO: Building development az aro extension..."
    make az
}

verify_aro_extension() {
    echo "INFO: Verifying aro extension..."
    grep -q 'dev_sources' ~/.azure/config || cat >>~/.azure/config <<EOF
[extension]
dev_sources = $PWD/python
EOF
}

set_storage_account() {
    echo "INFO: Setting storage account..."
    export SECRET_SA_ACCOUNT_NAME=rharosecretsdev make secrets
}

ask_to_create_default_env_config() {
    local answer
    read -p "Do you want to create a default env file? (existing one will be overwritten, if any) (y / n) " answer

    if [[ "$answer" == "y" || "$answer" == "Y" ]]; then
        create_env_file
    elif [[ "$answer" == "n" || "$answer" == "N" ]]; then
        echo "INFO: Skipping creation of default env file..."
    else
        echo "INFO: Unknown option, skipping step..."
    fi
}

create_env_file() {
    echo "INFO: Creating default env config file..."

    cat >env <<EOF
export LOCATION=eastus
export ARO_IMAGE=arointsvc.azurecr.io/aro:latest
export RP_MODE=development # to use a development RP running at https://localhost:8443/

source secrets/env
EOF
}

ask_to_create_Azure_deployment() {
    local answer
    read -p "Create Azure deployment in the current subscription ($AZURE_SUBSCRIPTION_ID)? (y / n / l (list existing deployments)) " answer

    if [[ "$answer" == "y" || "$answer" == "Y" ]]; then
        create_Azure_deployment
    elif [[ "$answer" == "n" || "$answer" == "N" ]]; then
        echo "INFO: Skipping creation of Azure deployment..."
    elif [[ "$answer" == "l" ]]; then
        list_Azure_deployment_names
        ask_to_create_Azure_deployment
    else
        echo "INFO: Unknown option, skipping step..."
    fi
}

list_Azure_deployment_names() {
    echo "INFO: Existing deployment names in the current subscription ($AZURE_SUBSCRIPTION_ID):"
    az deployment group list --resource-group $RESOURCEGROUP | jq '[ .[] | {deployment_name: ( .id ) | split("/deployments/")[1] } | .deployment_name ]'
}

create_Azure_deployment() {
    echo "INFO: Creating Azure deployment..."

    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n "databases-development-$USER" \
        --template-file pkg/deploy/assets/databases-development.json \
        --parameters \
        "databaseAccountName=$DATABASE_ACCOUNT_NAME" \
        "databaseName=$DATABASE_NAME" \
        >/dev/null

    echo "INFO: Azure deployment created."
}

source_env() {
    echo "INFO: Sourcing env file..."
    source ./env
}

run_the_RP() {
    echo "INFO: Running the ARO RP locally..."
    make runlocal-rp
}

main() {
    build_development_az_aro_extension
    verify_aro_extension
    set_storage_account
    ask_to_create_default_env_config
    source_env
    ask_to_create_Azure_deployment
    run_the_RP
}

main


#!/bin/bash -e
######## Helper file to run E2e either locally or using Azure DevOps Pipelines ########

if [[ $CI ]]; then
    set -o pipefail

    . secrets/env
    echo "##vso[task.setvariable variable=RP_MODE]$RP_MODE"

    set -a
    HIVEKUBECONFIGPATH="secrets/e2e-aks-kubeconfig"
    HIVE_KUBE_CONFIG_PATH_1="secrets/aks.kubeconfig"
    CLUSTER="v4-e2e-V$BUILD_BUILDID-$LOCATION"
    DATABASE_NAME="v4-e2e-V$BUILD_BUILDID-$LOCATION"
    PRIVATE_CLUSTER=true
    E2E_DELETE_CLUSTER=false
    set +a
fi

validate_rp_running() {
    echo "########## ï¼ŸChecking ARO RP Status ##########"
    ELAPSED=0
    while true; do
        sleep 5
        http_code=$(curl -k -s -o /dev/null -w '%{http_code}' https://localhost:8443/healthz/ready || true)
        case $http_code in
        "200")
            echo "########## âœ… ARO RP Running ##########"
            break
            ;;
        *)
            echo "Attempt $ELAPSED - local RP is NOT up. Code : $http_code, waiting"
            sleep 2
            # after 40 secs return exit 1 to not block ci
            ELAPSED=$((ELAPSED + 1))
            if [ $ELAPSED -eq 20 ]; then
                exit 1
            fi
            ;;
        esac
    done
}

run_rp() {
    echo "########## ðŸš€ Run ARO RP in background ##########"
    ./aro rp &
}

kill_rp() {
    echo "########## Kill the RP running in background ##########"
    rppid=$(lsof -t -i :8443)
    kill $rppid
    wait $rppid
}

validate_portal_running() {
    echo "########## ï¼ŸChecking Admin Portal Status ##########"
    ELAPSED=0
    while true; do
        sleep 5
        http_code=$(curl -k -s -o /dev/null -w '%{http_code}' https://localhost:8444/healthz/ready)
        case $http_code in
        "200")
            echo "########## âœ… ARO Admin Portal Running ##########"
            break
            ;;
        *)
            echo "Attempt $ELAPSED - local Admin Portal is NOT up. Code : $http_code, waiting"
            sleep 2
            # after 40 secs return exit 1 to not block ci
            ELAPSED=$((ELAPSED + 1))
            if [ $ELAPSED -eq 20 ]; then
                exit 1
            fi
            ;;
        esac
    done
}

run_portal() {
    echo "########## ðŸš€ Run Admin Portal in background ##########"
    export AZURE_ENVIRONMENT=AzurePublicCloud
    ./aro portal &
}

kill_portal() {
    echo "########## Kill the Admin Portal running in background ##########"
    rppid=$(lsof -t -i :8444)
    kill $rppid
    wait $rppid
}

run_vpn() {
    echo "########## ðŸš€ Run OpenVPN in background ##########"
    echo "Using Secret secrets/$VPN"
    sudo openvpn --config secrets/$VPN --daemon --writepid vpnpid
    sleep 10
}

kill_vpn() {
    echo "########## Kill the OpenVPN running in background ##########"
    while read pid; do sudo kill $pid; done <vpnpid
}

run_podman() {
    echo "########## ðŸš€ Run Podman in background ##########"
    podman --log-level=debug system service --time=0 tcp://127.0.0.1:8888 >podmanlog &
}

kill_podman() {
    echo "podman logs:"
    cat podmanlog
    echo "########## Kill the podman running in background ##########"
    rppid=$(lsof -t -i :8888)
    kill $rppid
    wait $rppid
}

validate_podman_running() {
    echo "########## ï¼ŸChecking podman Status ##########"
    ELAPSED=0
    while true; do
        sleep 5
        http_code=$(curl -k -s -o /dev/null -w '%{http_code}' http://localhost:8888/v1.30/_ping || true)
        case $http_code in
        "200")
            echo "########## âœ… Podman Running ##########"
            break
            ;;
        *)
            echo "Attempt $ELAPSED - podman is NOT up. Code : $http_code, waiting"
            sleep 2
            # after 40 secs return exit 1 to not block ci
            ELAPSED=$((ELAPSED + 1))
            if [ $ELAPSED -eq 20 ]; then
                exit 1
            fi
            ;;
        esac
    done
}

run_selenium() {
    echo "########## ðŸš€ Run Selenium in background ##########"
    podman -r --url tcp://localhost:8888 pull docker.io/selenium/standalone-edge:latest
    podman -r --url tcp://localhost:8888 run -d --name selenium-edge-standalone --network=host --shm-size=2g docker.io/selenium/standalone-edge:latest

}

kill_selenium() {
    podman stop -i selenium-edge-standalone
}

validate_selenium_running() {
    echo "########## ï¼ŸChecking selenium Status ##########"
    ELAPSED=0
    while true; do
        sleep 5
        http_code=$(curl -k -s -o /dev/null -w '%{http_code}' http://localhost:4444/status || true)
        case $http_code in
        "200")
            echo "########## âœ… Podman Running ##########"
            break
            ;;
        *)
            echo "Attempt $ELAPSED - selenium is NOT up. Code : $http_code, waiting"
            sleep 2
            # after 40 secs return exit 1 to not block ci
            ELAPSED=$((ELAPSED + 1))
            if [ $ELAPSED -eq 20 ]; then
                exit 1
            fi
            ;;
        esac
    done
}

deploy_e2e_db() {
    echo "########## ðŸ“¦ Creating new DB $DATABASE_NAME in $DATABASE_ACCOUNT_NAME ##########"

    az deployment group create \
        -g "$RESOURCEGROUP" \
        -n "databases-development-$DATABASE_NAME" \
        --template-file pkg/deploy/assets/databases-development.json \
        --parameters \
        "databaseAccountName=$DATABASE_ACCOUNT_NAME" \
        "databaseName=$DATABASE_NAME" \
        >/dev/null

}

register_sub() {
    echo "########## ðŸ”‘ Registering subscription ##########"
    curl -sko /dev/null -X PUT \
        -H 'Content-Type: application/json' \
        -d '{"state": "Registered", "properties": {"tenantId": "'"$AZURE_TENANT_ID"'"}}' \
        "https://localhost:8443/subscriptions/$AZURE_SUBSCRIPTION_ID?api-version=2.0"
}

clean_e2e_db() {
    echo "########## ðŸ§¹ Deleting DB $DATABASE_NAME ##########"
    az cosmosdb sql database delete --name $DATABASE_NAME \
        --yes \
        --account-name $DATABASE_ACCOUNT_NAME \
        --resource-group $RESOURCEGROUP >/dev/null
}

delete_e2e_cluster() {
    echo "########## ðŸ§¹ Deleting Cluster $CLUSTER ##########"
    if [[ $CI ]]; then
        ./cluster delete
    else
        go run ./hack/cluster delete
    fi
}

# TODO: CLUSTER and is also recalculated in multiple places
# in the billing pipelines :-(

if [[ -z $CLUSTER ]]; then
    echo "CLUSTER is not set, aborting"
    return 1
fi

if [[ -z $DATABASE_NAME ]]; then
    echo "DATABASE_NAME is not set, aborting"
    return 1
fi

echo "######################################"
echo "##### ARO V4 E2e helper sourced ######"
echo "######################################"
echo "######## Current settings : ##########"
echo
echo "LOCATION=$LOCATION"
echo "AZURE_SUBSCRIPTION_ID=$AZURE_SUBSCRIPTION_ID"
echo
echo "RP_MODE=$RP_MODE"
echo
echo "DATABASE_ACCOUNT_NAME=$DATABASE_ACCOUNT_NAME"
echo "DATABASE_NAME=$DATABASE_NAME"
echo "RESOURCEGROUP=$RESOURCEGROUP"
echo
echo "CLUSTER=$CLUSTER"
echo
echo "PROXY_HOSTNAME=$PROXY_HOSTNAME"
echo "######################################"

[[ $LOCATION ]] || (
    echo ">> LOCATION is not set please validate your ./secrets/env"
    return 128
)
[[ $RESOURCEGROUP ]] || (
    echo ">> RESOURCEGROUP is not set; please validate your ./secrets/env"
    return 128
)
[[ $PROXY_HOSTNAME ]] || (
    echo ">> PROXY_HOSTNAME is not set; please validate your ./secrets/env"
    return 128
)
[[ $DATABASE_ACCOUNT_NAME ]] || (
    echo ">> DATABASE_ACCOUNT_NAME is not set; please validate your ./secrets/env"
    return 128
)
[[ $DATABASE_NAME ]] || (
    echo ">> DATABASE_NAME is not set; please validate your ./secrets/env"
    return 128
)
[[ $AZURE_SUBSCRIPTION_ID ]] || (
    echo ">> AZURE_SUBSCRIPTION_ID is not set; please validate your ./secrets/env"
    return 128
)


#!/bin/bash

# The small go program below will validate that a
# FIPS validated crypto lib
cat > ./hack/fips/main.go << 'EOF'
package main

// Copyright (c) Microsoft Corporation.
// Licensed under the Apache License 2.0.

import (
	_ "crypto/tls/fipsonly"

	utillog "github.com/Azure/ARO-RP/pkg/util/log"
)

func main() {
	log := utillog.GetLogger()
	log.Println("FIPS mode enabled")
}
EOF
trap "rm ./hack/fips/main.go" EXIT
echo "Attempting to run program that requires FIPS crypto"
go run ./hack/fips/main.go


#!/bin/bash

cd ./portal/v2

if npm audit --omit=dev | grep -q 'found 0 vulnerabilities'; then
  echo "No vulnerabilities found."
  exit 0
else
  echo "Vulnerabilities found, please run `npm audit --omit=dev` locally and fix or record issues and create an ADO card."
  exit 1
fi


# Setup the VM
rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
rpm --import https://packages.microsoft.com/keys/microsoft.asc

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

cat >/etc/yum.repos.d/azure.repo <<'EOF'
[azure-cli]
name=azure-cli
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=yes
gpgcheck=yes
EOF

yum --enablerepo=rhui-rhel-7-server-rhui-optional-rpms -y install \
   azure-cli \
   docker \
   jq \
   gcc \
   rh-git29 \
   rh-python36 \
   tmpwatch \
   lttng-usr \
   gpgme-devel \
   libassuan-devel \
   socat

sed -i -e 's/^OPTIONS='\''/OPTIONS='\''-G cloud-user /' /etc/sysconfig/docker

systemctl enable docker
systemctl restart docker


#!/bin/bash -e
set +x

BASE=$( git rev-parse --show-toplevel)

HOSTNAME=$( hostname )
NAME="mdm"
MDMIMAGE=linuxgeneva-microsoft.azurecr.io/genevamdm:master_20211120.1
MDMFRONTENDURL=https://global.ppe.microsoftmetrics.com/
MDMSOURCEENVIRONMENT=$LOCATION
MDMSOURCEROLE=rp
MDMSOURCEROLEINSTANCE=$HOSTNAME

echo "Using:"

echo "Resourcegroup = $RESOURCEGROUP"
echo "User          = $USER"
echo "HOSTNAME      = $HOSTNAME"
echo "Containername = $NAME"
echo "Location      = $LOCATION"
echo "MDM image     = $MDMIMAGE"
echo "  (version hardcoded. Check against pkg/util/version/const.go if things don't work)"
echo "Geneva API URL= $MDMFRONTENDURL"
echo "MDMSOURCEENV  = $MDMSOURCEENVIRONMENT"
echo "MDMSOURCEROLE  = $MDMSOURCEROLE"
echo "MDMSOURCEROLEINSTANCE  = $MDMSOURCEROLEINSTANCE"

VMName="$USER-mdm-link"

CLOUDUSER="cloud-user"

if [ "$(az vm show -g $RESOURCEGROUP --name $VMName)" = "" ];
then
  echo "Creating VM $VMName in RG $RESOURCEGROUP"
  az vm create -g $RESOURCEGROUP -n $VMName --image RedHat:RHEL:7-LVM:latest --ssh-key-values @~/.ssh/id_rsa.pub --admin-username $CLOUDUSER
else
  echo "VM already exists, skipping..."
fi

PUBLICIP=$( az vm list-ip-addresses --name $VMName -g $RESOURCEGROUP | jq -r '.[0].virtualMachine.network.publicIpAddresses[0].ipAddress' )

echo "Found IP $PUBLICIP"

scp $BASE/secrets/rp-metrics-int.pem $CLOUDUSER@$PUBLICIP:mdm.pem
scp $BASE/hack/local-monitor-testing/configureRemote.sh $CLOUDUSER@$PUBLICIP:

ssh $CLOUDUSER@$PUBLICIP "sudo cp mdm.pem /etc/mdm.pem"
ssh $CLOUDUSER@$PUBLICIP "sudo ./configureRemote.sh"

ssh $CLOUDUSER@$PUBLICIP "sudo docker pull $MDMIMAGE"

cat <<EOF > $BASE/dockerStartCommand.sh
docker run \
  --entrypoint /usr/sbin/MetricsExtension \
  --hostname $HOSTNAME \
  --name $NAME \
  -d \
  --restart=always \
  -m 2g \
  -v /etc/mdm.pem:/etc/mdm.pem \
  -v /var/etw:/var/etw:z \
  $MDMIMAGE \
  -CertFile /etc/mdm.pem \
  -FrontEndUrl $MDMFRONTENDURL \
  -Logger Console \
  -LogLevel Debug \
  -PrivateKeyFile /etc/mdm.pem \
  -SourceEnvironment $MDMSOURCEENVIRONMENT \
  -SourceRole $MDMSOURCEROLE \
  -SourceRoleInstance $MDMSOURCEROLEINSTANCE
EOF

#disable SELINUX (don't shoot me)
ssh $CLOUDUSER@$PUBLICIP "sudo setenforce 0"
ssh $CLOUDUSER@$PUBLICIP "sudo getenforce"

#make it permanent
ssh $CLOUDUSER@$PUBLICIP "sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config"

ssh $CLOUDUSER@$PUBLICIP "sudo firewall-cmd --zone=public --add-port=12345/tcp --permanent"
ssh $CLOUDUSER@$PUBLICIP "sudo firewall-cmd --reload"

scp $BASE/dockerStartCommand.sh $CLOUDUSER@$PUBLICIP:
ssh $CLOUDUSER@$PUBLICIP "chmod +x dockerStartCommand.sh"
ssh $CLOUDUSER@$PUBLICIP "sudo ./dockerStartCommand.sh &"


#!/bin/bash
set +x
trap ctrl_c INT

function ctrl_c() {
    echo "** Trapped CTRL-C. Stopping  processes..."
    killProcesses
}

function killProcesses() {
    for pid in ${pids[*]}; do
        echo -n "Stopping local PID: $pid"
        kill $pid
        echo " stopped."
    done

    for pid in ${rempids[*]}; do
        echo -n "Stopping remote PID: $pid"
        ssh $CLOUDUSER@$PUBLICIP sudo kill $pid
        echo " stopped."
    done

    echo "All Stopped."
    exit 1
}

BASE=$( git rev-parse --show-toplevel)
SOCKETFILE="$BASE/cmd/aro/mdm_statsd.socket"

echo "Using:"

echo "Resourcegroup = $RESOURCEGROUP"
echo "User          = $USER"

VMName="$USER-mdm-link"
CLOUDUSER="cloud-user"

echo "Looking for a VM called $VMName and its public IP"
PUBLICIP=$( az vm list-ip-addresses --name $VMName -g $RESOURCEGROUP | jq -r '.[0].virtualMachine.network.publicIpAddresses[0].ipAddress' )

if [ "$PUBLICIP" == "" ] || [ "$PUBLICIP" == "null" ]; then
    echo "ERR: no PUBLICIP IP address found for $VMName. Giving up."

    exit 2
fi

echo -n "Found IP $PUBLICIP, starting socat on the mdm-link vm"
ssh $CLOUDUSER@$PUBLICIP 'sudo socat -v TCP-LISTEN:12345,fork UNIX-CONNECT:/var/etw/mdm_statsd.socket'  &
sleep 2
REMPS=$( ssh $CLOUDUSER@$PUBLICIP 'ps aux | grep "socat -v TCP-LISTEN:12345,fork UNIX-CONNECT:/var/etw/mdm_statsd.socket" | grep -v sudo | grep -v grep' )
REMPID=$( echo $REMPS |  awk '{print $2}' )
if [ "$REMPID" == "" ]; then
    echo ""
    echo "ERR: FAILED TO START REMOTE SOCAT.."
    killProcesses
    exit 1
fi

rempids[0]=$REMPID
echo "...remote socat started."
echo -n "Starting SSH Tunnel..."
ssh $CLOUDUSER@$PUBLICIP -N -L 12345:127.0.0.1:12345 -o ConnectTimeout=4 &
pids[0]=$!
sleep 5
kill -0 ${pids[0]}
if [ $? -eq 0 ]; then
    echo "...SSH Tunnel started. PID: ${pids[0]}."
else
    echo ""
    echo "ERR: FAILED TO START TUNNEL.."
    killProcesses
    exit 1
fi

if [ -e "$SOCKETFILE" ] ; then
    echo "Cleaning up old socket file."
    rm "$SOCKETFILE"
fi
echo -n "Starting local socat link to the tunnel..."
socat -v UNIX-LISTEN:$SOCKETFILE,fork TCP-CONNECT:127.0.0.1:12345 &
pids[1]=$!
sleep 2

kill -0 ${pids[1]}
if [ $? -eq 0 ]; then
    echo "...local socat started.PID: ${pids[1]}."
else
    echo "ERR: FAILED TO START SOCAT. Cleaning up:"
    echo "Killing SSH tunnel"
    killProcesses
    echo "Killed."
    exit 1
fi

echo ""
echo "**********************************************************************"
echo "*  Remote socat: Started. SSH Tunnel: Started. Local socat: Started. *"
echo "*                                                                    *"
echo "*      Hit CTRL-C to stop                                            *"
echo "*                                                                    *"
echo "**********************************************************************"
echo ""
echo ""
while true
do
    sleep 100
done


#/bin/bash

failedChecks=0
while read var; do
  [ -z "${!var}" ] && { echo "required $var is empty or not set."; let failedChecks=failedChecks+1; }
done << EOF
LOCATION
RESOURCEGROUP
USER
EOF

if [ $failedChecks -gt 0 ]; then
  exit 1
fi

#ARO-RP repo root folder
BASE=$( git rev-parse --show-toplevel)

SOCKETPATH="/var/home/core"

HOSTNAME=$( hostname )
NAME="mdm2"
MDMIMAGE=linuxgeneva-microsoft.azurecr.io/genevamdm:master_20211120.1
MDMFRONTENDURL=https://global.ppe.microsoftmetrics.com/
MDMSOURCEENVIRONMENT=$LOCATION
MDMSOURCEROLE=rp
MDMSOURCEROLEINSTANCE=$HOSTNAME

echo "Using:"

echo "Resourcegroup = $RESOURCEGROUP"
echo "User          = $USER"
echo "HOSTNAME      = $HOSTNAME"
echo "Containername = $NAME"
echo "Location      = $LOCATION"
echo "MDM image     = $MDMIMAGE"
echo "  (version hardcoded. Check against pkg/util/version/const.go if things don't work)"
echo "Geneva API URL= $MDMFRONTENDURL"
echo "MDMSOURCEENV  = $MDMSOURCEENVIRONMENT"
echo "MDMSOURCEROLE  = $MDMSOURCEROLE"
echo "MDMSOURCEROLEINSTANCE  = $MDMSOURCEROLEINSTANCE"

podman run \
  --entrypoint /usr/sbin/MetricsExtension \
  --hostname $HOSTNAME \
  --name $NAME \
  -p 8125:8125/udp \
  -d \
  -m 2g \
  -v $BASE/secrets/rp-metrics-int.pem:/etc/mdm.pem \
  $MDMIMAGE \
  -CertFile /etc/mdm.pem \
  -FrontEndUrl $MDMFRONTENDURL \
  -Logger Console \
  -LogLevel Debug \
  -PrivateKeyFile /etc/mdm.pem \
  -SourceEnvironment $MDMSOURCEENVIRONMENT \
  -SourceRole $MDMSOURCEROLE \
  -SourceRoleInstance $MDMSOURCEROLEINSTANCE \
  -Input statsd_udp


#/bin/bash

failedChecks=0
while read var; do
  [ -z "${!var}" ] && { echo "required $var is empty or not set."; let failedChecks=failedChecks+1; }
done << EOF
LOCATION
RESOURCEGROUP
USER
EOF

if [ $failedChecks -gt 0 ]; then
  exit 1
fi

BASE=$( git rev-parse --show-toplevel)

SOCKETPATH="$BASE/cmd/aro"

HOSTNAME=$( hostname )
NAME="mdm"
MDMIMAGE=linuxgeneva-microsoft.azurecr.io/genevamdm:master_20211120.1
MDMFRONTENDURL=https://global.ppe.microsoftmetrics.com/
MDMSOURCEENVIRONMENT=$LOCATION
MDMSOURCEROLE=rp
MDMSOURCEROLEINSTANCE=$HOSTNAME

echo "Using:"

echo "Resourcegroup = $RESOURCEGROUP"
echo "User          = $USER"
echo "HOSTNAME      = $HOSTNAME"
echo "Containername = $NAME"
echo "Location      = $LOCATION"
echo "MDM image     = $MDMIMAGE"
echo "  (version hardcoded. Check against pkg/util/version/const.go if things don't work)"
echo "Geneva API URL= $MDMFRONTENDURL"
echo "MDMSOURCEENV  = $MDMSOURCEENVIRONMENT"
echo "MDMSOURCEROLE  = $MDMSOURCEROLE"
echo "MDMSOURCEROLEINSTANCE  = $MDMSOURCEROLEINSTANCE"

podman run \
  --entrypoint /usr/sbin/MetricsExtension \
  --hostname $HOSTNAME \
  --name $NAME \
  -d \
  --restart=always \
  -m 2g \
  -v $BASE/secrets/rp-metrics-int.pem:/etc/mdm.pem \
  -v $SOCKETPATH:/var/etw:z \
  $MDMIMAGE \
  -CertFile /etc/mdm.pem \
  -FrontEndUrl $MDMFRONTENDURL \
  -Logger Console \
  -LogLevel Debug \
  -PrivateKeyFile /etc/mdm.pem \
  -SourceEnvironment $MDMSOURCEENVIRONMENT \
  -SourceRole $MDMSOURCEROLE \
  -SourceRoleInstance $MDMSOURCEROLEINSTANCE


echo "running RHUI fix"
yum update -y --disablerepo='*' --enablerepo='rhui-microsoft-azure*'

yum -y -x WALinuxAgent -x WALinuxAgent-udev update
yum -y install podman-docker

firewall-cmd --add-port=443/tcp --permanent

mkdir /root/.docker
cat >/root/.docker/config.json <<EOF
{
	"auths": {
		"${PROXYIMAGE%%/*}": {
			"auth": "$PROXYIMAGEAUTH"
		}
	}
}
EOF

mkdir -p /etc/containers/
touch /etc/containers/nodocker

docker pull "$PROXYIMAGE"

mkdir /etc/proxy
base64 -d <<<"$PROXYCERT" >/etc/proxy/proxy.crt
base64 -d <<<"$PROXYKEY" >/etc/proxy/proxy.key
base64 -d <<<"$PROXYCLIENTCERT" >/etc/proxy/proxy-client.crt
chown -R 1000:1000 /etc/proxy
chmod 0600 /etc/proxy/proxy.key

cat >/etc/sysconfig/proxy <<EOF
PROXY_IMAGE='$PROXYIMAGE'
EOF

cat >/etc/systemd/system/proxy.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/proxy
ExecStartPre=-/usr/bin/docker rm -f %n
ExecStart=/usr/bin/docker run --rm --name %n -p 443:8443 -v /etc/proxy:/secrets $PROXY_IMAGE
ExecStop=/usr/bin/docker stop %n
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

systemctl enable proxy.service

cat >/etc/cron.weekly/pull-image <<'EOF'
#!/bin/bash

docker pull $PROXYIMAGE
systemctl restart proxy.service
EOF
chmod +x /etc/cron.weekly/pull-image

cat >/etc/cron.weekly/yumupdate <<'EOF'
#!/bin/bash

yum update -y
EOF
chmod +x /etc/cron.weekly/yumupdate

cat >/etc/cron.daily/restart-proxy <<'EOF'
#!/bin/bash

systemctl restart proxy.service
EOF
chmod +x /etc/cron.daily/restart-proxy

(
	sleep 30
	reboot
) &


#!/bin/bash

echo "setting ssh password authentication"
# We need to manually set PasswordAuthentication to true in order for the VMSS Access JIT to work
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
systemctl reload sshd.service

echo "running RHUI fix"
yum update -y --disablerepo='*' --enablerepo='rhui-microsoft-azure*'

echo "running yum update"
yum -y -x WALinuxAgent -x WALinuxAgent-udev update --allowerasing

echo "extending partition table"
# Linux block devices are inconsistently named
# it's difficult to tie the lvm pv to the physical disk using /dev/disk files, which is why lvs is used here
physicalDisk="$(lvs -o devices -a | head -n2 | tail -n1 | cut -d ' ' -f 3 | cut -d \( -f 1 | tr -d '[:digit:]')"
growpart "$physicalDisk" 2

echo "extending filesystems"
lvextend -l +20%FREE /dev/rootvg/rootlv
xfs_growfs /

lvextend -l +100%FREE /dev/rootvg/varlv
xfs_growfs /var

rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8
rpm --import https://packages.microsoft.com/keys/microsoft.asc

for attempt in {1..5}; do
  yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm && break
  if [[ ${attempt} -lt 5 ]]; then sleep 10; else exit 1; fi
done

echo "configuring logrotate"
cat >/etc/logrotate.conf <<'EOF'
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 2 weeks worth of backlogs
rotate 2

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
        minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}
EOF

echo "configuring yum repository and running yum update"
cat >/etc/yum.repos.d/azure.repo <<'EOF'
[azure-cli]
name=azure-cli
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=yes
gpgcheck=yes

[azurecore]
name=azurecore
baseurl=https://packages.microsoft.com/yumrepos/azurecore
enabled=yes
gpgcheck=no
EOF

semanage fcontext -a -t var_log_t "/var/log/journal(/.*)?"
mkdir -p /var/log/journal

for attempt in {1..5}; do
  yum -y install clamav azsec-clamav azsec-monitor azure-cli azure-mdsd azure-security podman-docker openssl-perl python3 && break
  # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505
  if [[ ${attempt} -lt 5 ]]; then sleep 10; else exit 1; fi
done

echo "applying firewall rules"
# https://access.redhat.com/security/cve/cve-2020-13401
cat >/etc/sysctl.d/02-disable-accept-ra.conf <<'EOF'
net.ipv6.conf.all.accept_ra=0
EOF

cat >/etc/sysctl.d/01-disable-core.conf <<'EOF'
kernel.core_pattern = |/bin/true
EOF
sysctl --system

firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=8081/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent

echo "logging into prod acr"
export AZURE_CLOUD_NAME=$AZURECLOUDNAME
az login -i --allow-no-subscriptions

# The managed identity that the VM runs as only has a single roleassignment.
# This role assignment is ACRPull which is not necessarily present in the
# subscription we're deploying into.  If the identity does not have any
# role assignments scoped on the subscription we're deploying into, it will
# not show on az login -i, which is why the below line is commented.
# az account set -s "$SUBSCRIPTIONID"

# Suppress emulation output for podman instead of docker for az acr compatability
mkdir -p /etc/containers/
touch /etc/containers/nodocker

mkdir -p /root/.docker
REGISTRY_AUTH_FILE=/root/.docker/config.json az acr login --name "$(sed -e 's|.*/||' <<<"$ACRRESOURCEID")"

MDMIMAGE="${RPIMAGE%%/*}/${MDMIMAGE##*/}"
docker pull "$MDMIMAGE"
docker pull "$RPIMAGE"
docker pull "$FLUENTBITIMAGE"

az logout

echo "configuring fluentbit service"
mkdir -p /etc/fluentbit/
mkdir -p /var/lib/fluent

cat >/etc/fluentbit/fluentbit.conf <<'EOF'
[INPUT]
	Name systemd
	Tag journald
	Systemd_Filter _COMM=aro

[FILTER]
	Name modify
	Match journald
	Remove_wildcard _
	Remove TIMESTAMP

[OUTPUT]
	Name forward
	Match *
	Port 29230
EOF

echo "FLUENTBITIMAGE=$FLUENTBITIMAGE" >/etc/sysconfig/fluentbit

cat >/etc/systemd/system/fluentbit.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
RestartSec=1s
EnvironmentFile=/etc/sysconfig/fluentbit
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --security-opt label=disable \
  --entrypoint /opt/td-agent-bit/bin/td-agent-bit \
  --net=host \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -v /etc/fluentbit/fluentbit.conf:/etc/fluentbit/fluentbit.conf \
  -v /var/lib/fluent:/var/lib/fluent:z \
  -v /var/log/journal:/var/log/journal:ro \
  -v /etc/machine-id:/etc/machine-id:ro \
  $FLUENTBITIMAGE \
  -c /etc/fluentbit/fluentbit.conf

ExecStop=/usr/bin/docker stop %N
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring mdm service"
cat >/etc/sysconfig/mdm <<EOF
MDMFRONTENDURL='$MDMFRONTENDURL'
MDMIMAGE='$MDMIMAGE'
MDMSOURCEENVIRONMENT='$LOCATION'
MDMSOURCEROLE=gateway
MDMSOURCEROLEINSTANCE='$(hostname)'
EOF

mkdir /var/etw
cat >/etc/systemd/system/mdm.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/mdm
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --entrypoint /usr/sbin/MetricsExtension \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -m 2g \
  -v /etc/mdm.pem:/etc/mdm.pem \
  -v /var/etw:/var/etw:z \
  $MDMIMAGE \
  -CertFile /etc/mdm.pem \
  -FrontEndUrl $MDMFRONTENDURL \
  -Logger Console \
  -LogLevel Warning \
  -PrivateKeyFile /etc/mdm.pem \
  -SourceEnvironment $MDMSOURCEENVIRONMENT \
  -SourceRole $MDMSOURCEROLE \
  -SourceRoleInstance $MDMSOURCEROLEINSTANCE
ExecStop=/usr/bin/docker stop %N
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring aro-gateway service"
cat >/etc/sysconfig/aro-gateway <<EOF
ACR_RESOURCE_ID='$ACRRESOURCEID'
DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME'
AZURE_DBTOKEN_CLIENT_ID='$DBTOKENCLIENTID'
DBTOKEN_URL='$DBTOKENURL'
MDM_ACCOUNT="$RPMDMACCOUNT"
MDM_NAMESPACE=Gateway
GATEWAY_DOMAINS='$GATEWAYDOMAINS'
GATEWAY_FEATURES='$GATEWAYFEATURES'
RPIMAGE='$RPIMAGE'
EOF

cat >/etc/systemd/system/aro-gateway.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/aro-gateway
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -e ACR_RESOURCE_ID \
  -e DATABASE_ACCOUNT_NAME \
  -e AZURE_DBTOKEN_CLIENT_ID \
  -e DBTOKEN_URL \
  -e GATEWAY_DOMAINS \
  -e GATEWAY_FEATURES \
  -e MDM_ACCOUNT \
  -e MDM_NAMESPACE \
  -m 2g \
  -p 80:8080 \
  -p 8081:8081 \
  -p 443:8443 \
  -v /run/systemd/journal:/run/systemd/journal \
  -v /var/etw:/var/etw:z \
  $RPIMAGE \
  gateway
ExecStop=/usr/bin/docker stop -t 3600 %N
TimeoutStopSec=3600
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

chcon -R system_u:object_r:var_log_t:s0 /var/opt/microsoft/linuxmonagent

mkdir -p /var/lib/waagent/Microsoft.Azure.KeyVault.Store

echo "configuring mdsd and mdm services"
for var in "mdsd" "mdm"; do
cat >/etc/systemd/system/download-$var-credentials.service <<EOF
[Unit]
Description=Periodic $var credentials refresh

[Service]
Type=oneshot
ExecStart=/usr/local/bin/download-credentials.sh $var
EOF

cat >/etc/systemd/system/download-$var-credentials.timer <<EOF
[Unit]
Description=Periodic $var credentials refresh
After=network-online.target
Wants=network-online.target

[Timer]
OnBootSec=0min
OnCalendar=0/12:00:00
AccuracySec=5s

[Install]
WantedBy=timers.target
EOF
done

cat >/usr/local/bin/download-credentials.sh <<EOF
#!/bin/bash
set -eu

COMPONENT="\$1"
echo "Download \$COMPONENT credentials"

TEMP_DIR=\$(mktemp -d)
export AZURE_CONFIG_DIR=\$(mktemp -d)

echo "Logging into Azure..."
RETRIES=3
while [ "\$RETRIES" -gt 0 ]; do
    if az login -i --allow-no-subscriptions
    then
        echo "az login successful"
        break
    else
        echo "az login failed. Retrying..."
        let RETRIES-=1
        sleep 5
    fi
done

trap "cleanup" EXIT

cleanup() {
  az logout
  [[ "\$TEMP_DIR" =~ /tmp/.+ ]] && rm -rf \$TEMP_DIR
  [[ "\$AZURE_CONFIG_DIR" =~ /tmp/.+ ]] && rm -rf \$AZURE_CONFIG_DIR
}

if [ "\$COMPONENT" = "mdm" ]; then
  CURRENT_CERT_FILE="/etc/mdm.pem"
elif [ "\$COMPONENT" = "mdsd" ]; then
  CURRENT_CERT_FILE="/var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem"
else
  echo Invalid usage && exit 1
fi

SECRET_NAME="gwy-\${COMPONENT}"
NEW_CERT_FILE="\$TEMP_DIR/\$COMPONENT.pem"
for attempt in {1..5}; do
  az keyvault secret download --file \$NEW_CERT_FILE --id "https://$KEYVAULTPREFIX-gwy.$KEYVAULTDNSSUFFIX/secrets/\$SECRET_NAME" && break
  if [[ \$attempt -lt 5 ]]; then sleep 10; else exit 1; fi
done

if [ -f \$NEW_CERT_FILE ]; then
  if [ "\$COMPONENT" = "mdsd" ]; then
    chown syslog:syslog \$NEW_CERT_FILE
  else
    sed -i -ne '1,/END CERTIFICATE/ p' \$NEW_CERT_FILE
  fi
  if ! diff $NEW_CERT_FILE $CURRENT_CERT_FILE >/dev/null 2>&1; then
    chmod 0600 \$NEW_CERT_FILE
    mv \$NEW_CERT_FILE \$CURRENT_CERT_FILE
  fi
else
  echo Failed to refresh certificate for \$COMPONENT && exit 1
fi
EOF

chmod u+x /usr/local/bin/download-credentials.sh

systemctl enable download-mdsd-credentials.timer
systemctl enable download-mdm-credentials.timer

/usr/local/bin/download-credentials.sh mdsd
/usr/local/bin/download-credentials.sh mdm
MDSDCERTIFICATESAN=$(openssl x509 -in /var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem -noout -subject | sed -e 's/.*CN = //')

cat >/etc/systemd/system/watch-mdm-credentials.service <<EOF
[Unit]
Description=Watch for changes in mdm.pem and restarts the mdm service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart mdm.service

[Install]
WantedBy=multi-user.target
EOF

cat >/etc/systemd/system/watch-mdm-credentials.path <<EOF
[Path]
PathModified=/etc/mdm.pem

[Install]
WantedBy=multi-user.target
EOF

systemctl enable watch-mdm-credentials.path
systemctl start watch-mdm-credentials.path

mkdir /etc/systemd/system/mdsd.service.d
cat >/etc/systemd/system/mdsd.service.d/override.conf <<'EOF'
[Unit]
After=network-online.target
EOF

cat >/etc/default/mdsd <<EOF
MDSD_ROLE_PREFIX=/var/run/mdsd/default
MDSD_OPTIONS="-A -d -r \$MDSD_ROLE_PREFIX"

export MONITORING_GCS_ENVIRONMENT='$MDSDENVIRONMENT'
export MONITORING_GCS_ACCOUNT='$RPMDSDACCOUNT'
export MONITORING_GCS_REGION='$LOCATION'
export MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault
export MONITORING_GCS_AUTH_ID='$MDSDCERTIFICATESAN'
export MONITORING_GCS_NAMESPACE='$RPMDSDNAMESPACE'
export MONITORING_CONFIG_VERSION='$GATEWAYMDSDCONFIGVERSION'
export MONITORING_USE_GENEVA_CONFIG_SERVICE=true

export MONITORING_TENANT='$LOCATION'
export MONITORING_ROLE=gateway
export MONITORING_ROLE_INSTANCE='$(hostname)'

export MDSD_MSGPACK_SORT_COLUMNS=1
EOF

# setting MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault seems to have caused mdsd not
# to honour SSL_CERT_FILE any more, heaven only knows why.
mkdir -p /usr/lib/ssl/certs
csplit -f /usr/lib/ssl/certs/cert- -b %03d.pem /etc/pki/tls/certs/ca-bundle.crt /^$/1 {*} >/dev/null
c_rehash /usr/lib/ssl/certs

# we leave clientId blank as long as only 1 managed identity assigned to vmss
# if we have more than 1, we will need to populate with clientId used for off-node scanning
cat >/etc/default/vsa-nodescan-agent.config <<EOF
{
    "Nice": 19,
    "Timeout": 10800,
    "ClientId": "",
    "TenantId": "$AZURESECPACKVSATENANTID",
    "QualysStoreBaseUrl": "$AZURESECPACKQUALYSURL",
    "ProcessTimeout": 300,
    "CommandDelay": 0
  }
EOF

# we start a cron job to run every hour to ensure the said directory is accessible
# by the correct user as it gets created by root and may cause a race condition
# where root owns the dir instead of syslog
# TODO: https://msazure.visualstudio.com/AzureRedHatOpenShift/_workitems/edit/12591207
cat >/etc/cron.d/mdsd-chown-workaround <<EOF
SHELL=/bin/bash
PATH=/bin
0 * * * * root chown syslog:syslog /var/opt/microsoft/linuxmonagent/eh/EventNotice/arorplogs*
EOF

echo "enabling aro services"
for service in aro-gateway auoms azsecd azsecmond mdsd mdm chronyd fluentbit; do
  systemctl enable $service.service
done

for scan in baseline clamav software; do
  /usr/local/bin/azsecd config -s $scan -d P1D
done

echo "rebooting"
restorecon -RF /var/log/*
(sleep 30; reboot) &


#!/bin/bash

echo "setting ssh password authentication"
# We need to manually set PasswordAuthentication to true in order for the VMSS Access JIT to work
sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
systemctl reload sshd.service

echo "running RHUI fix"
yum update -y --disablerepo='*' --enablerepo='rhui-microsoft-azure*'

echo "running yum update"
yum -y -x WALinuxAgent -x WALinuxAgent-udev update --allowerasing

echo "extending partition table"
# Linux block devices are inconsistently named
# it's difficult to tie the lvm pv to the physical disk using /dev/disk files, which is why lvs is used here
physicalDisk="$(lvs -o devices -a | head -n2 | tail -n1 | cut -d ' ' -f 3 | cut -d \( -f 1 | tr -d '[:digit:]')"
growpart "$physicalDisk" 2

echo "extending filesystems"
lvextend -l +20%FREE /dev/rootvg/rootlv
xfs_growfs /

lvextend -l +100%FREE /dev/rootvg/varlv
xfs_growfs /var

echo "importing rpm repositories"
rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8
rpm --import https://packages.microsoft.com/keys/microsoft.asc

for attempt in {1..5}; do
  yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm && break
  if [[ ${attempt} -lt 5 ]]; then sleep 10; else exit 1; fi
done

echo "configuring logrotate"
cat >/etc/logrotate.conf <<'EOF'
# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 2 weeks worth of backlogs
rotate 2

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp and btmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    create 0664 root utmp
        minsize 1M
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}
EOF

echo "configuring yum repository and running yum update"
cat >/etc/yum.repos.d/azure.repo <<'EOF'
[azure-cli]
name=azure-cli
baseurl=https://packages.microsoft.com/yumrepos/azure-cli
enabled=yes
gpgcheck=yes

[azurecore]
name=azurecore
baseurl=https://packages.microsoft.com/yumrepos/azurecore
enabled=yes
gpgcheck=no
EOF

semanage fcontext -a -t var_log_t "/var/log/journal(/.*)?"
mkdir -p /var/log/journal

for attempt in {1..5}; do
yum -y install clamav azsec-clamav azsec-monitor azure-cli azure-mdsd azure-security podman podman-docker openssl-perl python3 && break
  # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505
  if [[ ${attempt} -lt 5 ]]; then sleep 10; else exit 1; fi
done

# https://access.redhat.com/security/cve/cve-2020-13401
echo "applying firewall rules"
cat >/etc/sysctl.d/02-disable-accept-ra.conf <<'EOF'
net.ipv6.conf.all.accept_ra=0
EOF

cat >/etc/sysctl.d/01-disable-core.conf <<'EOF'
kernel.core_pattern = |/bin/true
EOF
sysctl --system

firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --add-port=444/tcp --permanent
firewall-cmd --add-port=445/tcp --permanent
firewall-cmd --add-port=2222/tcp --permanent

export AZURE_CLOUD_NAME=$AZURECLOUDNAME

echo "logging into prod acr"
az login -i --allow-no-subscriptions

# Suppress emulation output for podman instead of docker for az acr compatability
mkdir -p /etc/containers/
touch /etc/containers/nodocker

mkdir -p /root/.docker
REGISTRY_AUTH_FILE=/root/.docker/config.json az acr login --name "$(sed -e 's|.*/||' <<<"$ACRRESOURCEID")"

MDMIMAGE="${RPIMAGE%%/*}/${MDMIMAGE##*/}"
docker pull "$MDMIMAGE"
docker pull "$RPIMAGE"
docker pull "$FLUENTBITIMAGE"

az logout

echo "configuring fluentbit service"
mkdir -p /etc/fluentbit/
mkdir -p /var/lib/fluent

cat >/etc/fluentbit/fluentbit.conf <<'EOF'
[INPUT]
	Name systemd
	Tag journald
	Systemd_Filter _COMM=aro

[FILTER]
	Name modify
	Match journald
	Remove_wildcard _
	Remove TIMESTAMP

[FILTER]
	Name rewrite_tag
	Match journald
	Rule $LOGKIND asyncqos asyncqos true

[FILTER]
	Name modify
	Match asyncqos
	Remove CLIENT_PRINCIPAL_NAME
	Remove FILE
	Remove COMPONENT

[FILTER]
	Name rewrite_tag
	Match journald
	Rule $LOGKIND ifxaudit ifxaudit false

[OUTPUT]
	Name forward
	Match *
	Port 29230
EOF

echo "FLUENTBITIMAGE=$FLUENTBITIMAGE" >/etc/sysconfig/fluentbit

cat >/etc/systemd/system/fluentbit.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=0

[Service]
RestartSec=1s
EnvironmentFile=/etc/sysconfig/fluentbit
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --security-opt label=disable \
  --entrypoint /opt/td-agent-bit/bin/td-agent-bit \
  --net=host \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -v /etc/fluentbit/fluentbit.conf:/etc/fluentbit/fluentbit.conf \
  -v /var/lib/fluent:/var/lib/fluent:z \
  -v /var/log/journal:/var/log/journal:ro \
  -v /etc/machine-id:/etc/machine-id:ro \
  $FLUENTBITIMAGE \
  -c /etc/fluentbit/fluentbit.conf

ExecStop=/usr/bin/docker stop %N
Restart=always
RestartSec=5
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

mkdir /etc/aro-rp
base64 -d <<<"$ADMINAPICABUNDLE" >/etc/aro-rp/admin-ca-bundle.pem
if [[ -n "$ARMAPICABUNDLE" ]]; then
  base64 -d <<<"$ARMAPICABUNDLE" >/etc/aro-rp/arm-ca-bundle.pem
fi
chown -R 1000:1000 /etc/aro-rp

echo "configuring mdm service"
cat >/etc/sysconfig/mdm <<EOF
MDMFRONTENDURL='$MDMFRONTENDURL'
MDMIMAGE='$MDMIMAGE'
MDMSOURCEENVIRONMENT='$LOCATION'
MDMSOURCEROLE=rp
MDMSOURCEROLEINSTANCE='$(hostname)'
EOF

mkdir /var/etw
cat >/etc/systemd/system/mdm.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/mdm
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --entrypoint /usr/sbin/MetricsExtension \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -m 2g \
  -v /etc/mdm.pem:/etc/mdm.pem \
  -v /var/etw:/var/etw:z \
  $MDMIMAGE \
  -CertFile /etc/mdm.pem \
  -FrontEndUrl $MDMFRONTENDURL \
  -Logger Console \
  -LogLevel Warning \
  -PrivateKeyFile /etc/mdm.pem \
  -SourceEnvironment $MDMSOURCEENVIRONMENT \
  -SourceRole $MDMSOURCEROLE \
  -SourceRoleInstance $MDMSOURCEROLEINSTANCE
ExecStop=/usr/bin/docker stop %N
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring aro-rp service"
cat >/etc/sysconfig/aro-rp <<EOF
ACR_RESOURCE_ID='$ACRRESOURCEID'
ADMIN_API_CLIENT_CERT_COMMON_NAME='$ADMINAPICLIENTCERTCOMMONNAME'
ARM_API_CLIENT_CERT_COMMON_NAME='$ARMAPICLIENTCERTCOMMONNAME'
AZURE_ARM_CLIENT_ID='$ARMCLIENTID'
AZURE_FP_CLIENT_ID='$FPCLIENTID'
AZURE_FP_SERVICE_PRINCIPAL_ID='$FPSERVICEPRINCIPALID'
BILLING_E2E_STORAGE_ACCOUNT_ID='$BILLINGE2ESTORAGEACCOUNTID'
CLUSTER_MDSD_ACCOUNT='$CLUSTERMDSDACCOUNT'
CLUSTER_MDSD_CONFIG_VERSION='$CLUSTERMDSDCONFIGVERSION'
CLUSTER_MDSD_NAMESPACE='$CLUSTERMDSDNAMESPACE'
DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME'
DOMAIN_NAME='$LOCATION.$CLUSTERPARENTDOMAINNAME'
GATEWAY_DOMAINS='$GATEWAYDOMAINS'
GATEWAY_RESOURCEGROUP='$GATEWAYRESOURCEGROUPNAME'
KEYVAULT_PREFIX='$KEYVAULTPREFIX'
MDM_ACCOUNT='$RPMDMACCOUNT'
MDM_NAMESPACE=RP
MDSD_ENVIRONMENT='$MDSDENVIRONMENT'
RP_FEATURES='$RPFEATURES'
RPIMAGE='$RPIMAGE'
ARO_INSTALL_VIA_HIVE='$CLUSTERSINSTALLVIAHIVE'
ARO_HIVE_DEFAULT_INSTALLER_PULLSPEC='$CLUSTERDEFAULTINSTALLERPULLSPEC'
ARO_ADOPT_BY_HIVE='$CLUSTERSADOPTBYHIVE'
USE_CHECKACCESS='$USECHECKACCESS'
EOF

cat >/etc/systemd/system/aro-rp.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/aro-rp
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -e ACR_RESOURCE_ID \
  -e ADMIN_API_CLIENT_CERT_COMMON_NAME \
  -e ARM_API_CLIENT_CERT_COMMON_NAME \
  -e AZURE_ARM_CLIENT_ID \
  -e AZURE_FP_CLIENT_ID \
  -e BILLING_E2E_STORAGE_ACCOUNT_ID \
  -e CLUSTER_MDSD_ACCOUNT \
  -e CLUSTER_MDSD_CONFIG_VERSION \
  -e CLUSTER_MDSD_NAMESPACE \
  -e DATABASE_ACCOUNT_NAME \
  -e DOMAIN_NAME \
  -e GATEWAY_DOMAINS \
  -e GATEWAY_RESOURCEGROUP \
  -e KEYVAULT_PREFIX \
  -e MDM_ACCOUNT \
  -e MDM_NAMESPACE \
  -e MDSD_ENVIRONMENT \
  -e RP_FEATURES \
  -e ARO_INSTALL_VIA_HIVE \
  -e ARO_HIVE_DEFAULT_INSTALLER_PULLSPEC \
  -e ARO_ADOPT_BY_HIVE \
  -e USE_CHECKACCESS \
  -m 2g \
  -p 443:8443 \
  -v /etc/aro-rp:/etc/aro-rp \
  -v /run/systemd/journal:/run/systemd/journal \
  -v /var/etw:/var/etw:z \
  $RPIMAGE \
  rp
ExecStop=/usr/bin/docker stop -t 3600 %N
TimeoutStopSec=3600
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring aro-dbtoken service"
cat >/etc/sysconfig/aro-dbtoken <<EOF
DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME'
AZURE_DBTOKEN_CLIENT_ID='$DBTOKENCLIENTID'
AZURE_GATEWAY_SERVICE_PRINCIPAL_ID='$GATEWAYSERVICEPRINCIPALID'
KEYVAULT_PREFIX='$KEYVAULTPREFIX'
MDM_ACCOUNT='$RPMDMACCOUNT'
MDM_NAMESPACE=DBToken
RPIMAGE='$RPIMAGE'
EOF

cat >/etc/systemd/system/aro-dbtoken.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/aro-dbtoken
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -e AZURE_GATEWAY_SERVICE_PRINCIPAL_ID \
  -e DATABASE_ACCOUNT_NAME \
  -e AZURE_DBTOKEN_CLIENT_ID \
  -e KEYVAULT_PREFIX \
  -e MDM_ACCOUNT \
  -e MDM_NAMESPACE \
  -m 2g \
  -p 445:8445 \
  -v /run/systemd/journal:/run/systemd/journal \
  -v /var/etw:/var/etw:z \
  $RPIMAGE \
  dbtoken
ExecStop=/usr/bin/docker stop -t 3600 %N
TimeoutStopSec=3600
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring aro-monitor service"
cat >/etc/sysconfig/aro-monitor <<EOF
CLUSTER_MDM_ACCOUNT='$CLUSTERMDMACCOUNT'
CLUSTER_MDM_NAMESPACE=BBM
DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME'
KEYVAULT_PREFIX='$KEYVAULTPREFIX'
MDM_ACCOUNT='$RPMDMACCOUNT'
MDM_NAMESPACE=BBM
RPIMAGE='$RPIMAGE'
EOF

cat >/etc/systemd/system/aro-monitor.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target

[Service]
EnvironmentFile=/etc/sysconfig/aro-monitor
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -e CLUSTER_MDM_ACCOUNT \
  -e CLUSTER_MDM_NAMESPACE \
  -e DATABASE_ACCOUNT_NAME \
  -e KEYVAULT_PREFIX \
  -e MDM_ACCOUNT \
  -e MDM_NAMESPACE \
  -m 2.5g \
  -v /run/systemd/journal:/run/systemd/journal \
  -v /var/etw:/var/etw:z \
  $RPIMAGE \
  monitor
Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target
EOF

echo "configuring aro-portal service"
cat >/etc/sysconfig/aro-portal <<EOF
AZURE_PORTAL_ACCESS_GROUP_IDS='$PORTALACCESSGROUPIDS'
AZURE_PORTAL_CLIENT_ID='$PORTALCLIENTID'
AZURE_PORTAL_ELEVATED_GROUP_IDS='$PORTALELEVATEDGROUPIDS'
DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME'
KEYVAULT_PREFIX='$KEYVAULTPREFIX'
MDM_ACCOUNT='$RPMDMACCOUNT'
MDM_NAMESPACE=Portal
PORTAL_HOSTNAME='$LOCATION.admin.$RPPARENTDOMAINNAME'
RPIMAGE='$RPIMAGE'
EOF

cat >/etc/systemd/system/aro-portal.service <<'EOF'
[Unit]
After=network-online.target
Wants=network-online.target
StartLimitInterval=0

[Service]
EnvironmentFile=/etc/sysconfig/aro-portal
ExecStartPre=-/usr/bin/docker rm -f %N
ExecStart=/usr/bin/docker run \
  --hostname %H \
  --name %N \
  --rm \
  --cap-drop net_raw \
  -e AZURE_PORTAL_ACCESS_GROUP_IDS \
  -e AZURE_PORTAL_CLIENT_ID \
  -e AZURE_PORTAL_ELEVATED_GROUP_IDS \
  -e DATABASE_ACCOUNT_NAME \
  -e KEYVAULT_PREFIX \
  -e MDM_ACCOUNT \
  -e MDM_NAMESPACE \
  -e PORTAL_HOSTNAME \
  -m 2g \
  -p 444:8444 \
  -p 2222:2222 \
  -v /run/systemd/journal:/run/systemd/journal \
  -v /var/etw:/var/etw:z \
  $RPIMAGE \
  portal
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target
EOF

echo "configuring mdsd and mdm services"
chcon -R system_u:object_r:var_log_t:s0 /var/opt/microsoft/linuxmonagent

mkdir -p /var/lib/waagent/Microsoft.Azure.KeyVault.Store

for var in "mdsd" "mdm"; do
cat >/etc/systemd/system/download-$var-credentials.service <<EOF
[Unit]
Description=Periodic $var credentials refresh

[Service]
Type=oneshot
ExecStart=/usr/local/bin/download-credentials.sh $var
EOF

cat >/etc/systemd/system/download-$var-credentials.timer <<EOF
[Unit]
Description=Periodic $var credentials refresh
After=network-online.target
Wants=network-online.target

[Timer]
OnBootSec=0min
OnCalendar=0/12:00:00
AccuracySec=5s

[Install]
WantedBy=timers.target
EOF
done

cat >/usr/local/bin/download-credentials.sh <<EOF
#!/bin/bash
set -eu

COMPONENT="\$1"
echo "Download \$COMPONENT credentials"

TEMP_DIR=\$(mktemp -d)
export AZURE_CONFIG_DIR=\$(mktemp -d)

echo "Logging into Azure..."
RETRIES=3
while [ "\$RETRIES" -gt 0 ]; do
    if az login -i --allow-no-subscriptions
    then
        echo "az login successful"
        break
    else
        echo "az login failed. Retrying..."
        let RETRIES-=1
        sleep 5
    fi
done

trap "cleanup" EXIT

cleanup() {
  az logout
  [[ "\$TEMP_DIR" =~ /tmp/.+ ]] && rm -rf \$TEMP_DIR
  [[ "\$AZURE_CONFIG_DIR" =~ /tmp/.+ ]] && rm -rf \$AZURE_CONFIG_DIR
}

if [ "\$COMPONENT" = "mdm" ]; then
  CURRENT_CERT_FILE="/etc/mdm.pem"
elif [ "\$COMPONENT" = "mdsd" ]; then
  CURRENT_CERT_FILE="/var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem"
else
  echo Invalid usage && exit 1
fi

SECRET_NAME="rp-\${COMPONENT}"
NEW_CERT_FILE="\$TEMP_DIR/\$COMPONENT.pem"
for attempt in {1..5}; do
  az keyvault secret download --file \$NEW_CERT_FILE --id "https://$KEYVAULTPREFIX-svc.$KEYVAULTDNSSUFFIX/secrets/\$SECRET_NAME" && break
  if [[ \$attempt -lt 5 ]]; then sleep 10; else exit 1; fi
done

if [ -f \$NEW_CERT_FILE ]; then
  if [ "\$COMPONENT" = "mdsd" ]; then
    chown syslog:syslog \$NEW_CERT_FILE
  else
    sed -i -ne '1,/END CERTIFICATE/ p' \$NEW_CERT_FILE
  fi
  if ! diff $NEW_CERT_FILE $CURRENT_CERT_FILE >/dev/null 2>&1; then
    chmod 0600 \$NEW_CERT_FILE
    mv \$NEW_CERT_FILE \$CURRENT_CERT_FILE
  fi
else
  echo Failed to refresh certificate for \$COMPONENT && exit 1
fi
EOF

chmod u+x /usr/local/bin/download-credentials.sh

systemctl enable download-mdsd-credentials.timer
systemctl enable download-mdm-credentials.timer

/usr/local/bin/download-credentials.sh mdsd
/usr/local/bin/download-credentials.sh mdm
MDSDCERTIFICATESAN=$(openssl x509 -in /var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem -noout -subject | sed -e 's/.*CN = //')

cat >/etc/systemd/system/watch-mdm-credentials.service <<EOF
[Unit]
Description=Watch for changes in mdm.pem and restarts the mdm service

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl restart mdm.service

[Install]
WantedBy=multi-user.target
EOF

cat >/etc/systemd/system/watch-mdm-credentials.path <<EOF
[Path]
PathModified=/etc/mdm.pem

[Install]
WantedBy=multi-user.target
EOF

systemctl enable watch-mdm-credentials.path
systemctl start watch-mdm-credentials.path

mkdir /etc/systemd/system/mdsd.service.d
cat >/etc/systemd/system/mdsd.service.d/override.conf <<'EOF'
[Unit]
After=network-online.target
EOF

cat >/etc/default/mdsd <<EOF
MDSD_ROLE_PREFIX=/var/run/mdsd/default
MDSD_OPTIONS="-A -d -r \$MDSD_ROLE_PREFIX"

export MONITORING_GCS_ENVIRONMENT='$MDSDENVIRONMENT'
export MONITORING_GCS_ACCOUNT='$RPMDSDACCOUNT'
export MONITORING_GCS_REGION='$LOCATION'
export MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault
export MONITORING_GCS_AUTH_ID='$MDSDCERTIFICATESAN'
export MONITORING_GCS_NAMESPACE='$RPMDSDNAMESPACE'
export MONITORING_CONFIG_VERSION='$RPMDSDCONFIGVERSION'
export MONITORING_USE_GENEVA_CONFIG_SERVICE=true

export MONITORING_TENANT='$LOCATION'
export MONITORING_ROLE=rp
export MONITORING_ROLE_INSTANCE='$(hostname)'

export MDSD_MSGPACK_SORT_COLUMNS=1
EOF

# setting MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault seems to have caused mdsd not
# to honour SSL_CERT_FILE any more, heaven only knows why.
mkdir -p /usr/lib/ssl/certs
csplit -f /usr/lib/ssl/certs/cert- -b %03d.pem /etc/pki/tls/certs/ca-bundle.crt /^$/1 {*} >/dev/null
c_rehash /usr/lib/ssl/certs

# we leave clientId blank as long as only 1 managed identity assigned to vmss
# if we have more than 1, we will need to populate with clientId used for off-node scanning
cat >/etc/default/vsa-nodescan-agent.config <<EOF
{
    "Nice": 19,
    "Timeout": 10800,
    "ClientId": "",
    "TenantId": "$AZURESECPACKVSATENANTID",
    "QualysStoreBaseUrl": "$AZURESECPACKQUALYSURL",
    "ProcessTimeout": 300,
    "CommandDelay": 0
  }
EOF

# we start a cron job to run every hour to ensure the said directory is accessible
# by the correct user as it gets created by root and may cause a race condition
# where root owns the dir instead of syslog
# TODO: https://msazure.visualstudio.com/AzureRedHatOpenShift/_workitems/edit/12591207
cat >/etc/cron.d/mdsd-chown-workaround <<EOF
SHELL=/bin/bash
PATH=/bin
0 * * * * root chown syslog:syslog /var/opt/microsoft/linuxmonagent/eh/EventNotice/arorplogs*
EOF

echo "enabling aro services"
for service in aro-dbtoken aro-monitor aro-portal aro-rp auoms azsecd azsecmond mdsd mdm chronyd fluentbit; do
  systemctl enable $service.service
done

for scan in baseline clamav software; do
  /usr/local/bin/azsecd config -s $scan -d P1D
done

echo "rebooting"
restorecon -RF /var/log/*
(sleep 30; reboot) &


#!/bin/bash

set -eu

template_src_path="gktemplates-src"
template_path="gktemplates"

main() {

  if [[ ! -d ${template_path} ]]; then
    mkdir -p "${template_path}"
  fi

  for tmpl in $(find ${template_src_path} -name '*.tmpl'); do
    filename="$(basename -- ${tmpl} .tmpl).yaml"
    echo "Generating ${template_path}/${filename} from ${tmpl}"
    gomplate -f "${tmpl}" > "${template_path}/${filename}"

    src_dir="$(dirname "${tmpl}")"
    for req in src.rego src_test.rego; do
      if [[ ! -f "${src_dir}/${req}" ]]; then
        echo "${src_dir}/${req} is missing"
        exit 1
      fi
    done
  done
}

main


#!/bin/bash

set -eu

template_src_path="gktemplates-src"
constraint_path="gkconstraints"
constraint_test_path="gkconstraints-test"

echo "opa test:"
for folder in ${template_src_path}/*
do
  echo "opa test ${folder}/*.rego"
  opa test ${folder}/*.rego
done

echo "gator test:"
if [[ ! -d ${constraint_test_path} ]]; then
  mkdir -p "${constraint_test_path}"
fi
for file in ${constraint_path}/*
do
  echo "expand constraints $file"
  filename="$(basename -- ${file})"
  sed 's/{{.Enforcement}}/deny/g' $file > $constraint_test_path/$filename
done

for folder in ${template_src_path}/*
do
  echo "gator verify ${folder}"
  gator verify ${folder}
done


#!/bin/bash
set -e
set -x

if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then
    mkdir -p /tmp/build-golang/src/github.com/json-iterator
    ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go
fi
export GOPATH=/tmp/build-golang
go get -u github.com/golang/dep/cmd/dep
cd /tmp/build-golang/src/github.com/json-iterator/go
exec $GOPATH/bin/dep ensure -update


#!/usr/bin/env bash

set -e
echo "" > coverage.txt

for d in $(go list ./... | grep -v vendor); do
    go test -coverprofile=profile.out -coverpkg=github.com/json-iterator/go $d
    if [ -f profile.out ]; then
        cat profile.out >> coverage.txt
        rm profile.out
    fi
done


#!/bin/sh

cd s2/cmd/_s2sx/ || exit 1
go generate .


#!/usr/bin/env bash

set -e
echo "" > coverage.txt

for d in $(go list ./... | grep -v vendor); do
    go test -race -coverprofile=profile.out -covermode=atomic "$d"
    if [ -f profile.out ]; then
        cat profile.out >> coverage.txt
        rm profile.out
    fi
done


#!/usr/bin/env bash

set -e
echo "" > coverage.txt

for d in $(go list ./... | grep -v vendor); do
    go test -coverprofile=profile.out -coverpkg=github.com/modern-go/concurrent $d
    if [ -f profile.out ]; then
        cat profile.out >> coverage.txt
        rm profile.out
    fi
done