diff --git a/.tekton/git-pr-status/listener-git-pr-status.yaml b/.tekton/git-pr-status/listener-git-pr-status.yaml index c9ecabd7..06f27204 100644 --- a/.tekton/git-pr-status/listener-git-pr-status.yaml +++ b/.tekton/git-pr-status/listener-git-pr-status.yaml @@ -85,6 +85,15 @@ spec: - name: us_south_reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" resourcetemplates: - apiVersion: v1 kind: PersistentVolumeClaim @@ -159,6 +168,12 @@ spec: value: $(params.us_south_cluster_id) - name: us_south_reservation_id value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) workspaces: - name: pipeline-ws persistentVolumeClaim: diff --git a/.tekton/git-pr-status/pipeline-git-pr-status.yaml b/.tekton/git-pr-status/pipeline-git-pr-status.yaml index 85a8a3e9..cbe63a0e 100644 --- a/.tekton/git-pr-status/pipeline-git-pr-status.yaml +++ b/.tekton/git-pr-status/pipeline-git-pr-status.yaml @@ -63,6 +63,15 @@ spec: - name: reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: pipeline-ws tasks: @@ -193,6 +202,12 @@ spec: value: $(params.reservation_id) - name: pr-revision value: $(params.pr-revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) - name: wes-hpc-da-ubuntu-pr runAfter: [git-clone, pre-requisites-install, ssh-key-creation] taskRef: @@ -227,6 +242,12 @@ spec: value: $(params.reservation_id) - name: pr-revision value: $(params.pr-revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) - name: ssh-key-deletion runAfter: [wes-hpc-da-rhel-pr, wes-hpc-da-ubuntu-pr] taskRef: @@ -239,62 +260,6 @@ spec: value: $(params.pipeline-debug) - name: pr-revision value: $(params.pr-revision) - - name: display-test-run-pr-output-log - runAfter: [git-clone, set-git-pr-running, wes-hpc-da-rhel-pr, wes-hpc-da-ubuntu-pr] - workspaces: - - name: workspace - workspace: pipeline-ws - taskSpec: - workspaces: - - name: workspace - description: The git repo will be cloned onto the volume backing this workspace - mountPath: /artifacts - steps: - - name: test-run-output-pr-log-rhel-ubuntu - image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest - workingDir: "/artifacts" - command: ["/bin/bash", "-c"] - args: - - | - #!/bin/bash - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - name: test-run-output-pr-log-rhel-ubuntu-error-check - image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest - workingDir: "/artifacts" - command: ["/bin/bash", "-c"] - args: - - | - #!/bin/bash - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - echo "*******************************************************" - if [ -d "$DIRECTORY" ]; then - # Check any error message in the test run output log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/test_output/log*") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in the test run output log. Please check log." - fi - fi - echo "*******************************************************" - else - echo "$DIRECTORY does not exits" - exit 1 - fi - name: inspect-wes-hpc-infra-log runAfter: [git-clone, set-git-pr-running, wes-hpc-da-rhel-pr, wes-hpc-da-ubuntu-pr] workspaces: @@ -306,7 +271,7 @@ spec: description: The git repo will be cloned onto the volume backing this workspace mountPath: /artifacts steps: - - name: inspect-infra-error-rhel-pr + - name: error-check-on-pr-rhel-log onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" @@ -314,65 +279,19 @@ spec: args: - | #!/bin/bash - LOG_FILE="pipeline-testrunbasic-rhel*" - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - else - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - fi - fi - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installations" - exit 1 - fi - - name: inspect-infra-error-ubuntu-pr + LOG_FILE="pipeline-pr-rhel*" + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" "PR" + - name: error-check-on-pr-ubuntu-log image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" command: ["/bin/bash", "-c"] args: - | #!/bin/bash - LOG_FILE="pipeline-testrunbasic-ubuntu*" - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - else - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - fi - fi - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installations" - exit 1 - fi + LOG_FILE="pipeline-pr-ubuntu*" + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" "PR" finally: - name: set-git-commit-status taskRef: diff --git a/.tekton/git-trigger/listener-git-trigger.yaml b/.tekton/git-trigger/listener-git-trigger.yaml index bf14d40c..87215a41 100644 --- a/.tekton/git-trigger/listener-git-trigger.yaml +++ b/.tekton/git-trigger/listener-git-trigger.yaml @@ -92,6 +92,15 @@ spec: - name: us_south_reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" resourcetemplates: - apiVersion: v1 kind: PersistentVolumeClaim @@ -172,6 +181,12 @@ spec: value: $(params.us_south_cluster_id) - name: us_south_reservation_id value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) workspaces: - name: pipeline-ws persistentVolumeClaim: @@ -227,6 +242,12 @@ spec: value: $(params.us_south_cluster_id) - name: us_south_reservation_id value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) --- apiVersion: tekton.dev/v1beta1 kind: EventListener diff --git a/.tekton/git-trigger/pipeline-git-trigger.yaml b/.tekton/git-trigger/pipeline-git-trigger.yaml index 1892a6dc..105df27f 100644 --- a/.tekton/git-trigger/pipeline-git-trigger.yaml +++ b/.tekton/git-trigger/pipeline-git-trigger.yaml @@ -92,6 +92,15 @@ spec: - name: us_south_reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: pipeline-ws tasks: @@ -202,6 +211,12 @@ spec: value: $(params.us_south_reservation_id) - name: revision value: $(params.revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) - name: wes-hpc-da-ubuntu runAfter: [git-clone, pre-requisites-install, ssh-key-creation] taskRef: @@ -254,8 +269,130 @@ spec: value: $(params.us_south_reservation_id) - name: revision value: $(params.revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) + - name: wes-hpc-da-region + runAfter: [git-clone, pre-requisites-install, ssh-key-creation] + taskRef: + name: wes-hpc-da-region + workspaces: + - name: workspace + workspace: pipeline-ws + params: + - name: repository + value: $(params.repository) + - name: pipeline-debug + value: $(params.pipeline-debug) + - name: ssh_keys + value: $(params.ssh_keys) + - name: zone + value: $(params.zone) + - name: cluster_prefix + value: $(params.cluster_prefix) + - name: resource_group + value: $(params.resource_group) + - name: remote_allowed_ips + value: $(params.remote_allowed_ips) + - name: compute_image_name_rhel + value: $(params.compute_image_name_rhel) + - name: compute_image_name_ubuntu + value: $(params.compute_image_name_ubuntu) + - name: login_image_name + value: $(params.login_image_name) + - name: cluster_id + value: $(params.cluster_id) + - name: reservation_id + value: $(params.reservation_id) + - name: us_east_zone + value: $(params.us_east_zone) + - name: us_east_cluster_id + value: $(params.us_east_cluster_id) + - name: us_east_reservation_id + value: $(params.us_east_reservation_id) + - name: eu_de_zone + value: $(params.eu_de_zone) + - name: eu_de_cluster_id + value: $(params.eu_de_cluster_id) + - name: eu_de_reservation_id + value: $(params.eu_de_reservation_id) + - name: us_south_zone + value: $(params.us_south_zone) + - name: us_south_cluster_id + value: $(params.us_south_cluster_id) + - name: us_south_reservation_id + value: $(params.us_south_reservation_id) + - name: revision + value: $(params.revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) + - name: wes-hpc-da-negative + runAfter: [git-clone, pre-requisites-install, ssh-key-creation] + taskRef: + name: wes-hpc-da-negative + workspaces: + - name: workspace + workspace: pipeline-ws + params: + - name: repository + value: $(params.repository) + - name: pipeline-debug + value: $(params.pipeline-debug) + - name: ssh_keys + value: $(params.ssh_keys) + - name: zone + value: $(params.zone) + - name: cluster_prefix + value: $(params.cluster_prefix) + - name: resource_group + value: $(params.resource_group) + - name: remote_allowed_ips + value: $(params.remote_allowed_ips) + - name: compute_image_name_rhel + value: $(params.compute_image_name_rhel) + - name: compute_image_name_ubuntu + value: $(params.compute_image_name_ubuntu) + - name: login_image_name + value: $(params.login_image_name) + - name: cluster_id + value: $(params.cluster_id) + - name: reservation_id + value: $(params.reservation_id) + - name: us_east_zone + value: $(params.us_east_zone) + - name: us_east_cluster_id + value: $(params.us_east_cluster_id) + - name: us_east_reservation_id + value: $(params.us_east_reservation_id) + - name: eu_de_zone + value: $(params.eu_de_zone) + - name: eu_de_cluster_id + value: $(params.eu_de_cluster_id) + - name: eu_de_reservation_id + value: $(params.eu_de_reservation_id) + - name: us_south_zone + value: $(params.us_south_zone) + - name: us_south_cluster_id + value: $(params.us_south_cluster_id) + - name: us_south_reservation_id + value: $(params.us_south_reservation_id) + - name: revision + value: $(params.revision) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) - name: ssh-key-deletion - runAfter: [wes-hpc-da-rhel, wes-hpc-da-ubuntu] + runAfter: [wes-hpc-da-rhel, wes-hpc-da-ubuntu, wes-hpc-da-negative, wes-hpc-da-region] taskRef: name: ssh-key-deletion workspaces: @@ -299,51 +436,24 @@ spec: description: The git repo will be cloned onto the volume backing this workspace mountPath: /artifacts steps: - - name: test-run-output-log-rhel-ubuntu-suite + - name: display-test-output-log-rhel-ubuntu-suite image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" command: ["/bin/bash", "-c"] args: - | #!/bin/bash - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - name: test-run-output-log-rhel-ubuntu-suite-error-check + source .tekton/scripts/issue_track.sh + display_test_output + - name: error-check-test-output-log-rhel-ubuntu-suite image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" command: ["/bin/bash", "-c"] args: - | #!/bin/bash - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - echo "*******************************************************" - if [ -d "$DIRECTORY" ]; then - # Check any error message in the test run output log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/test_output/log*") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in the test run output log. Please check log." - fi - fi - echo "*******************************************************" - else - echo "$DIRECTORY does not exits" - exit 1 - fi + source .tekton/scripts/issue_track.sh + check_error_test_output - name: inspect-wes-hpc-infra-log runAfter: [git-clone, wes-hpc-da-rhel, wes-hpc-da-ubuntu] workspaces: @@ -355,7 +465,7 @@ spec: description: The git repo will be cloned onto the volume backing this workspace mountPath: /artifacts steps: - - name: inspect-infra-error-rhel-suite + - name: error-check-on-rhel-suite-log onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" @@ -364,32 +474,9 @@ spec: - | #!/bin/bash LOG_FILE="pipeline-rhel-suite*" - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - else - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - fi - fi - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installations" - exit 1 - fi - - name: inspect-infra-error-ubuntu-suite + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" + - name: error-check-on-ubuntu-suite-log image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest workingDir: "/artifacts" command: ["/bin/bash", "-c"] @@ -397,28 +484,25 @@ spec: - | #!/bin/bash LOG_FILE="pipeline-ubuntu-suite*" - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "$error_check" - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - else - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - fi - fi - else - echo "$DIRECTORY does not exits" - exit 1 - fi - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installations" - exit 1 - fi + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" + - name: error-check-on-regions-suite-log + image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest + workingDir: "/artifacts" + command: ["/bin/bash", "-c"] + args: + - | + #!/bin/bash + LOG_FILE="pipeline-regions-suite*" + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" + - name: error-check-on-negative-suite-log + image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest + workingDir: "/artifacts" + command: ["/bin/bash", "-c"] + args: + - | + #!/bin/bash + LOG_FILE="pipeline-negative-suite*" + source .tekton/scripts/issue_track.sh + issue_track "${LOG_FILE}" diff --git a/.tekton/scripts/common_utils.sh b/.tekton/scripts/common_utils.sh new file mode 100644 index 00000000..4d267e4d --- /dev/null +++ b/.tekton/scripts/common_utils.sh @@ -0,0 +1,37 @@ +#!/bin/bash +echo "************************************************" +get_commit_ssh_key() { + CICD_SSH_KEY=cicd + REVISION=$1 + if [ "${REVISION}" ]; then + CICD_SSH_KEY=$(echo $CICD_SSH_KEY-"$REVISION") + else + CICD_SSH_KEY=$CICD_SSH_KEY-tekton + fi +} + +get_pr_ssh_key() { + PR_REVISION=$1 + CICD_SSH_KEY=cicd + CICD_SSH_KEY=$(echo $CICD_SSH_KEY-"$PR_REVISION") +} + +git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv +echo "export PATH=$PATH:$HOME/.tfenv/bin" >> ~/.bashrc +ln -s ~/.tfenv/bin/* /usr/local/bin +tfenv install 1.5.7 +tfenv use 1.5.7 +terraform --version + +cd "$(pwd)"/ && +echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && +echo "export GOROOT=$(pwd)/go" >> ~/.bashrc +# shellcheck source=/dev/null. +source ~/.bashrc +go version + +python3 -m pip install --upgrade pip +python3 -m pip install --pre --upgrade requests==2.20.0 +python3 -m pip install --pre --upgrade ibm-cos-sdk==2.0.1 + +echo "************************************************" diff --git a/.tekton/scripts/cos_data.py b/.tekton/scripts/cos_data.py new file mode 100644 index 00000000..8bd063c0 --- /dev/null +++ b/.tekton/scripts/cos_data.py @@ -0,0 +1,90 @@ +import glob +import os +import sys + +import ibm_boto3 +from ibm_botocore.client import ClientError, Config + + +class DownloadFromCOS: + + def upload_file(self, bucket_name, file_path, filename): + print(f"-- working on file {filename}") + try: + self.client.upload_file( + Filename=filename, Bucket=bucket_name, Key=file_path + ) + print(f"--- {filename} successfully uploaded in {file_path}!") + except ClientError as be: + print("[CLIENT ERROR]: {0}\n".format(be)) + self.return_code += 1 + except Exception as e: + print("[CLIENT ERROR] Unable to upload file to COS: {0}".format(e)) + self.return_code += 1 + + def upload_multiple_files(self, FILE_NAME_FULLPATH, bucket_name, file_path): + for filename in glob.glob(f"{FILE_NAME_FULLPATH}"): + file_path += filename + self.upload_file(filename, bucket_name, file_path) + + def download_file(self, bucket_name, filename): + print(f"-- working on file {filename}") + try: + self.client.download_file( + Bucket=bucket_name, Key=filename, Filename=filename + ) + print(f"--- {filename} successfully downloaded!") + except ClientError as be: + print("[CLIENT ERROR]: {0}\n".format(be)) + self.return_code += 1 + except Exception as e: + print("[CLIENT ERROR] Unable to download file from COS: {0}".format(e)) + self.return_code += 1 + + def delete_file(self, bucket_name, filename): + print(f"-- working on file {filename}") + try: + self.client.delete_object(Bucket=bucket_name, Key=filename) + print(f"--- {filename} successfully deleted!") + except ClientError as be: + print("[CLIENT ERROR]: {0}\n".format(be)) + self.return_code += 1 + except Exception as e: + print("[CLIENT ERROR] Unable to download file from COS: {0}".format(e)) + self.return_code += 1 + + def main(self): + # Create S3 Client with constants for IBM COS values + region = os.environ["COS_REGION"] + self.client = ibm_boto3.client( + "s3", + ibm_api_key_id=os.environ["COS_API_KEY_ID"], + ibm_service_instance_id=os.environ["COS_INSTANCE_CRN"], + config=Config(signature_version="oauth"), + endpoint_url=f"https://s3.{region}.cloud-object-storage.appdomain.cloud", + ) + ACTION = sys.argv[1] + FOLDER = "" + TARGET_PATH = "" + if ACTION == "UPLOAD": + FILENAME = sys.argv[2] + TARGET_PATH = sys.argv[3] + else: + FOLDER = sys.argv[2] + + bucket_name = os.environ["COS_BUCKET"] + self.return_code = 0 + + if ACTION == "UPLOAD": + self.upload_file(bucket_name, TARGET_PATH, FILENAME) + else: + objects = self.client.list_objects(Bucket=bucket_name, Prefix=FOLDER) + for obj in objects["Contents"]: + if ACTION == "DELETE": + self.delete_file(bucket_name, obj["Key"]) + elif ACTION == "DOWNLOAD": + self.download_file(bucket_name, obj["Key"]) + return self.return_code + + +DownloadFromCOS().main() diff --git a/.tekton/scripts/cos_upload.sh b/.tekton/scripts/cos_upload.sh new file mode 100644 index 00000000..891ed800 --- /dev/null +++ b/.tekton/scripts/cos_upload.sh @@ -0,0 +1,20 @@ +#!/bin/bash +cos_upload() { + CHECK_PR=$1 + export COS_REGION=${cos_region:?} + export COS_API_KEY_ID=$API_KEY + export COS_BUCKET=${cos_bucket:?} + export COS_INSTANCE_CRN=${cos_instance_crn:?} + CURRENT_DATE="$(date +%d-%m-%Y)" + COS_FOLDER="TEKTON/$CURRENT_DATE" + + COMMIT_MESSAGE="$(git log -1 --pretty=format:%s)" + if [[ -z "$COMMIT_MESSAGE" ]]; then + COMMIT_MESSAGE="manual" + fi + + if [[ -z "$CHECK_PR" ]]; then + python3 /artifacts/.tekton/scripts/cos_data.py UPLOAD "$DIRECTORY"/test_output/log* "$COS_FOLDER"/TEST_OUTPUT/"$COMMIT_MESSAGE"/log-"$(date +%d-%m-%Y-%H-%M-%S)" + fi + python3 /artifacts/.tekton/scripts/cos_data.py UPLOAD "$LOG_FILE" "$COS_FOLDER"/LOG_DATA/"$COMMIT_MESSAGE"/"$LOG_FILE".log +} diff --git a/.tekton/scripts/issue_track.sh b/.tekton/scripts/issue_track.sh new file mode 100644 index 00000000..39bd37e9 --- /dev/null +++ b/.tekton/scripts/issue_track.sh @@ -0,0 +1,81 @@ +#!/bin/bash +issue_track() { + LOG_FILE=$1 + CHECK_PR_OR_NEAGTIVE=$2 + CHECK_TASK=$3 + DIRECTORY="/artifacts/tests" + if [ -d "$DIRECTORY" ]; then + if [[ "${CHECK_PR_OR_NEAGTIVE}" != "negative_suite" ]]; then + # Track error/fail from the suites log file + log_error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") + if [[ "$log_error_check" ]]; then + # Skip printing error/fail suites logs on task window + if [[ "${CHECK_TASK}" != "TASK" ]]; then + echo "$log_error_check" + echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." + exit 1 + else + echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." + exit 1 + fi + fi + fi + + if [[ "${CHECK_PR_OR_NEAGTIVE}" != "PR" ]]; then + # Track test_output log file initiated or not + test_output_file_check=$(find $DIRECTORY/test_output/log* 2>/dev/null) + if [[ -z "$test_output_file_check" ]]; then + echo "Test output log file not initiated." + exit 1 + fi + fi + + # Track suites log file initiated or not + log_file_check=$(find $DIRECTORY/*.cicd 2>/dev/null) + if [[ -z "$log_file_check" ]]; then + echo "Test Suite have not initated and log file not created, check with packages or binaries installation" + exit 1 + fi + else + echo "$DIRECTORY does not exits" + exit 1 + fi +} + +display_test_output() { + DIRECTORY="/artifacts/tests" + if [ -d "$DIRECTORY" ]; then + # Display test_output log file + test_output_file_check=$(find $DIRECTORY/test_output/log* 2>/dev/null) + if [[ -z "$test_output_file_check" ]]; then + echo "Test output log file not initiated." + exit 1 + else + echo "********************** Display Test Output Log Start ********************" + cat $DIRECTORY/test_output/log* + echo "********************** Display Test Output Log End **********************" + fi + else + echo "$DIRECTORY does not exits" + exit 1 + fi +} + +check_error_test_output() { + DIRECTORY="/artifacts/tests" + if [ -d "$DIRECTORY" ]; then + # Check error in test_output log + log_error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' ${DIRECTORY/test_output/log*}") + if [[ "$log_error_check" ]]; then + echo "********************** Check Error in Test Output Log Start *************" + echo "$log_error_check" + echo "********************** Check Error in Test Output Log End **********************" + echo "Found Error/FAIL/ERROR in the test run output log. Please check log." + else + echo "No Error found in ${DIRECTORY/test_output/log*}" + fi + else + echo "$DIRECTORY does not exits" + exit 1 + fi +} diff --git a/.tekton/scripts/ssh_create_delete.sh b/.tekton/scripts/ssh_create_delete.sh new file mode 100644 index 00000000..d09ab857 --- /dev/null +++ b/.tekton/scripts/ssh_create_delete.sh @@ -0,0 +1,91 @@ +#!/bin/bash +REGIONS=("us-south" "eu-de" "us-east") +CICD_SSH_KEY=cicd +if [ -z "${PR_REVISION}" ] && [ "${REVISION}" ]; then +CICD_SSH_KEY=$(echo $CICD_SSH_KEY-"$REVISION") +elif [ "${PR_REVISION}" ] && [ -z "${REVISION}" ]; then +CICD_SSH_KEY=$(echo $CICD_SSH_KEY-"$PR_REVISION") +else +resource_group=$CICD_SSH_KEY-tekton +fi + +ssh_key_create() { +file=/artifacts/.ssh +if [ ! -e "$file" ]; then + echo "$file does not exist, creating ssh-key-pairs." + mkdir /artifacts/.ssh + ssh_key_pair=$(eval "ssh-keygen -t rsa -N '' -f /artifacts/.ssh/id_rsa <<< y") + if echo "$ssh_key_pair" | grep -q "Generating public/private rsa key pair"; then + echo "SSH-KEY pairs generated" + else + echo "Issue with creating ssh-key pairs $ssh_key_pair" + fi +else + echo "$file exists, making use of it." +fi + +# Looping all region to create SSH-KEYS +for region in "${REGIONS[@]}"; + do + disable_update_check=$(eval "ibmcloud config --check-version=false") + echo "$disable_update_check" + auhtenticate=$(eval "ibmcloud login --apikey $API_KEY -r $region") + if [[ $auhtenticate = *OK* ]]; then + echo "************SSH-KEY creation process in $region ************" + check_key=$(eval "ibmcloud is keys | grep $CICD_SSH_KEY | awk '{print $2}'") + if [[ -z "$check_key" ]]; then + echo "$CICD_SSH_KEY creating in $region" + ssh_key_create=$(eval "ibmcloud is key-create $CICD_SSH_KEY @/artifacts/.ssh/id_rsa.pub --resource-group-name $resource_group") + if [[ $ssh_key_create = *Created* ]]; then + echo "$CICD_SSH_KEY created in $region" + else + echo "ssh-key creation failed in $region" + exit 1 + fi + else + echo "$CICD_SSH_KEY already exists in region $region. So, deleting exist key $CICD_SSH_KEY in region $region" + ssh_key_delete=$(eval "ibmcloud is key-delete $CICD_SSH_KEY -f") + if [[ $ssh_key_delete = *deleted* ]]; then + echo "Exist $CICD_SSH_KEY deleted in $region" + echo "New $CICD_SSH_KEY creating in $region" + ssh_key_create=$(eval "ibmcloud is key-create $CICD_SSH_KEY @//artifacts/.ssh/id_rsa.pub --resource-group-name $resource_group") + if [[ $ssh_key_create = *Created* ]]; then + echo "New $CICD_SSH_KEY created in $region" + else + echo "ssh-key creation failed in $region" + exit 1 + fi + else + echo "ssh-key deletion failed in $region" + fi + fi + echo "************SSH-KEY create process in $region done ************" + else + echo "Issue Login with IBMCLOUD $auhtenticate" + exit 1 + fi + done + } + +ssh_key_delete() { +# Looping all region to create SSH-KEYS +for region in "${REGIONS[@]}"; + do + disable_update_check=$(eval "ibmcloud config --check-version=false") + echo "$disable_update_check" + auhtenticate=$(eval "ibmcloud login --apikey $API_KEY -r $region") + if [[ $auhtenticate = *OK* ]]; then + echo "************SSH-KEY deletion process in $region ************" + ssh_key_delete=$(eval "ibmcloud is key-delete $CICD_SSH_KEY -f") + if [[ $ssh_key_delete = *deleted* ]]; then + echo "$CICD_SSH_KEY deleted in $region" + else + echo "ssh-key deletion failed in $region" + fi + echo "************SSH-KEY delete process in $region done ************" + else + echo "Issue Login with IBMCLOUD $auhtenticate" + exit 1 + fi + done + } diff --git a/.tekton/scripts/suites.sh b/.tekton/scripts/suites.sh new file mode 100644 index 00000000..2f08e952 --- /dev/null +++ b/.tekton/scripts/suites.sh @@ -0,0 +1,149 @@ +#!/bin/bash +common_suite() { + test_cases="$1" + suite="$2" + compute_image_name="$3" + CHECK_PR_SUITE="$4" + for file in .tekton/scripts/*.sh + do + # shellcheck source=/dev/null + source "$file" + done + export TF_VAR_ibmcloud_api_key=$API_KEY + DIRECTORY="/artifacts/tests" + if [ -d "$DIRECTORY" ]; then + cd $DIRECTORY || exit + test_cases="${test_cases//,/|}" + LOG_FILE=pipeline-${suite}-$(date +%d-%m-%Y-%H-%M-%S).cicd + export LOG_FILE + echo "**************Validating on ${suite} **************" + if [[ "$CHECK_PR_SUITE" ]]; then + # get ssh-key created based on pr-id + get_pr_ssh_key "${PR_REVISION}" + SSH_KEY=${CICD_SSH_KEY:?} COMPUTE_IMAGE_NAME=${compute_image_name:?} LOGIN_NODE_IMAGE_NAME=${login_image_name:?} \ + ZONE=${zone:?} RESERVATION_ID=${reservation_id:?} CLUSTER_ID=${cluster_id:?} RESOURCE_GROUP=${resource_group:?} \ + go test -v -timeout 9000m -run "${test_cases}" | tee -a "$LOG_FILE" + # Upload log/test_output files to cos bucket + cos_upload "PR" + # Checking any error/issue from log file for pr + issue_track "${LOG_FILE}" "PR" "TASK" + + else + # get ssh-key created based on commit-id + get_commit_ssh_key "${REVISION}" + SSH_KEY=${CICD_SSH_KEY:?} US_EAST_ZONE=${us_east_zone:?} US_EAST_CLUSTER_ID=${us_east_cluster_id:?} \ + US_EAST_RESERVATION_ID=${us_east_reservation_id:?} US_SOUTH_ZONE=${us_south_zone:?} \ + US_SOUTH_CLUSTER_ID=${us_south_cluster_id:?} US_SOUTH_RESERVATION_ID=${us_south_reservation_id:?} \ + EU_DE_ZONE=${eu_de_zone:?} EU_DE_CLUSTER_ID=${eu_de_cluster_id:?} EU_DE_RESERVATION_ID=${eu_de_reservation_id:?} \ + EU_DE_RESERVATION_ID=${eu_de_reservation_id:?} COMPUTE_IMAGE_NAME=${compute_image_name:?} \ + LOGIN_NODE_IMAGE_NAME=${login_image_name:?} ZONE=${zone:?} RESERVATION_ID=${reservation_id:?} \ + CLUSTER_ID=${cluster_id:?} RESOURCE_GROUP=${resource_group:?} \ + go test -v -timeout 9000m -run "${test_cases}" | tee -a "$LOG_FILE" + # Upload log/test_output files to cos bucket + cos_upload + + if [[ "${suite}" == "negative_suite" ]]; then + # Skipping error/issue track from log file for commit/push to negative testcases + issue_track "${LOG_FILE}" "negative_suite" "TASK" + else + # Checking any error/issue from log file for commit/push + issue_track "${LOG_FILE}" + fi + fi + else + pwd + ls -a + echo "$DIRECTORY does not exists" + exit 1 + fi +} + +# pr based suite on rhel +pr_rhel_suite() { + suite=pr-rhel + test_cases="TestRunDefault" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" "PR" +} + +# pr based suite on ubuntu +pr_ubuntu_suite() { + suite=pr-ubuntu + test_cases="TestRunDefault" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_ubuntu:?}" "PR" +} + +# commit based suite on rhel-suite-1 +rhel_suite_1() { + suite=rhel-suite-1 + test_cases="TestRunBasic,TestRunAppCenter,TestRunNoKMSAndHTOff" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" +} + +# commit based suite on rhel-suite-2 +rhel_suite_2() { + suite=rhel-suite-2 + test_cases="TestRunLDAP,TestRunLDAPAndPac,TestRunCustomRGAsNonDefault" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" +} + +# commit based suite on rhel-suite-3 +rhel_suite_3() { + suite=rhel-suite-3 + test_cases="TestRunCreateVpc" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" +} + +# commit based suite on ubuntu-suite-1 +ubuntu_suite_1() { + suite=ubuntu-suite-1 + test_cases="TestRunVpcWithCustomDns" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_ubuntu:?}" +} + +# commit based suite on ubuntu-suite-2 +ubuntu_suite_2() { + suite=ubuntu-suite-2 + test_cases="TestRunUsingExistingKMS,TestRunLDAPAndPac,TestRunCustomRGAsNull" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_ubuntu:?}" +} + +# commit based suite on ubuntu-suite-3 +ubuntu_suite_3() { + suite=ubuntu-suite-3 + test_cases="TestRunBasic,TestRunNoKMSAndHTOff" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_ubuntu:?}" +} + +# regions based suite on regions-suite +regions_suite() { + suite=regions-suite + test_cases="TestRunInUsEastRegion,TestRunInEuDeRegion,TestRunInUSSouthRegion,TestRunCIDRsAsNonDefault,TestRunExistingPACEnvironment" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" +} + +# negative based suite on negative-suite +negative_suite() { + suite=negative-suite + test_cases="TestRunWithoutMandatory,TestRunInvalidReservationIDAndContractID,TestRunInvalidLDAPServerIP,TestRunInvalidLDAPUsernamePassword,TestRunInvalidAPPCenterPassword,TestRunInvalidDomainName,TestRunKMSInstanceNameAndKMSKeyNameWithInvalidValue,TestRunExistSubnetIDVpcNameAsNull" + new_line="${test_cases//,/$'\n'}" + echo "************** Going to run ${suite} ${new_line} **************" + common_suite "${test_cases}" "${suite}" "${compute_image_name_rhel:?}" +} diff --git a/.tekton/task-infra-rhel.yaml b/.tekton/task-infra-rhel.yaml index c033dbf4..eafca2c0 100644 --- a/.tekton/task-infra-rhel.yaml +++ b/.tekton/task-infra-rhel.yaml @@ -83,6 +83,15 @@ spec: - name: us_south_reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: workspace mountPath: /artifacts @@ -130,6 +139,12 @@ spec: value: $(params.us_south_cluster_id) - name: us_south_reservation_id value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) steps: - name: rhel-suite-1 onError: continue @@ -148,70 +163,8 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - echo -e "************** Going to run in RHEL-Suite-1 ************** - 1.TestRunBasic - 2.TestRunAppCenter - 3.TestRunInUsEastRegion - 4.TestRunInEuDeRegion - 5.TestRunInUSSouthRegion - 6.TestRunNoKMSAndHTOff" - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-rhel-suite-1-$(date +%d%m%Y).cicd - echo "**************Validating on RHEL-Suite-1**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_rhel LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunBasic|TestRunAppCenter|TestRunInUsEastRegion|TestRunInEuDeRegion|TestRunInUSSouthRegion|TestRunNoKMSAndHTOff" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + rhel_suite_1 - name: rhel-suite-2 onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest @@ -229,67 +182,8 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - echo "************** Going to run in RHEL-Suite-2 ************** - 1.TestRunLDAP - 2.TestRunLDAPAndPac - 3.TestRunCustomRGAsNonDefault" - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-rhel-suite-2-$(date +%d%m%Y).cicd - echo "**************Validating on RHEL-Suite-2**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_rhel LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunLDAP|TestRunLDAPAndPac|TestRunCustomRGAsNonDefault" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + rhel_suite_2 - name: rhel-suite-3 onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest @@ -307,64 +201,5 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - echo "************** Going to run in UBUNTU-Suite-3 ************** - 1.TestRunCreateVpc - 1.1 RunHpcExistingVpcSubnetId - 1.2 RunHpcExistingVpcCidr - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-rhel-suite-3-$(date +%d%m%Y).cicd - echo "**************Validating on RHEL-Suite-3**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_rhel LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunCreateVpc" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + rhel_suite_3 diff --git a/.tekton/task-negative.yaml b/.tekton/task-negative.yaml new file mode 100644 index 00000000..76c2ec75 --- /dev/null +++ b/.tekton/task-negative.yaml @@ -0,0 +1,167 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: wes-hpc-da-negative +spec: + params: + - name: ibmcloud-api + description: the ibmcloud api + default: https://cloud.ibm.com + - name: continuous-delivery-context-secret + description: name of the secret containing the continuous delivery pipeline context secrets + default: secure-properties + - name: ibmcloud-apikey-secret-key + description: field in the secret that contains the api key used to login to ibmcloud + default: ibmcloud_api_key + - name: pipeline-debug + description: Pipeline debug mode. Value can be 0 or 1. Default to 0 + default: "0" + - name: revision + description: | + the git revision/commit to update the git HEAD to. + Default is to mean only use the branch + default: "" + - name: directory-name + default: "." + - name: repository + description: the git repo url + - name: ssh_keys + default: "" + description: List of names of the SSH keys that is configured in your IBM Cloud account, used to establish a connection to the IBM Cloud HPC bastion and login node. Ensure that the SSH key is present in the same resource group and region where the cluster is being provisioned. If you do not have an SSH key in your IBM Cloud account, create one by according to [SSH Keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). + - name: zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: cluster_prefix + description: Prefix that is used to name the IBM Cloud HPC cluster and IBM Cloud resources that are provisioned to build the IBM Cloud HPC cluster instance. You cannot create more than one instance of the IBM Cloud HPC cluster with the same name. Ensure that the name is unique. + default: cicd-wes + - name: resource_group + description: Resource group name from your IBM Cloud account where the VPC resources should be deployed. Note. If the resource group value is set as null, automation creates two different RG with the name (workload-rg and service-rg). For additional information on resource groups, see [Managing resource groups](https://cloud.ibm.com/docs/account?topic=account-rgs). + default: Default + - name: remote_allowed_ips + default: "" + description: Comma-separated list of IP addresses that can access the IBM Cloud HPC cluster instance through an SSH interface. For security purposes, provide the public IP addresses assigned to the devices that are authorized to establish SSH connections (for example, [\"169.45.117.34\"]). To fetch the IP address of the device, use [https://ipv4.icanhazip.com/](https://ipv4.icanhazip.com/). + - name: compute_image_name_rhel + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v1). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: compute_image_name_ubuntu + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v1). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: login_image_name + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster login node. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v2). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: us_east_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: us_east_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: us_east_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: eu_de_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: eu_de_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: eu_de_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: us_south_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: us_south_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: us_south_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" + workspaces: + - name: workspace + mountPath: /artifacts + stepTemplate: + env: + - name: API_KEY + valueFrom: + secretKeyRef: + name: $(params.continuous-delivery-context-secret) + key: $(params.ibmcloud-apikey-secret-key) + optional: true + - name: PIPELINE_DEBUG + value: $(params.pipeline-debug) + - name: REVISION + value: $(params.revision) + - name: ssh_keys + value: $(params.ssh_keys) + - name: zone + value: $(params.zone) + - name: resource_group + value: $(params.resource_group) + - name: compute_image_name_rhel + value: $(params.compute_image_name_rhel) + - name: login_image_name + value: $(params.login_image_name) + - name: cluster_id + value: $(params.cluster_id) + - name: reservation_id + value: $(params.reservation_id) + - name: us_east_zone + value: $(params.us_east_zone) + - name: us_east_cluster_id + value: $(params.us_east_cluster_id) + - name: us_east_reservation_id + value: $(params.us_east_reservation_id) + - name: eu_de_zone + value: $(params.eu_de_zone) + - name: eu_de_cluster_id + value: $(params.eu_de_cluster_id) + - name: eu_de_reservation_id + value: $(params.eu_de_reservation_id) + - name: us_south_zone + value: $(params.us_south_zone) + - name: us_south_cluster_id + value: $(params.us_south_cluster_id) + - name: us_south_reservation_id + value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) + steps: + - name: negative-scenario + onError: continue + image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest + workingDir: "/artifacts" + imagePullPolicy: Always + command: ["/bin/bash", "-c"] + args: + - | + #!/bin/bash + + if [[ "${PIPELINE_DEBUG}" == "true" ]]; then + pwd + env + trap env EXIT + set -x + fi + + source .tekton/scripts/suites.sh + negative_suite diff --git a/.tekton/task-pr-rhel.yaml b/.tekton/task-pr-rhel.yaml index 46e53391..b7ce24e2 100644 --- a/.tekton/task-pr-rhel.yaml +++ b/.tekton/task-pr-rhel.yaml @@ -57,6 +57,15 @@ spec: - name: pr-revision description: the commit/revision in the source branch of the PullRequest that is to be built default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: workspace mountPath: /artifacts @@ -91,6 +100,12 @@ spec: value: $(params.cluster_id) - name: reservation_id value: $(params.reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) workingDir: "/artifacts" imagePullPolicy: Always command: ["/bin/bash", "-c"] @@ -105,59 +120,5 @@ spec: set -x fi - PR_REVISION=$(echo $PR_REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$PR_REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-testrunbasic-rhel-$(date +%d%m%Y).cicd - echo "**************Validating on TestRunBasic**************" - SSH_KEY=$CICD_SSH_KEY COMPUTE_IMAGE_NAME=$compute_image_name_rhel LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunDefault" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + pr_rhel_suite diff --git a/.tekton/task-pr-ubuntu.yaml b/.tekton/task-pr-ubuntu.yaml index 68dbf99e..60cbd326 100644 --- a/.tekton/task-pr-ubuntu.yaml +++ b/.tekton/task-pr-ubuntu.yaml @@ -57,6 +57,15 @@ spec: - name: pr-revision description: the commit/revision in the source branch of the PullRequest that is to be built default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: workspace mountPath: /artifacts @@ -91,6 +100,12 @@ spec: value: $(params.cluster_id) - name: reservation_id value: $(params.reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) workingDir: "/artifacts" imagePullPolicy: Always command: ["/bin/bash", "-c"] @@ -105,59 +120,5 @@ spec: set -x fi - PR_REVISION=$(echo $PR_REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$PR_REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-testrunbasic-ubuntu-$(date +%d%m%Y).cicd - echo "**************Validating on TestRunBasic**************" - SSH_KEY=$CICD_SSH_KEY COMPUTE_IMAGE_NAME=$compute_image_name_ubuntu LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunDefault" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + pr_ubuntu_suite diff --git a/.tekton/task-region.yaml b/.tekton/task-region.yaml new file mode 100644 index 00000000..aa2a133b --- /dev/null +++ b/.tekton/task-region.yaml @@ -0,0 +1,167 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: wes-hpc-da-region +spec: + params: + - name: ibmcloud-api + description: the ibmcloud api + default: https://cloud.ibm.com + - name: continuous-delivery-context-secret + description: name of the secret containing the continuous delivery pipeline context secrets + default: secure-properties + - name: ibmcloud-apikey-secret-key + description: field in the secret that contains the api key used to login to ibmcloud + default: ibmcloud_api_key + - name: pipeline-debug + description: Pipeline debug mode. Value can be 0 or 1. Default to 0 + default: "0" + - name: revision + description: | + the git revision/commit to update the git HEAD to. + Default is to mean only use the branch + default: "" + - name: directory-name + default: "." + - name: repository + description: the git repo url + - name: ssh_keys + default: "" + description: List of names of the SSH keys that is configured in your IBM Cloud account, used to establish a connection to the IBM Cloud HPC bastion and login node. Ensure that the SSH key is present in the same resource group and region where the cluster is being provisioned. If you do not have an SSH key in your IBM Cloud account, create one by according to [SSH Keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). + - name: zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: cluster_prefix + description: Prefix that is used to name the IBM Cloud HPC cluster and IBM Cloud resources that are provisioned to build the IBM Cloud HPC cluster instance. You cannot create more than one instance of the IBM Cloud HPC cluster with the same name. Ensure that the name is unique. + default: cicd-wes + - name: resource_group + description: Resource group name from your IBM Cloud account where the VPC resources should be deployed. Note. If the resource group value is set as null, automation creates two different RG with the name (workload-rg and service-rg). For additional information on resource groups, see [Managing resource groups](https://cloud.ibm.com/docs/account?topic=account-rgs). + default: Default + - name: remote_allowed_ips + default: "" + description: Comma-separated list of IP addresses that can access the IBM Cloud HPC cluster instance through an SSH interface. For security purposes, provide the public IP addresses assigned to the devices that are authorized to establish SSH connections (for example, [\"169.45.117.34\"]). To fetch the IP address of the device, use [https://ipv4.icanhazip.com/](https://ipv4.icanhazip.com/). + - name: compute_image_name_rhel + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v1). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: compute_image_name_ubuntu + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v1). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: login_image_name + description: Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster login node. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/hpc-spectrum-LSF#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v2). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. + default: "" + - name: cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: us_east_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: us_east_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: us_east_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: eu_de_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: eu_de_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: eu_de_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: us_south_zone + default: "" + description: The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). + - name: us_south_cluster_id + description: Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservation. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. + default: "" + - name: us_south_reservation_id + description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). + default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" + workspaces: + - name: workspace + mountPath: /artifacts + stepTemplate: + env: + - name: API_KEY + valueFrom: + secretKeyRef: + name: $(params.continuous-delivery-context-secret) + key: $(params.ibmcloud-apikey-secret-key) + optional: true + - name: PIPELINE_DEBUG + value: $(params.pipeline-debug) + - name: REVISION + value: $(params.revision) + - name: ssh_keys + value: $(params.ssh_keys) + - name: zone + value: $(params.zone) + - name: resource_group + value: $(params.resource_group) + - name: compute_image_name_rhel + value: $(params.compute_image_name_rhel) + - name: login_image_name + value: $(params.login_image_name) + - name: cluster_id + value: $(params.cluster_id) + - name: reservation_id + value: $(params.reservation_id) + - name: us_east_zone + value: $(params.us_east_zone) + - name: us_east_cluster_id + value: $(params.us_east_cluster_id) + - name: us_east_reservation_id + value: $(params.us_east_reservation_id) + - name: eu_de_zone + value: $(params.eu_de_zone) + - name: eu_de_cluster_id + value: $(params.eu_de_cluster_id) + - name: eu_de_reservation_id + value: $(params.eu_de_reservation_id) + - name: us_south_zone + value: $(params.us_south_zone) + - name: us_south_cluster_id + value: $(params.us_south_cluster_id) + - name: us_south_reservation_id + value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) + steps: + - name: regions-scenario + onError: continue + image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest + workingDir: "/artifacts" + imagePullPolicy: Always + command: ["/bin/bash", "-c"] + args: + - | + #!/bin/bash + + if [[ "${PIPELINE_DEBUG}" == "true" ]]; then + pwd + env + trap env EXIT + set -x + fi + + source .tekton/scripts/suites.sh + regions_suite diff --git a/.tekton/task-ssh-key-creation.yaml b/.tekton/task-ssh-key-creation.yaml index 4aa8bf7c..adbe5565 100644 --- a/.tekton/task-ssh-key-creation.yaml +++ b/.tekton/task-ssh-key-creation.yaml @@ -45,12 +45,11 @@ spec: value: $(params.pr-revision) - name: REVISION value: $(params.revision) + - name: resource_group + value: $(params.resource_group) steps: - name: ssh-key-creation image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest - env: - - name: resource_group - value: $(params.resource_group) workingDir: "/artifacts" imagePullPolicy: Always command: ["/bin/bash", "-c"] @@ -65,66 +64,5 @@ spec: set -x fi - CICD_SSH_KEY=cicd - if [ -z "${PR_REVISION}" ]; then - REVISION=$(echo $REVISION) - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - else - PR_REVISION=$(echo $PR_REVISION) - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$PR_REVISION) - fi - - mkdir /artifacts/.ssh - ssh_key_pair=$(eval "ssh-keygen -t rsa -N '' -f /artifacts/.ssh/id_rsa <<< y") - - ibmcloud_login () { - local regions=("$1") - local API_KEY=("$2") - local for_create_or_delete="$3" - # Looping all region to create SSH-KEYS - for region in ${regions[@]}; - do - disable_update_check=$(eval "ibmcloud config --check-version=false") - auhtenticate=$(eval "ibmcloud login --apikey $API_KEY -r $region") - echo "$auhtenticate" - if [[ $auhtenticate = *OK* ]]; then - echo "************SSH-KEY create progress in $region ************" - if echo $for_create_or_delete | grep -q "create"; then - check_key=`ibmcloud is keys | grep "cicd-toolchain" | awk '{print $2}'` - if [[ -z "$check_key" ]]; then - echo "$CICD_SSH_KEY creating in $region" - ssh_key_create=$(eval "ibmcloud is key-create $CICD_SSH_KEY @/artifacts/.ssh/id_rsa.pub --resource-group-name $resource_group") - if [[ $ssh_key_create = *Created* ]]; then - echo "$CICD_SSH_KEY created in $region" - else - echo "ssh-key creation failed in $region" - exit 1 - fi - else - echo "$CICD_SSH_KEY already exists in region $region. So, deleting exist key $CICD_SSH_KEY in region $region" - ssh_key_delete=$(eval "ibmcloud is key-delete $CICD_SSH_KEY -f") - if [[ $ssh_key_delete = *deleted* ]]; then - echo "Exist $CICD_SSH_KEY deleted in $region" - echo "New $CICD_SSH_KEY creating in $region" - ssh_key_create=$(eval "ibmcloud is key-create $CICD_SSH_KEY @/artifacts/.ssh/id_rsa.pub --resource-group-name $resource_group") - if [[ $ssh_key_create = *Created* ]]; then - echo "New $CICD_SSH_KEY created in $region" - else - echo "ssh-key creation failed in $region" - exit 1 - fi - else - echo "ssh-key deletion failed in $region" - fi - fi - echo "************SSH-KEY create progress in $region done ************" - fi - else - echo "Issue Login with IBMCLOUD $auhtenticate" - exit 1 - fi - done - } - - regions="us-south eu-de us-east" - ibmcloud_login "${regions}" "${API_KEY}" "create" + source .tekton/scripts/ssh_create_delete.sh + ssh_key_create diff --git a/.tekton/task-ssh-key-deletion.yaml b/.tekton/task-ssh-key-deletion.yaml index 83f51f8e..7cd39af1 100644 --- a/.tekton/task-ssh-key-deletion.yaml +++ b/.tekton/task-ssh-key-deletion.yaml @@ -60,42 +60,5 @@ spec: set -x fi - CICD_SSH_KEY=cicd - if [ -z "${PR_REVISION}" ]; then - REVISION=$(echo $REVISION) - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - else - PR_REVISION=$(echo $PR_REVISION) - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$PR_REVISION) - fi - - ibmcloud_login () { - local regions=("$1") - local API_KEY=("$2") - local for_create_or_delete="$3" - echo "$regions" - # Looping all region to create SSH-KEYS - for region in ${regions[@]}; - do - echo "$region" - disable_update_check=$(eval "ibmcloud config --check-version=false") - auhtenticate=$(eval "ibmcloud login --apikey $API_KEY -r $region") - echo "$auhtenticate" - if [[ $auhtenticate = *OK* ]]; then - if echo $for_create_or_delete | grep -q "delete"; then - ssh_key_delete=$(eval "ibmcloud is key-delete $CICD_SSH_KEY -f") - if [[ $ssh_key_delete = *deleted* ]]; then - echo "$CICD_SSH_KEY deleted in $region" - else - echo "ssh-key deletion failed in $region" - fi - fi - else - echo "Issue Login with IBMCLOUD $auhtenticate" - exit 1 - fi - done - } - - regions="us-south eu-de us-east" - ibmcloud_login "${regions}" "${API_KEY}" "delete" + source .tekton/scripts/ssh_create_delete.sh + ssh_key_delete diff --git a/.tekton/test-infra-ubuntu.yaml b/.tekton/test-infra-ubuntu.yaml index 7f5d7dd1..393c4165 100644 --- a/.tekton/test-infra-ubuntu.yaml +++ b/.tekton/test-infra-ubuntu.yaml @@ -83,6 +83,15 @@ spec: - name: us_south_reservation_id description: Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (_). default: "" + - name: cos_region + description: The cos region name. + default: "" + - name: cos_bucket + description: The cos bucket name. + default: "" + - name: cos_instance_crn + description: The cos instance crn. + default: "" workspaces: - name: workspace mountPath: /artifacts @@ -130,6 +139,12 @@ spec: value: $(params.us_south_cluster_id) - name: us_south_reservation_id value: $(params.us_south_reservation_id) + - name: cos_region + value: $(params.cos_region) + - name: cos_bucket + value: $(params.cos_bucket) + - name: cos_instance_crn + value: $(params.cos_instance_crn) steps: - name: ubuntu-suite-1 onError: continue @@ -148,68 +163,8 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - echo "************** Going to run in UBUNTU-Suite-1 ************** - 1.TestRunBasic - 2.TestRunInUsEastRegion - 3.TestRunInUSSouthRegion - 4.TestRunNoKMSAndHTOff" - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-ubuntu-suite-1-$(date +%d%m%Y).cicd - echo "**************Validating on UBUNTU-Suite-1**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_ubuntu LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunBasic|TestRunInUsEastRegion|TestRunInUSSouthRegion|TestRunNoKMSAndHTOff" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + ubuntu_suite_1 - name: ubuntu-suite-2 onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest @@ -227,70 +182,8 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - ibmcloud plugin install key-protect -f - - echo "************** Going to run in UBUNTU-Suite-2 ************** - 1.TestRunUsingExistingKMS - 2.TestRunLDAPAndPac - 3.TestRunCustomRGAsNull - 4.TestRunCustomRGAsNonDefault" - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-ubuntu-suite-2-$(date +%d%m%Y).cicd - echo "**************Validating on UBUNTU-Suite-2**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_ubuntu LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunUsingExistingKMS|TestRunLDAPAndPac|TestRunCustomRGAsNull|TestRunCustomRGAsNonDefault" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + ubuntu_suite_2 - name: ubuntu-suite-3 onError: continue image: icr.io/continuous-delivery/pipeline/pipeline-base-ubi:latest @@ -308,66 +201,5 @@ spec: set -x fi - REVISION=$(echo $REVISION) - CICD_SSH_KEY=cicd - CICD_SSH_KEY=$(echo $CICD_SSH_KEY-$REVISION) - - git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv - echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.bashrc - ln -s ~/.tfenv/bin/* /usr/local/bin - tfenv install 1.5.7 - tfenv use 1.5.7 - terraform --version - - cd $(pwd)/ && - echo "export PATH=\$PATH:$(pwd)/go/bin:\$HOME/go/bin" >> ~/.bashrc && - echo "export GOROOT=$(pwd)/go" >> ~/.bashrc - source ~/.bashrc - go version - - echo "************** Going to run in UBUNTU-Suite-3 ************** - 1.TestRunVpcWithCustomDns - 1.1 RunHpcExistingVpcCustomDnsExist - 1.2 RunHpcExistingVpcCustomExistDnsNew - 1.3 RunHpcNewVpcCustomNullExistDns - 1.4 RunHpcNewVpcExistCustomDnsNull" - - export TF_VAR_ibmcloud_api_key=$API_KEY - export SSH_FILE_PATH="/artifacts/.ssh/id_rsa" - - # Check artifacts/tests folder exists or not - DIRECTORY="/artifacts/tests" - if [ -d "$DIRECTORY" ]; then - cd $DIRECTORY - LOG_FILE=pipeline-ubuntu-suite-3-$(date +%d%m%Y).cicd - echo "**************Validating on UBUNTU-Suite-3**************" - SSH_KEY=$CICD_SSH_KEY US_EAST_ZONE=$us_east_zone US_EAST_CLUSTER_ID=$us_east_cluster_id US_EAST_RESERVATION_ID=$us_east_reservation_id US_SOUTH_ZONE=$us_south_zone US_SOUTH_CLUSTER_ID=$us_south_cluster_id US_SOUTH_RESERVATION_ID=$us_south_reservation_id EU_DE_ZONE=$eu_de_zone EU_DE_CLUSTER_ID=$eu_de_cluster_id EU_DE_RESERVATION_ID=$eu_de_reservation_id EU_DE_RESERVATION_ID=$eu_de_reservation_id COMPUTE_IMAGE_NAME=$compute_image_name_ubuntu LOGIN_NODE_IMAGE_NAME=$login_image_name ZONE=$zone RESERVATION_ID=$reservation_id CLUSTER_ID=$cluster_id RESOURCE_GROUP=$resource_group go test -v -timeout 9000m -run "TestRunVpcWithCustomDns" | tee -a $LOG_FILE - else - pwd - ls -a - echo "$DIRECTORY does not exists" - exit 1 - fi - - echo "*******************************************************" - count=`ls -1 $DIRECTORY/test_output/log* 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated and log file not created, check with packages or binaries installation" - exit 1 - else - cat $DIRECTORY/test_output/log* - fi - echo "*******************************************************" - - count=`ls -1 $DIRECTORY/*.cicd 2>/dev/null | wc -l` - if [ $count == 0 ]; then - echo "Test Suite have not initated, check with packages or binaries installation" - exit 1 - fi - - # Check any error message on the plan/apply log - error_check=$(eval "grep -E -w 'FAIL|Error|ERROR' $DIRECTORY/$LOG_FILE") - if [[ "$error_check" ]]; then - echo "Found Error/FAIL/ERROR in plan/apply log. Please check log." - exit 1 - fi + source .tekton/scripts/suites.sh + ubuntu_suite_3 diff --git a/ibm_catalog.json b/ibm_catalog.json index 3d780261..c324fcb9 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -72,36 +72,10 @@ "key": "cluster_id" }, { - "key": "bastion_ssh_keys", - "type": "array", - "default_value": "", - "display_name": "VPC SSH Key", - "required": true, - "custom_config": { - "type": "vpc_ssh_key", - "grouping": "deployment", - "original_grouping": "deployment", - "config_constraints": { - "selection": "multi_select", - "valueType": "name" - } - } + "key": "bastion_ssh_keys" }, { - "key": "compute_ssh_keys", - "type": "array", - "default_value": "", - "display_name": "VPC SSH Key", - "required": true, - "custom_config": { - "type": "vpc_ssh_key", - "grouping": "deployment", - "original_grouping": "deployment", - "config_constraints": { - "selection": "multi_select", - "valueType": "name" - } - } + "key": "compute_ssh_keys" }, { "key": "remote_allowed_ips" @@ -163,13 +137,43 @@ "key": "scc_enable" }, { - "key": "scc_profile" + "key": "scc_profile", + "default_value": "CIS IBM Cloud Foundations Benchmark", + "options": [ + { + "displayname": "CIS IBM Cloud Foundations Benchmark", + "value": "CIS IBM Cloud Foundations Benchmark" + }, + { + "displayname": "IBM Cloud Framework for Financial Services", + "value": "IBM Cloud Framework for Financial Services" + } + ] }, { "key": "scc_profile_version" }, { - "key": "scc_location" + "key": "scc_location", + "default_value": "us-south", + "options": [ + { + "displayname": "us-south", + "value": "us-south" + }, + { + "displayname": "eu-de", + "value": "eu-de" + }, + { + "displayname": "ca-tor", + "value": "ca-tor" + }, + { + "displayname": "eu-es", + "value": "eu-es" + } + ] }, { "key": "scc_event_notification_plan", @@ -344,34 +348,63 @@ ], "iam_permissions": [ { + "service_name": "cloud-object-storage", "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:writer" - ], - "service_name": "cloud-object-storage" + "crn:v1:bluemix:public:iam::::serviceRole:Writer", + "crn:v1:bluemix:public:iam::::role:ConfigReader" + ] }, { "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:Manager" + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" ], "service_name": "dns-svcs" }, { + "service_name": "kms", "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:Manager" - ], - "service_name": "kms" + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:ConfigReader" + ] }, { + "service_name": "compliance", + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Administrator" + ] + }, + { + "service_name": "secrets-manager", + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Administrator" + ] + }, + { + "service_name": "is.share", "role_crns": [ "crn:v1:bluemix:public:iam::::role:Editor" - ], - "service_name": "is.vpc" + ] + }, + { + "service_name": "iam-identity", + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ] + }, + { + "service_name": "databases-for-mysql", + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Editor" + ] }, { "role_crns": [ "crn:v1:bluemix:public:iam::::role:Editor" ], - "service_name": "dns-svcs" + "service_name": "is.vpc" }, { "service_name": "is.flow-log-collector", @@ -427,7 +460,7 @@ { "diagram": { "caption": "IBM Cloud HPC", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-hpc/main/hpcaas-arch-1.5.0.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-hpc/main/hpcaas-arch-1.6.svg", "type": "image/svg+xml" }, "description": "This deployable architecture creates a VPC to run your HPC workload within a single zone from IBM Cloud. A login node is deployed in a separate subnet and security group to access your HPC environment. The HPC management nodes are in a different subnet and security group. In addition, clusters of virtual server instances are provisioned for high availability and are pre-installed with the IBM Spectrum LSF scheduler for HPC workload job management. The IBM Spectrum LSF scheduler dynamically creates compute nodes and deletes them after job completion. Also, IBM Cloud File Storage for VPC is provisioned for configuration or data sharing between HPC management and compute nodes." diff --git a/modules/bootstrap/variables.tf b/modules/bootstrap/variables.tf index a370470e..d40e75cc 100644 --- a/modules/bootstrap/variables.tf +++ b/modules/bootstrap/variables.tf @@ -83,9 +83,9 @@ variable "existing_kms_instance_guid" { } variable "skip_iam_authorization_policy" { - type = string - default = null - description = "Skip IAM Authorization policy" + type = bool + default = false + description = "Set to false if authorization policy is required for VPC block storage volumes to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for block storage volume](https://cloud.ibm.com/docs/vpc?topic=vpc-block-s2s-auth&interface=ui)." } ########################################################################### diff --git a/modules/file_storage/outputs.tf b/modules/file_storage/outputs.tf index ae7a5df9..08ec4741 100644 --- a/modules/file_storage/outputs.tf +++ b/modules/file_storage/outputs.tf @@ -27,6 +27,11 @@ output "mount_paths_excluding_first" { value = length(ibm_is_share_mount_target.share_target_sg[*].mount_path) > 1 ? slice(ibm_is_share_mount_target.share_target_sg[*].mount_path, 1, length(ibm_is_share_mount_target.share_target_sg[*].mount_path)) : [] } +output "total_mount_paths" { + description = "Total Mount paths" + value = ibm_is_share_mount_target.share_target_sg[*].mount_path +} + #output "mount_paths_excluding_first" { # description = "Mount paths excluding the first element" # value = ibm_is_share_mount_target.share_target_vpc[*].mount_path[1:] diff --git a/modules/landing_zone_vsi/configuration_steps/compute_user_data_fragment.sh b/modules/landing_zone_vsi/configuration_steps/compute_user_data_fragment.sh index c676aa80..e3998692 100644 --- a/modules/landing_zone_vsi/configuration_steps/compute_user_data_fragment.sh +++ b/modules/landing_zone_vsi/configuration_steps/compute_user_data_fragment.sh @@ -54,58 +54,76 @@ elif grep -q "NAME=\"Ubuntu\"" /etc/os-release; then fi fi -# TODO: Conditional NFS mount +# Setup VPC FileShare | NFS Mount LSF_TOP="/opt/ibm/lsf" -# Setup file share +echo "Initiating LSF share mount" >> $logfile + +# Function to attempt NFS mount with retries +mount_nfs_with_retries() { + local server_path=$1 + local client_path=$2 + local retries=5 + local success=false + + rm -rf "${client_path}" + mkdir -p "${client_path}" + + for (( j=0; j> $logfile + if mount | grep -q "${client_path}"; then + echo "Mount successful for ${server_path} on ${client_path}" >> $logfile + success=true + break + else + echo "Attempt $((j+1)) of $retries failed for ${server_path} on ${client_path}" >> $logfile + sleep 2 + fi + done + + if [ "$success" = true ]; then + chmod 777 "${client_path}" + echo "${server_path} ${client_path} nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0" >> /etc/fstab + else + echo "Mount not found for ${server_path} on ${client_path} after $retries attempts." >> $logfile + rm -rf "${client_path}" + fi + + # Convert success to numeric for return + if [ "$success" = true ]; then + return 0 + else + return 1 + fi +} + +# Setup LSF share if [ -n "${nfs_server_with_mount_path}" ]; then echo "File share ${nfs_server_with_mount_path} found" >> $logfile nfs_client_mount_path="/mnt/lsf" - rm -rf "${nfs_client_mount_path}" - mkdir -p "${nfs_client_mount_path}" - # Mount LSF TOP - mount -t nfs -o sec=sys "$nfs_server_with_mount_path" "$nfs_client_mount_path" >> $logfile - # Verify mount - if mount | grep "$nfs_client_mount_path"; then - echo "Mount found" >> $logfile + if mount_nfs_with_retries "${nfs_server_with_mount_path}" "${nfs_client_mount_path}"; then + # Move stuff to shared fs + for dir in conf work das_staging_area; do + rm -rf "${LSF_TOP}/$dir" + ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}/$dir" + done + chown -R lsfadmin:root "${LSF_TOP}" else - echo "No mount found, exiting!" >> $logfile + echo "Mount not found for ${nfs_server_with_mount_path}, Exiting !!" >> $logfile exit 1 fi - # Update mount to fstab for automount - echo "$nfs_server_with_mount_path $nfs_client_mount_path nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0 " >> /etc/fstab - for dir in conf work das_staging_area; do - rm -rf "${LSF_TOP}/$dir" # this local data can go away - ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}" # we link from shared fs - chown -R lsfadmin:root "${LSF_TOP}" - done fi echo "Setting LSF share is completed." >> $logfile # Setup Custom file shares echo "Setting custom file shares." >> $logfile -# Setup file share if [ -n "${custom_file_shares}" ]; then echo "Custom file share ${custom_file_shares} found" >> $logfile file_share_array=(${custom_file_shares}) mount_path_array=(${custom_mount_paths}) length=${#file_share_array[@]} - for (( i=0; i> $logfile - # Verify mount - if mount | grep "${file_share_array[$i]}"; then - echo "Mount found" >> $logfile - else - echo "No mount found" >> $logfile - rm -rf "${mount_path_array[$i]}" - fi - # Update permission to 777 for all users to access - chmod 777 "${mount_path_array[$i]}" - # Update mount to fstab for automount - echo "${file_share_array[$i]} ${mount_path_array[$i]} nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0 " >> /etc/fstab + + for (( i=0; i> $logfile diff --git a/modules/landing_zone_vsi/configuration_steps/configure_management_vsi.sh b/modules/landing_zone_vsi/configuration_steps/configure_management_vsi.sh index 722e196e..bfa7a9a9 100644 --- a/modules/landing_zone_vsi/configuration_steps/configure_management_vsi.sh +++ b/modules/landing_zone_vsi/configuration_steps/configure_management_vsi.sh @@ -162,11 +162,6 @@ LSF_RSH="ssh -o 'PasswordAuthentication no' -o 'StrictHostKeyChecking no'" EOT sed -i "s/LSF_MASTER_LIST=.*/LSF_MASTER_LIST=\"${mgmt_hostnames}\"/g" $LSF_CONF_FILE - # Updating the worker node count to 2000 when no VPC file share is declared. - if [[ $vpc_file_share_count == 0 ]]; then - sed -i 's/THRESHOLD\[250\]/THRESHOLD\[2000\]/' $LSF_CONF_FILE - fi - if [ "$hyperthreading" == true ]; then ego_define_ncpus="threads" else @@ -577,7 +572,7 @@ dns_domain="${dns_domain}" ManagementHostNames="${mgmt_hostnames}" lsf_public_key="${cluster_public_key_content}" hyperthreading=${hyperthreading} -nfs_server_with_mount_path="" +nfs_server_with_mount_path="${nfs_server_with_mount_path}" custom_file_shares="${custom_file_shares}" custom_mount_paths="${custom_mount_paths}" login_ip_address="${login_ip}" @@ -635,116 +630,137 @@ fi ########### LSFSETUP-END ################################################################## ########################################################################################### -echo "Setting LSF share" -# Setup file share -if [ -n "${nfs_server_with_mount_path}" ]; then - echo "File share ${nfs_server_with_mount_path} found" - nfs_client_mount_path="/mnt/lsf" - rm -rf "${nfs_client_mount_path}" - mkdir -p "${nfs_client_mount_path}" - # Mount LSF TOP - mount -t nfs -o sec=sys "$nfs_server_with_mount_path" "$nfs_client_mount_path" - # Verify mount - if mount | grep "$nfs_client_mount_path"; then - echo "Mount found" - else - echo "No mount found, exiting!" - exit 1 - fi - # Update mount to fstab for automount - echo "$nfs_server_with_mount_path $nfs_client_mount_path nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0 " >> /etc/fstab +echo "Initiating LSF share mount" - # Move stuff to shared fs - for dir in conf work das_staging_area; do - if [ "$on_primary" == "true" ]; then - rm -rf "${nfs_client_mount_path}/$dir" # avoid old data already in shared fs - mv "${LSF_TOP}/$dir" "${nfs_client_mount_path}" # this local data goes to shared fs +# Function to attempt NFS mount with retries +mount_nfs_with_retries() { + local server_path=$1 + local client_path=$2 + local retries=5 + local success=false + + rm -rf "${client_path}" + mkdir -p "${client_path}" + + for (( j=0; j> $logfile + if mount | grep -q "${client_path}"; then + echo "Mount successful for ${server_path} on ${client_path}" + success=true + break else - rm -rf "${LSF_TOP}/$dir" # this local data can go away + echo "Attempt $((j+1)) of $retries failed for ${server_path} on ${client_path}" + sleep 2 fi - ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}" # locally link to shared fs - chown -R lsfadmin:root "${LSF_TOP}" done - # Sharing the lsfsuite..conf folder - if [ "$on_primary" == "true" ]; then - rm -rf "${nfs_client_mount_path}/gui-conf" - mv "${LSF_SUITE_GUI_CONF}" "${nfs_client_mount_path}/gui-conf" - chown -R lsfadmin:root "${nfs_client_mount_path}/gui-conf" + if [ "$success" = true ]; then + chmod 777 "${client_path}" + echo "${server_path} ${client_path} nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0" >> /etc/fstab else - rm -rf "${LSF_SUITE_GUI_CONF}" - fi - ln -fs "${nfs_client_mount_path}/gui-conf" "${LSF_SUITE_GUI_CONF}" - chown -R lsfadmin:root "${LSF_SUITE_GUI_CONF}" - - # Create a data directory for sharing HPC workload data - if [ "$on_primary" == "true" ]; then - mkdir -p "${nfs_client_mount_path}/data" - ln -s "${nfs_client_mount_path}/data" "$LSF_TOP/work/data" - chown -R lsfadmin:root "$LSF_TOP/work/data" + echo "Mount not found for ${server_path} on ${client_path} after $retries attempts." + rm -rf "${client_path}" fi - # VNC Sessions - if [ "$on_primary" == "true" ]; then - mkdir -p "${nfs_client_mount_path}/repository-path" - # With this change, LDAP User can able to submit the job from App Center UI. - chmod -R 777 "${nfs_client_mount_path}/repository-path" - chown -R lsfadmin:root "${nfs_client_mount_path}/repository-path" + # Convert success to numeric for return + if [ "$success" = true ]; then + return 0 + else + return 1 fi +} - # Create folder in shared file system to store logs - mkdir -p "${nfs_client_mount_path}/log/${HOSTNAME}" - chown -R lsfadmin:root "${nfs_client_mount_path}/log" - if [ "$(ls -A ${LSF_TOP}/log)" ]; then - # Move all existing logs to the new folder - mv ${LSF_TOP}/log/* "${nfs_client_mount_path}/log/${HOSTNAME}" - fi - # Remove the original folder and create symlink so the user can still access to default location - rm -rf "${LSF_TOP}/log" - ln -fs "${nfs_client_mount_path}/log/${HOSTNAME}" "${LSF_TOP}/log" - chown -R lsfadmin:root "${LSF_TOP}/log" - - # Create log folder for pac and set proper owner - mkdir -p "${nfs_client_mount_path}/gui-logs" - chown -R lsfadmin:root "${nfs_client_mount_path}/gui-logs" - # Move PAC logs to shared folder - mkdir -p "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" - if [ -d "${LSF_SUITE_GUI}/logs/${HOSTNAME}" ] && [ "$(ls -A ${LSF_SUITE_GUI}/logs/"${HOSTNAME}")" ]; then - mv "${LSF_SUITE_GUI}/logs/${HOSTNAME}" "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" +# Setup LSF share +if [ -n "${nfs_server_with_mount_path}" ]; then + echo "File share ${nfs_server_with_mount_path} found" + nfs_client_mount_path="/mnt/lsf" + if mount_nfs_with_retries "${nfs_server_with_mount_path}" "${nfs_client_mount_path}"; then + # Move stuff to shared fs + for dir in conf work das_staging_area; do + if [ "$on_primary" == "true" ]; then + rm -rf "${nfs_client_mount_path}/$dir" # avoid old data already in shared fs + mv "${LSF_TOP}/$dir" "${nfs_client_mount_path}" # this local data goes to shared fs + else + rm -rf "${LSF_TOP}/$dir" # this local data can go away + fi + ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}" # locally link to shared fs + chown -R lsfadmin:root "${LSF_TOP}" + done + + # Sharing the lsfsuite.conf folder + if [ "$on_primary" == "true" ]; then + rm -rf "${nfs_client_mount_path}/gui-conf" + mv "${LSF_SUITE_GUI_CONF}" "${nfs_client_mount_path}/gui-conf" + chown -R lsfadmin:root "${nfs_client_mount_path}/gui-conf" + else + rm -rf "${LSF_SUITE_GUI_CONF}" + fi + ln -fs "${nfs_client_mount_path}/gui-conf" "${LSF_SUITE_GUI_CONF}" + chown -R lsfadmin:root "${LSF_SUITE_GUI_CONF}" + + # Create a data directory for sharing HPC workload data + if [ "$on_primary" == "true" ]; then + mkdir -p "${nfs_client_mount_path}/data" + ln -s "${nfs_client_mount_path}/data" "$LSF_TOP/work/data" + chown -R lsfadmin:root "$LSF_TOP/work/data" + fi + + # Sharing the 10.1 folder + if [ "$on_primary" == "true" ]; then + rm -rf "${nfs_client_mount_path}/10.1" + mv "${LSF_TOP_VERSION}" "${nfs_client_mount_path}" + ln -s "${nfs_client_mount_path}/10.1" "${LSF_TOP_VERSION}" + chown -R lsfadmin:root "${LSF_TOP_VERSION}" + fi + + # VNC Sessions + if [ "$on_primary" == "true" ]; then + mkdir -p "${nfs_client_mount_path}/repository-path" + # With this change, LDAP User can able to submit the job from App Center UI. + chmod -R 777 "${nfs_client_mount_path}/repository-path" + chown -R lsfadmin:root "${nfs_client_mount_path}/repository-path" + fi + + # Create folder in shared file system to store logs + mkdir -p "${nfs_client_mount_path}/log/${HOSTNAME}" + chown -R lsfadmin:root "${nfs_client_mount_path}/log" + if [ "$(ls -A ${LSF_TOP}/log)" ]; then + # Move all existing logs to the new folder + mv ${LSF_TOP}/log/* "${nfs_client_mount_path}/log/${HOSTNAME}" + fi + # Remove the original folder and create symlink so the user can still access to default location + rm -rf "${LSF_TOP}/log" + ln -fs "${nfs_client_mount_path}/log/${HOSTNAME}" "${LSF_TOP}/log" + chown -R lsfadmin:root "${LSF_TOP}/log" + + # Create log folder for pac and set proper owner + mkdir -p "${nfs_client_mount_path}/gui-logs" + chown -R lsfadmin:root "${nfs_client_mount_path}/gui-logs" + # Move PAC logs to shared folder + mkdir -p "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" + if [ -d "${LSF_SUITE_GUI}/logs/${HOSTNAME}" ] && [ "$(ls -A ${LSF_SUITE_GUI}/logs/${HOSTNAME})" ]; then + mv "${LSF_SUITE_GUI}/logs/${HOSTNAME}" "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" + fi + chown -R lsfadmin:root "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" + ln -fs "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" "${LSF_SUITE_GUI}/logs/${HOSTNAME}" + chown -R lsfadmin:root "${LSF_SUITE_GUI}/logs/${HOSTNAME}" fi - chown -R lsfadmin:root "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" - ln -fs "${nfs_client_mount_path}/gui-logs/${HOSTNAME}" "${LSF_SUITE_GUI}/logs/${HOSTNAME}" - chown -R lsfadmin:root "${LSF_SUITE_GUI}/logs/${HOSTNAME}" else - echo "No mount point value found, exiting!" + echo "Mount not found for ${nfs_server_with_mount_path}, Exiting !!" exit 1 fi echo "Setting LSF share is completed." # Setup Custom file shares echo "Setting custom file shares." -# Setup file share if [ -n "${custom_file_shares}" ]; then echo "Custom file share ${custom_file_shares} found" file_share_array=(${custom_file_shares}) mount_path_array=(${custom_mount_paths}) length=${#file_share_array[@]} + for (( i=0; i> /etc/fstab + mount_nfs_with_retries "${file_share_array[$i]}" "${mount_path_array[$i]}" done fi echo "Setting custom file shares is completed." diff --git a/modules/landing_zone_vsi/configuration_steps/management_values.tpl b/modules/landing_zone_vsi/configuration_steps/management_values.tpl index be3e111b..564fbaf7 100644 --- a/modules/landing_zone_vsi/configuration_steps/management_values.tpl +++ b/modules/landing_zone_vsi/configuration_steps/management_values.tpl @@ -36,7 +36,6 @@ hyperthreading="${hyperthreading}" network_interface=${network_interface} dns_domain="${dns_domain}" mount_path="${mount_path}" -vpc_file_share_count="${vpc_file_share_count}" custom_file_shares="${custom_file_shares}" custom_mount_paths="${custom_mount_paths}" contract_id="${contract_id}" diff --git a/modules/landing_zone_vsi/locals.tf b/modules/landing_zone_vsi/locals.tf index 1ccbe93f..e9872e58 100644 --- a/modules/landing_zone_vsi/locals.tf +++ b/modules/landing_zone_vsi/locals.tf @@ -177,7 +177,7 @@ locals { mount_path = share.mount_path nfs_share = share.nfs_share } - if share.nfs_share != null && share.nfs_share != "" + if share.mount_path != "/mnt/lsf" && share.nfs_share != null && share.nfs_share != "" ] vpc_file_share = [ @@ -187,6 +187,6 @@ locals { size = share.size iops = share.iops } - if share.size != null && share.iops != null + if share.mount_path != "/mnt/lsf" && share.size != null && share.iops != null ] } diff --git a/modules/landing_zone_vsi/template_files.tf b/modules/landing_zone_vsi/template_files.tf index 7e080bbf..73826b27 100644 --- a/modules/landing_zone_vsi/template_files.tf +++ b/modules/landing_zone_vsi/template_files.tf @@ -80,7 +80,6 @@ data "template_file" "management_values" { network_interface = local.vsi_interfaces[0] dns_domain = var.dns_domain_names["compute"] mount_path = var.share_path - vpc_file_share_count = var.vpc_file_share_count custom_mount_paths = join(" ", concat(local.vpc_file_share[*]["mount_path"], local.nfs_file_share[*]["mount_path"])) custom_file_shares = join(" ", concat([for file_share in var.file_share : file_share], local.nfs_file_share[*]["nfs_share"])) contract_id = var.contract_id diff --git a/modules/landing_zone_vsi/templates/login_vsi.sh b/modules/landing_zone_vsi/templates/login_vsi.sh index 48bc6d96..d67b6450 100644 --- a/modules/landing_zone_vsi/templates/login_vsi.sh +++ b/modules/landing_zone_vsi/templates/login_vsi.sh @@ -108,63 +108,80 @@ EOT sh $command && (crontab -l 2>/dev/null; echo "@reboot $command") | crontab - fi -# Setup Default LSF Share +echo "Initiating LSF share mount" >> $logfile +# Function to attempt NFS mount with retries +mount_nfs_with_retries() { + local server_path=$1 + local client_path=$2 + local retries=5 + local success=false + + rm -rf "${client_path}" + mkdir -p "${client_path}" + + for (( j=0; j> $logfile + if mount | grep -q "${client_path}"; then + echo "Mount successful for ${server_path} on ${client_path}" >> $logfile + success=true + break + else + echo "Attempt $((j+1)) of $retries failed for ${server_path} on ${client_path}" >> $logfile + sleep 2 + fi + done + + if [ "$success" = true ]; then + echo "${server_path} ${client_path} nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0" >> /etc/fstab + else + echo "Mount not found for ${server_path} on ${client_path} after $retries attempts." >> $logfile + rm -rf "${client_path}" + fi + + if [ "$success" = true ]; then + return 0 + else + return 1 + fi +} + +# Setup LSF share if [ -n "${nfs_server_with_mount_path}" ]; then - echo "Setting Default LSF share." >> $logfile echo "File share ${nfs_server_with_mount_path} found" >> $logfile nfs_client_mount_path="/mnt/lsf" - rm -rf "${nfs_client_mount_path}" rm -rf /opt/ibm/lsf/conf/ rm -rf /opt/ibm/lsf/work/ - mkdir -p "${nfs_client_mount_path}" - # Mount LSF TOP - mount -t nfs4 -o sec=sys,vers=4.1 "$nfs_server_with_mount_path" "$nfs_client_mount_path" >> $logfile - # Verify mount - if mount | grep "$nfs_client_mount_path"; then - echo "Mount found" >> $logfile + if mount_nfs_with_retries "${nfs_server_with_mount_path}" "${nfs_client_mount_path}"; then + # Move stuff to shared fs + for dir in conf work; do + mv "${LSF_TOP}/$dir" "${nfs_client_mount_path}" + ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}" + done + chown -R lsfadmin:root "${LSF_TOP}" else - echo "No mount found, exiting!" >> $logfile + echo "Mount not found for ${nfs_server_with_mount_path}, Exiting !!" >> $logfile exit 1 fi - # Update mount to fstab for automount - echo "$nfs_server_with_mount_path $nfs_client_mount_path nfs rw,sec=sys,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev 0 0 " >> /etc/fstab - for dir in conf work; do - mv "${LSF_TOP}/$dir" "${nfs_client_mount_path}" - ln -fs "${nfs_client_mount_path}/$dir" "${LSF_TOP}" - chown -R lsfadmin:root "${LSF_TOP}" - done - echo "Setting Default LSF share is completed." >> $logfile else - echo "No mount point value found, exiting!" >> $logfile + echo "No NFS server mount path provided, Exiting !!" >> $logfile exit 1 fi +echo "Setting LSF share is completed." >> $logfile -# Setup Custom File shares +# Setup Custom file shares +echo "Setting custom file shares." >> $logfile if [ -n "${custom_file_shares}" ]; then - echo "Setting custom file shares." >> $logfile - echo "Custom file share ${custom_file_shares} found" >> $logfile + echo "Custom file share ${custom_file_shares} found" >> $logfile file_share_array=(${custom_file_shares}) mount_path_array=(${custom_mount_paths}) length=${#file_share_array[@]} + for (( i=0; i> /etc/fstab - echo "Setting custom file shares is completed." >> $logfile done fi +echo "Setting custom file shares is completed." >> $logfile echo "source ${LSF_CONF}/profile.lsf" >> "${lsfadmin_home_dir}"/.bashrc echo "source ${LSF_CONF}/profile.lsf" >> /root/.bashrc diff --git a/modules/landing_zone_vsi/variables.tf b/modules/landing_zone_vsi/variables.tf index e799780f..ab3bdaff 100644 --- a/modules/landing_zone_vsi/variables.tf +++ b/modules/landing_zone_vsi/variables.tf @@ -236,11 +236,6 @@ variable "file_share" { description = "VPC file share mount points considering the ip address and the file share name" } -variable "vpc_file_share_count" { - type = number - description = "Requested number of VPC file shares." -} - variable "login_private_ips" { description = "Login private IPs" type = string diff --git a/modules/observability_instance/datasources.tf b/modules/observability_instance/datasources.tf index d6ad0b90..6be8d171 100644 --- a/modules/observability_instance/datasources.tf +++ b/modules/observability_instance/datasources.tf @@ -1,7 +1,8 @@ data "ibm_iam_auth_token" "tokendata" {} data "http" "sysdig_prws_key" { - url = "https://${var.location}.monitoring.cloud.ibm.com/api/token" + count = var.cloud_monitoring_provision ? 1 : 0 + url = "https://${var.location}.monitoring.cloud.ibm.com/api/token" # Optional request headers request_headers = { diff --git a/modules/observability_instance/outputs.tf b/modules/observability_instance/outputs.tf index be07af0f..b6864301 100644 --- a/modules/observability_instance/outputs.tf +++ b/modules/observability_instance/outputs.tf @@ -16,7 +16,7 @@ output "log_analysis_ingestion_key" { } output "cloud_monitoring_prws_key" { - value = var.cloud_monitoring_provision ? jsondecode(data.http.sysdig_prws_key.response_body).token.key : null + value = var.cloud_monitoring_provision ? jsondecode(data.http.sysdig_prws_key[0].response_body).token.key : null description = "IBM Cloud Monitoring Prometheus Remote Write ingestion key" sensitive = true } diff --git a/samples/configs/hpc_catalog_values.json b/samples/configs/hpc_catalog_values.json index 021f035c..7c484492 100644 --- a/samples/configs/hpc_catalog_values.json +++ b/samples/configs/hpc_catalog_values.json @@ -7,5 +7,60 @@ "reservation_id" : "Please fill here", "bastion_ssh_keys" : "[\"Please fill here\"]", "compute_ssh_keys" : "[\"Please fill here\"]", - "remote_allowed_ips" : "[\"Please fill here\"]" + "remote_allowed_ips" : "[\"Please fill here\"]", + "vpc_name" : "__NULL__", + "cluster_subnet_ids" : "[]", + "login_subnet_id" : "__NULL__", + "vpc_cidr" : "10.241.0.0/18", + "vpc_cluster_private_subnets_cidr_blocks" : "[\"10.241.0.0/20\"]", + "vpc_cluster_login_private_subnets_cidr_blocks" : "[\"10.241.16.0/28\"]", + "dns_domain_name" : "{compute = \"hpcaas.com\"}", + "dns_instance_id" : "__NULL__", + "dns_custom_resolver_id" : "__NULL__", + "enable_cos_integration" : "false", + "cos_instance_name" : "__NULL__", + "enable_fip" : "true", + "management_image_name" : "hpcaas-lsf10-rhel88-v7", + "compute_image_name" : "hpcaas-lsf10-rhel88-compute-v5", + "login_image_name" : "hpcaas-lsf10-rhel88-compute-v5", + "login_node_instance_type" : "bx2-2x8", + "management_node_instance_type" : "bx2-16x64", + "management_node_count" : "3", + "custom_file_shares" : "[{mount_path = \"/mnt/vpcstorage/tools\", size = 100, iops = 2000 }, { mount_path = \"/mnt/vpcstorage/data\", size = 100, iops = 6000 }, { mount_path = \"/mnt/scale/tools\", nfs_share = \"\" }]", + "storage_security_group_id" : "__NULL__", + "hyperthreading_enabled" : "true", + "vpn_enabled" : "false", + "TF_VERSION" : "1.5", + "TF_PARALLELISM" : "250", + "key_management" : "key_protect", + "kms_instance_name" : "__NULL__", + "kms_key_name" : "__NULL__", + "enable_app_center" : "false", + "app_center_gui_pwd" : "", + "app_center_high_availability" : "true", + "existing_certificate_instance" : "", + "enable_vpc_flow_logs" : "false", + "observability_atracker_on_cos_enable" : "true", + "enable_ldap" : "false", + "ldap_basedns" : "hpcaas.com", + "ldap_server" : "null", + "ldap_admin_password" : "", + "ldap_user_name" : "", + "ldap_user_password" : "", + "ldap_vsi_profile" : "cx2-2x4", + "ldap_vsi_osimage_name" : "ibm-ubuntu-22-04-3-minimal-amd64-1", + "skip_iam_authorization_policy" : "false", + "skip_iam_share_authorization_policy" : "false", + "scc_enable" : "false", + "scc_profile" : "CIS IBM Cloud Foundations Benchmark", + "scc_profile_version" : "1.0.0", + "scc_location" : "us-south", + "scc_event_notification_plan" : "lite", + "observability_monitoring_enable" : "false", + "observability_monitoring_on_compute_nodes_enable" : "false", + "observability_monitoring_plan" : "graduated-tier", + "bastion_instance_name" : "__NULL__", + "bastion_instance_public_ip" : "__NULL__", + "bastion_security_group_id" : "__NULL__", + "bastion_ssh_private_key" : "__NULL__" } diff --git a/samples/configs/hpc_schematics_values.json b/samples/configs/hpc_schematics_values.json index a7171cad..4038e33e 100644 --- a/samples/configs/hpc_schematics_values.json +++ b/samples/configs/hpc_schematics_values.json @@ -59,7 +59,7 @@ "value": "Default", "type": "string", "secure": false, - "description": "Specify the existing resource group name from your IBM Cloud account where the VPC resources should be deployed. By default, the resource group name is set to 'Default.' Note that in some older accounts, the resource group name may be 'default,' so please validate the resource_group name before deployment. If the resource group value is set to null, the automation will create two different resource groups named 'workload-rg' and 'service-rg.' For more information on resource groups, refer to Managing resource groups." + "description": "Specify the existing resource group name from your IBM Cloud account where the VPC resources should be deployed. By default, the resource group name is set to 'Default.' Note that in some older accounts, the resource group name may be 'default,' so please validate the resource_group name before deployment. If the resource group value is set to the string \"null\", the automation will create two different resource groups named 'workload-rg' and 'service-rg.' For more information on resource groups, refer to Managing resource groups." }, { @@ -110,6 +110,374 @@ "type": "list(string)", "secure": false, "description": "Comma-separated list of IP addresses that can access the IBM Cloud HPC cluster instance through an SSH interface. For security purposes, provide the public IP addresses assigned to the devices that are authorized to establish SSH connections (for example, [\"169.45.117.34\"]). To fetch the IP address of the device, use [https://ipv4.icanhazip.com/](https://ipv4.icanhazip.com/)." + }, + { + "name": "vpc_name", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Name of an existing VPC in which the cluster resources will be deployed. If no value is given, then a new VPC will be provisioned for the cluster. [Learn more](https://cloud.ibm.com/docs/vpc)" + }, + { + "name": "cluster_subnet_ids", + "value": "[]", + "type": "list(string)", + "secure": false, + "description": "Provide the list of existing subnet ID under the existing VPC where the cluster will be provisioned. One subnet ID is required as input value. Supported zones are: eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone." + }, + { + "name": "login_subnet_id", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the list of existing subnet ID under the existing VPC, where the login/bastion server will be provisioned. One subnet id is required as input value for the creation of login node and bastion in the same zone as the management nodes. Note: Provide a different subnet id for login_subnet_id, do not overlap or provide the same subnet id that was already provided for cluster_subnet_ids." + }, + { + "name": "vpc_cidr", + "value": "10.241.0.0/18", + "type": "string", + "secure": false, + "description": "Creates the address prefix for the new VPC, when the vpc_name variable is empty. The VPC requires an address prefix for creation of subnet in a single zone. The subnet are created with the specified CIDR blocks. For more information, see [Setting IP ranges](https://cloud.ibm.com/docs/vpc?topic=vpc-vpc-addressing-plan-design)." + }, + { + "name": "vpc_cluster_private_subnets_cidr_blocks", + "value": "[\"10.241.0.0/20\"]", + "type": "list(string)", + "secure": false, + "description": "Provide the CIDR block required for the creation of the compute cluster's private subnet. One CIDR block is required. If using a hybrid environment, modify the CIDR block to avoid conflicts with any on-premises CIDR blocks. Ensure the selected CIDR block size can accommodate the maximum number of management and dynamic compute nodes expected in your cluster. For more information on CIDR block size selection, refer to the documentation, see [Choosing IP ranges for your VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-choosing-ip-ranges-for-your-vpc)." + }, + { + "name": "vpc_cluster_login_private_subnets_cidr_blocks", + "value": "[\"10.241.16.0/28\"]", + "type": "list(string)", + "secure": false, + "description": "Provide the CIDR block required for the creation of the login cluster's private subnet. Only one CIDR block is needed. If using a hybrid environment, modify the CIDR block to avoid conflicts with any on-premises CIDR blocks. Since the login subnet is used only for the creation of login virtual server instances, provide a CIDR range of /28." + }, + { + "name": "dns_domain_name", + "value": "{compute= \"hpcaas.com\"}", + "type": "object({compute = string})", + "secure": false, + "description": "IBM Cloud DNS Services domain name to be used for the IBM Cloud HPC cluster." + }, + { + "name": "dns_instance_id", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the id of existing IBM Cloud DNS services domain to skip creating a new DNS service instance name.Note: If dns_instance_id is not equal to null, a new dns zone will be created under the existing dns service instance." + }, + { + "name": "dns_custom_resolver_id", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the id of existing IBM Cloud DNS custom resolver to skip creating a new custom resolver. If the value is set to null, a new dns custom resolver shall be created and associated to the vpc. Note: A VPC can be associated only to a single custom resolver, please provide the id of custom resolver if it is already associated to the VPC." + }, + { + "name": "enable_cos_integration", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set to true to create an extra cos bucket to integrate with HPC cluster deployment." + }, + { + "name": "cos_instance_name", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the name of the existing cos instance to store vpc flow logs." + }, + { + "name": "enable_fip", + "value": "true", + "type": "bool", + "secure": false, + "description": "The solution supports multiple ways to connect to your IBM Cloud HPC cluster for example, using a login node, or using VPN or direct connection. If connecting to the IBM Cloud HPC cluster using VPN or direct connection, set this value to false." + }, + { + "name": "management_image_name", + "value": "hpcaas-lsf10-rhel88-v7", + "type": "string", + "secure": false, + "description": "Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster management nodes. By default, the solution uses a RHEL88 base image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering." + }, + { + "name": "compute_image_name", + "value": "hpcaas-lsf10-rhel88-compute-v5", + "type": "string", + "secure": false, + "description": "Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v4). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering." + + }, + { + "name": "login_image_name", + "value": "hpcaas-lsf10-rhel88-compute-v5", + "type": "string", + "secure": false, + "description": "Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster login node. By default, the solution uses a RHEL 8-6 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v4). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering." + }, + { + "name": "login_node_instance_type", + "value": "bx2-2x8", + "type": "string", + "secure": false, + "description": "Specify the virtual server instance profile type to be used to create the login node for the IBM Cloud HPC cluster. For choices on profile types, see [Instance profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles)." + }, + { + "name": "management_node_instance_type", + "value": "bx2-16x64", + "type": "string", + "secure": false, + "description" : "Specify the virtual server instance profile type to be used to create the management nodes for the IBM Cloud HPC cluster. For choices on profile types, see [Instance profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles)." + }, + { + "name": "management_node_count", + "value": "3", + "type": "number", + "secure": false, + "description": "Number of management nodes. This is the total number of management nodes. Enter a value between 1 and 10." + }, + { + "name": "custom_file_shares", + "value": "[{mount_path = \"/mnt/vpcstorage/tools\", size = 100, iops = 2000 }, { mount_path = \"/mnt/vpcstorage/data\", size = 100, iops = 6000 }, { mount_path = \"/mnt/scale/tools\", nfs_share = \"\" }]", + "type": "list(object({mount_path = string,size = optional(number),iops = optional(number),nfs_share = optional(string)}))", + "secure": false, + "description": "Mount points and sizes in GB and IOPS range of file shares that can be used to customize shared file storage layout. Provide the details for up to 5 shares. Each file share size in GB supports different range of IOPS. For more information, see [file share IOPS value](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles&interface=ui)" + }, + { "name": "storage_security_group_id", + "value": "__NULL__", + "type": "string", + "secure": false, + "description" : "Provide the security group id that is created from Scale storage, if the nfs_share is not equal to null from cluster_file_share variable." + }, + { + "name": "hyperthreading_enabled", + "value": "true", + "type": "bool", + "secure": false, + "description": "Setting this to true will enable hyper-threading in the compute nodes of the cluster (default). Otherwise, hyper-threading will be disabled." + }, + { + "name": "vpn_enabled", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set the value as true to deploy a VPN gateway for VPC in the cluster." + }, + { + "name": "key_management", + "value": "key_protect", + "type": "string", + "secure": false, + "description": "Set the value as key_protect to enable customer managed encryption for boot volume and file share. If the key_management is set as null, IBM Cloud resources will be always be encrypted through provider managed." + }, + { + "name": "kms_instance_name", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the name of the existing Key Protect instance associated with the Key Management Service. Note: To use existing kms_instance_name set key_management as key_protect. The name can be found under the details of the KMS, see [View key-protect ID](https://cloud.ibm.com/docs/key-protect?topic=key-protect-retrieve-instance-ID&interface=ui)." + }, + { + "name": "kms_key_name", + "value": "__NULL__", + "type": "string", + "secure": false, + "description": "Provide the existing kms key name that you want to use for the IBM Cloud HPC cluster. Note: kms_key_name to be considered only if key_management value is set as key_protect.(for example kms_key_name: my-encryption-key)." + }, + { + "name": "enable_app_center", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set to true to enable the IBM Spectrum LSF Application Center GUI (default: false). [System requirements](https://www.ibm.com/docs/en/slac/10.2.0?topic=requirements-system-102-fix-pack-14) for IBM Spectrum LSF Application Center Version 10.2 Fix Pack 14." + }, + { + "name": "app_center_gui_pwd", + "value": "", + "type": "string", + "secure": true, + "description": "Password for IBM Spectrum LSF Application Center GUI. Note: Password should be at least 8 characters, must have one number, one lowercase letter, one uppercase letter, and at least one special character." + }, + { "name": "app_center_high_availability", + "value": "true", + "type": "bool", + "secure": false, + "description": "Set to false to disable the IBM Spectrum LSF Application Center GUI High Availability (default: true)." + }, + { "name": "existing_certificate_instance", + "value": "", + "type": "string", + "secure": false, + "description": "When app_center_high_availability is enable/set as true, The Application Center will be configured for high availability and requires a Application Load Balancer Front End listener to use a certificate CRN value stored in the Secret Manager. Provide the valid 'existing_certificate_instance' to configure the Application load balancer." + }, + { + "name": "enable_vpc_flow_logs", + "value": "false", + "type": "bool", + "secure": false, + "description": "Flag to enable VPC flow logs. If true, a flow log collector will be created." + }, + { + "name": "observability_atracker_on_cos_enable", + "value": "true", + "type": "bool", + "secure": false, + "description": "Enable Activity tracker service instance connected to Cloud Object Storage (COS). All the events will be stored into COS so that customers can connect to it and read those events or ingest them in their system." + }, + { + "name": "enable_ldap", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set this option to true to enable LDAP for IBM Cloud HPC, with the default value set to false." + }, + { + "name": "ldap_basedns", + "value": "hpcaas.com", + "type": "string", + "secure": false, + "description": "The dns domain name is used for configuring the LDAP server. If an LDAP server is already in existence, ensure to provide the associated DNS domain name." + }, + { + "name": "ldap_server", + "value": "null", + "type": "string", + "secure": false, + "description": "Provide the IP address for the existing LDAP server. If no address is given, a new LDAP server will be created." + }, + { + "name": "ldap_admin_password", + "value": "", + "type": "string", + "secure": true, + "description": "The LDAP administrative password should be 8 to 20 characters long, with a mix of at least three alphabetic characters, including one uppercase and one lowercase letter. It must also include two numerical digits and at least one special character from (~@_+:) are required. It is important to avoid including the username in the password for enhanced security.[This value is ignored for an existing LDAP server]." + }, + { + "name": "ldap_user_name", + "value": "", + "type": "string", + "secure": false, + "description": "Custom LDAP User for performing cluster operations. Note: Username should be between 4 to 32 characters, (any combination of lowercase and uppercase letters).[This value is ignored for an existing LDAP server]" + }, + { + "name": "ldap_user_password", + "value": "", + "type": "string", + "secure": true, + "description": "The LDAP user password should be 8 to 20 characters long, with a mix of at least three alphabetic characters, including one uppercase and one lowercase letter. It must also include two numerical digits and at least one special character from (~@_+:) are required.It is important to avoid including the username in the password for enhanced security.[This value is ignored for an existing LDAP server]." + }, + { + "name": "ldap_vsi_profile", + "value": "cx2-2x4", + "type": "string", + "secure": false, + "description": "Profile to be used for LDAP virtual server instance." + }, + { + "name": "ldap_vsi_osimage_name", + "value": "ibm-ubuntu-22-04-3-minimal-amd64-1", + "type": "string", + "secure": false, + "description": "Image name to be used for provisioning the LDAP instances." + }, + { + "name": "skip_iam_authorization_policy", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set to false if authorization policy is required for VPC block storage volumes to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for block storage volume](https://cloud.ibm.com/docs/vpc?topic=vpc-block-s2s-auth&interface=ui)." + }, + { + "name": "skip_iam_share_authorization_policy", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set it to false if authorization policy is required for VPC file share to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for VPC file share](https://cloud.ibm.com/docs/vpc?topic=vpc-file-s2s-auth&interface=ui)." + }, + { + "name": "scc_enable", + "value": "false", + "type": "bool", + "secure": false, + "description": "Flag to enable SCC instance creation. If true, an instance of SCC (Security and Compliance Center) will be created." + }, + { + "name": "scc_profile", + "value": "CIS IBM Cloud Foundations Benchmark", + "type": "string", + "secure": false, + "description": "Profile to be set on the SCC Instance (accepting empty, 'CIS IBM Cloud Foundations Benchmark' and 'IBM Cloud Framework for Financial Services')" + }, + { + "name": "scc_profile_version", + "value": "1.0.0", + "type": "string", + "secure": false, + "description": "Version of the Profile to be set on the SCC Instance (accepting empty, CIS and Financial Services profiles versions)" + }, + { + "name": "scc_location", + "value": "us-south", + "type": "string", + "secure": false, + "description": "Location where the SCC instance is provisioned (possible choices 'us-south', 'eu-de', 'ca-tor', 'eu-es')" + }, + { + "name": "scc_event_notification_plan", + "value": "lite", + "type": "string", + "secure": false, + "description": "Event Notifications Instance plan to be used (it's used with S.C.C. instance), possible values 'lite' and 'standard'" + }, + { "name": "observability_monitoring_enable", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set false to disable IBM Cloud Monitoring integration. If enabled, infrastructure and LSF application metrics from Management Nodes will be ingested." + }, + { + "name": "observability_monitoring_on_compute_nodes_enable", + "value": "false", + "type": "bool", + "secure": false, + "description": "Set false to disable IBM Cloud Monitoring integration. If enabled, infrastructure metrics from Compute Nodes will be ingested." + }, + { + "name": "observability_monitoring_plan", + "value": "graduated-tier", + "type": "string", + "secure": false, + "description" : "Type of service plan for IBM Cloud Monitoring instance. You can choose one of the following: lite, graduated-tier. For all details visit [IBM Cloud Monitoring Service Plans](https://cloud.ibm.com/docs/monitoring?topic=monitoring-service_plans)." + }, + { + "name": "bastion_instance_name", + "value": "__NULL__", + "type": "string", + "secure": false, + "description" : "Bastion instance name. If none given then new bastion will be created." + }, + { + "name": "bastion_instance_public_ip", + "value": "__NULL__", + "type": "string", + "secure": false, + "description" : "Bastion instance public ip address." + }, + { + "name": "bastion_security_group_id", + "value": "__NULL__", + "type": "string", + "secure": false, + "description" : "Bastion security group id." + }, + { + "name": "bastion_ssh_private_key", + "value": "__NULL__", + "type": "string", + "secure": false, + "description" : "Bastion SSH private key path, which will be used to login to bastion host." } ] } diff --git a/solutions/hpc/README.md b/solutions/hpc/README.md index c18c20c4..c91d57d8 100644 --- a/solutions/hpc/README.md +++ b/solutions/hpc/README.md @@ -1,161 +1,26 @@ -## Requirements +IBM Cloud HPC is a deployable architecture where you can deploy both HPC scheduling software and compute clusters to run and manage your compute-intensive HPC workloads. You can reserve capacity on a recurring hourly basis from a dedicated IBM Cloud resource pool where the clusters of VPC virtual server instances can be provisioned. -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.3 | -| [http](#requirement\_http) | 3.4.3 | -| [ibm](#requirement\_ibm) | 1.66.0 | -| [null](#requirement\_null) | 3.2.2 | +## Before you begin +### Configure your IBM Cloud settings +Set up and configure an IBM Cloud account. For more information, click [here](https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-before-you-begin-deploying#confirm-cloud-settings) +### Generate an API key +Generate an API key for your IBM Cloud account where the IBM Cloud HPC cluster will be deployed. For more information, click [here](https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-before-you-begin-deploying#set-IAM-permissions). +### Create an SSH key +Create an SSH key in your IBM Cloud account. This is your SSH key that you will use to access the IBM Cloud HPC cluster. For more information, click [here](https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-before-you-begin-deploying#create-ssh-key). -## Providers +## Required resources +### Understand the cluster configuration +Familiarize yourself with the IBM Cloud HPC deployable architecture:
https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-ibm-cloud-hpc -| Name | Version | -|------|---------| -| [http](#provider\_http) | 3.4.3 | -| [ibm](#provider\_ibm) | 1.66.0 | -| [null](#provider\_null) | 3.2.2 | +## Deploying the environment +Deploy the IBM Cloud HPC cluster:
https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-deploy-architecture -## Modules +## Cleaning up deployed environments +If you no longer need your deployed IBM Cloud HPC cluster, you can clean it up from your environment: 
https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-cleaning-up-deployed-environments -| Name | Source | Version | -|------|--------|---------| -| [alb](#module\_alb) | ./../../modules/alb | n/a | -| [alb\_api](#module\_alb\_api) | ./../../modules/alb_api | n/a | -| [bastion\_inventory](#module\_bastion\_inventory) | ./../../modules/inventory | n/a | -| [bootstrap](#module\_bootstrap) | ./../../modules/bootstrap | n/a | -| [ce\_project](#module\_ce\_project) | ./../../modules/ce_project | n/a | -| [check\_cluster\_status](#module\_check\_cluster\_status) | ./../../modules/null/remote_exec | n/a | -| [check\_node\_status](#module\_check\_node\_status) | ./../../modules/null/remote_exec | n/a | -| [cloud\_monitoring\_instance\_creation](#module\_cloud\_monitoring\_instance\_creation) | ../../modules/observability_instance | n/a | -| [compute\_candidate\_dns\_records](#module\_compute\_candidate\_dns\_records) | ./../../modules/dns_record | n/a | -| [compute\_dns\_records](#module\_compute\_dns\_records) | ./../../modules/dns_record | n/a | -| [compute\_inventory](#module\_compute\_inventory) | ./../../modules/inventory | n/a | -| [db](#module\_db) | ../../modules/database/mysql | n/a | -| [dns](#module\_dns) | ./../../modules/dns | n/a | -| [file\_storage](#module\_file\_storage) | ../../modules/file_storage | n/a | -| [generate\_db\_adminpassword](#module\_generate\_db\_adminpassword) | ../../modules/security/password | n/a | -| [ipvalidation\_cluster\_subnet](#module\_ipvalidation\_cluster\_subnet) | ../../modules/custom/subnet_cidr_check | n/a | -| [ipvalidation\_login\_subnet](#module\_ipvalidation\_login\_subnet) | ../../modules/custom/subnet_cidr_check | n/a | -| [landing\_zone](#module\_landing\_zone) | ../../modules/landing_zone | n/a | -| [landing\_zone\_vsi](#module\_landing\_zone\_vsi) | ../../modules/landing_zone_vsi | n/a | -| [ldap\_inventory](#module\_ldap\_inventory) | ./../../modules/inventory | n/a | -| [ldap\_vsi\_dns\_records](#module\_ldap\_vsi\_dns\_records) | ./../../modules/dns_record | n/a | -| [login\_fip\_removal](#module\_login\_fip\_removal) | ./../../modules/null/local_exec | n/a | -| [login\_inventory](#module\_login\_inventory) | ./../../modules/inventory | n/a | -| [login\_vsi\_dns\_records](#module\_login\_vsi\_dns\_records) | ./../../modules/dns_record | n/a | -| [my\_ip](#module\_my\_ip) | ../../modules/my_ip | n/a | -| [scc\_instance\_and\_profile](#module\_scc\_instance\_and\_profile) | ./../../modules/security/scc | n/a | -| [validate\_ldap\_server\_connection](#module\_validate\_ldap\_server\_connection) | ./../../modules/null/ldap_remote_exec | n/a | -| [validation\_script\_executor](#module\_validation\_script\_executor) | ./../../modules/null/remote_exec | n/a | +## Getting support -## Resources - -| Name | Type | -|------|------| -| [ibm_dns_resource_record.pac_cname](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/resources/dns_resource_record) | resource | -| [ibm_is_subnet_public_gateway_attachment.zone_1_attachment](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/resources/is_subnet_public_gateway_attachment) | resource | -| [null_resource.destroy_compute_resources](https://registry.terraform.io/providers/hashicorp/null/3.2.2/docs/resources/resource) | resource | -| [http_http.reservation_id_validation](https://registry.terraform.io/providers/hashicorp/http/3.4.3/docs/data-sources/http) | data source | -| [ibm_iam_auth_token.auth_token](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/iam_auth_token) | data source | -| [ibm_is_public_gateways.public_gateways](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_public_gateways) | data source | -| [ibm_is_region.region](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_region) | data source | -| [ibm_is_subnet.existing_login_subnet](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_subnet) | data source | -| [ibm_is_subnet.existing_subnet](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_subnet) | data source | -| [ibm_is_vpc.existing_vpc](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_vpc) | data source | -| [ibm_is_vpc.itself](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_vpc) | data source | -| [ibm_is_vpc.vpc](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_vpc) | data source | -| [ibm_is_vpc_address_prefixes.existing_vpc](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.66.0/docs/data-sources/is_vpc_address_prefixes) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [TF\_PARALLELISM](#input\_TF\_PARALLELISM) | Parallelism/ concurrent operations limit. Valid values are between 1 and 256, both inclusive. [Learn more](https://www.terraform.io/docs/internals/graph.html#walking-the-graph). | `string` | `"250"` | no | -| [TF\_VALIDATION\_SCRIPT\_FILES](#input\_TF\_VALIDATION\_SCRIPT\_FILES) | List of script file names used by validation test suites. If provided, these scripts will be executed as part of validation test suites execution. | `list(string)` | `[]` | no | -| [TF\_VERSION](#input\_TF\_VERSION) | The version of the Terraform engine that's used in the Schematics workspace. | `string` | `"1.5"` | no | -| [app\_center\_gui\_pwd](#input\_app\_center\_gui\_pwd) | Password for IBM Spectrum LSF Application Center GUI. Note: Password should be at least 8 characters, must have one number, one lowercase letter, one uppercase letter, and at least one special character. | `string` | `""` | no | -| [app\_center\_high\_availability](#input\_app\_center\_high\_availability) | Set to false to disable the IBM Spectrum LSF Application Center GUI High Availability (default: true). If the value is set as true, provide a certificate instance crn under existing\_certificate\_instance value for the VPC load balancer to enable HTTPS connections.[certificate instance requirements](https://cloud.ibm.com/docs/allowlist/hpc-service?topic=hpc-service-before-deploy-application-center). | `bool` | `true` | no | -| [bastion\_instance\_name](#input\_bastion\_instance\_name) | Bastion instance name. If none given then new bastion will be created. | `string` | `null` | no | -| [bastion\_instance\_public\_ip](#input\_bastion\_instance\_public\_ip) | Bastion instance public ip address. | `string` | `null` | no | -| [bastion\_security\_group\_id](#input\_bastion\_security\_group\_id) | Bastion security group id. | `string` | `null` | no | -| [bastion\_ssh\_keys](#input\_bastion\_ssh\_keys) | Provide the list of SSH key names configured in your IBM Cloud account to establish a connection to the IBM Cloud HPC bastion and login node. Ensure the SSH key is present in the same resource group and region where the cluster is being provisioned. If you do not have an SSH key in your IBM Cloud account, create one by following the provided instructions.[SSH Keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `list(string)` | n/a | yes | -| [bastion\_ssh\_private\_key](#input\_bastion\_ssh\_private\_key) | Bastion SSH private key path, which will be used to login to bastion host. | `string` | `null` | no | -| [cluster\_id](#input\_cluster\_id) | Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservations. This can be up to 39 alphanumeric characters including the underscore (\_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment. | `string` | n/a | yes | -| [cluster\_prefix](#input\_cluster\_prefix) | Prefix that is used to name the IBM Cloud HPC cluster and IBM Cloud resources that are provisioned to build the IBM Cloud HPC cluster instance. You cannot create more than one instance of the IBM Cloud HPC cluster with the same name. Ensure that the name is unique. Prefix must start with a lowercase letter and contain only lowercase letters, digits, and hyphens in between. Hyphens must be followed by at least one lowercase letter or digit. There are no leading, trailing, or consecutive hyphens.Character length for cluster\_prefix should be less than 16. | `string` | `"hpcaas"` | no | -| [cluster\_subnet\_ids](#input\_cluster\_subnet\_ids) | Provide the list of existing subnet ID under the existing VPC where the cluster will be provisioned. One subnet ID is required as input value. Supported zones are: eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone. | `list(string)` | `[]` | no | -| [compute\_image\_name](#input\_compute\_image\_name) | Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster dynamic compute nodes. By default, the solution uses a RHEL 8-8 base OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v4). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. | `string` | `"hpcaas-lsf10-rhel88-compute-v5"` | no | -| [compute\_ssh\_keys](#input\_compute\_ssh\_keys) | Provide the list of SSH key names configured in your IBM Cloud account to establish a connection to the IBM Cloud HPC cluster node. Ensure the SSH key is present in the same resource group and region where the cluster is being provisioned. If you do not have an SSH key in your IBM Cloud account, create one by following the provided instructions.[SSH Keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `list(string)` | n/a | yes | -| [cos\_instance\_name](#input\_cos\_instance\_name) | Provide the name of the existing cos instance to store vpc flow logs. | `string` | `null` | no | -| [custom\_file\_shares](#input\_custom\_file\_shares) | Mount points and sizes in GB and IOPS range of file shares that can be used to customize shared file storage layout. Provide the details for up to 5 shares. Each file share size in GB supports different range of IOPS. For more information, see [file share IOPS value](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles&interface=ui). |
list(object({
mount_path = string,
size = optional(number),
iops = optional(number),
nfs_share = optional(string)
}))
|
[
{
"iops": 2000,
"mount_path": "/mnt/vpcstorage/tools",
"size": 100
},
{
"iops": 6000,
"mount_path": "/mnt/vpcstorage/data",
"size": 100
},
{
"mount_path": "/mnt/scale/tools",
"nfs_share": ""
}
]
| no | -| [dns\_custom\_resolver\_id](#input\_dns\_custom\_resolver\_id) | Provide the id of existing IBM Cloud DNS custom resolver to skip creating a new custom resolver. If the value is set to null, a new dns custom resolver shall be created and associated to the vpc. Note: A VPC can be associated only to a single custom resolver, please provide the id of custom resolver if it is already associated to the VPC. | `string` | `null` | no | -| [dns\_domain\_name](#input\_dns\_domain\_name) | IBM Cloud DNS Services domain name to be used for the IBM Cloud HPC cluster. |
object({
compute = string
#storage = string
#protocol = string
})
|
{
"compute": "hpcaas.com"
}
| no | -| [dns\_instance\_id](#input\_dns\_instance\_id) | Provide the id of existing IBM Cloud DNS services domain to skip creating a new DNS service instance name.Note: If dns\_instance\_id is not equal to null, a new dns zone will be created under the existing dns service instance. | `string` | `null` | no | -| [enable\_app\_center](#input\_enable\_app\_center) | Set to true to enable the IBM Spectrum LSF Application Center GUI (default: false). [System requirements](https://www.ibm.com/docs/en/slac/10.2.0?topic=requirements-system-102-fix-pack-14) for IBM Spectrum LSF Application Center Version 10.2 Fix Pack 14. | `bool` | `false` | no | -| [enable\_cos\_integration](#input\_enable\_cos\_integration) | Set to true to create an extra cos bucket to integrate with HPC cluster deployment. | `bool` | `false` | no | -| [enable\_fip](#input\_enable\_fip) | The solution supports multiple ways to connect to your IBM Cloud HPC cluster for example, using a login node, or using VPN or direct connection. If connecting to the IBM Cloud HPC cluster using VPN or direct connection, set this value to false. | `bool` | `true` | no | -| [enable\_ldap](#input\_enable\_ldap) | Set this option to true to enable LDAP for IBM Cloud HPC, with the default value set to false. | `bool` | `false` | no | -| [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | Flag to enable VPC flow logs. If true, a flow log collector will be created. | `bool` | `false` | no | -| [existing\_certificate\_instance](#input\_existing\_certificate\_instance) | When app\_center\_high\_availability is enable/set as true, The Application Center will be configured for high availability and requires a Application Load Balancer Front End listener to use a certificate CRN value stored in the Secret Manager. Provide the valid 'existing\_certificate\_instance' to configure the Application load balancer. | `string` | `""` | no | -| [hyperthreading\_enabled](#input\_hyperthreading\_enabled) | Setting this to true will enable hyper-threading in the compute nodes of the cluster (default). Otherwise, hyper-threading will be disabled. | `bool` | `true` | no | -| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | IBM Cloud API key for the IBM Cloud account where the IBM Cloud HPC cluster needs to be deployed. For more information on how to create an API key, see [Managing user API keys](https://cloud.ibm.com/docs/account?topic=account-userapikey). | `string` | n/a | yes | -| [key\_management](#input\_key\_management) | Set the value as key\_protect to enable customer managed encryption for boot volume and file share. If the key\_management is set as null, IBM Cloud resources will be always be encrypted through provider managed. | `string` | `"key_protect"` | no | -| [kms\_instance\_name](#input\_kms\_instance\_name) | Provide the name of the existing Key Protect instance associated with the Key Management Service. Note: To use existing kms\_instance\_name set key\_management as key\_protect. The name can be found under the details of the KMS, see [View key-protect ID](https://cloud.ibm.com/docs/key-protect?topic=key-protect-retrieve-instance-ID&interface=ui). | `string` | `null` | no | -| [kms\_key\_name](#input\_kms\_key\_name) | Provide the existing kms key name that you want to use for the IBM Cloud HPC cluster. Note: kms\_key\_name to be considered only if key\_management value is set as key\_protect.(for example kms\_key\_name: my-encryption-key). | `string` | `null` | no | -| [ldap\_admin\_password](#input\_ldap\_admin\_password) | The LDAP administrative password should be 8 to 20 characters long, with a mix of at least three alphabetic characters, including one uppercase and one lowercase letter. It must also include two numerical digits and at least one special character from (~@\_+:) are required. It is important to avoid including the username in the password for enhanced security.[This value is ignored for an existing LDAP server]. | `string` | `""` | no | -| [ldap\_basedns](#input\_ldap\_basedns) | The dns domain name is used for configuring the LDAP server. If an LDAP server is already in existence, ensure to provide the associated DNS domain name. | `string` | `"hpcaas.com"` | no | -| [ldap\_server](#input\_ldap\_server) | Provide the IP address for the existing LDAP server. If no address is given, a new LDAP server will be created. | `string` | `"null"` | no | -| [ldap\_user\_name](#input\_ldap\_user\_name) | Custom LDAP User for performing cluster operations. Note: Username should be between 4 to 32 characters, (any combination of lowercase and uppercase letters).[This value is ignored for an existing LDAP server] | `string` | `""` | no | -| [ldap\_user\_password](#input\_ldap\_user\_password) | The LDAP user password should be 8 to 20 characters long, with a mix of at least three alphabetic characters, including one uppercase and one lowercase letter. It must also include two numerical digits and at least one special character from (~@\_+:) are required.It is important to avoid including the username in the password for enhanced security.[This value is ignored for an existing LDAP server]. | `string` | `""` | no | -| [ldap\_vsi\_osimage\_name](#input\_ldap\_vsi\_osimage\_name) | Image name to be used for provisioning the LDAP instances. By default ldap server are created on Ubuntu based OS flavour. | `string` | `"ibm-ubuntu-22-04-3-minimal-amd64-1"` | no | -| [ldap\_vsi\_profile](#input\_ldap\_vsi\_profile) | Specify the virtual server instance profile type to be used to create the ldap node for the IBM Cloud HPC cluster. For choices on profile types, see [Instance profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles). | `string` | `"cx2-2x4"` | no | -| [login\_image\_name](#input\_login\_image\_name) | Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster login node. By default, the solution uses a RHEL 8-8 OS image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). The solution also offers, Ubuntu 22-04 OS base image (hpcaas-lsf10-ubuntu2204-compute-v4). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. | `string` | `"hpcaas-lsf10-rhel88-compute-v5"` | no | -| [login\_node\_instance\_type](#input\_login\_node\_instance\_type) | Specify the virtual server instance profile type to be used to create the login node for the IBM Cloud HPC cluster. For choices on profile types, see [Instance profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles). | `string` | `"bx2-2x8"` | no | -| [login\_subnet\_id](#input\_login\_subnet\_id) | Provide the list of existing subnet ID under the existing VPC, where the login/bastion server will be provisioned. One subnet id is required as input value for the creation of login node and bastion in the same zone as the management nodes. Note: Provide a different subnet id for login\_subnet\_id, do not overlap or provide the same subnet id that was already provided for cluster\_subnet\_ids. | `string` | `null` | no | -| [management\_image\_name](#input\_management\_image\_name) | Name of the custom image that you want to use to create virtual server instances in your IBM Cloud account to deploy the IBM Cloud HPC cluster management nodes. By default, the solution uses a RHEL88 base image with additional software packages mentioned [here](https://cloud.ibm.com/docs/ibm-spectrum-lsf#create-custom-image). If you would like to include your application-specific binary files, follow the instructions in [ Planning for custom images ](https://cloud.ibm.com/docs/vpc?topic=vpc-planning-custom-images) to create your own custom image and use that to build the IBM Cloud HPC cluster through this offering. | `string` | `"hpcaas-lsf10-rhel88-v7"` | no | -| [management\_node\_count](#input\_management\_node\_count) | Number of management nodes. This is the total number of management nodes. Enter a value between 1 and 10. | `number` | `3` | no | -| [management\_node\_instance\_type](#input\_management\_node\_instance\_type) | Specify the virtual server instance profile type to be used to create the management nodes for the IBM Cloud HPC cluster. For choices on profile types, see [Instance profiles](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles). | `string` | `"bx2-16x64"` | no | -| [observability\_atracker\_on\_cos\_enable](#input\_observability\_atracker\_on\_cos\_enable) | Enable Activity tracker service instance connected to Cloud Object Storage (COS). All the events will be stored into COS so that customers can connect to it and read those events or ingest them in their system. | `bool` | `true` | no | -| [observability\_monitoring\_enable](#input\_observability\_monitoring\_enable) | Set false to disable IBM Cloud Monitoring integration. If enabled, infrastructure and LSF application metrics from Management Nodes will be ingested. | `bool` | `false` | no | -| [observability\_monitoring\_on\_compute\_nodes\_enable](#input\_observability\_monitoring\_on\_compute\_nodes\_enable) | Set false to disable IBM Cloud Monitoring integration. If enabled, infrastructure metrics from Compute Nodes will be ingested. | `bool` | `false` | no | -| [observability\_monitoring\_plan](#input\_observability\_monitoring\_plan) | Type of service plan for IBM Cloud Monitoring instance. You can choose one of the following: lite, graduated-tier. For all details visit [IBM Cloud Monitoring Service Plans](https://cloud.ibm.com/docs/monitoring?topic=monitoring-service_plans). | `string` | `"graduated-tier"` | no | -| [remote\_allowed\_ips](#input\_remote\_allowed\_ips) | Comma-separated list of IP addresses that can access the IBM Cloud HPC cluster instance through an SSH interface. For security purposes, provide the public IP addresses assigned to the devices that are authorized to establish SSH connections (for example, ["169.45.117.34"]). To fetch the IP address of the device, use [https://ipv4.icanhazip.com/](https://ipv4.icanhazip.com/). | `list(string)` | n/a | yes | -| [reservation\_id](#input\_reservation\_id) | Ensure that you have received the reservation ID from IBM technical sales. Reservation ID is a unique identifier to distinguish different IBM Cloud HPC service agreements. It must start with a letter and can only contain letters, numbers, hyphens (-), or underscores (\_). | `string` | n/a | yes | -| [resource\_group](#input\_resource\_group) | Specify the existing resource group name from your IBM Cloud account where the VPC resources should be deployed. By default, the resource group name is set to 'Default.' Note that in some older accounts, the resource group name may be 'default,' so please validate the resource\_group name before deployment. If the resource group value is set to null, the automation will create two different resource groups named 'workload-rg' and 'service-rg.' For more information on resource groups, refer to Managing resource groups. | `string` | `"Default"` | no | -| [scc\_enable](#input\_scc\_enable) | Flag to enable SCC instance creation. If true, an instance of SCC (Security and Compliance Center) will be created. | `bool` | `false` | no | -| [scc\_event\_notification\_plan](#input\_scc\_event\_notification\_plan) | Event Notifications Instance plan to be used (it's used with S.C.C. instance), possible values 'lite' and 'standard'. | `string` | `"lite"` | no | -| [scc\_location](#input\_scc\_location) | Location where the SCC instance is provisioned (possible choices 'us-south', 'eu-de', 'ca-tor', 'eu-es') | `string` | `"us-south"` | no | -| [scc\_profile](#input\_scc\_profile) | Profile to be set on the SCC Instance (accepting empty, 'CIS IBM Cloud Foundations Benchmark' and 'IBM Cloud Framework for Financial Services') | `string` | `"CIS IBM Cloud Foundations Benchmark"` | no | -| [scc\_profile\_version](#input\_scc\_profile\_version) | Version of the Profile to be set on the SCC Instance (accepting empty, CIS and Financial Services profiles versions) | `string` | `"1.0.0"` | no | -| [skip\_iam\_authorization\_policy](#input\_skip\_iam\_authorization\_policy) | Set to false if authorization policy is required for VPC block storage volumes to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for block storage volume](https://cloud.ibm.com/docs/vpc?topic=vpc-block-s2s-auth&interface=ui). | `string` | `false` | no | -| [skip\_iam\_share\_authorization\_policy](#input\_skip\_iam\_share\_authorization\_policy) | Set it to false if authorization policy is required for VPC file share to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for VPC file share](https://cloud.ibm.com/docs/vpc?topic=vpc-file-s2s-auth&interface=ui). | `bool` | `false` | no | -| [storage\_security\_group\_id](#input\_storage\_security\_group\_id) | Provide the storage security group ID created from the Spectrum Scale storage cluster if the nfs\_share value is updated to use the scale fileset mountpoints under the cluster\_file\_share variable. | `string` | `null` | no | -| [vpc\_cidr](#input\_vpc\_cidr) | Creates the address prefix for the new VPC, when the vpc\_name variable is empty. The VPC requires an address prefix for creation of subnet in a single zone. The subnet are created with the specified CIDR blocks. For more information, see [Setting IP ranges](https://cloud.ibm.com/docs/vpc?topic=vpc-vpc-addressing-plan-design). | `string` | `"10.241.0.0/18"` | no | -| [vpc\_cluster\_login\_private\_subnets\_cidr\_blocks](#input\_vpc\_cluster\_login\_private\_subnets\_cidr\_blocks) | Provide the CIDR block required for the creation of the login cluster's private subnet. Only one CIDR block is needed. If using a hybrid environment, modify the CIDR block to avoid conflicts with any on-premises CIDR blocks. Since the login subnet is used only for the creation of login virtual server instances, provide a CIDR range of /28. | `list(string)` |
[
"10.241.16.0/28"
]
| no | -| [vpc\_cluster\_private\_subnets\_cidr\_blocks](#input\_vpc\_cluster\_private\_subnets\_cidr\_blocks) | Provide the CIDR block required for the creation of the compute cluster's private subnet. One CIDR block is required. If using a hybrid environment, modify the CIDR block to avoid conflicts with any on-premises CIDR blocks. Ensure the selected CIDR block size can accommodate the maximum number of management and dynamic compute nodes expected in your cluster. For more information on CIDR block size selection, refer to the documentation, see [Choosing IP ranges for your VPC](https://cloud.ibm.com/docs/vpc?topic=vpc-choosing-ip-ranges-for-your-vpc). | `list(string)` |
[
"10.241.0.0/20"
]
| no | -| [vpc\_name](#input\_vpc\_name) | Name of an existing VPC in which the cluster resources will be deployed. If no value is given, then a new VPC will be provisioned for the cluster. [Learn more](https://cloud.ibm.com/docs/vpc) | `string` | `null` | no | -| [vpn\_enabled](#input\_vpn\_enabled) | Set the value as true to deploy a VPN gateway for VPC in the cluster. | `bool` | `false` | no | -| [zones](#input\_zones) | The IBM Cloud zone name within the selected region where the IBM Cloud HPC cluster should be deployed and requires a single zone input value. Supported zones are: eu-de-2 and eu-de-3 for eu-de, us-east-1 and us-east-3 for us-east, and us-south-1 for us-south. The management nodes, file storage shares, and compute nodes will be deployed in the same zone.[Learn more](https://cloud.ibm.com/docs/vpc?topic=vpc-creating-a-vpc-in-a-different-region#get-zones-using-the-cli). | `list(string)` |
[
"us-east-1"
]
| no | - -## Outputs - -| Name | Description | -|------|-------------| -| [application\_center\_tunnel](#output\_application\_center\_tunnel) | Available if IBM Spectrum LSF Application Center GUI is installed | -| [application\_center\_url](#output\_application\_center\_url) | Available if IBM Spectrum LSF Application Center GUI is installed | -| [application\_center\_url\_note](#output\_application\_center\_url\_note) | Available if IBM Spectrum LSF Application Center GUI is installed in High Availability | -| [cloud\_monitoring\_url](#output\_cloud\_monitoring\_url) | IBM Cloud Monitoring URL | -| [image\_entry\_found](#output\_image\_entry\_found) | Available if the image name provided is located within the image map | -| [ldap\_hostnames](#output\_ldap\_hostnames) | LDAP nodes have these hostnames: | -| [ldap\_ips](#output\_ldap\_ips) | LDAP nodes have these IPs: | -| [login\_hostnames](#output\_login\_hostnames) | Login nodes have these hostnames: | -| [login\_ips](#output\_login\_ips) | Login nodes have these IPs: | -| [management\_candidate\_hostnames](#output\_management\_candidate\_hostnames) | Management candidate nodes have these hostnames: | -| [management\_candidate\_ips](#output\_management\_candidate\_ips) | Management candidate nodes have these IPs: | -| [management\_hostname](#output\_management\_hostname) | Management node has this hostname: | -| [management\_ip](#output\_management\_ip) | Management node has this IP: | -| [region\_name](#output\_region\_name) | The region name in which the cluster resources have been deployed | -| [remote\_allowed\_cidr](#output\_remote\_allowed\_cidr) | The following IPs/networks are allow-listed for incoming connections | -| [ssh\_to\_ldap\_node](#output\_ssh\_to\_ldap\_node) | SSH command to connect to LDAP node | -| [ssh\_to\_login\_node](#output\_ssh\_to\_login\_node) | SSH command to connect to Login node | -| [ssh\_to\_management\_node\_1](#output\_ssh\_to\_management\_node\_1) | SSH command to connect to HPC cluster | -| [vpc\_name](#output\_vpc\_name) | The VPC name in which the cluster resources have been deployed | +This offering is provided and supported by [IBM Corporation](https://www.ibm.com/mysupport). To get help with the IBM Cloud HPC offering please contact IBM HPC Cloud support using: +* URL https://www.ibm.com/mysupport +* Call IBM support - country-based numbers listed [here](https://www.ibm.com/planetwide). +IBM Cloud HPC support is provided 24x7x365 for Severity 1 issues and during client business hours (8 AM to 5 PM) for Severity 2, 3 and 4 issues. diff --git a/solutions/hpc/input_validation.tf b/solutions/hpc/input_validation.tf index decf2e94..c253320f 100644 --- a/solutions/hpc/input_validation.tf +++ b/solutions/hpc/input_validation.tf @@ -131,7 +131,7 @@ locals { # LDAP Admin Password Validation validate_ldap_adm_pwd = var.enable_ldap && var.ldap_server == "null" ? (length(var.ldap_admin_password) >= 8 && length(var.ldap_admin_password) <= 20 && can(regex("^(.*[0-9]){2}.*$", var.ldap_admin_password))) && can(regex("^(.*[A-Z]){1}.*$", var.ldap_admin_password)) && can(regex("^(.*[a-z]){1}.*$", var.ldap_admin_password)) && can(regex("^.*[~@_+:].*$", var.ldap_admin_password)) && can(regex("^[^!#$%^&*()=}{\\[\\]|\\\"';?.<,>-]+$", var.ldap_admin_password)) : local.ldap_server_status - ldap_adm_password_msg = "Password that is used for LDAP admin.The password must contain at least 8 characters and at most 20 characters. For a strong password, at least three alphabetic characters are required, with at least one uppercase and one lowercase letter. Two numbers, and at least one special character. Make sure that the password doesn't include the username." + ldap_adm_password_msg = "Password that is used for LDAP admin. The password must contain at least 8 characters and at most 20 characters. For a strong password, at least three alphabetic characters are required, with at least one uppercase and one lowercase letter. Two numbers, and at least one special character. Make sure that the password doesn't include the username." # tflint-ignore: terraform_unused_declarations validate_ldap_adm_pwd_chk = regex( "^${local.ldap_adm_password_msg}$", @@ -147,7 +147,7 @@ locals { # LDAP User Password Validation validate_ldap_usr_pwd = var.enable_ldap && var.ldap_server == "null" ? (length(var.ldap_user_password) >= 8 && length(var.ldap_user_password) <= 20 && can(regex("^(.*[0-9]){2}.*$", var.ldap_user_password))) && can(regex("^(.*[A-Z]){1}.*$", var.ldap_user_password)) && can(regex("^(.*[a-z]){1}.*$", var.ldap_user_password)) && can(regex("^.*[~@_+:].*$", var.ldap_user_password)) && can(regex("^[^!#$%^&*()=}{\\[\\]|\\\"';?.<,>-]+$", var.ldap_user_password)) : local.ldap_server_status - ldap_usr_password_msg = "Password that is used for LDAP user.The password must contain at least 8 characters and at most 20 characters. For a strong password, at least three alphabetic characters are required, with at least one uppercase and one lowercase letter. Two numbers, and at least one special character. Make sure that the password doesn't include the username." + ldap_usr_password_msg = "Password that is used for LDAP user. The password must contain at least 8 characters and at most 20 characters. For a strong password, at least three alphabetic characters are required, with at least one uppercase and one lowercase letter. Two numbers, and at least one special character. Make sure that the password doesn't include the username." # tflint-ignore: terraform_unused_declarations validate_ldap_usr_pwd_chk = regex( "^${local.ldap_usr_password_msg}$", diff --git a/solutions/hpc/locals.tf b/solutions/hpc/locals.tf index 5e7a4e8b..d59a97ce 100644 --- a/solutions/hpc/locals.tf +++ b/solutions/hpc/locals.tf @@ -72,7 +72,27 @@ locals { compute_subnet_id = local.compute_subnets[0].id compute_security_group_id = module.landing_zone_vsi.compute_sg_id management_instance_count = var.management_node_count - default_share = local.management_instance_count > 0 ? [ + + valid_lsf_shares = [ + for share in var.custom_file_shares : + { + mount_path = "/mnt/lsf" + nfs_share = share.nfs_share + } + if share.mount_path == "/mnt/lsf" && share.nfs_share != "" && share.nfs_share != null + ] + + valid_default_vpc_share = [ + for share in var.custom_file_shares : + { + mount_path = "/mnt/lsf" + size = share.size + iops = share.size + } + if share.mount_path == "/mnt/lsf" && share.size != null && share.iops != null + ] + + default_share = local.management_instance_count > 0 && length(local.valid_lsf_shares) == 0 && length(local.valid_default_vpc_share) == 0 ? [ { mount_path = "/mnt/lsf" size = 100 @@ -87,10 +107,10 @@ locals { size = share.size iops = share.iops } - if share.size != null && share.iops != null + if share.size != null && share.iops != null && share.mount_path != "/mnt/lsf" ] - total_shares = concat(local.default_share, local.vpc_file_share) + total_shares = concat(length(local.valid_default_vpc_share) == 1 ? local.valid_default_vpc_share : local.default_share, local.vpc_file_share) # total_shares = 10 file_shares = [ @@ -197,7 +217,7 @@ locals { } locals { - share_path = module.file_storage.mount_path_1 + share_path = length(local.valid_lsf_shares) > 0 ? join(", ", local.valid_lsf_shares[*].nfs_share) : module.file_storage.mount_path_1 } ########################################################################### diff --git a/solutions/hpc/main.tf b/solutions/hpc/main.tf index a9e006d0..b7b4a0fe 100644 --- a/solutions/hpc/main.tf +++ b/solutions/hpc/main.tf @@ -95,7 +95,6 @@ module "landing_zone_vsi" { kms_encryption_enabled = local.kms_encryption_enabled boot_volume_encryption_key = local.boot_volume_encryption_key share_path = local.share_path - vpc_file_share_count = length(local.vpc_file_share) hyperthreading_enabled = var.hyperthreading_enabled app_center_gui_pwd = var.app_center_gui_pwd enable_app_center = var.enable_app_center @@ -103,7 +102,7 @@ module "landing_zone_vsi" { cluster_id = local.cluster_id management_node_count = var.management_node_count management_node_instance_type = var.management_node_instance_type - file_share = module.file_storage.mount_paths_excluding_first + file_share = length(local.valid_lsf_shares) > 0 ? module.file_storage.total_mount_paths : module.file_storage.mount_paths_excluding_first mount_path = var.custom_file_shares login_node_instance_type = var.login_node_instance_type bastion_subnets = local.bastion_subnets diff --git a/solutions/hpc/variables.tf b/solutions/hpc/variables.tf index 5d4fb56e..d5d00f6d 100644 --- a/solutions/hpc/variables.tf +++ b/solutions/hpc/variables.tf @@ -17,7 +17,7 @@ variable "ibmcloud_api_key" { ############################################################################## variable "resource_group" { - description = "Specify the existing resource group name from your IBM Cloud account where the VPC resources should be deployed. By default, the resource group name is set to 'Default.' Note that in some older accounts, the resource group name may be 'default,' so please validate the resource_group name before deployment. If the resource group value is set to null, the automation will create two different resource groups named 'workload-rg' and 'service-rg.' For more information on resource groups, refer to Managing resource groups." + description = "Specify the existing resource group name from your IBM Cloud account where the VPC resources should be deployed. By default, the resource group name is set to 'Default.' Note that in some older accounts, the resource group name may be 'default,' so please validate the resource_group name before deployment. If the resource group value is set to the string \"null\", the automation will create two different resource groups named 'workload-rg' and 'service-rg.' For more information on resource groups, refer to Managing resource groups." type = string default = "Default" validation { @@ -60,7 +60,7 @@ variable "cluster_id" { description = "Ensure that you have received the cluster ID from IBM technical sales. A unique identifer for HPC cluster used by IBM Cloud HPC to differentiate different HPC clusters within the same reservations. This can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. You cannot change the cluster ID after deployment." validation { condition = 0 < length(var.cluster_id) && length(var.cluster_id) < 40 && can(regex("^[a-zA-Z0-9_.-]+$", var.cluster_id)) - error_message = "The ID can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. Other special characters and spaces are not allowed." + error_message = "The Cluster ID can be up to 39 alphanumeric characters including the underscore (_), the hyphen (-), and the period (.) characters. Other special characters and spaces are not allowed." } } @@ -221,15 +221,11 @@ variable "custom_file_shares" { nfs_share = optional(string) })) default = [{ mount_path = "/mnt/vpcstorage/tools", size = 100, iops = 2000 }, { mount_path = "/mnt/vpcstorage/data", size = 100, iops = 6000 }, { mount_path = "/mnt/scale/tools", nfs_share = "" }] - description = "Mount points and sizes in GB and IOPS range of file shares that can be used to customize shared file storage layout. Provide the details for up to 5 shares. Each file share size in GB supports different range of IOPS. For more information, see [file share IOPS value](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles&interface=ui)." + description = "Provide details for customizing your shared file storage layout, including mount points, sizes in GB, and IOPS ranges for up to five file shares. Each file share size in GB supports a different IOPS range. If the cluster requires creating more than 256 dynamic nodes, only provide the details of the NFS share and use \"/mnt/lsf\" as the mount path for the internal file share. If not, a default VPC file share will be created, which supports up to 256 nodes. For more information, see [file share IOPS value](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-profiles&interface=ui)." validation { condition = length([for item in var.custom_file_shares : item if item.nfs_share == null]) <= 5 error_message = "The VPC storage custom file share count \"custom_file_shares\" must be less than or equal to 5. Unlimited NFS mounts are allowed." } - validation { - condition = !anytrue([for mounts in var.custom_file_shares : mounts.mount_path == "/mnt/lsf"]) - error_message = "The mount path /mnt/lsf is reserved for internal usage and can't be used as file share mount_path." - } validation { condition = length([for mounts in var.custom_file_shares : mounts.mount_path]) == length(toset([for mounts in var.custom_file_shares : mounts.mount_path])) error_message = "Mount path values should not be duplicated." @@ -505,7 +501,7 @@ variable "ldap_vsi_osimage_name" { } variable "skip_iam_authorization_policy" { - type = string + type = bool default = false description = "Set to false if authorization policy is required for VPC block storage volumes to access kms. This can be set to true if authorization policy already exists. For more information on how to create authorization policy manually, see [creating authorization policies for block storage volume](https://cloud.ibm.com/docs/vpc?topic=vpc-block-s2s-auth&interface=ui)." } diff --git a/tests/common_utils/log_utils.go b/tests/common_utils/log_utils.go index bf1bffb8..d90c6424 100644 --- a/tests/common_utils/log_utils.go +++ b/tests/common_utils/log_utils.go @@ -15,6 +15,8 @@ type AggregatedLogger struct { infoLogger *log.Logger warnLogger *log.Logger errorLogger *log.Logger + passLogger *log.Logger + failLogger *log.Logger } // NewAggregatedLogger creates a new instance of AggregatedLogger. @@ -34,6 +36,8 @@ func NewAggregatedLogger(logFileName string) (*AggregatedLogger, error) { infoLogger: log.New(file, "", 0), warnLogger: log.New(file, "", 0), errorLogger: log.New(file, "", 0), + passLogger: log.New(file, "", 0), + failLogger: log.New(file, "", 0), }, nil } @@ -64,3 +68,17 @@ func (l *AggregatedLogger) Error(t *testing.T, message string) { l.errorLogger.Printf(format, getLogArgs(t, message)...) logger.Log(t, getLogArgs(t, message)...) } + +// Error logs error messages. +func (l *AggregatedLogger) PASS(t *testing.T, message string) { + format := "[%s] [PASS] [%s] : %v\n" + l.passLogger.Printf(format, getLogArgs(t, message)...) + logger.Log(t, getLogArgs(t, message)...) +} + +// Error logs error messages. +func (l *AggregatedLogger) FAIL(t *testing.T, message string) { + format := "[%s] [FAIL] [%s] : %v\n" + l.failLogger.Printf(format, getLogArgs(t, message)...) + logger.Log(t, getLogArgs(t, message)...) +} diff --git a/tests/other_test.go b/tests/other_test.go index 301ac855..171a5ffe 100644 --- a/tests/other_test.go +++ b/tests/other_test.go @@ -8,7 +8,8 @@ import ( "github.com/stretchr/testify/require" - terra "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" utils "github.com/terraform-ibm-modules/terraform-ibm-hpc/common_utils" lsf "github.com/terraform-ibm-modules/terraform-ibm-hpc/lsf" @@ -346,6 +347,7 @@ func TestRunUsingExistingKMS(t *testing.T) { // Retrieve cluster information from environment variables envVars := GetEnvVars() + // Create service instance and KMS key using IBMCloud CLI err := lsf.CreateServiceInstanceandKmsKey(t, os.Getenv("TF_VAR_ibmcloud_api_key"), utils.GetRegion(envVars.Zone), envVars.DefaultResourceGroup, kmsInstanceName, lsf.KMS_KEY_NAME, testLogger) require.NoError(t, err, "Service instance and KMS key creation failed") @@ -362,6 +364,8 @@ func TestRunUsingExistingKMS(t *testing.T) { // Skip test teardown for further inspection options.SkipTestTearDown = true + + // Ensure the service instance and KMS key are deleted after the test defer lsf.DeleteServiceInstanceAndAssociatedKeys(t, os.Getenv("TF_VAR_ibmcloud_api_key"), utils.GetRegion(envVars.Zone), envVars.DefaultResourceGroup, kmsInstanceName, testLogger) defer options.TestTearDown() @@ -672,21 +676,18 @@ func TestRunWithoutMandatory(t *testing.T) { // Getting absolute path of solutions/hpc abs, err := filepath.Abs("solutions/hpc") - - if err != nil { - require.Error(t, err, "Absolute path is:: %v", abs) - } + require.NoError(t, err, "Unable to get absolute path") terrPath := strings.ReplaceAll(abs, "tests/", "") // Define Terraform options - terraformOptions := terra.WithDefaultRetryableErrors(t, &terra.Options{ + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ TerraformDir: terrPath, Vars: map[string]interface{}{}, }) // Initialize and plan the Terraform deployment - _, err = terra.InitAndPlanE(t, terraformOptions) + _, err = terraform.InitAndPlanE(t, terraformOptions) // If there is an error, check if it contains specific mandatory fields if err != nil { @@ -697,6 +698,8 @@ func TestRunWithoutMandatory(t *testing.T) { utils.VerifyDataContains(t, err.Error(), "remote_allowed_ips", testLogger) // Assert that the result is true if all mandatory fields are missing assert.True(t, result) + } else { + t.Error("Expected error did not occur") } } @@ -730,8 +733,8 @@ func TestRunCIDRsAsNonDefault(t *testing.T) { lsf.ValidateBasicClusterConfiguration(t, options, testLogger) } -// TestExistingPACEnvironment tests the validation of an existing PAC environment configuration. -func TestExistingPACEnvironment(t *testing.T) { +// TestRunExistingPACEnvironment tests the validation of an existing PAC environment configuration. +func TestRunExistingPACEnvironment(t *testing.T) { // Parallelize the test to run concurrently with others t.Parallel() @@ -760,3 +763,579 @@ func TestExistingPACEnvironment(t *testing.T) { lsf.ValidateClusterConfigurationWithAPPCenterForExistingEnv(t, config.BastionIP, config.LoginNodeIP, config.ClusterID, config.ReservationID, config.ClusterPrefixName, config.ResourceGroup, config.KeyManagement, config.Zones, config.DnsDomainName, config.ManagementNodeIPList, config.HyperthreadingEnabled, testLogger) } + +// TestRunInvalidReservationIDAndContractID tests invalid cluster_id and reservation_id values +func TestRunInvalidReservationIDAndContractID(t *testing.T) { + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + // Log the initiation of cluster creation process + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Define invalid cluster_id and reservation_id values + invalidClusterIDs := []string{ + "too_long_cluster_id_1234567890_abcdefghijklmnopqrstuvwxyz", //pragma: allowlist secret + "invalid@cluster!id#", + "", + } + + invalidReservationIDs := []string{ + "1invalid_reservation", + "invalid_reservation@id", + "ContractIBM", + "", + } + + // Getting absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Loop over all combinations of invalid cluster_id and reservation_id values + for _, clusterID := range invalidClusterIDs { + for _, reservationID := range invalidReservationIDs { + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": clusterID, + "reservation_id": reservationID, + }, + }) + + // Initialize and plan the Terraform deployment + _, err := terraform.InitAndPlanE(t, terraformOptions) + + // If there is an error, check if it contains specific mandatory fields + if err != nil { + clusterIDError := utils.VerifyDataContains(t, err.Error(), "cluster_id", testLogger) + reservationIDError := utils.VerifyDataContains(t, err.Error(), "reservation_id", testLogger) + result := clusterIDError && reservationIDError + // Assert that the result is true if all mandatory fields are missing + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid clusterID and ReservationID") + } else { + testLogger.FAIL(t, "Validation failed: Expected error did not contain required fields: cluster_id or reservation_id") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur on Invalid clusterID and ReservationID validation") + } + } + } +} + +// TestRunInvalidLDAPServerIP validates cluster creation with invalid LDAP server IP. +func TestRunInvalidLDAPServerIP(t *testing.T) { + // Parallelize the test to run concurrently with others + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + if strings.ToLower(envVars.EnableLdap) == "true" { + // Check if the LDAP credentials are provided + if len(envVars.LdapAdminPassword) == 0 || len(envVars.LdapUserName) == 0 || len(envVars.LdapUserPassword) == 0 { + require.FailNow(t, "LDAP credentials are missing. Make sure LDAP admin password, LDAP user name, and LDAP user password are provided.") + } + } else { + require.FailNow(t, "LDAP is not enabled. Set the 'enable_ldap' environment variable to 'true' to enable LDAP.") + } + + // Get the absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "enable_ldap": true, + "ldap_admin_password": envVars.LdapAdminPassword, //pragma: allowlist secret + "ldap_server": "10.10.10.10", + }, + }) + + // Apply the Terraform configuration + _, err = terraform.InitAndApplyE(t, terraformOptions) + + // Check if an error occurred during apply + assert.Error(t, err, "Expected an error during apply") + + if err != nil { + // Check if the error message contains specific keywords indicating LDAP server IP issues + result := utils.VerifyDataContains(t, err.Error(), "The connection to the existing LDAP server 10.10.10.10 failed", testLogger) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid LDAP server IP") + } else { + testLogger.FAIL(t, "Validation failed: Invalid LDAP server IP") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur on Invalid LDAP Server IP") + } + + // Cleanup resources + defer terraform.Destroy(t, terraformOptions) +} + +// TestRunInvalidLDAPUsernamePassword tests invalid LDAP username and password +func TestRunInvalidLDAPUsernamePassword(t *testing.T) { + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + // Log the initiation of cluster creation process + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Define invalid ldap username and password values + invalidLDAPUsername := []string{ + "usr", + "user@1234567890123456789012345678901", + "", + "user 1234", + } + + invalidLDAPPassword := []string{ + "password", + "PasswoRD123", + "password123", + "Password@", + "Password123", + "password@12345678901234567890", + } + + // Getting absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Loop over all combinations of invalid ldap username and password values + for _, username := range invalidLDAPUsername { + for _, password := range invalidLDAPPassword { //pragma: allowlist secret + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "enable_ldap": true, + "ldap_user_name": username, + "ldap_user_password": password, //pragma: allowlist secret + "ldap_admin_password": password, //pragma: allowlist secret + }, + }) + + // Initialize and plan the Terraform deployment + _, err := terraform.InitAndPlanE(t, terraformOptions) + + // If there is an error, check if it contains specific mandatory fields + if err != nil { + usernameError := utils.VerifyDataContains(t, err.Error(), "ldap_user_name", testLogger) + userPasswordError := utils.VerifyDataContains(t, err.Error(), "ldap_usr_pwd", testLogger) + adminPasswordError := utils.VerifyDataContains(t, err.Error(), "ldap_adm_pwd", testLogger) + result := usernameError && userPasswordError && adminPasswordError + // Assert that the result is true if all mandatory fields are missing + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid LDAP username LDAP user password ,LDAP admin password") + } else { + testLogger.FAIL(t, "Validation failed: Expected error did not contain required fields: ldap_user_name, ldap_user_password or ldap_admin_password") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not contain required fields: ldap_user_name, ldap_user_password or ldap_admin_password") + } + } + } +} + +// TestRunInvalidAPPCenterPassword tests invalid values for app center password +func TestRunInvalidAPPCenterPassword(t *testing.T) { + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + // Log the initiation of cluster creation process + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + invalidAPPCenterPwd := []string{ + "pass@1234", + "Pass1234", + "Pas@12", + "", + } + + // Loop over all combinations of invalid cluster_id and reservation_id values + for _, password := range invalidAPPCenterPwd { //pragma: allowlist secret + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Getting absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "enable_app_center": true, + "app_center_gui_pwd": password, + }, + }) + + // Initialize and plan the Terraform deployment + _, err = terraform.InitAndPlanE(t, terraformOptions) + + // If there is an error, check if it contains specific mandatory fields + if err != nil { + result := utils.VerifyDataContains(t, err.Error(), "app_center_gui_pwd", testLogger) + + // Assert that the result is true if all mandatory fields are missing + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid Application Center Password") + } else { + testLogger.FAIL(t, "Validation failed: Invalid Application Center Password") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur on Invalid Application Center Password") + } + } +} + +// TestRunInvalidDomainName validates cluster creation with invalid domain name. +func TestRunInvalidDomainName(t *testing.T) { + // Parallelize the test to run concurrently with others + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Get the absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "dns_domain_name": map[string]string{"compute": "sample"}, + }, + }) + + // Apply the Terraform configuration + _, err = terraform.InitAndPlanE(t, terraformOptions) + + // Check if an error occurred during apply + assert.Error(t, err, "Expected an error during apply") + + if err != nil { + // Check if the error message contains specific keywords indicating domain name issues + result := utils.VerifyDataContains(t, err.Error(), "The domain name provided for compute is not a fully qualified domain name", testLogger) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid domain name") + } else { + testLogger.FAIL(t, "Validation failed: Invalid domain name") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur on Invalid domain name") + } +} + +// TestRunKMSInstanceNameAndKMSKeyNameWithInvalidValue tests the creation of KMS instances and KMS key names with invalid values +func TestRunKMSInstanceNameAndKMSKeyNameWithInvalidValue(t *testing.T) { + // Parallelize the test to run concurrently with others + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // Service instance name + randomString := utils.GenerateRandomString() + kmsInstanceName := "cicd-" + randomString + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Create service instance and KMS key using IBMCloud CLI + err := lsf.CreateServiceInstanceandKmsKey(t, os.Getenv("TF_VAR_ibmcloud_api_key"), utils.GetRegion(envVars.Zone), envVars.DefaultResourceGroup, kmsInstanceName, lsf.KMS_KEY_NAME, testLogger) + require.NoError(t, err, "Failed to create service instance and KMS key") + + // Ensure the service instance and KMS key are deleted after the test + defer lsf.DeleteServiceInstanceAndAssociatedKeys(t, os.Getenv("TF_VAR_ibmcloud_api_key"), utils.GetRegion(envVars.Zone), envVars.DefaultResourceGroup, kmsInstanceName, testLogger) + + testLogger.Info(t, "Service instance and KMS key created successfully: "+t.Name()) + + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Failed to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + const ( + invalidKMSKeyName = "sample-key" + invalidKMSInstanceName = "sample-ins" + noKeyErrorMsg = "No keys with name sample-key" + noInstanceErrorMsg = "No resource instance found with name [sample-ins]" + noInstanceIDErrorMsg = "Please make sure you are passing the kms_instance_name if you are passing kms_key_name" + ) + + // Test with valid instance ID and invalid key name + terraformOptionsCase1 := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "kms_instance_name": kmsInstanceName, + "kms_key_name": invalidKMSKeyName, + }, + }) + + _, err = terraform.InitAndPlanE(t, terraformOptionsCase1) + if err != nil { + result := utils.VerifyDataContains(t, err.Error(), noKeyErrorMsg, testLogger) + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Valid instance ID and invalid key name") + } else { + testLogger.FAIL(t, "Validation failed: Valid instance ID and invalid key name") + } + } else { + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur with valid instance ID and invalid key name") + } + + // Test with invalid instance ID and valid key name + terraformOptionsCase2 := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "kms_instance_name": invalidKMSInstanceName, + "kms_key_name": lsf.KMS_KEY_NAME, + }, + }) + + _, err = terraform.InitAndPlanE(t, terraformOptionsCase2) + if err != nil { + result := utils.VerifyDataContains(t, err.Error(), noInstanceErrorMsg, testLogger) + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Invalid instance ID and valid key name") + } else { + testLogger.FAIL(t, "Validation failed: Invalid instance ID and valid key name") + } + } else { + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur with invalid instance ID and valid key name") + } + + // Test without instance ID and valid key name + terraformOptionsCase3 := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "kms_key_name": lsf.KMS_KEY_NAME, + }, + }) + + _, err = terraform.InitAndPlanE(t, terraformOptionsCase3) + if err != nil { + result := utils.VerifyDataContains(t, err.Error(), noInstanceIDErrorMsg, testLogger) + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Without instance ID and valid key name") + } else { + testLogger.FAIL(t, "Validation failed: Without instance ID and valid key name") + } + } else { + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur without instance ID and valid key name") + } +} + +// Verify that existing subnet_id has an input value, then there should be an entry for 'vpc_name' +func TestRunExistSubnetIDVpcNameAsNull(t *testing.T) { + // Parallelize the test to run concurrently with others + t.Parallel() + + // Setup test suite + setupTestSuite(t) + + testLogger.Info(t, "Cluster creation process initiated for "+t.Name()) + + // HPC cluster prefix + hpcClusterPrefix := utils.GenerateTimestampedClusterPrefix(utils.GenerateRandomString()) + + // Retrieve cluster information from environment variables + envVars := GetEnvVars() + + // Create test options, set up test environment + options, err := setupOptionsVpc(t, hpcClusterPrefix, createVpcTerraformDir, envVars.DefaultResourceGroup) + require.NoError(t, err, "Error setting up test options: %v", err) + + // Skip test teardown for further inspection + options.SkipTestTearDown = true + defer options.TestTearDown() + + // Run the test + output, err := options.RunTest() + require.NoError(t, err, "Error running consistency test: %v", err) + require.NotNil(t, output, "Expected non-nil output, but got nil") + outputs := (options.LastTestTerraformOutputs) + + bastionsubnetId, computesubnetIds := utils.GetSubnetIds(outputs) + + // Get the absolute path of solutions/hpc + abs, err := filepath.Abs("solutions/hpc") + require.NoError(t, err, "Unable to get absolute path") + + terrPath := strings.ReplaceAll(abs, "tests/", "") + + // Define Terraform options + terraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: terrPath, + Vars: map[string]interface{}{ + "cluster_prefix": hpcClusterPrefix, + "bastion_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "compute_ssh_keys": utils.SplitAndTrim(envVars.SSHKey, ","), + "zones": utils.SplitAndTrim(envVars.Zone, ","), + "remote_allowed_ips": utils.SplitAndTrim(envVars.RemoteAllowedIPs, ","), + "cluster_id": envVars.ClusterID, + "reservation_id": envVars.ReservationID, + "cluster_subnet_ids": utils.SplitAndTrim(computesubnetIds, ","), + "login_subnet_id": bastionsubnetId, + }, + }) + + // Apply the Terraform configuration + _, err = terraform.InitAndPlanE(t, terraformOptions) + + // Check if an error occurred during plan + assert.Error(t, err, "Expected an error during plan") + + if err != nil { + // Check if the error message contains specific keywords indicating vpc name issues + result := utils.VerifyDataContains(t, err.Error(), "If the cluster_subnet_ids are provided, the user should also provide the vpc_name", testLogger) && + utils.VerifyDataContains(t, err.Error(), "Provided cluster subnets should be in appropriate zone", testLogger) && + utils.VerifyDataContains(t, err.Error(), "Provided login subnet should be within the vpc entered", testLogger) && + utils.VerifyDataContains(t, err.Error(), "Provided login subnet should be in appropriate zone", testLogger) && + utils.VerifyDataContains(t, err.Error(), "Provided cluster subnets should be within the vpc entered", testLogger) && + utils.VerifyDataContains(t, err.Error(), "Provided existing cluster_subnet_ids should have public gateway attached", testLogger) + assert.True(t, result) + if result { + testLogger.PASS(t, "Validation succeeded: Without VPC name and with valid cluster_subnet_ids and login_subnet_id") + } else { + testLogger.FAIL(t, "Validation failed: Without VPC name and with valid cluster_subnet_ids and login_subnet_id") + } + } else { + // Log an error if the expected error did not occur + t.Error("Expected error did not occur") + testLogger.FAIL(t, "Expected error did not occur on Without VPC name and with valid cluster_subnet_ids and login_subnet_id") + } +} diff --git a/tests/test_config.yml b/tests/test_config.yml index e0aa2a35..91140854 100644 --- a/tests/test_config.yml +++ b/tests/test_config.yml @@ -9,7 +9,7 @@ login_node_instance_type: bx2-2x8 login_image_name: hpcaas-lsf10-rhel88-compute-v5 management_image_name: hpcaas-lsf10-rhel88-v7 compute_image_name: hpcaas-lsf10-rhel88-compute-v5 -management_node_instance_type: bx2-16x64 +management_node_instance_type: bx2-2x8 management_node_count: 2 enable_vpc_flow_logs: false key_management: key_protect