diff --git a/stackit/internal/services/cdn/cdn_acc_test.go b/stackit/internal/services/cdn/cdn_acc_test.go index 100329554..42c2387f7 100644 --- a/stackit/internal/services/cdn/cdn_acc_test.go +++ b/stackit/internal/services/cdn/cdn_acc_test.go @@ -34,19 +34,30 @@ var ( credentialsName = "acc-c" + acctest.RandStringFromCharSet(3, acctest.CharSetAlpha) credentialsNameUpdated = "acc-c-updated" + acctest.RandStringFromCharSet(3, acctest.CharSetAlpha) httpTestName = "acc-h" + acctest.RandStringFromCharSet(3, acctest.CharSetAlpha) - dnsNameHttp = fmt.Sprintf("tf-%s.runs.onstackit.cloud", httpTestName) - dnsRecordNameHttp = uuid.NewString() - cert, key = makeCertAndKey(testutil.OrganizationId) + + // FIX: Reverted to stackit.gg as used in the working old code to avoid reserved domain rejection + dnsNameHttp = fmt.Sprintf("tf-acc-%s.stackit.gg", strings.Split(uuid.NewString(), "-")[0]) + dnsRecordNameHttp = uuid.NewString() + + // Build the full domain name here so we can use it to sign the certificate + fullDomainNameHttp = fmt.Sprintf("%s.%s", dnsRecordNameHttp, dnsNameHttp) + + cert, key = makeCertAndKey(testutil.OrganizationId, fullDomainNameHttp) ) var ( //go:embed testdata/resource-bucket.tf resourceBucket string - //go:embed testdata/resource-http.tf - resourceHttp string + //go:embed testdata/resource-http-base.tf + resourceHttpBase string + + //go:embed testdata/resource-http-custom-domain.tf + resourceHttpCustomDomain string ) +var resourceHttpFull = resourceHttpBase + "\n" + resourceHttpCustomDomain + var testConfigVarsBucket = config.Variables{ "project_id": config.StringVariable(testutil.ProjectId), "bucket_name": config.StringVariable(bucketName), @@ -90,7 +101,7 @@ func configVarsHttpUpdated() config.Variables { return updatedConfig } -func makeCertAndKey(organization string) (cert, key []byte) { +func makeCertAndKey(organization, domain string) (cert, key []byte) { privateKey, err := rsa.GenerateKey(cryptoRand.Reader, 2048) if err != nil { fmt.Printf("failed to generate key: %s", err.Error()) @@ -100,10 +111,11 @@ func makeCertAndKey(organization string) (cert, key []byte) { Issuer: pkix.Name{CommonName: organization}, Subject: pkix.Name{ Organization: []string{organization}, + CommonName: domain, // Required by most modern TLS validations }, - NotBefore: time.Now(), - NotAfter: time.Now().Add(time.Hour), - + DNSNames: []string{domain}, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour), KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, @@ -129,14 +141,13 @@ func makeCertAndKey(organization string) (cert, key []byte) { } func TestAccCDNDistributionHttp(t *testing.T) { - fullDomainName := fmt.Sprintf("%s.%s", testutil.ConvertConfigVariable(testConfigVarsHttp["dns_record_name"]), testutil.ConvertConfigVariable(testConfigVarsHttp["dns_name"])) resource.Test(t, resource.TestCase{ ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories, CheckDestroy: testAccCheckCDNDistributionDestroy, Steps: []resource.TestStep{ - // Distribution Create + // Distribution Create (Only Base config) { - Config: testutil.CdnProviderConfig() + "\n" + resourceHttp, + Config: testutil.CdnProviderConfig() + "\n" + resourceHttpBase, ConfigVariables: testConfigVarsHttp, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "distribution_id"), @@ -166,22 +177,22 @@ func TestAccCDNDistributionHttp(t *testing.T) { resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "status", "ACTIVE"), ), }, - // Wait step, that confirms the CNAME record has "propagated" + // Wait step, confirms the CNAME record has "propagated" before trying to add the custom domain { - Config: testutil.CdnProviderConfig() + "\n" + resourceHttp, + Config: testutil.CdnProviderConfig() + "\n" + resourceHttpBase, ConfigVariables: testConfigVarsHttp, Check: func(_ *terraform.State) error { - _, err := blockUntilDomainResolves(fullDomainName) + _, err := blockUntilDomainResolves(fullDomainNameHttp) return err }, }, - // Custom Domain Create + // Custom Domain Create (Now using Full config) { - Config: testutil.CdnProviderConfig() + "\n" + resourceHttp, + Config: testutil.CdnProviderConfig() + "\n" + resourceHttpFull, ConfigVariables: testConfigVarsHttp, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "status", "ACTIVE"), - resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "name", fullDomainName), + resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "name", fullDomainNameHttp), resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "certificate.version", "1"), resource.TestCheckResourceAttrPair("stackit_cdn_distribution.distribution", "distribution_id", "stackit_cdn_custom_domain.custom_domain", "distribution_id"), resource.TestCheckResourceAttrPair("stackit_cdn_distribution.distribution", "project_id", "stackit_cdn_custom_domain.custom_domain", "project_id"), @@ -235,7 +246,7 @@ func TestAccCDNDistributionHttp(t *testing.T) { }, // Data Source { - Config: testutil.CdnProviderConfig() + "\n" + resourceHttp, + Config: testutil.CdnProviderConfig() + "\n" + resourceHttpFull, ConfigVariables: testConfigVarsHttp, Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("data.stackit_cdn_distribution.distribution", "distribution_id"), @@ -243,7 +254,7 @@ func TestAccCDNDistributionHttp(t *testing.T) { resource.TestCheckResourceAttrSet("data.stackit_cdn_distribution.distribution", "updated_at"), resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.#", "2"), resource.TestCheckResourceAttrSet("data.stackit_cdn_distribution.distribution", "domains.0.name"), - resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.1.name", fullDomainName), + resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.1.name", fullDomainNameHttp), resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.0.status", "ACTIVE"), resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.1.status", "ACTIVE"), resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "domains.0.type", "managed"), @@ -268,14 +279,14 @@ func TestAccCDNDistributionHttp(t *testing.T) { resource.TestCheckResourceAttr("data.stackit_cdn_distribution.distribution", "status", "ACTIVE"), resource.TestCheckResourceAttr("data.stackit_cdn_custom_domain.custom_domain", "status", "ACTIVE"), - resource.TestCheckResourceAttr("data.stackit_cdn_custom_domain.custom_domain", "name", fullDomainName), + resource.TestCheckResourceAttr("data.stackit_cdn_custom_domain.custom_domain", "name", fullDomainNameHttp), resource.TestCheckResourceAttr("data.stackit_cdn_custom_domain.custom_domain", "certificate.version", "1"), resource.TestCheckResourceAttrPair("stackit_cdn_distribution.distribution", "distribution_id", "stackit_cdn_custom_domain.custom_domain", "distribution_id"), ), }, // Update { - Config: testutil.CdnProviderConfig() + "\n" + resourceHttp, + Config: testutil.CdnProviderConfig() + "\n" + resourceHttpFull, ConfigVariables: configVarsHttpUpdated(), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "distribution_id"), @@ -283,7 +294,7 @@ func TestAccCDNDistributionHttp(t *testing.T) { resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "updated_at"), resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.#", "2"), resource.TestCheckResourceAttrSet("stackit_cdn_distribution.distribution", "domains.0.name"), - resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.1.name", fullDomainName), + resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.1.name", fullDomainNameHttp), resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.0.status", "ACTIVE"), resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.1.status", "ACTIVE"), resource.TestCheckResourceAttr("stackit_cdn_distribution.distribution", "domains.0.type", "managed"), @@ -309,7 +320,7 @@ func TestAccCDNDistributionHttp(t *testing.T) { ), resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "status", "ACTIVE"), - resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "name", fullDomainName), + resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "name", fullDomainNameHttp), resource.TestCheckResourceAttr("stackit_cdn_custom_domain.custom_domain", "certificate.version", "1"), resource.TestCheckResourceAttrPair("stackit_cdn_distribution.distribution", "distribution_id", "stackit_cdn_custom_domain.custom_domain", "distribution_id"), resource.TestCheckResourceAttrPair("stackit_cdn_distribution.distribution", "project_id", "stackit_cdn_custom_domain.custom_domain", "project_id"), @@ -490,10 +501,10 @@ func testAccCheckCDNDistributionDestroy(s *terraform.State) error { const ( recordCheckInterval time.Duration = 3 * time.Second - recordCheckAttempts = 100 // wait up to 5 minutes for record to be come available (normally takes less than 2 minutes) + recordCheckAttempts = 100 // wait up to 5 minutes for record to become available (normally takes less than 2 minutes) ) -func blockUntilDomainResolves(domain string) (string, error) { +func blockUntilDomainResolves(domain string) (net.IP, error) { // Create a custom resolver that bypasses the local system DNS settings/cache // and queries Google DNS (8.8.8.8) directly. r := &net.Resolver{ @@ -506,17 +517,23 @@ func blockUntilDomainResolves(domain string) (string, error) { return d.DialContext(ctx, network, "8.8.8.8:53") }, } + // wait until it becomes ready - isReady := func() (string, error) { + isReady := func() (net.IP, error) { // Use a context for the individual query timeout ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - cname, err := r.LookupCNAME(ctx, domain) + ips, err := r.LookupIP(ctx, "ip", domain) if err != nil { - return "", fmt.Errorf("error looking up CNAME for domain %s: %w", domain, err) + return nil, fmt.Errorf("error looking up IP for domain %s: %w", domain, err) + } + for _, ip := range ips { + if ip.String() != "" { + return ip, nil + } } - return cname, nil + return nil, fmt.Errorf("no IP for domain: %v", domain) } return retry(recordCheckAttempts, recordCheckInterval, isReady) @@ -525,7 +542,7 @@ func blockUntilDomainResolves(domain string) (string, error) { func retry[T any](attempts int, sleep time.Duration, f func() (T, error)) (T, error) { var zero T var errOuter error - for range attempts { + for i := 0; i < attempts; i++ { dist, err := f() if err == nil { return dist, nil diff --git a/stackit/internal/services/cdn/testdata/resource-http.tf b/stackit/internal/services/cdn/testdata/resource-http-base.tf similarity index 68% rename from stackit/internal/services/cdn/testdata/resource-http.tf rename to stackit/internal/services/cdn/testdata/resource-http-base.tf index 489bece48..3275fd0a5 100644 --- a/stackit/internal/services/cdn/testdata/resource-http.tf +++ b/stackit/internal/services/cdn/testdata/resource-http-base.tf @@ -23,6 +23,7 @@ resource "stackit_dns_zone" "dns_zone" { type = "primary" default_ttl = 3600 } + resource "stackit_dns_record_set" "dns_record" { project_id = var.project_id zone_id = stackit_dns_zone.dns_zone.zone_id @@ -48,7 +49,6 @@ resource "stackit_cdn_distribution" "distribution" { (var.backend_origin_url) = var.geofencing_list } } - regions = var.regions blocked_countries = var.blocked_countries } } @@ -56,22 +56,4 @@ resource "stackit_cdn_distribution" "distribution" { data "stackit_cdn_distribution" "distribution" { project_id = var.project_id distribution_id = stackit_cdn_distribution.distribution.distribution_id -} - -# custom domain -resource "stackit_cdn_custom_domain" "custom_domain" { - project_id = var.project_id - distribution_id = stackit_cdn_distribution.distribution.distribution_id - name = "${stackit_dns_record_set.dns_record.name}.${stackit_dns_zone.dns_zone.dns_name}" - certificate = { - certificate = var.certificate - private_key = var.private_key - } -} - -data "stackit_cdn_custom_domain" "custom_domain" { - project_id = var.project_id - distribution_id = stackit_cdn_distribution.distribution.distribution_id - name = "${stackit_dns_record_set.dns_record.name}.${stackit_dns_zone.dns_zone.dns_name}" - depends_on = [stackit_cdn_custom_domain.custom_domain] -} +} \ No newline at end of file diff --git a/stackit/internal/services/cdn/testdata/resource-http-custom-domain.tf b/stackit/internal/services/cdn/testdata/resource-http-custom-domain.tf new file mode 100644 index 000000000..2caddf9c4 --- /dev/null +++ b/stackit/internal/services/cdn/testdata/resource-http-custom-domain.tf @@ -0,0 +1,17 @@ +# custom domain +resource "stackit_cdn_custom_domain" "custom_domain" { + project_id = var.project_id + distribution_id = stackit_cdn_distribution.distribution.distribution_id + name = "${stackit_dns_record_set.dns_record.name}.${stackit_dns_zone.dns_zone.dns_name}" + certificate = { + certificate = var.certificate + private_key = var.private_key + } +} + +data "stackit_cdn_custom_domain" "custom_domain" { + project_id = var.project_id + distribution_id = stackit_cdn_distribution.distribution.distribution_id + name = "${stackit_dns_record_set.dns_record.name}.${stackit_dns_zone.dns_zone.dns_name}" + depends_on = [stackit_cdn_custom_domain.custom_domain] +} \ No newline at end of file