diff --git a/.gitignore b/.gitignore index 6f898ba0af..0c73ff5ddd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ report.html output.xml test-screenshots bin +*.ova # drone secrets.yml diff --git a/installer/docs/DESIGN.md b/installer/docs/DESIGN.md index e17f10175f..70301902ba 100644 --- a/installer/docs/DESIGN.md +++ b/installer/docs/DESIGN.md @@ -167,6 +167,11 @@ components should use this certificate for user facing connections and can acces this directory as a read only volume to the component container (`-v /storage/data/certs:/path/on/container:ro`) +For user provided certificates, the user must provide in PEM format a server certificate, unencrypted +server private key, and certificate authority certificate. If the server private key is not in PKCS8 +format (beginning with `-----BEGIN PRIVATE KEY-----`), the appliance will attempt to convert it into +PKCS8 format before saving it for use by the appliance. + `/storage/data/certs/` contains: ``` - cert_gen_type # self-signed or custom @@ -188,6 +193,22 @@ this directory as a read only volume to the component container https://github.com/koalaman/shellcheck +## Networking + +The VIC appliance has one NIC. The VIC appliance will respond to ICMP echo requests and has the +following ports open for services running on the appliance. Users may customize ports for certain +services during appliance deployment. + +``` +22 SSH +80 Loading page and redirect to Getting Started Page +443 Harbor Registry +8282 Admiral Container Management Portal +8443 VIC Machine API +9443 VIC appliance Getting Started Page +``` + + ## Component Inclusion and Continuous Integration Components are pulled in by the build to create the appliance. Components may depend on additional diff --git a/tests/manual-test-cases/Group5-Interoperability-Tests/5-02-OVA-Upgrade.robot b/tests/manual-test-cases/Group5-Interoperability-Tests/5-02-OVA-Upgrade.robot index d76cdeda5a..9fc4b3481e 100644 --- a/tests/manual-test-cases/Group5-Interoperability-Tests/5-02-OVA-Upgrade.robot +++ b/tests/manual-test-cases/Group5-Interoperability-Tests/5-02-OVA-Upgrade.robot @@ -28,10 +28,7 @@ OVA Upgrade Setup Run Keyword And Ignore Error Nimbus Cleanup ${list} ${false} Log To Console \nStart downloading vic-v1.2.1-4104e5f9.ova... ${pid1}= Start Process wget -nc https://storage.googleapis.com/vic-product-ova-releases/vic-v1.2.1-4104e5f9.ova shell=True - ${latest-ova}= Run gsutil ls -l gs://vic-product-ova-builds/ | grep -v TOTAL | sort -k2r | (head -n1 ; dd of=/dev/null 2>&1 /dev/null) | xargs | cut -d ' ' -f 3 | cut -d '/' -f 4 - Log To Console \nStart downloading ${latest-ova}... - ${pid2}= Start Process wget -nc https://storage.googleapis.com/vic-product-ova-builds/${latest-ova} shell=True - + ${latest-ova}= Download Latest VIC Appliance OVA ${esx1} ${esx2} ${esx3} ${vc} ${esx1-ip} ${esx2-ip} ${esx3-ip} ${vc-ip}= Create a Simple VC Cluster Log To Console Finished Creating Cluster ${vc} Set Suite Variable @{list} ${esx1} ${esx2} ${esx3} %{NIMBUS_USER}-${vc} @@ -46,7 +43,6 @@ OVA Upgrade Setup Set Environment Variable TEST_DATASTORE datastore1 ${ret}= Wait For Process ${pid1} - ${ret}= Wait For Process ${pid2} *** Test Cases *** Test @@ -56,7 +52,7 @@ Test Set Global Variable ${OVA_USERNAME_ROOT} root Set Global Variable ${OVA_PASSWORD_ROOT} e2eFunctionalTest Install VIC Product OVA vic-v1.2.1-4104e5f9.ova %{OVA_NAME} - + Set Global Variable ${FIREFOX_BROWSER} firefox Set Global Variable ${GRID_URL} http://selenium-hub:4444/wd/hub Set Global Variable ${EXPLICIT_WAIT} 30 @@ -77,4 +73,3 @@ Test Set Environment Variable OVA_NAME OVA-5-02-TEST-LATEST Install VIC Product OVA ${latest-ova} %{OVA_NAME} - diff --git a/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.md b/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.md new file mode 100644 index 0000000000..fb74e204e5 --- /dev/null +++ b/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.md @@ -0,0 +1,41 @@ +Test 6-01 - OVA TLS +======= + +# Purpose: +To verify the VIC OVA appliance works with various TLS certificate configuration + +# References: + +# Environment: +This test requires access to a vCenter environment + +# Test Cases: + +### User Provided Certificate + +#### Test Steps: + +1. Generate a certificate and certificate authority +2. Supply generated certificate and certificate authority during deploy of VIC appliance +3. Initialize the VIC appliance +4. Wait for services to start and verify that the provided certificate is used by all services + running on the VIC appliance + +#### Expected Outcome: +The VIC appliance deployment should succeed without error and the provided TLS certificate should be +used for all services running on the VIC appliance + + +### User Provided Certificate PKCS8 + +#### Test Steps: + +1. Generate a certificate with private key in PKCS8 format and certificate authority +2. Supply generated certificate and certificate authority during deploy of VIC appliance +3. Initialize the VIC appliance +4. Wait for services to start and verify that the provided certificate is used by all services + running on the VIC appliance + +#### Expected Outcome: +The VIC appliance deployment should succeed without error and the provided TLS certificate should be +used for all services running on the VIC appliance diff --git a/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.robot b/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.robot new file mode 100644 index 0000000000..407632c938 --- /dev/null +++ b/tests/manual-test-cases/Group6-OVA-TLS/6-01-OVA-TLS.robot @@ -0,0 +1,97 @@ +# Copyright 2018 VMware, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License + +*** Settings *** +Documentation Test 6-01 - OVA TLS +Resource ../../resources/Util.robot +Suite Setup Wait Until Keyword Succeeds 10x 10m OVA Setup +Suite Teardown Run Keyword And Ignore Error Nimbus Cleanup ${list} +Test Teardown Cleanup VIC Product OVA %{OVA_NAME} + +*** Variables *** +${esx_number}= 3 +${datacenter}= ha-datacenter + +*** Keywords *** +OVA Setup + [Timeout] 110 minutes + Run Keyword And Ignore Error Nimbus Cleanup ${list} ${false} + + ${latest-ova}= Download Latest VIC Appliance OVA + Set Environment Variable LATEST_OVA ${latest-ova} + + ${esx1} ${esx2} ${esx3} ${vc} ${esx1-ip} ${esx2-ip} ${esx3-ip} ${vc-ip}= Create a Simple VC Cluster + Log To Console Finished Creating Cluster ${vc} + Set Suite Variable @{list} ${esx1} ${esx2} ${esx3} %{NIMBUS_USER}-${vc} + + Set Environment Variable TEST_URL ${vc-ip} + Set Environment Variable TEST_USERNAME Administrator@vsphere.local + Set Environment Variable TEST_PASSWORD Admin\!23 + Set Environment Variable BRIDGE_NETWORK bridge + Set Environment Variable PUBLIC_NETWORK vm-network + Set Environment Variable TEST_RESOURCE /ha-datacenter/host/cls + Set Environment Variable TEST_TIMEOUT 30m + Set Environment Variable TEST_DATASTORE datastore1 + +*** Test Cases *** +User Provided Certificate + Log To Console \nStarting user provided certificate test... + ${ova-name}= Get Test OVA Name + Set Environment Variable OVA_NAME ${ova-name} + Global Environment Setup + + # Generate CA and wildcard cert for *. + Cleanup Generated Certificate + Log Generating certificates for %{DOMAIN} + Generate Certificate Authority + Generate Wildcard Server Certificate + + ${tls_cert}= Get Server Certificate "*.%{DOMAIN}".cert.pem + ${tls_cert_key}= Get Server Key "*.%{DOMAIN}".key.pem + ${ca_cert}= Get Certificate Authority CRT + + Log ${tls_cert} + Log ${tls_cert_key} + Log ${ca_cert} + + ${ova-ip}= Install VIC Product OVA %{LATEST_OVA} %{OVA_NAME} ${tls_cert} ${tls_cert_key} ${ca_cert} + + Wait Until Keyword Succeeds 10x 15s Verify VIC Appliance TLS Certificates ${ova-ip} issuer=/C=US/ST=California/L=Los Angeles/O=Stark Enterprises/OU=Stark Enterprises Certificate Authority/CN=Stark Enterprises Global CA + Cleanup Generated Certificate + + +User Provided Certificate PKCS8 + Log To Console \nStarting user provided certificate test... + ${ova-name}= Get Test OVA Name + Set Environment Variable OVA_NAME ${ova-name} + Global Environment Setup + + # Generate CA and wildcard cert for *. + Cleanup Generated Certificate + Log Generating certificates for %{DOMAIN} + Generate Certificate Authority + Generate Wildcard Server Certificate + + ${tls_cert}= Get Server Certificate "*.%{DOMAIN}".cert.pem + ${tls_cert_key}= Get Server Key "*.%{DOMAIN}".key.pem + ${ca_cert}= Get Certificate Authority CRT + + Log ${tls_cert} + Log ${tls_cert_key} + Log ${ca_cert} + + ${ova-ip}= Install VIC Product OVA %{LATEST_OVA} %{OVA_NAME} ${tls_cert} ${tls_cert_key} ${ca_cert} + + Wait Until Keyword Succeeds 10x 15s Verify VIC Appliance TLS Certificates ${ova-ip} issuer=/C=US/ST=California/L=Los Angeles/O=Stark Enterprises/OU=Stark Enterprises Certificate Authority/CN=Stark Enterprises Global CA + Cleanup Generated Certificate diff --git a/tests/manual-test-cases/Group6-OVA-TLS/TestCases.md b/tests/manual-test-cases/Group6-OVA-TLS/TestCases.md new file mode 100644 index 0000000000..39067c2fba --- /dev/null +++ b/tests/manual-test-cases/Group6-OVA-TLS/TestCases.md @@ -0,0 +1,5 @@ +Group 6 - OVA TLS +======= + +[Test 6-01 - OVA TLS](6-01-OVA-TLS.md) +- diff --git a/tests/manual-test-cases/README.md b/tests/manual-test-cases/README.md new file mode 100644 index 0000000000..d3519d309f --- /dev/null +++ b/tests/manual-test-cases/README.md @@ -0,0 +1,25 @@ +# Nightly Tests + +## Running Locally + +Set `test_secrets.yml` values + +``` +NIMBUS_USER= +NIMBUS_PASSWORD= +NIMBUS_GW= +DRONE_BUILD_NUMBER=1 +DOMAIN=eng.vmware.com +``` + +Run desired test suite + +``` +docker run --rm -v /go/src/github.com/vmware/vic-product:/go --env-file test_secrets.yml gcr.io/eminent-nation-87317/vic-integration-test:1.46 pybot tests/manual-test-cases/Group6-OVA-TLS +``` + +If selenium grid is needed, start it and replace `${GRID_URL}` in `Util.robot` with your IP address + +``` +docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q) && docker run -d -p 4444:4444 --net grid --name selenium-hub selenium/hub:3.9.1 && docker run -d --net grid -e HUB_HOST=selenium-hub -v /dev/shm:/dev/shm --name firefox1 selenium/node-firefox:3.9.1 +``` diff --git a/tests/manual-test-cases/TestGroups.md b/tests/manual-test-cases/TestGroups.md index aee410c762..d789cb7c19 100644 --- a/tests/manual-test-cases/TestGroups.md +++ b/tests/manual-test-cases/TestGroups.md @@ -6,3 +6,5 @@ VIC Integration Test Suite - [Group 5 - Interoperability Tests](Group5-Interoperability-Tests/TestCases.md) - +[Group 6 - OVA TLS](Group6-OVA-TLS/TestCases.md) +- diff --git a/tests/resources/Cert-Util.robot b/tests/resources/Cert-Util.robot new file mode 100644 index 0000000000..604737b4d5 --- /dev/null +++ b/tests/resources/Cert-Util.robot @@ -0,0 +1,127 @@ +# Copyright 2017 VMware, Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License + +*** Settings *** +Documentation This resource contains keywords related to creating and using certificates. Requires scripts in infra/integration-image/scripts be available in PATH + +*** Keywords *** +Cleanup Generated Certificate + [Arguments] ${DIR}=/root/ca + Run rm -rf ${DIR} + +Generate Certificate Authority + # Generates CA (private/ca.key.pem, certs/ca.cert.pem, certs/STARK_ENTERPRISES_ROOT_CA.crt) in OUT_DIR + [Arguments] ${CA_NAME}=STARK_ENTERPRISES_ROOT_CA ${OUT_DIR}=/root/ca + Log To Console Generating Certificate Authority + ${rc} ${out}= Run And Return Rc And Output generate-ca.sh -c ${CA_NAME} -d ${OUT_DIR} + Log ${out} + Should Be Equal As Integers ${rc} 0 + + +Generate Wildcard Server Certificate + # Generates key and signs with CA for *.DOMAIN (csr/*.DOMAIN.csr.pem, + # private/*.DOMAIN.key.pem, certs/*.DOMAIN.cert.pem) in OUT_DIR + [Arguments] ${DOMAIN}=%{DOMAIN} ${OUT_DIR}=/root/ca ${CA_NAME}=STARK_ENTERPRISES_ROOT_CA + Log To Console Generating Wildcard Server Certificate + Run Keyword Generate Server Key And CSR *.${DOMAIN} ${OUT_DIR} + Run Keyword Sign Server CSR ${CA_NAME} *.${DOMAIN} ${OUT_DIR} + Run Keyword Create Certificate Bundle CA_NAME=${CA_NAME} SRC_DIR=${OUT_DIR} CN=*.${DOMAIN} + ${out}= Run ls -al ${OUT_DIR}/csr + Log ${out} + ${out}= Run ls -al ${OUT_DIR}/private + Log ${out} + ${out}= Run ls -al ${OUT_DIR}/certs + Log ${out} + + +Generate Server Key And CSR + # Generates key and CSR (private/DOMAIN.key.pem, csr/DOMAIN.csr.pem) in OUT_DIR + [Arguments] ${CN}=%{DOMAIN} ${OUT_DIR}=/root/ca + Log To Console Generating Server Key And CSR + ${out}= Run generate-server-key-csr.sh -d ${OUT_DIR} -n ${CN} + Log ${out} + + +Sign Server CSR + # Generates certificate signed by CA (certs/DOMAIN.cert.pem) in OUT_DIR + [Arguments] ${CA_NAME}=STARK_ENTERPRISES_ROOT_CA ${CN}=%{DOMAIN} ${OUT_DIR}=/root/ca + Log To Console Signing Server CSR + ${out}= Run sign-csr.sh -c ${CA_NAME} -d ${OUT_DIR} -n ${CN} + Log ${out} + + +Trust Certificate Authority + # Installs root certificate into trust store on Debian based distro + [Arguments] ${CRT_FILE}=/root/ca/certs/STARK_ENTERPRISES_ROOT_CA.crt + Log To Console Installing CA + ${rc} ${out}= Run And Return Rc And Output ubuntu-install-ca.sh -f ${CRT_FILE} + Should Be Equal As Integers ${rc} 0 + Log ${out} + + +Reload Default Certificate Authorities + # Reloads default certificates into trust store on Debian based distro + # Removes all user provided CAs + Log To Console Reloading Default CAs + ${rc} ${out}= Run And Return Rc And Output ubuntu-reload-cas.sh + Should Be Equal As Integers ${rc} 0 + Log ${out} + + +Create Certificate Bundle + [Arguments] ${CA_NAME}=STARK_ENTERPRISES_ROOT_CA ${SRC_DIR}=/root/ca ${OUT_FILE}=/root/ca/cert-bundle.tgz ${CN}=%{DOMAIN} ${TMP_DIR}=/root/ca/bundle + ${rc} ${out}= Run And Return Rc And Output bundle-certs.sh -c ${CA_NAME} -d ${SRC_DIR} -f ${OUT_FILE} -n ${CN} -o ${TMP_DIR} + Should Be Equal As Integers ${rc} 0 + Log ${out} + + +Get Certificate Authority CRT + # Return ascii armored certificate from file e.g. `-----BEGIN CERTIFICATE-----` + [Arguments] ${CA_CRT}=STARK_ENTERPRISES_ROOT_CA.crt ${DIR}=/root/ca/certs + ${out}= Run cat ${DIR}/${CA_CRT} + [Return] ${out} + + +Get Server Certificate + # Return ascii armored certificate from file e.g. `-----BEGIN CERTIFICATE-----` + # PEM must be provided if using a wildcard cert not specified by DOMAIN + [Arguments] ${PEM}=%{DOMAIN}.cert.pem ${DIR}=/root/ca/certs + ${out}= Run cat ${DIR}/${PEM} + [Return] ${out} + + +Get Server Key + # Return ascii armored key from file e.g. `-----BEGIN RSA PRIVATE KEY-----` + # PEM must be provided if using a wildcard cert not specified by DOMAIN + [Arguments] ${PEM}=%{DOMAIN}.key.pem ${DIR}=/root/ca/private + ${out}= Run cat ${DIR}/${PEM} + [Return] ${out} + + +Get PKCS8 Server Key + # Convert server key to PKCS8 and return + [Arguments] ${PEM}=%{DOMAIN}.key.pem ${DIR}=/root/ca/private + cp ${PEM} ${PEM}.tmp + rm ${PEM} + openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in ${PEM}.tmp -out ${PEM} + ${out}= Run cat ${DIR}/${PEM} + [Return] ${out} + + +Get Remote Certificate + # Connect to remote (:) and get the cert + [Arguments] ${remote} + ${output}= Run openssl s_client -showcerts -connect ${remote} + Log ${output} + [Return] ${output} diff --git a/tests/resources/OVA-Util.robot b/tests/resources/OVA-Util.robot index 4e2c1e7c4a..a7935b880a 100644 --- a/tests/resources/OVA-Util.robot +++ b/tests/resources/OVA-Util.robot @@ -25,6 +25,19 @@ Get Test OVA Name ${name}= Evaluate 'OVA-%{DRONE_BUILD_NUMBER}-' + str(random.randint(1000,9999)) modules=random [Return] ${name} +Download Latest VIC Appliance OVA + ${latest-ova}= Run gsutil ls -l gs://vic-product-ova-builds/ | grep -v TOTAL | sort -k2r | (head -n1 ; dd of=/dev/null 2>&1 /dev/null) | xargs | cut -d ' ' -f 3 | cut -d '/' -f 4 + Log To Console \nStart downloading ${latest-ova}... + # ${pid1}= Start Process wget https://storage.googleapis.com/vic-product-ova-builds/${latest-ova} shell=True + ${pid1}= Start Process gsutil cp gs://vic-product-ova-builds/${latest-ova} . shell=True + ${ret}= Wait For Process ${pid1} + ${output}= Run ls -alh + Log ${output} + Log ${ret.stdout} + Log ${ret.stderr} + Log To Console \nFinished downloading ${latest-ova} + [Return] ${latest-ova} + Set Test OVA IP If Available Log To Console \nCheck VIC appliance and set OVA_IP env variable... Set Common Test OVA Name @@ -35,12 +48,13 @@ Set Test OVA IP If Available Install VIC Product OVA Only [Tags] secret - [Arguments] ${ova-file} ${ova-name} + [Arguments] ${ova-file} ${ova-name} ${tls_cert}=${EMPTY} ${tls_cert_key}=${EMPTY} ${ca_cert}=${EMPTY} Log To Console \nInstalling VIC appliance... - ${output}= Run ovftool --datastore=%{TEST_DATASTORE} --noSSLVerify --acceptAllEulas --name=${ova-name} --diskMode=thin --powerOn --X:waitForIp --X:injectOvfEnv --X:enableHiddenProperties --prop:appliance.root_pwd='${OVA_PASSWORD_ROOT}' --prop:appliance.permit_root_login=True --net:"Network"="%{PUBLIC_NETWORK}" ${ova-file} 'vi://%{TEST_USERNAME}:%{TEST_PASSWORD}@%{TEST_URL}%{TEST_RESOURCE}' + ${output}= Run ovftool --datastore=%{TEST_DATASTORE} --noSSLVerify --acceptAllEulas --name=${ova-name} --diskMode=thin --powerOn --X:waitForIp --X:injectOvfEnv --X:enableHiddenProperties --prop:appliance.root_pwd='${OVA_PASSWORD_ROOT}' --prop:appliance.permit_root_login=True --prop:appliance.tls_cert="${tls_cert}" --prop:appliance.tls_cert_key="${tls_cert_key}" --prop:appliance.ca_cert="${ca_cert}" --net:"Network"="%{PUBLIC_NETWORK}" ${ova-file} 'vi://%{TEST_USERNAME}:%{TEST_PASSWORD}@%{TEST_URL}%{TEST_RESOURCE}' + Log ${output} Should Contain ${output} Completed successfully Should Contain ${output} Received IP address: - + ${output}= Split To Lines ${output} ${ova-ip}= Set Variable NULL :FOR ${line} IN @{output} @@ -48,18 +62,19 @@ Install VIC Product OVA Only \ ${ip}= Run Keyword If ${status} Fetch From Right ${line} ${SPACE} \ ${ova-ip}= Run Keyword If ${status} Set Variable ${ip} ELSE Set Variable ${ova-ip} + Log ${ova-ip} Wait For Register Page ${ova-ip} Set Environment Variable OVA_IP ${ova-ip} Install VIC Product OVA [Tags] secret - [Arguments] ${ova-file} ${ova-name} + [Arguments] ${ova-file} ${ova-name} ${tls_cert}=${EMPTY} ${tls_cert_key}=${EMPTY} ${ca_cert}=${EMPTY} Log To Console \nInstalling VIC appliance and validating services... - Install VIC Product OVA Only ${ova-file} ${ova-name} + Install VIC Product OVA Only ${ova-file} ${ova-name} ${tls_cert} ${tls_cert_key} ${ca_cert} # set env var for ova ip Wait For Online Components %{OVA_IP} - + # validate complete installation on UI Log To Console Initializing the OVA using the getting started ui... Set Browser Variables @@ -170,3 +185,23 @@ Copy Support Bundle # copy log bundle ${output}= Run command and Return output sshpass -p ${OVA_PASSWORD_ROOT} scp -o StrictHostKeyChecking\=no -o UserKnownHostsFile=/dev/null ${OVA_USERNAME_ROOT}@${ova-ip}:${file} . + +Verify VIC Appliance TLS Certificates + # Verify that services are using the provided TLS certificate + # Match based on {validate-string} from openssl output + [Arguments] ${ova-ip} ${validate-string} + # Verify that the supplied certificate is presented on web interface + ${output}= Get Remote Certificate ${ova-ip}:9443 + Should Contain ${output} ${validate-string} + + # Verify that the supplied certificate is presented on the Admiral interface + ${output}= Get Remote Certificate ${ova-ip}:8282 + Should Contain ${output} ${validate-string} + + # Verify that the supplied certificate is presented on the VIC Machine API interface + ${output}= Get Remote Certificate ${ova-ip}:8443 + Should Contain ${output} ${validate-string} + + # Verify that the supplied certificate is presented on the Harbor interface + ${output}= Get Remote Certificate ${ova-ip}:443 + Should Contain ${output} ${validate-string} diff --git a/tests/resources/Util.robot b/tests/resources/Util.robot index e39b70defa..e76b25b3e8 100644 --- a/tests/resources/Util.robot +++ b/tests/resources/Util.robot @@ -20,6 +20,7 @@ Library requests Library Process Library SSHLibrary 5 minute Library DateTime +Resource Cert-Util.robot Resource OVA-Util.robot Resource VC-Util.robot Resource VCH-Util.robot