From aaf4ac3af2c128fec62deaa58bfac65faf20203b Mon Sep 17 00:00:00 2001 From: Prem Kumar Kalle Date: Thu, 27 Apr 2023 16:21:23 -0700 Subject: [PATCH] Update e2e tests to use custom certs and image signature verification Signed-off-by: Prem Kumar Kalle --- Makefile | 12 +++++-- test/e2e/Makefile | 31 +++++++++++----- .../framework/config_lifecycle_operations.go | 35 ++++++++++++++++++- test/e2e/framework/framework.go | 12 ++++--- .../framework/plugin_lifecycle_operations.go | 1 - .../plugin_lifecycle_suite_test.go | 18 +++++++++- .../plugin_sync_lifecycle_suite_test.go | 18 +++++++++- 7 files changed, 108 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 0afdf8615..c1f3d9a9e 100644 --- a/Makefile +++ b/Makefile @@ -178,19 +178,25 @@ test: fmt ## Run Tests .PHONY: e2e-cli-core ## Execute all CLI Core E2E Tests e2e-cli-core: start-test-central-repo e2e-cli-core-all ## Execute all CLI Core E2E Tests +.PHONY: setup-custom-cert-for-test-central-repo +setup-custom-cert-for-test-central-repo: ## Setup up the custom ca cert for test-central-repo in the config file + echo "Adding docker test central repo cert to the config file" + TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" $(ROOT_DIR)/bin/tanzu config cert delete localhost:9876 || true + $(ROOT_DIR)/bin/tanzu config cert add --host localhost:9876 --ca-certificate $(ROOT_DIR)/hack/central-repo/certs/localhost.crt + .PHONY: start-test-central-repo -start-test-central-repo: stop-test-central-repo ## Starts up a test central repository locally with docker +start-test-central-repo: stop-test-central-repo setup-custom-cert-for-test-central-repo ## Starts up a test central repository locally with docker @if [ ! -d $(ROOT_DIR)/hack/central-repo/registry-content ]; then \ (cd $(ROOT_DIR)/hack/central-repo && tar xjf registry-content.bz2 || true;) \ fi @docker run --rm -d -p 9876:443 --name central \ - -v $(ROOT_DIR)/hack/central-repo/certs:/certs \ + -v $(ROOT_DIR)/hack/central-repo/certs:/certs \ -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/localhost.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/localhost.key \ -v $(ROOT_DIR)/hack/central-repo/registry-content:/var/lib/registry \ mirror.gcr.io/library/registry:2 > /dev/null && \ - echo "Started docker test central repo with images:" && \ + echo "Started docker test central repo with images:" && \ $(ROOT_DIR)/hack/central-repo/upload-plugins.sh info .PHONY: stop-test-central-repo diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 3d14d4400..223217708 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -18,10 +18,23 @@ ifndef TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL = gcr.io/eminent-nation-87317/tanzu-cli/test/v1/plugins/plugin-inventory:latest endif +ifndef TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST +TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST = localhost:9876 +endif + +ifndef TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_CA_CERT_PATH +TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_CA_CERT_PATH = ${ROOT_DIR}/hack/central-repo/certs/localhost.crt +endif + ifndef TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL -TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL = localhost:9876/tanzu-cli/plugins/central:small +TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL = ${TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST}/tanzu-cli/plugins/central:small endif +ifndef TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH +TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH = ${ROOT_DIR}/hack/central-repo/cosign-key-pair/cosign.pub +endif + + .PHONY: e2e-cli-core-all ## Execute all CLI Core E2E Tests e2e-cli-core-all: e2e-cli-lifecycle e2e-cli-config e2e-cli-plugin-compatibility-test e2e-context-k8s-tests e2e-context-tmc-test e2e-cli-plugin-lifecycle-sync-test @@ -29,12 +42,12 @@ e2e-cli-core-all: e2e-cli-lifecycle e2e-cli-config e2e-cli-plugin-compatibility- .PHONY: e2e-cli-lifecycle ## Execute CLI life cycle specific e2e tests e2e-cli-lifecycle: - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test ${ROOT_DIR}/test/e2e/cli_lifecycle -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ .PHONY: e2e-cli-config ## Execute CLI config life cycle specific e2e tests e2e-cli-config: - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test ${ROOT_DIR}/test/e2e/config -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ .PHONY: e2e-cli-plugin-compatibility-test ## Execute CLI Core Plugin Compatibility E2E test cases @@ -44,7 +57,7 @@ e2e-cli-plugin-compatibility-test: else \ export TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL=$(TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL) ; \ export TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_VERIFICATION_SKIP_LIST=$(TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL) ; \ - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test ${ROOT_DIR}/test/e2e/plugins_compatibility -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ fi @@ -54,15 +67,17 @@ e2e-cli-plugin-lifecycle-sync-test: echo "***Skipping Plugin life cycle test cases because environment variables TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL is not set***" ; \ else \ export TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL) ; \ - export TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_VERIFICATION_SKIP_LIST=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL) ; \ - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH=$(TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH) ; \ + export TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST=${TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST} ; \ + export TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_CA_CERT_PATH=${TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_CA_CERT_PATH} ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test ${ROOT_DIR}/test/e2e/plugin_lifecycle -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ ${GO} test ${ROOT_DIR}/test/e2e/plugin_sync -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ fi .PHONY: e2e-context-k8s-tests ## Execute CLI context life cycle e2e tests for k8s target e2e-context-k8s-tests: - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test `go list ${ROOT_DIR}/test/e2e/context/... | grep -v test/e2e/context/tmc` -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ## To run TMC tests, we need to set environment variables TANZU_API_TOKEN and TANZU_CLI_TMC_UNSTABLE_URL, in case of github workflow, these are set as github environment variables @@ -71,6 +86,6 @@ e2e-context-tmc-test: @if [ "${TANZU_API_TOKEN}" = "" ] || [ "$(TANZU_CLI_TMC_UNSTABLE_URL)" = "" ]; then \ echo "***Skipping TMC specific e2e tests cases because environment variables TANZU_API_TOKEN and TANZU_CLI_TMC_UNSTABLE_URL are not set***" ; \ else \ - export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="Yes" ; \ + export TANZU_CLI_CEIP_OPT_IN_PROMPT_ANSWER="No" ; \ ${GO} test ${ROOT_DIR}/test/e2e/context/tmc -timeout ${E2E_TEST_TIMEOUT} -race -coverprofile ${E2E_TEST_OUTPUT} ${GOTEST_VERBOSE} ; \ fi diff --git a/test/e2e/framework/config_lifecycle_operations.go b/test/e2e/framework/config_lifecycle_operations.go index db81251be..f1fc20117 100644 --- a/test/e2e/framework/config_lifecycle_operations.go +++ b/test/e2e/framework/config_lifecycle_operations.go @@ -45,17 +45,38 @@ type ConfigLifecycleOps interface { IsCLIConfigurationFilesExists() bool } +// ConfigCertOps performs "tanzu config cert" command operations +type ConfigCertOps interface { + // ConfigCertAdd adds cert config for a host, and returns stdOut and error info + ConfigCertAdd(certAddOpts *CertAddOptions, opts ...E2EOption) (string, error) + + // ConfigCertDelete deletes cert config for a host, and returns error info + ConfigCertDelete(hostname string, opts ...E2EOption) error +} + +type ConfigCmdOps interface { + ConfigLifecycleOps + ConfigCertOps +} + // configOps is the implementation of ConfOps interface type configOps struct { cmdExe CmdOps } -func NewConfOps() ConfigLifecycleOps { +func NewConfOps() ConfigCmdOps { return &configOps{ cmdExe: NewCmdOps(), } } +type CertAddOptions struct { + Host string + CACertificatePath string + SkipCertVerify string + Insecure string +} + // GetConfig gets the tanzu config func (co *configOps) GetConfig(opts ...E2EOption) (*configapi.ClientConfig, error) { out, _, err := co.cmdExe.TanzuCmdExec(ConfigGet, opts...) @@ -154,3 +175,15 @@ func (co *configOps) IsCLIConfigurationFilesExists() bool { } return false } + +func (co *configOps) ConfigCertAdd(certAddOpts *CertAddOptions, opts ...E2EOption) (string, error) { + certAddCmd := fmt.Sprintf(ConfigCertAdd, "%s", certAddOpts.Host, certAddOpts.CACertificatePath, certAddOpts.SkipCertVerify, certAddOpts.Insecure) + out, _, err := co.cmdExe.TanzuCmdExec(certAddCmd, opts...) + return out.String(), err +} + +func (co *configOps) ConfigCertDelete(host string, opts ...E2EOption) error { + certDeleteCmd := fmt.Sprintf(ConfigCertDelete, "%s", host) + _, _, err := co.cmdExe.TanzuCmdExec(certDeleteCmd, opts...) + return err +} diff --git a/test/e2e/framework/framework.go b/test/e2e/framework/framework.go index 06f3162d2..3131f5182 100644 --- a/test/e2e/framework/framework.go +++ b/test/e2e/framework/framework.go @@ -26,6 +26,8 @@ const ( ConfigInit = "%s config init" ConfigServerList = "%s config server list" ConfigServerDelete = "%s config server delete %s -y" + ConfigCertAdd = "%s config cert add --host %s --ca-certificate %s --skip-cert-verify %s --insecure %s" + ConfigCertDelete = "%s config cert delete %s" // Plugin commands UpdatePluginSource = "%s plugin source update %s --uri %s" @@ -48,9 +50,11 @@ const ( PluginKey = "%s_%s_%s" // Plugins - Name_Target_Versions // Central repository - TanzuCliE2ETestCentralRepositoryURL = "TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL" - TanzuCliE2ETestLocalCentralRepositoryURL = "TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL" - + TanzuCliE2ETestCentralRepositoryURL = "TANZU_CLI_E2E_TEST_CENTRAL_REPO_URL" + TanzuCliE2ETestLocalCentralRepositoryURL = "TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_URL" + TanzuCliE2ETestLocalCentralRepositoryPluginDiscoveryImageSignaturePublicKeyPath = "TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH" + TanzuCliE2ETestLocalCentralRepositoryHost = "TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_HOST" + TanzuCliE2ETestLocalCentralRepositoryCACertPath = "TANZU_CLI_E2E_TEST_LOCAL_CENTRAL_REPO_CA_CERT_PATH" // General constants True = "true" Installed = "installed" @@ -165,7 +169,7 @@ func CLICoreDescribe(text string, body func()) bool { // Framework has all helper functions to write CLI e2e test cases type Framework struct { CliOps - Config ConfigLifecycleOps + Config ConfigCmdOps KindCluster ClusterOps PluginCmd PluginCmdOps // performs plugin command operations PluginHelper PluginHelperOps // helper (pre-setup) for plugin cmd operations diff --git a/test/e2e/framework/plugin_lifecycle_operations.go b/test/e2e/framework/plugin_lifecycle_operations.go index c73bf7eaa..b8607ec94 100644 --- a/test/e2e/framework/plugin_lifecycle_operations.go +++ b/test/e2e/framework/plugin_lifecycle_operations.go @@ -77,7 +77,6 @@ type DiscoveryOptions struct { type pluginCmdOps struct { cmdExe CmdOps - PluginCmdOps } func NewPluginLifecycleOps() PluginCmdOps { diff --git a/test/e2e/plugin_lifecycle/plugin_lifecycle_suite_test.go b/test/e2e/plugin_lifecycle/plugin_lifecycle_suite_test.go index 2a58eb0c9..3ffe7ec98 100644 --- a/test/e2e/plugin_lifecycle/plugin_lifecycle_suite_test.go +++ b/test/e2e/plugin_lifecycle/plugin_lifecycle_suite_test.go @@ -35,10 +35,26 @@ var _ = BeforeSuite(func() { e2eTestLocalCentralRepoURL = os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryURL) Expect(e2eTestLocalCentralRepoURL).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository URL", framework.TanzuCliE2ETestLocalCentralRepositoryURL)) - // setup the test central repo + // set up the test central repo _, err := tf.PluginCmd.UpdatePluginDiscoverySource(&framework.DiscoveryOptions{Name: "default", SourceType: framework.SourceType, URI: e2eTestLocalCentralRepoURL}) Expect(err).To(BeNil(), "should not get any error for plugin source update") + e2eTestLocalCentralRepoPluginHost := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryHost) + Expect(e2eTestLocalCentralRepoPluginHost).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository host", framework.TanzuCliE2ETestLocalCentralRepositoryHost)) + + e2eTestLocalCentralRepoCACertPath := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryCACertPath) + Expect(e2eTestLocalCentralRepoCACertPath).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository CA cert path", framework.TanzuCliE2ETestLocalCentralRepositoryCACertPath)) + + // set up the CA cert fort local central repository + _ = tf.Config.ConfigCertDelete(e2eTestLocalCentralRepoPluginHost) + _, err = tf.Config.ConfigCertAdd(&framework.CertAddOptions{Host: e2eTestLocalCentralRepoPluginHost, CACertificatePath: e2eTestLocalCentralRepoCACertPath, SkipCertVerify: "false", Insecure: "false"}) + Expect(err).To(BeNil()) + + // set up the local central repository discovery image public key path + e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryPluginDiscoveryImageSignaturePublicKeyPath) + Expect(e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository discovery image signature public key path", framework.TanzuCliE2ETestLocalCentralRepositoryPluginDiscoveryImageSignaturePublicKeyPath)) + os.Setenv("TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH", e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath) + // search plugin groups and make sure there plugin groups available pluginGroups = SearchAllPluginGroups(tf) diff --git a/test/e2e/plugin_sync/plugin_sync_lifecycle_suite_test.go b/test/e2e/plugin_sync/plugin_sync_lifecycle_suite_test.go index e1a04b447..c5780045d 100644 --- a/test/e2e/plugin_sync/plugin_sync_lifecycle_suite_test.go +++ b/test/e2e/plugin_sync/plugin_sync_lifecycle_suite_test.go @@ -41,10 +41,26 @@ var _ = BeforeSuite(func() { e2eTestLocalCentralRepoURL = os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryURL) Expect(e2eTestLocalCentralRepoURL).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository URL", framework.TanzuCliE2ETestLocalCentralRepositoryURL)) - // setup the test central repo + // set up the test central repo _, err := tf.PluginCmd.UpdatePluginDiscoverySource(&framework.DiscoveryOptions{Name: "default", SourceType: framework.SourceType, URI: e2eTestLocalCentralRepoURL}) Expect(err).To(BeNil(), "should not get any error for plugin source update") + e2eTestLocalCentralRepoPluginHost := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryHost) + Expect(e2eTestLocalCentralRepoPluginHost).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository host", framework.TanzuCliE2ETestLocalCentralRepositoryHost)) + + e2eTestLocalCentralRepoCACertPath := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryCACertPath) + Expect(e2eTestLocalCentralRepoCACertPath).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository CA cert path", framework.TanzuCliE2ETestLocalCentralRepositoryCACertPath)) + + // set up the CA cert fort local central repository + _ = tf.Config.ConfigCertDelete(e2eTestLocalCentralRepoPluginHost) + _, err = tf.Config.ConfigCertAdd(&framework.CertAddOptions{Host: e2eTestLocalCentralRepoPluginHost, CACertificatePath: e2eTestLocalCentralRepoCACertPath, SkipCertVerify: "false", Insecure: "false"}) + Expect(err).To(BeNil()) + + // set up the local central repository discovery image public key path + e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath := os.Getenv(framework.TanzuCliE2ETestLocalCentralRepositoryPluginDiscoveryImageSignaturePublicKeyPath) + Expect(e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath).NotTo(BeEmpty(), fmt.Sprintf("environment variable %s should set with local central repository discovery image signature public key path", framework.TanzuCliE2ETestLocalCentralRepositoryPluginDiscoveryImageSignaturePublicKeyPath)) + os.Setenv("TANZU_CLI_PLUGIN_DISCOVERY_IMAGE_SIGNATURE_PUBLIC_KEY_PATH", e2eTestLocalCentralRepoPluginDiscoveryImageSignaturePublicKeyPath) + // search plugin groups and make sure there plugin groups available pluginGroups = helper.SearchAllPluginGroups(tf)