From 8c0a0545e6f771533216fc33271544ae46b136b9 Mon Sep 17 00:00:00 2001 From: aguilard Date: Mon, 13 Nov 2023 13:16:32 +0000 Subject: [PATCH] Feature 10982: Public Cloud Robot Suite Add scripts needed in tests image container for public clouds: creating and deleting VMs, k8s cluster, etc. Change-Id: Ia454aedfd8e4fd0c100fc82a12ace725b01491dd Signed-off-by: aguilard --- build-debpkg.sh | 2 +- cloud-scripts/add-vim-and-k8scluster.sh | 56 +++++ cloud-scripts/create-k8s.sh | 297 ++++++++++++++++++++++++ cloud-scripts/create-osm-vm.sh | 71 ++++++ cloud-scripts/delete-k8s.sh | 106 +++++++++ cloud-scripts/delete-osm-vm.sh | 66 ++++++ cloud-scripts/remote-extract-logs.sh | 39 ++++ cloud-scripts/remote-install-osm.sh | 54 +++++ 8 files changed, 690 insertions(+), 1 deletion(-) create mode 100755 cloud-scripts/add-vim-and-k8scluster.sh create mode 100755 cloud-scripts/create-k8s.sh create mode 100755 cloud-scripts/create-osm-vm.sh create mode 100755 cloud-scripts/delete-k8s.sh create mode 100755 cloud-scripts/delete-osm-vm.sh create mode 100755 cloud-scripts/remote-extract-logs.sh create mode 100755 cloud-scripts/remote-install-osm.sh diff --git a/build-debpkg.sh b/build-debpkg.sh index 6214460..26441d1 100755 --- a/build-debpkg.sh +++ b/build-debpkg.sh @@ -15,7 +15,7 @@ # under the License. -PKG_DIRECTORIES="robot-systest conformance-tests" +PKG_DIRECTORIES="robot-systest conformance-tests cloud-scripts" PKG_FILES="CONTRIBUTING.md LICENSE README.md charm.sh requirements.txt" MDG_NAME=tests DEB_INSTALL=debian/osm-${MDG_NAME}.install diff --git a/cloud-scripts/add-vim-and-k8scluster.sh b/cloud-scripts/add-vim-and-k8scluster.sh new file mode 100755 index 0000000..98010d5 --- /dev/null +++ b/cloud-scripts/add-vim-and-k8scluster.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Add VIM to OSM +if [ "${CLOUD_TYPE}" == "azure" ]; then + echo "Adding VIM to OSM" + set +x + osm vim-create --name "$VIM_TARGET" --account_type "$CLOUD_TYPE" --auth_url http://www.azure.com \ + --user "$AZURE_CLIENT_ID" --password "$AZURE_SECRET" --tenant "$AZURE_TENANT" --description "None" \ + --config "{region_name: '$AZURE_REGION', resource_group: '$RESOURCE_GROUP', + subscription_id: '$AZURE_SUBSCRIPTION_ID', vnet_name: '$VNET_NAME', + flavors_pattern: '$AZURE_FLAVORS_PATTERN'}" + sleep 10 + osm vim-show "$VIM_TARGET" +elif [ "${CLOUD_TYPE}" == "gcp" ]; then + echo "CLOUD_TYPE '${CLOUD_TYPE}' still not supported" + exit +else + echo "CLOUD_TYPE '${CLOUD_TYPE}' not valid" + exit +fi + +# Add SDN controller to OSM +if [ -n "$SDNC_TYPE" ] && [ -n "$SDNC_USER" ] && [ -n "$SDNC_URL" ]; then + echo "Adding $SDNC_TYPE SDN controller to OSM" + set +x + osm sdnc-create --name sdnc --user "$SDNC_USER" --password "$SDNC_PASSWORD" --url "$SDNC_URL" --type "$SDNC_TYPE" + sleep 3 + osm sdnc-list + # TO-DO: add port-mapping file to VIM + # osm vim-update "$VIM_TARGET" --sdn_controller sdnc --sdn_port_mapping port-mapping-etsi-vim.yaml +fi + +# Add K8s cluster to OSM +if [ -n "$K8S_CREDENTIALS" ] && [ -n "$VIM_TARGET" ] && [ -n "$K8S_IMAGE_NAME" ]; then + echo "Adding K8s cluster to OSM" + osm k8scluster-add --creds $K8S_CREDENTIALS --version v1 --vim $VIM_TARGET \ + --k8s-nets "{'net1': '$VIM_MGMT_NET'}" $K8S_IMAGE_NAME --description "Robot cluster" + sleep 20 + osm k8scluster-show $K8S_IMAGE_NAME +fi diff --git a/cloud-scripts/create-k8s.sh b/cloud-scripts/create-k8s.sh new file mode 100755 index 0000000..2fcaf40 --- /dev/null +++ b/cloud-scripts/create-k8s.sh @@ -0,0 +1,297 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Create a new VM for installing a k8s cluster and its NSG on Azure. SSH key pair ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub must exist. +# To do this it reads the following environment variables: +# - K8S_IMAGE_NAME: name of the new VM +# - RESOURCE_GROUP: name of the resource-group where the VM will be created +# - VNET_NAME: name of the virtual network when creating a new one or referencing an existing one +# - VIM_MGMT_NET: name or ID of the subnet to which the VM will be connected +# - SOURCE_IMAGE_NAME: name of operating system image used (e.g. "Canonical:0001-com-ubuntu-server-jammy:22_04-lts:latest") +# - K8S_FLAVOR_NAME: the VM size to be created (e.g. "Standard_A2_v2") +# - PRIORITY: "Low", "Regular" or Spot" +function create_azure_vm { + set -eux + az vm create --resource-group "${RESOURCE_GROUP}" --name "${K8S_IMAGE_NAME}" --image "${SOURCE_IMAGE_NAME}" --size "${K8S_FLAVOR_NAME}" --vnet-name "${VNET_NAME}" --subnet "${VIM_MGMT_NET}" --public-ip-address "" --admin-username ubuntu --priority "${PRIORITY}" + export K8S_IP=$(az vm show -d -g "${RESOURCE_GROUP}" -n "${K8S_IMAGE_NAME}" --query privateIps | tr -d \") + # Add a security group rule + INTERFACE_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${K8S_IMAGE_NAME} --query networkProfile.networkInterfaces[0].id) + INTERFACE_ID=${INTERFACE_ID:1:-1} + SECURITY_GROUP_ID=$(az network nic show --id ${INTERFACE_ID} --query networkSecurityGroup.id) + SECURITY_GROUP_ID=${SECURITY_GROUP_ID:1:-1} + SECURITY_GROUP_NAME=$(az resource show --ids ${SECURITY_GROUP_ID} --query name) + SECURITY_GROUP_NAME=${SECURITY_GROUP_NAME:1:-1} + az network nsg rule create -n microk8s --nsg-name ${SECURITY_GROUP_NAME} --priority 2000 -g ${RESOURCE_GROUP} --description "Microk8s port" --protocol TCP --destination-port-ranges 16443 +} + +# Create a new VM for installing a k8s cluster on GCP. SSH key pair ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub must exist. +# To do this it reads the following environment variables: +# - K8S_IMAGE_NAME: name of the new VM +# - GCP_PROJECT: name of project where the VM will be allocated +# - GCP_ZONE: name of the zone (e.g. "europe-west1-b") +# - VIM_MGMT_NET: name or ID of the subnet to which the VM will be connected +# - GCP_MACHINE_TYPE: machine type used for the instance (e.g. "e2-standard-4", run 'gcloud compute machine-types list') +# - GCP_IMAGE_PROJECT: the Google Cloud project against which all image and image family references will be resolved (e.g. "ubuntu-os-cloud") +# - GCP_IMAGE_FAMILY: the image family for the operating system that the boot disk will be initialized with (e.g. "ubuntu-2204-lts") +# - GCP_DISK_SIZE: disk size ib GB +function create_gcp_vm { + gcloud compute instances create "${K8S_IMAGE_NAME}" --project="${GCP_PROJECT}" --zone="${GCP_ZONE}" --machine-type="${GCP_MACHINE_TYPE}" \ + --network-interface=network-tier=PREMIUM,subnet=${VIM_MGMT_NET} --maintenance-policy=MIGRATE \ + --image-family=${GCP_IMAGE_FAMILY} --image-project=${GCP_IMAGE_PROJECT} --metadata-from-file=ssh-keys=${HOME}/.ssh/id_rsa.pub \ + --create-disk=auto-delete=yes,boot=yes,image-family=${GCP_IMAGE_FAMILY},image-project=${GCP_IMAGE_PROJECT},device-name=${K8S_IMAGE_NAME},mode=rw,size=${GCP_DISK_SIZE} -q +} + +# Install via SSH a microk8s cluster on a VM. Writes a kubeconfig.yaml file in $ROBOT_REPORT_FOLDER path. +# To do this it reads the following environment variables: +# - K8S_IP: IP address of the target machine +function install_remote_microk8s { + set +e + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@"${K8S_IP}" 'sudo apt-get update -y && sudo apt-get upgrade -y && sudo reboot' + sleep 90 + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${K8S_IP} << EOF 2>&1 +set -eux +sudo snap install yq +sudo snap install microk8s --classic +sudo usermod -a -G microk8s ubuntu +newgrp microk8s +sudo microk8s.status --wait-ready +sudo microk8s.enable storage dns +set +eux +EOF + + # Enable MetalLB + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${K8S_IP} << 'EOF' 2>&1 +set -eux +PRIVATE_IP=$(hostname -I | awk '{print $1}') +echo ${PRIVATE_IP} +sudo microk8s.enable metallb:${PRIVATE_IP}-${PRIVATE_IP} +EOF + + # Update the certificate to allow connections from outside as well + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${K8S_IP} << EOF 2>&1 +set -aux +sudo sed -i "s/\#MOREIPS/IP.3 = ${K8S_IP}/g" /var/snap/microk8s/current/certs/csr.conf.template +cat /var/snap/microk8s/current/certs/csr.conf.template +EOF + + # Save the credentials + echo ================================================================ + echo K8s cluster credentials: + echo ================================================================ + echo + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${K8S_IP} \ +'sudo microk8s.config' | sed "s/server: .*/server: https:\/\/${K8S_IP}:16443/g" \ +| tee ${ROBOT_REPORT_FOLDER}/kubeconfig.yaml +} + +# Create an AKS cluster with one node on Azure using a new subnet. Writes a kubeconfig.yaml file in $ROBOT_REPORT_FOLDER path. +# Required the following environment variables: +# - K8S_IMAGE_NAME: name of the AKS cluster to be created +# - RESOURCE_GROUP: name of the resource-group where the VM will be created +# - VNET_NAME: name of the virtual network when creating a new one or referencing an existing one +# - K8S_FLAVOR_NAME: the VM size to be created (e.g. "Standard_D4as_v4") +# IMPORTANT: required a vnet at least /16 because the it's created a new subnet with a random third byte +function create_azure_aks { + # Gets first subnet prefix and creates a new one with random number in third byte + set -eux + SUBNET_PREFIX=$(az network vnet show --resource-group "${RESOURCE_GROUP}" --name "${VNET_NAME}" --query subnets[0].addressPrefix -o tsv) + IFS=. read BYTE1 BYTE2 BYTE3 BYTE4 <<< "$SUBNET_PREFIX" + IFS=/ read BYTE4 MASK <<< "$BYTE4" + if [ "$MASK" -ge "24" ]; then + BYTE3=$((100 + ($RANDOM % 50) * 2)) + PREFIX="$BYTE1.$BYTE2.${BYTE3}.$BYTE4/$MASK" + SUBNET_NAME="aks-${BYTE3}" + BYTE3=$((BYTE3 + 1)) + CIDR="$BYTE1.$BYTE2.${BYTE3}.$BYTE4/$MASK" + DNS_IP="$BYTE1.$BYTE2.${BYTE3}.10" + # Verifies that new subnet does not exist previously + az network vnet subnet show --resource-group "${RESOURCE_GROUP}" --vnet-name "${VNET_NAME}" --name "$SUBNET_NAME" -o table + if [ "$?" -ne 0 ]; then + # Creates the subnet in $VNET_NAME network + az network vnet subnet create --resource-group "${RESOURCE_GROUP}" --vnet-name "${VNET_NAME}" --name "$SUBNET_NAME" --address-prefixes "${PREFIX}" + if [ "$?" -eq 0 ]; then + SUBNET_ID=$(az network vnet subnet show --resource-group OSM-CTIO --vnet-name "${VNET_NAME}" --name "${SUBNET_NAME}" --query id -o tsv) + + # Creates k8s cluster + az aks create -y --resource-group "${RESOURCE_GROUP}" --name "${K8S_IMAGE_NAME}" --node-count 1 --node-vm-size "${K8S_FLAVOR_NAME}" --dns-service-ip "${DNS_IP}" --network-plugin kubenet --service-cidr "${CIDR}" --vnet-subnet-id "${SUBNET_ID}" + az aks get-credentials --resource-group "${RESOURCE_GROUP}" --name "${K8S_IMAGE_NAME}" --admin -f ${ROBOT_REPORT_FOLDER}/kubeconfig.yaml + fi + fi + fi +} + +# Create a GKE cluster with one node on GCP. Writes a kubeconfig.yaml file in $ROBOT_REPORT_FOLDER path. +# Required the following environment variables: +# - K8S_IMAGE_NAME: name of the GKE cluster to be created +# - GCP_PROJECT: name of project where the cluster will be allocated +# - GCP_ZONE: name of the zone (e.g. "europe-west1-b") +# - GCP_MACHINE_TYPE: machine type used for the instance (e.g. "e2-standard-4", run 'gcloud compute machine-types list') +# - GCP_DISK_SIZE: disk size ib GB +function create_gcp_gke { + gcloud container clusters create "${K8S_IMAGE_NAME}" --project="${GCP_PROJECT}" --zone="${GCP_ZONE}" --num-nodes=1 --machine-type="${GCP_MACHINE_TYPE}" --disk-size "${GCP_DISK_SIZE}" --enable-ip-alias --image-type "COS_CONTAINERD" +} + +# Get kubeconfig.yaml from a GKE cluster on GCP. Writes a kubeconfig.yaml file in $ROBOT_REPORT_FOLDER path. +function get_gke_kubeconfig { + set -eu -o pipefail + FILE=${ROBOT_REPORT_FOLDER}/kubeconfig.yaml + SA=osm-sa + NAMESPACE=osm + echo "Creating the Kubernetes Service Account with minimal RBAC permissions." + kubectl apply -f - < $FILE < ${ROBOT_REPORT_FOLDER}/k8s_environment.rc +export CLOUD_TYPE="${CLOUD_TYPE}" +export USE_PAAS_K8S="${USE_PAAS_K8S}" +EOF + +# Branch by USE_PAAS_K8S and CLOUD_TYPE values +if [ "${USE_PAAS_K8S}" == "FALSE" ]; then + echo "Creating a new IaaS k8s cluster in ${CLOUD_TYPE}" + if [ "${CLOUD_TYPE}" == "azure" ]; then + # Create VM on Azure + create_azure_vm + elif [ "${CLOUD_TYPE}" == "gcp" ]; then + # Create VM on GCP + create_gcp_vm + else + echo "CLOUD_TYPE '${CLOUD_TYPE}' not valid for IaaS" + exit + fi + # Add environment variables + echo "export K8S_IP=\"${K8S_IP}\"" >> ${ROBOT_REPORT_FOLDER}/k8s_environment.rc + echo "export K8S_IMAGE_NAME=\"${K8S_IMAGE_NAME}\"" >> ${ROBOT_REPORT_FOLDER}/k8s_environment.rc + + # MicroK8s installation + install_remote_microk8s +else + echo "Creating a new PaaS k8s cluster in ${CLOUD_TYPE}" + if [ "${CLOUD_TYPE}" == "azure" ]; then + create_azure_aks + echo "export K8S_IMAGE_NAME=\"${K8S_IMAGE_NAME}\"" >> ${ROBOT_REPORT_FOLDER}/k8s_environment.rc + elif [ "${CLOUD_TYPE}" == "gcp" ]; then + create_gcp_gke + get_gke_kubeconfig + echo "export K8S_IMAGE_NAME=\"${K8S_IMAGE_NAME}\"" >> ${ROBOT_REPORT_FOLDER}/k8s_environment.rc + else + echo "CLOUD_TYPE '${CLOUD_TYPE}' not valid for PaaS" + fi +fi + +# Add K8S_CREDENTIALS environment variable +echo "export K8S_CREDENTIALS=${ROBOT_REPORT_FOLDER}/kubeconfig.yaml" >> ${ROBOT_REPORT_FOLDER}/k8s_environment.rc +echo File with new environment was created at ${ROBOT_REPORT_FOLDER}/k8s_environment.rc + diff --git a/cloud-scripts/create-osm-vm.sh b/cloud-scripts/create-osm-vm.sh new file mode 100755 index 0000000..454cb06 --- /dev/null +++ b/cloud-scripts/create-osm-vm.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Create a new VM for installing OSM and its NSG on Azure. SSH key pair files ~/.ssh/id_rsa +# and ~/.ssh/id_rsa.pub must exist. The NEW_OSM_IP variable is set with IP address. +# To do this it reads the following environment variables: +# - OSM_IMAGE_NAME: name of the new VM +# - RESOURCE_GROUP: name of the resource-group where the VM will be created +# - VNET_NAME: name of the virtual network when creating a new one or referencing an existing one +# - VIM_MGMT_NET: name or ID of the subnet to which the VM will be connected +# - SOURCE_IMAGE_NAME: name of operating system image used (e.g. "Canonical:0001-com-ubuntu-server-jammy:22_04-lts:latest") +# - FLAVOR_NAME: the VM size to be created (e.g. "Standard_D4as_v4") +# - PRIORITY: "Low", "Regular" or Spot" +function create_azure_vm { + # Create the VM in resource-group + set -eux + az vm create --resource-group "${RESOURCE_GROUP}" --name "${OSM_IMAGE_NAME}" --image "${SOURCE_IMAGE_NAME}" --size "${FLAVOR_NAME}" --vnet-name "${VNET_NAME}" --subnet "${VIM_MGMT_NET}" --public-ip-address "" --admin-username ubuntu --priority "${PRIORITY}" --os-disk-size-gb 64 + export NEW_OSM_IP=$(az vm show -d -g "${RESOURCE_GROUP}" -n "${OSM_IMAGE_NAME}" --query privateIps | tr -d \") + + # Add a security group rule + INTERFACE_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${OSM_IMAGE_NAME} --query networkProfile.networkInterfaces[0].id) + INTERFACE_ID=${INTERFACE_ID:1:-1} + SECURITY_GROUP_ID=$(az network nic show --id ${INTERFACE_ID} --query networkSecurityGroup.id) + SECURITY_GROUP_ID=${SECURITY_GROUP_ID:1:-1} + SECURITY_GROUP_NAME=$(az resource show --ids ${SECURITY_GROUP_ID} --query name) + SECURITY_GROUP_NAME=${SECURITY_GROUP_NAME:1:-1} + az network nsg rule create -n osm --nsg-name ${SECURITY_GROUP_NAME} --priority 2000 -g ${RESOURCE_GROUP} --description "NBI and Prometheus ports" --protocol TCP --destination-port-ranges 9999 9091 +} + +if [ -n "${1:-}" ]; then # If there is an argument, it must be the hostname + export OSM_IMAGE_NAME=$1 +else + export OSM_IMAGE_NAME=osmtest$(date '+%Y%m%d%H%M') +fi + +# Branch by CLOUD_TYPE value ("azure", "gcp") +if [ "${CLOUD_TYPE}" == "azure" ]; then + # Azure VIM + create_azure_vm +elif [ "${CLOUD_TYPE}" == "gcp" ]; then + # Google Cloud VIM + export OSM_IMAGE_NAME=$(echo $OSM_IMAGE_NAME | sed "s/_/-/g") + echo "CLOUD_TYPE '${CLOUD_TYPE}' still not supported" + exit +else + echo "Invalid cloud type: ${CLOUD_TYPE}" +fi + +# Log new environment variables +mkdir -p ${ROBOT_REPORT_FOLDER} +cat < ${ROBOT_REPORT_FOLDER}/osm_environment.rc +export CLOUD_TYPE="${CLOUD_TYPE}" +export OSM_HOSTNAME="${NEW_OSM_IP}" +export OSM_IMAGE_NAME="${OSM_IMAGE_NAME}" +EOF +echo File with new environment was created at ${ROBOT_REPORT_FOLDER}/osm_environment.rc diff --git a/cloud-scripts/delete-k8s.sh b/cloud-scripts/delete-k8s.sh new file mode 100755 index 0000000..99f0153 --- /dev/null +++ b/cloud-scripts/delete-k8s.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Delete a VM and its resources (nic, disk, nsg, public IP) on Azure. +# To do this it reads the following environment variables: +# - K8S_NAME: name of the VM +# - RESOURCE_GROUP: name of the resource-group where the VM is +function delete_azure_vm { + set -eux + INTERFACE_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${K8S_NAME} --query networkProfile.networkInterfaces[0].id) + INTERFACE_ID=${INTERFACE_ID:1:-1} + OS_DISK_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${K8S_NAME} --query storageProfile.osDisk.managedDisk.id) + OS_DISK_ID=${OS_DISK_ID:1:-1} + SECURITY_GROUP_ID=$(az network nic show --id ${INTERFACE_ID} --query networkSecurityGroup.id) + SECURITY_GROUP_ID=${SECURITY_GROUP_ID:1:-1} + PUBLIC_IP_ID=$(az network nic show --id ${INTERFACE_ID} --query ipConfigurations[0].publicIpAddress.id) + PUBLIC_IP_ID=${PUBLIC_IP_ID:1:-1} + az vm delete --resource-group ${RESOURCE_GROUP} --name ${K8S_NAME} --yes + az network nic delete --id ${INTERFACE_ID} + az disk delete --id ${OS_DISK_ID} --yes + az network nsg delete --id ${SECURITY_GROUP_ID} + if [ -n "${PUBLIC_IP_ID}" ]; then + az network public-ip delete --id ${PUBLIC_IP_ID} + fi +} + +# Delete an existing AKS cluster and its subnet. +# Required the following environment variables: +# - K8S_NAME: name of the AKS +# - RESOURCE_GROUP: name of the resource-group where the AKS was created +function delete_azure_aks { + SUBNET_ID=$(az aks show --resource-group "${RESOURCE_GROUP}" --name ${K8S_NAME} --query agentPoolProfiles[].vnetSubnetId -o tsv) + az aks delete -y --resource-group "${RESOURCE_GROUP}" --name "${K8S_NAME}" + az network vnet subnet delete --ids "${SUBNET_ID}" +} + +# Delete a VM on GCP. +# To do this it reads the following environment variables: +# - K8S_NAME: name of the VM +# - GCP_PROJECT: name of project where the VM is +# - GCP_ZONE: name of the zone +function delete_gcp_vm { + gcloud compute instances delete "${K8S_NAME}" --project="${GCP_PROJECT}" --zone="${GCP_ZONE}" --delete-disks all -q +} + +# Delete an existing GKE cluster. +# Required the following environment variables: +# - K8S_NAME: name of the AKS +# - GCP_PROJECT: name of project where the VM is +# - GCP_ZONE: name of the zone +function delete_gcp_gke { + gcloud container clusters delete "${K8S_NAME}" --project="${GCP_PROJECT}" --zone="${GCP_ZONE}" -q +} + +# If there is an argument, it must be the cluster name +if [ -n "${1:-}" ]; then + K8S_NAME=$1 +else + K8S_NAME="${K8S_IMAGE_NAME}" +fi +# Default USE_PAAS_K8S is "FALSE" +if [ -z "${USE_PAAS_K8S}" ]; then + USE_PAAS_K8S="FALSE" +fi +# Branch by USE_PAAS_K8S and CLOUD_TYPE values +if [ "${USE_PAAS_K8S}" == "FALSE" ]; then + # Deletes k8s cluster in a cloud's VM + echo "Deleting IaaS k8s cluster in ${CLOUD_TYPE}" + if [ "${CLOUD_TYPE}" == "azure" ]; then + # Azure VIM + delete_azure_vm + elif [ "${CLOUD_TYPE}" == "gcp" ]; then + # GCP VIM + delete_gcp_vm + else + echo "Invalid cloud type: ${CLOUD_TYPE}" + fi +else + # Deletes k8s cluster as PaaS in cloud + if [ "${CLOUD_TYPE}" == "azure" ]; then + echo "Deleting PaaS k8s cluster in Azure" + delete_azure_aks + elif [ "${CLOUD_TYPE}" == "gcp" ]; then + echo "Deleting PaaS k8s cluster in GCP" + delete_gcp_gke + else + echo "Invalid cloud type: ${CLOUD_TYPE}" + fi + +fi + diff --git a/cloud-scripts/delete-osm-vm.sh b/cloud-scripts/delete-osm-vm.sh new file mode 100755 index 0000000..5328cbe --- /dev/null +++ b/cloud-scripts/delete-osm-vm.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +# Delete a VM and its resources (nic, disk, nsg, public IP) on Azure. +# To do this it reads the following environment variables: +# - VM_NAME: name of the VM +# - RESOURCE_GROUP: name of the resource-group where the VM is +function delete_azure_vm { + set -eux + INTERFACE_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${VM_NAME} --query networkProfile.networkInterfaces[0].id) + INTERFACE_ID=${INTERFACE_ID:1:-1} + OS_DISK_ID=$(az vm show --resource-group ${RESOURCE_GROUP} --name ${VM_NAME} --query storageProfile.osDisk.managedDisk.id) + OS_DISK_ID=${OS_DISK_ID:1:-1} + SECURITY_GROUP_ID=$(az network nic show --id ${INTERFACE_ID} --query networkSecurityGroup.id) + SECURITY_GROUP_ID=${SECURITY_GROUP_ID:1:-1} + PUBLIC_IP_ID=$(az network nic show --id ${INTERFACE_ID} --query ipConfigurations[0].publicIpAddress.id) + PUBLIC_IP_ID=${PUBLIC_IP_ID:1:-1} + az vm delete --resource-group ${RESOURCE_GROUP} --name ${VM_NAME} --yes + az network nic delete --id ${INTERFACE_ID} + az disk delete --id ${OS_DISK_ID} --yes + az network nsg delete --id ${SECURITY_GROUP_ID} + if [ -n "${PUBLIC_IP_ID}" ]; then + az network public-ip delete --id ${PUBLIC_IP_ID} + fi +} + +# Delete a VM on GCP. +# To do this it reads the following environment variables: +# - VM_NAME: name of the VM +# - GCP_PROJECT: name of project where the VM is +# - GCP_ZONE: name of the zone +function delete_gcp_vm { + gcloud compute instances delete "${VM_NAME}" --project="${GCP_PROJECT}" --zone="${GCP_ZONE}" --delete-disks all -q +} + +if [ -n "${1:-}" ]; then # If there is an argument, it must be the hostname + VM_NAME=$1 +else + VM_NAME="${OSM_IMAGE_NAME}" +fi + +# Branch by CLOUD_TYPE value ("azure", "gcp") +if [ "${CLOUD_TYPE}" == "azure" ]; then + # Azure VIM + delete_azure_vm +elif [ "${CLOUD_TYPE}" == "gcp" ]; then + # GCP VIM + delete_gcp_vm +else + echo "Invalid cloud type: ${CLOUD_TYPE}" +fi diff --git a/cloud-scripts/remote-extract-logs.sh b/cloud-scripts/remote-extract-logs.sh new file mode 100755 index 0000000..b304826 --- /dev/null +++ b/cloud-scripts/remote-extract-logs.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +set -e + +# Extracts logs from "deployments" +for MODULE in 'grafana' 'keystone' 'lcm' 'mon' 'nbi' 'pol' 'ro' 'ngui' 'airflow-scheduler' 'pushgateway-prometheus-pushgateway' 'webhook-translator' +do + echo Saving ${MODULE} logs... + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${OSM_HOSTNAME} \ + 'kubectl -n osm logs deployment/"'${MODULE}'" --all-containers=true 2>&1 | cat' > "${ROBOT_REPORT_FOLDER}"/"osm-deploy-${MODULE}".log +done + +# Extracts logs from "statefulsets" +for MODULE in 'kafka' 'mongo' 'mysql' 'prometheus' 'zookeeper' 'alertmanager' +do + echo Saving ${MODULE} logs... + ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${OSM_HOSTNAME} \ + 'kubectl -n osm logs statefulset/"'${MODULE}'" --all-containers=true 2>&1 | cat' > "${ROBOT_REPORT_FOLDER}"/"osm-sts-${MODULE}".log +done + +echo +echo All logs saved to ${ROBOT_REPORT_FOLDER}/ + diff --git a/cloud-scripts/remote-install-osm.sh b/cloud-scripts/remote-install-osm.sh new file mode 100755 index 0000000..1b91020 --- /dev/null +++ b/cloud-scripts/remote-install-osm.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +####################################################################################### +# Copyright ETSI Contributors and Others. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. +####################################################################################### + +ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@"${OSM_HOSTNAME}" \ +'sudo apt-get update -y && sudo apt-get upgrade -y && sudo reboot' + +sleep 90 + +# OSM installation +INSTALLER_PARAMETERS="-R ${REPO_BASE} -t ${DOCKER_TAG} -r ${REPO_NAME} -y" +echo "INSTALLER_URL: $INSTALLER_URL" +echo "INSTALLER_PARAMETERS: $INSTALLER_PARAMETERS" +ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${OSM_HOSTNAME} << EOF 2>&1 +set -eux +wget "${INSTALLER_URL}" +chmod +x install_osm.sh +./install_osm.sh ${INSTALLER_PARAMETERS} 2>&1 | tee osm_install_log.txt +set +eux +EOF + +# # Installs additional tools for telemetry +# set +eux +# ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${OSM_HOSTNAME} 'sudo apt-get install -y sysstat' +# set -eux + +# Gets Juju password from LCM env file +set +eux +JUJU_PWD=$(ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@${OSM_HOSTNAME} 'kubectl -n osm exec -ti deploy/lcm -- env | grep OSMLCM_VCA_SECRET | cut -d = -f 2') +set -eux + +# Updates environment variables and logs them +export JUJU_PASSWORD="${JUJU_PWD}" + +# Logs new/updated environment variables +cat <> ${ROBOT_REPORT_FOLDER}/osm_environment.rc +export JUJU_PASSWORD="${JUJU_PWD}" +EOF + +echo Environment was updated at ${ROBOT_REPORT_FOLDER}/osm_environment.rc -- 2.17.1