Feature 10923: Advanced cluster management 88/14988/3
authorgarciadeblas <gerardo.garciadeblas@telefonica.com>
Thu, 13 Feb 2025 09:23:34 +0000 (10:23 +0100)
committergarciadeblas <gerardo.garciadeblas@telefonica.com>
Fri, 21 Feb 2025 11:01:45 +0000 (12:01 +0100)
Change-Id: I384d1d3f6263876650681ed4d3b96709f08f45d8
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
README.md
robot-systest/lib/advanced_cluster_mgmt_lib.resource [new file with mode: 0644]
robot-systest/testsuite/gitops_01-advanced_cluster_management.robot [new file with mode: 0644]

index 1c32dcb..45f7424 100644 (file)
--- a/README.md
+++ b/README.md
@@ -202,6 +202,7 @@ The following tags exist for each testsuite:
   - `cluster_slices`: `slice_01`, `slice_02`
   - `cluster_heal`: `heal_01`, `heal_02`, `heal_03`, `heal_04`
   - `cluster_osm_rest`: `sol003_01`
+  - `cluster_gitops`: `gitops_01`
 - daily: for all testsuites that will run in the daily job
 - regression: for all testsuites that should pass in the current stable branch
 - sanity: for all testsuites that should be passed by each commit in the
diff --git a/robot-systest/lib/advanced_cluster_mgmt_lib.resource b/robot-systest/lib/advanced_cluster_mgmt_lib.resource
new file mode 100644 (file)
index 0000000..de9bb5d
--- /dev/null
@@ -0,0 +1,240 @@
+*** Comments ***
+# Copyright 2020 Canonical Ltd.
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+
+*** Settings ***
+Documentation   Library providing keywords for CRUD operations over clusters,
+...             OKAs and KSUs with OSM client.
+Library   OperatingSystem
+Library   String
+
+
+*** Variables ***
+${SUCCESS_RETURN_CODE}   0
+${CLUSTER_LAUNCH_MAX_WAIT_TIME}   12min
+${CLUSTER_LAUNCH_POL_TIME}   30sec
+${CLUSTER_DELETE_MAX_WAIT_TIME}   12min
+${CLUSTER_DELETE_POL_TIME}   30sec
+${OKA_OPERATION_MAX_WAIT_TIME}   5min
+${OKA_OPERATION_POL_TIME}   15sec
+${KSU_CREATION_MAX_WAIT_TIME}   10min
+${KSU_CREATION_POL_TIME}   30sec
+${KSU_DELETION_MAX_WAIT_TIME}   7min
+${KSU_DELETION_POL_TIME}   15sec
+
+
+*** Keywords ***
+Create Cluster
+    [Documentation]   Create a Kubernetes cluster in OSM using the name, version, nodes, etc., passed as arguments.
+    [Arguments]   ${name}   ${vim_account}   ${description}   ${vm_size}   ${version}   ${nodes}   ${region}   ${resource_group}   ${wait_flag}=True
+    ${command}=   Catenate
+    ...   osm cluster-create ${name}
+    ...   --node-count ${nodes}
+    ...   --node-size ${vm_size}
+    ...   --version ${version}
+    ...   --vim-account ${vim_account}
+    ...   --description ${description}
+    ...   --region-name ${region}
+    ...   --resource-group ${resource_group}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   ${command}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=Cluster creation failed: ${stdout}
+    ${cluster_id}=   Set Variable   ${stdout}
+    Log   ${cluster_id}
+    Check Cluster Age Keys   ${cluster_id}
+    IF   ${wait_flag} == True
+        Wait Until Keyword Succeeds   ${CLUSTER_LAUNCH_MAX_WAIT_TIME}   ${CLUSTER_LAUNCH_POL_TIME}
+        ...   Check For Cluster To Be Ready   ${name}
+    END
+    RETURN   ${cluster_id}
+
+Check Cluster Age Keys
+    [Documentation]   Check AGE keys in the cluster
+    [Arguments]   ${cluster_name}
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm cluster-show ${cluster_name} -o jsonpath='{.age_privkey}'
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    # TODO: Check if privkey contains the expected value
+    Log   privkey is ${stdout}
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm cluster-show ${cluster_name} -o jsonpath='{.age_pubkey}'
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    # TODO: Check if pubkey contains the expected value
+    Log   pubkey is ${stdout}
+
+Delete Cluster
+    [Documentation]   Unregister/delete a Kubernetes cluster from OSM.
+    [Arguments]   ${cluster_name}   ${wait_flag}=True
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-delete ${cluster_name}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=Cluster deletion failed: ${stdout}
+    IF   ${wait_flag} == True
+        Wait Until Keyword Succeeds   ${CLUSTER_DELETE_MAX_WAIT_TIME}   ${CLUSTER_DELETE_POL_TIME}
+        ...    Check For Cluster Deletion Status   ${cluster_name}
+    END
+
+Check For Cluster Deletion Status
+    [Documentation]   Check if a Kubernetes cluster identified by name is deleted or in error state.
+    [Arguments]   ${cluster_name}
+    ${rc}   ${output}=   Run And Return Rc And Output   osm cluster-show ${cluster_name}
+    Log   ${rc},${output}
+    ${rc}   ${resourceState}=   Run And Return Rc And Output   osm cluster-show ${cluster_name} -o jsonpath='{.resourceState}'
+    Log   ${rc},${resourceState}
+    IF   '$rc' == '$SUCCESS_RETURN_CODE' and '$resourceState' == 'ERROR'
+        Fail   Cluster is in error state and will not be deleted.
+    ELSE
+        Log   Either the cluster ${cluster_name} has been deleted or it is in a valid state.
+        Check For Cluster To Be Deleted   ${cluster_name}
+    END
+
+Get Clusters
+    [Documentation]   Get the list of Kubernetes clusters in OSM, and return it.
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-list
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    Log   ${stdout}
+    RETURN   ${stdout}
+
+Check For Cluster To Be Ready
+    [Documentation]   Check if a Kubernetes cluster is ready (the resourceState must be READY).
+    [Arguments]   ${cluster_name}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-show ${cluster_name}
+    Log   ${rc},${stdout}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-show ${cluster_name} -o jsonpath='{.resourceState}'
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    Should Be Equal As Strings   ${stdout}   READY
+
+Check For Cluster To Be Deleted
+    [Documentation]   Check if a Kubernetes cluster identified by name is not present in OSM.
+    [Arguments]   ${cluster_name}
+    ${matches}=   Get Regexp Matches   ${cluster_name}   ^[0-9a-fA-F-]{36}$
+    Log   ${matches}
+    IF   ${matches} != @{EMPTY}
+        Log   ${cluster_name} is a valid UUID
+        ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-list --filter _id="${cluster_name}" | grep ${cluster_name}
+    ELSE
+        Log   ${cluster_name} is not a valid UUID, so it will be treated as a name
+        ${rc}   ${stdout}=   Run And Return Rc And Output   osm cluster-list --filter name="${cluster_name}" | grep ${cluster_name}
+    END
+    Log   ${rc},${stdout}
+    Should Be Empty   ${stdout}
+
+Add OKA Package
+    [Documentation]   Add OKA package to OSM
+    [Arguments]   ${oka_name}   ${oka_folder}   ${oka_profile}   ${wait_flag}=True
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm oka-add ${oka_name} ${oka_folder} --description ${oka_name} --profile-type ${oka_profile}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=OKA addition failed: ${stdout}
+    ${oka_id}=   Set Variable   ${stdout}
+    Log   ${oka_id}
+    IF   ${wait_flag} == True
+        Wait Until Keyword Succeeds   ${OKA_OPERATION_MAX_WAIT_TIME}   ${OKA_OPERATION_POL_TIME}
+        ...    Check For OKA To Be Ready   ${oka_id}
+    END
+    RETURN   ${oka_id}
+
+Delete OKA Package
+    [Documentation]   Delete OKA package from OSM
+    [Arguments]   ${oka_name}   ${wait_flag}=True
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm oka-delete ${oka_name}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=OKA deletion failed: ${stdout}
+    IF   ${wait_flag} == True
+        Wait Until Keyword Succeeds   ${OKA_OPERATION_MAX_WAIT_TIME}   ${OKA_OPERATION_POL_TIME}
+        ...    Check For OKA To Be Deleted   ${oka_name}
+    END
+
+Check For OKA To Be Ready
+    [Documentation]   Check if an OKA is ready (the resourceState must be READY).
+    [Arguments]   ${oka_name}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm oka-show ${oka_name}
+    Log   ${rc},${stdout}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm oka-show ${oka_name} -o jsonpath='{.resourceState}'
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    Should Be Equal As Strings   ${stdout}   READY
+
+Check For OKA To Be Deleted
+    [Documentation]   Check if an OKA identified by oka_name is not present in OSM.
+    [Arguments]   ${oka_name}
+    ${rc}   ${output}=   Run And Return Rc And Output   osm oka-show ${oka_name}
+    Log   ${rc},${output}
+    ${matches}=   Get Regexp Matches   ${oka_name}   ^[0-9a-fA-F-]{36}$
+    Log   ${matches}
+    IF   ${matches} != @{EMPTY}
+        Log   ${oka_name} is a valid UUID
+        ${rc}   ${stdout}=   Run And Return Rc And Output   osm oka-list --filter _id="${oka_name}" | grep ${oka_name}
+    ELSE
+        Log   ${oka_name} is not a valid UUID, so it will be treated as a name
+        ${rc}   ${stdout}=   Run And Return Rc And Output   osm oka-list --filter name="${oka_name}" | grep ${oka_name}
+    END
+    Log   ${rc},${stdout}
+    Should Be Empty   ${stdout}
+
+Create KSU
+    [Documentation]   Create a KSU
+    [Arguments]   ${ksu_name}   ${ksu_description}   ${profile}   ${profile_type}   ${oka_name}   ${ksu_params_file}   ${wait_flag}=True
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm ksu-create --ksu ${ksu_name} --description ${ksu_description} --profile ${profile} --profile-type ${profile_type} --oka ${oka_name} --params ${ksu_params_file}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=KSU creation failed: ${stdout}
+    ${ksu_id}=   Set Variable   ${stdout}
+    Log   ${ksu_id}
+    IF   ${wait_flag} == True
+        Wait Until Keyword Succeeds   ${KSU_CREATION_MAX_WAIT_TIME}   ${KSU_CREATION_POL_TIME}
+        ...    Check For KSU To Be Ready   ${ksu_id}
+    END
+    RETURN   ${ksu_id}
+
+Delete KSU
+    [Documentation]   Delete KSU from OSM
+    [Arguments]   ${ksu_name}   ${wait_flag}=True
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...   osm ksu-delete ${ksu_name}
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=KSU deletion failed: ${stdout}
+    IF   ${wait_flag} == True
+       Wait Until Keyword Succeeds   ${KSU_DELETION_MAX_WAIT_TIME}   ${KSU_DELETION_POL_TIME}
+       ...    Check For KSU To Be Deleted   ${ksu_name}
+    END
+
+Check For KSU To Be Ready
+    [Documentation]   Check if a KSU is ready (the resourceState must be READY).
+    [Arguments]   ${ksu_name}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm ksu-show ${ksu_name}
+    Log   ${rc},${stdout}
+    ${rc}   ${stdout}=   Run And Return Rc And Output   osm ksu-show ${ksu_name} -o jsonpath='{.resourceState}'
+    Log   ${rc},${stdout}
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    Should Be Equal As Strings   ${stdout}   READY
+
+Check For KSU To Be Deleted
+    [Documentation]   Check if a KSU identified by ksu_name is not present in OSM.
+    [Arguments]   ${ksu_name}
+    ${rc}   ${output}=   Run And Return Rc And Output   osm ksu-show ${ksu_name}
+    Log   ${rc},${output}
+    ${matches}=   Get Regexp Matches   ${ksu_name}   ^[0-9a-fA-F-]{36}$
+    Log   ${matches}
+    IF   ${matches} != @{EMPTY}
+       Log   ${ksu_name} is a valid UUID
+       ${rc}   ${stdout}=   Run And Return Rc And Output   osm ksu-list --filter _id="${ksu_name}" | grep ${ksu_name}
+    ELSE
+       Log   ${ksu_name} is not a valid UUID, so it will be treated as a name
+       ${rc}   ${stdout}=   Run And Return Rc And Output   osm ksu-list --filter name="${ksu_name}" | grep ${ksu_name}
+    END
+    Log   ${rc},${stdout}
+    Should Be Empty   ${stdout}
diff --git a/robot-systest/testsuite/gitops_01-advanced_cluster_management.robot b/robot-systest/testsuite/gitops_01-advanced_cluster_management.robot
new file mode 100644 (file)
index 0000000..e308a58
--- /dev/null
@@ -0,0 +1,112 @@
+*** Comments ***
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+
+*** Settings ***
+Documentation   [GITOPS-01] Advanced Cluster Management.
+
+Library   OperatingSystem
+Library   String
+Library   Collections
+Library   Process
+
+Resource   ../lib/advanced_cluster_mgmt_lib.resource
+
+Test Tags   gitops_01   cluster_gitops
+
+Suite Teardown   Run Keyword And Ignore Error   Suite Cleanup
+
+
+*** Variables ***
+# OKA packages
+${OKA_FOLDER}   '%{PACKAGES_FOLDER}/oka'
+${OKA_PKG1}   apps/testapp
+${OKA_NAME1}   testapp
+${OKA_PROFILE1}   app-profile
+${OKA_PKG2}   apps/testacme
+${OKA_NAME2}   testacme
+${OKA_PROFILE2}   app-profile
+${OKA_PKG3}   apps/jenkins
+${OKA_NAME3}   jenkins
+${OKA_PROFILE3}   app-profile
+
+# Cluster
+${CLUSTER_NAME}   gitops01
+${CLUSTER_DESCRIPTION}   "Cluster for gitops01 Robot test suite"
+${CLUSTER_VM_SIZE}   Standard_D2_v2
+${CLUSTER_NODES}   2
+${REGION_NAME}   northeurope
+${RESOURCE_GROUP}   OSM-CTIO
+${KUBERNETES_VERSION}   "1.30"
+
+# KSUs
+${KSU_NAME1}   testapp
+${KSU_NAME2}   testacme
+${KSU_NAME3}   jenkins
+
+
+*** Test Cases ***
+Add OKA Packages For The Testsuite
+    [Documentation]   Add OKA packages for the testsuite.
+    [Tags]   oka   create
+    Add OKA Package   ${OKA_NAME1}   '${OKA_FOLDER}/${OKA_PKG1}'   ${OKA_PROFILE1}
+    Add OKA Package   ${OKA_NAME2}   '${OKA_FOLDER}/${OKA_PKG2}'   ${OKA_PROFILE2}
+    Add OKA Package   ${OKA_NAME3}   '${OKA_FOLDER}/${OKA_PKG3}'   ${OKA_PROFILE3}
+
+Create Cluster For Testsuite in Azure
+    [Documentation]   Create K8s cluster for the testsuite.
+    [Tags]   cluster   create
+    ${id}=   Create Cluster   ${CLUSTER_NAME}   %{VIM_TARGET}   ${CLUSTER_DESCRIPTION}   ${CLUSTER_VM_SIZE}   ${KUBERNETES_VERSION}   ${CLUSTER_NODES}   ${REGION_NAME}   ${RESOURCE_GROUP}
+    Set Suite Variable   ${CLUSTER_ID}   ${id}
+    Log   ${CLUSTER_ID}
+
+Get Cluster Kubeconfig
+    [Documentation]   Get Kubeconfig for the cluster.
+    [Tags]   cluster
+    ${rc}   ${stdout}=   Run And Return Rc And Output
+    ...    osm cluster-show ${CLUSTER_NAME} -o jsonpath='{.credentials}' | yq -y
+    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
+    Log   ${stdout}
+
+Create KSU3
+    [Documentation]   Create KSU3 based on ${OKA_NAME3} with params.
+    [Tags]   ksu   create
+    ${id}=   Create KSU   ${KSU_NAME3}   ${KSU_NAME3}   ${CLUSTER_NAME}   app-profile   ${OKA_NAME3}   ${OKA_FOLDER}/apps/jenkins-params.yaml
+    Set Suite Variable   ${KSU_ID3}   ${id}
+    Log   ${KSU_ID3}
+
+Delete KSU3
+    [Documentation]   Delete KSU3 based on ${OKA_NAME3}.
+    [Tags]   cleanup   ksu
+    Delete KSU   ${KSU_ID3}
+
+Delete Cluster For Testsuite
+    [Documentation]   Delete K8s cluster for the testsuite.
+    [Tags]   cleanup   cluster
+    Delete Cluster   ${CLUSTER_NAME}
+
+Delete OKA Packages For The Testsuite
+    [Documentation]   Delete OKA packages for the testsuite.
+    [Tags]   cleanup   oka
+    Delete OKA Package   ${OKA_NAME1}
+    Delete OKA Package   ${OKA_NAME2}
+    Delete OKA Package   ${OKA_NAME3}
+
+
+*** Keywords ***
+Suite Cleanup
+    [Documentation]   Test Suit Cleanup: Deleting cluster, KSUs, OKAs
+    Run Keyword If Any Tests Failed   Delete Cluster   ${CLUSTER_NAME}
+    Run Keyword If Any Tests Failed   Delete OKA Package   ${OKA_NAME1}
+    Run Keyword If Any Tests Failed   Delete OKA Package   ${OKA_NAME2}
+    Run Keyword If Any Tests Failed   Delete OKA Package   ${OKA_NAME3}