From d2b7cae3dcc3fc44647d3a3bd8434639b5dc48eb Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Thu, 15 Feb 2024 17:33:21 +0100 Subject: [PATCH 1/2] K8S-9358 fix cluster provisioning with dynamic openstack cloud credentials --- Makefile | 3 ++ metakube/resource_cluster_schema.go | 45 ------------------------- metakube/resource_cluster_test.go | 52 +++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index fbca1bd..84aa7d6 100644 --- a/Makefile +++ b/Makefile @@ -16,6 +16,9 @@ default: install build: goimportscheck go build -v -o ${BINARY} +build-debug: goimportscheck + go build -v -gcflags='all=-N -l' -o ${BINARY} + install: build mkdir -p ~/.terraform.d/plugins/${DOMAIN}/${NAMESPACE}/${PKG_NAME}/${VERSION}/${PLATFORM} mv ${BINARY} ~/.terraform.d/plugins/${DOMAIN}/${NAMESPACE}/${PKG_NAME}/${VERSION}/${PLATFORM} diff --git a/metakube/resource_cluster_schema.go b/metakube/resource_cluster_schema.go index 669c47c..14c5722 100644 --- a/metakube/resource_cluster_schema.go +++ b/metakube/resource_cluster_schema.go @@ -1,7 +1,6 @@ package metakube import ( - "os" "regexp" "time" @@ -293,29 +292,6 @@ func metakubeResourceClusterOpenstackCloudSpecFields() map[string]*schema.Schema MaxItems: 1, Optional: true, ConflictsWith: []string{"spec.0.cloud.0.openstack.0.application_credentials"}, - DiffSuppressFunc: func(_, _, _ string, d *schema.ResourceData) bool { - v, ok := d.GetOkConfigured("spec.0.cloud.0.openstack.0.application_credentials") - if ok && len(v.([]interface{})) != 0 { - return false - } - - v, ok = d.GetOkConfigured("spec.0.cloud.0.openstack.0.user_credentials") - if !ok || len(v.([]interface{})) == 0 { - return true - } - for _, item := range [][]string{ - {"username", "OS_USERNAME"}, - {"password", "OS_PASSWORD"}, - {"project_id", "OS_PROJECT_ID"}, - {"project_name", "OS_PROJECT_NAME"}, - } { - _, ok := d.GetOkConfigured("spec.0.cloud.0.openstack.0.user_credentials.0." + item[0]) - if ok || os.Getenv(item[1]) != "" { - return false - } - } - return true - }, Elem: &schema.Resource{ Schema: metakubeResourceClusterOpenstackCloudSpecUserCredentialsFields(), }, @@ -325,27 +301,6 @@ func metakubeResourceClusterOpenstackCloudSpecFields() map[string]*schema.Schema MaxItems: 1, Optional: true, ConflictsWith: []string{"spec.0.cloud.0.openstack.0.user_credentials"}, - DiffSuppressFunc: func(_, _, _ string, d *schema.ResourceData) bool { - v, ok := d.GetOkConfigured("spec.0.cloud.0.openstack.0.user_credentials") - if ok && len(v.([]interface{})) != 0 { - return false - } - - v, ok = d.GetOkConfigured("spec.0.cloud.0.openstack.0.application_credentials") - if !ok || len(v.([]interface{})) == 0 { - return true - } - for _, item := range [][]string{ - {"id", "OS_APPLICATION_CREDENTIAL_ID"}, - {"secret", "OS_APPLICATION_CREDENTIAL_SECRET"}, - } { - _, ok := d.GetOkConfigured("spec.0.cloud.0.openstack.0.application_credentials.0." + item[0]) - if ok || os.Getenv(item[1]) != "" { - return false - } - } - return true - }, Elem: &schema.Resource{ Schema: metakubeResourceClusterOpenstackCloudSpecApplicationCredentialsFields(), }, diff --git a/metakube/resource_cluster_test.go b/metakube/resource_cluster_test.go index 5995eaf..aebdbac 100644 --- a/metakube/resource_cluster_test.go +++ b/metakube/resource_cluster_test.go @@ -187,6 +187,7 @@ func TestAccMetakubeCluster_Openstack_ApplicationCredentials(t *testing.T) { Version: os.Getenv(testEnvK8sVersionOpenstack), OpenstackApplicationCredentialID: os.Getenv(testEnvOpenstackApplicationCredentialsID), OpenstackApplicationCredentialSecret: os.Getenv(testEnvOpenstackApplicationCredentialsSecret), + Dynamic: false, } var config strings.Builder if err := clusterOpenstackApplicationCredentialsBasicTemplate.Execute(&config, data); err != nil { @@ -215,6 +216,45 @@ func TestAccMetakubeCluster_Openstack_ApplicationCredentials(t *testing.T) { }) } +func TestAccMetakubeCluster_Openstack_ApplicationCredentials_Dynammic(t *testing.T) { + t.Parallel() + var cluster models.Cluster + resourceName := "metakube_cluster.acctest_cluster" + data := &clusterOpenstackApplicationCredentailsData{ + Name: makeRandomName() + "-appcred-dynamic", + DatacenterName: os.Getenv(testEnvOpenstackNodeDC), + ProjectID: os.Getenv(testEnvProjectID), + Version: os.Getenv(testEnvK8sVersionOpenstack), + OpenstackApplicationCredentialID: os.Getenv(testEnvOpenstackApplicationCredentialsID), + OpenstackApplicationCredentialSecret: os.Getenv(testEnvOpenstackApplicationCredentialsSecret), + Dynamic: true, + } + var config strings.Builder + if err := clusterOpenstackApplicationCredentialsBasicTemplate.Execute(&config, data); err != nil { + t.Fatal(err) + } + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckForOpenstack(t) }, + Providers: testAccProviders, + ExternalProviders: map[string]resource.ExternalProvider{ + "openstack": { + Source: "terraform-provider-openstack/openstack", + }, + }, + CheckDestroy: testAccCheckMetaKubeClusterDestroy, + Steps: []resource.TestStep{ + { + Config: config.String(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckMetaKubeClusterExists(&cluster), + resource.TestCheckResourceAttrSet(resourceName, "spec.0.cloud.0.openstack.0.application_credentials.0.id"), + resource.TestCheckResourceAttrSet(resourceName, "spec.0.cloud.0.openstack.0.application_credentials.0.secret"), + ), + }, + }, + }) +} + func TestAccMetakubeCluster_Openstack_UpgradeVersion(t *testing.T) { t.Parallel() var cluster models.Cluster @@ -383,6 +423,7 @@ type clusterOpenstackApplicationCredentailsData struct { Version string OpenstackApplicationCredentialID string OpenstackApplicationCredentialSecret string + Dynamic bool } var clusterOpenstackApplicationCredentialsBasicTemplate = mustParseTemplate("clusterOpenstackApplicationCredentials", ` @@ -394,6 +435,12 @@ terraform { } } +{{ if .Dynamic }} +resource "openstack_identity_application_credential_v3" "app_credential" { + name = "{{ .Name }}" + } +{{ end }} + resource "metakube_cluster" "acctest_cluster" { name = "{{ .Name }}" dc_name = "{{ .DatacenterName }}" @@ -413,8 +460,13 @@ resource "metakube_cluster" "acctest_cluster" { cloud { openstack { application_credentials { +{{ if .Dynamic }} + id=openstack_identity_application_credential_v3.app_credential.id + secret=openstack_identity_application_credential_v3.app_credential.secret +{{ else }} id="{{ .OpenstackApplicationCredentialID }}" secret="{{ .OpenstackApplicationCredentialSecret }}" +{{ end }} } } } From 0b1e892f6efbe59ffb4257cd541f39f22672e26b Mon Sep 17 00:00:00 2001 From: Robert Nemeti Date: Tue, 20 Feb 2024 12:45:59 +0100 Subject: [PATCH 2/2] add OS_REGION to provider --- .gitlab-ci.yml | 6 +++--- metakube/provider_test.go | 2 ++ metakube/resource_cluster_test.go | 25 ++++++++++++++++++++++- metakube/resource_node_deployment_test.go | 3 +++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc54351..a8234f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,7 +36,7 @@ env: paths: - test.env rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /k8s-.*/ || $CI_PIPELINE_SOURCE == "web" + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /k8s-.*/i || $CI_PIPELINE_SOURCE == "web" test: stage: test @@ -48,8 +48,8 @@ test: - go test -race $(go list ./... | grep -v /vendor/) - go build -race -ldflags "-extldflags '-static'" -o $CI_PROJECT_DIR/mybinary - go test ./metakube -v -sweep=all - - TF_ACC=1 go test ./metakube -v -timeout 3h --parallel 10 -run TestAcc + - TF_ACC=1 go test ./metakube -v -timeout 3h -parallel 10 -run TestAcc needs: - env rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /k8s-.*/ || $CI_PIPELINE_SOURCE == "web" + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /k8s-.*/i || $CI_PIPELINE_SOURCE == "web" diff --git a/metakube/provider_test.go b/metakube/provider_test.go index a85c196..a496a85 100644 --- a/metakube/provider_test.go +++ b/metakube/provider_test.go @@ -32,6 +32,7 @@ const ( testEnvOpenstackPassword = "METAKUBE_OPENSTACK_PASSWORD" testEnvOpenstackProjectID = "METAKUBE_OPENSTACK_PROJECT_ID" testEnvOpenstackProjectName = "METAKUBE_OPENSTACK_PROJECT_NAME" + testEnvOpenstackRegion = "METAKUBE_OPENSTACK_REGION" testEnvOpenstackImage = "METAKUBE_OPENSTACK_IMAGE" testEnvOpenstackImage2 = "METAKUBE_OPENSTACK_IMAGE2" testEnvOpenstackFlavor = "METAKUBE_OPENSTACK_FLAVOR" @@ -84,6 +85,7 @@ func testAccPreCheckForOpenstack(t *testing.T) { checkEnv(t, testEnvOpenstackPassword) checkEnv(t, testEnvOpenstackProjectID) checkEnv(t, testEnvOpenstackProjectName) + checkEnv(t, testEnvOpenstackRegion) checkEnv(t, testEnvOpenstackNodeDC) checkEnv(t, testEnvOpenstackImage) checkEnv(t, testEnvOpenstackImage2) diff --git a/metakube/resource_cluster_test.go b/metakube/resource_cluster_test.go index aebdbac..9b5240d 100644 --- a/metakube/resource_cluster_test.go +++ b/metakube/resource_cluster_test.go @@ -56,6 +56,7 @@ func TestAccMetakubeCluster_Openstack_Basic(t *testing.T) { OpenstackUser: os.Getenv(testEnvOpenstackUsername), OpenstackPassword: os.Getenv(testEnvOpenstackPassword), OpenstackProjectID: os.Getenv(testEnvOpenstackProjectID), + OpenstackRegion: os.Getenv(testEnvOpenstackRegion), DatacenterName: os.Getenv(testEnvOpenstackNodeDC), ProjectID: os.Getenv(testEnvProjectID), Version: os.Getenv(testEnvK8sVersionOpenstack), @@ -222,6 +223,11 @@ func TestAccMetakubeCluster_Openstack_ApplicationCredentials_Dynammic(t *testing resourceName := "metakube_cluster.acctest_cluster" data := &clusterOpenstackApplicationCredentailsData{ Name: makeRandomName() + "-appcred-dynamic", + OpenstackAuthURL: os.Getenv(testEnvOpenstackAuthURL), + OpenstackUser: os.Getenv(testEnvOpenstackUsername), + OpenstackPassword: os.Getenv(testEnvOpenstackPassword), + OpenstackProjectID: os.Getenv(testEnvOpenstackProjectID), + OpenstackRegion: os.Getenv(testEnvOpenstackRegion), DatacenterName: os.Getenv(testEnvOpenstackNodeDC), ProjectID: os.Getenv(testEnvProjectID), Version: os.Getenv(testEnvK8sVersionOpenstack), @@ -269,6 +275,7 @@ func TestAccMetakubeCluster_Openstack_UpgradeVersion(t *testing.T) { OpenstackProjectID: os.Getenv(testEnvOpenstackProjectID), DatacenterName: os.Getenv(testEnvOpenstackNodeDC), ProjectID: os.Getenv(testEnvProjectID), + OpenstackRegion: os.Getenv(testEnvOpenstackRegion), } var result strings.Builder if err := clusterOpenstackBasicTemplate.Execute(&result, data); err != nil { @@ -312,6 +319,7 @@ type clusterOpenstackBasicData struct { OpenstackUser string OpenstackPassword string OpenstackProjectID string + OpenstackRegion string Name string DatacenterName string @@ -337,6 +345,7 @@ provider "openstack" { user_name = "{{ .OpenstackUser }}" password = "{{ .OpenstackPassword }}" tenant_id = "{{ .OpenstackProjectID }}" + region = "{{ .OpenstackRegion }}" } resource "metakube_cluster" "acctest_cluster" { @@ -417,6 +426,12 @@ resource "openstack_networking_subnet_v2" "subnet_tf_test" { }`) type clusterOpenstackApplicationCredentailsData struct { + OpenstackAuthURL string + OpenstackUser string + OpenstackPassword string + OpenstackProjectID string + OpenstackRegion string + Name string DatacenterName string ProjectID string @@ -436,9 +451,17 @@ terraform { } {{ if .Dynamic }} +provider "openstack" { + auth_url = "{{ .OpenstackAuthURL }}" + user_name = "{{ .OpenstackUser }}" + password = "{{ .OpenstackPassword }}" + tenant_id = "{{ .OpenstackProjectID }}" + region = "{{ .OpenstackRegion }}" +} + resource "openstack_identity_application_credential_v3" "app_credential" { name = "{{ .Name }}" - } +} {{ end }} resource "metakube_cluster" "acctest_cluster" { diff --git a/metakube/resource_node_deployment_test.go b/metakube/resource_node_deployment_test.go index 8780b08..077a6cf 100644 --- a/metakube/resource_node_deployment_test.go +++ b/metakube/resource_node_deployment_test.go @@ -23,6 +23,7 @@ func TestAccMetakubeNodeDeployment_Openstack_Basic(t *testing.T) { OpenstackUser: os.Getenv(testEnvOpenstackUsername), OpenstackPassword: os.Getenv(testEnvOpenstackPassword), OpenstackProjectID: os.Getenv(testEnvOpenstackProjectID), + OpenstackRegion: os.Getenv(testEnvOpenstackRegion), DatacenterName: os.Getenv(testEnvOpenstackNodeDC), ProjectID: os.Getenv(testEnvProjectID), ClusterVersion: os.Getenv(testEnvK8sVersionOpenstack), @@ -130,6 +131,7 @@ type nodeDeploymentBasicData struct { OpenstackUser string OpenstackPassword string OpenstackProjectID string + OpenstackRegion string Name string DatacenterName string @@ -155,6 +157,7 @@ var nodeDeploymentBasicTemplate = mustParseTemplate("nodeDeploymentBasic", ` user_name = "{{ .OpenstackUser }}" password = "{{ .OpenstackPassword }}" tenant_id = "{{ .OpenstackProjectID }}" + region = "{{ .OpenstackRegion }}" } data "openstack_images_image_v2" "image" {