From 727b57db2b170422eab124880224f10cf1e1024d Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 13:09:05 -0700 Subject: [PATCH 1/6] support write-only password fields: certificate_wo + private_key_wo --- mmv1/products/compute/SslCertificate.yaml | 50 ++++++++++++++- .../examples/ssl_certificate_basic_wo.tf.tmpl | 11 ++++ .../update_encoder/ssl_certificate.tmpl | 18 ++++++ .../resource_compute_ssl_certificate_test.go | 64 +++++++++++++++++++ 4 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 mmv1/templates/terraform/examples/ssl_certificate_basic_wo.tf.tmpl create mode 100644 mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl diff --git a/mmv1/products/compute/SslCertificate.yaml b/mmv1/products/compute/SslCertificate.yaml index 9a9a30bfb35f..e5b43fc79e62 100644 --- a/mmv1/products/compute/SslCertificate.yaml +++ b/mmv1/products/compute/SslCertificate.yaml @@ -49,6 +49,7 @@ async: collection_url_key: 'items' custom_code: extra_schema_entry: 'templates/terraform/extra_schema_entry/ssl_certificate.tmpl' + encoder: 'templates/terraform/encoder/ssl_certificate.tmpl' examples: - name: 'ssl_certificate_basic' primary_resource_id: 'default' @@ -56,6 +57,12 @@ examples: - 'name_prefix' # Uses id.UniqueId skip_vcr: true + - name: 'ssl_certificate_basic_wo' + primary_resource_id: 'default' + ignore_read_extra: + - 'name_prefix' + # Uses id.UniqueId + skip_vcr: true - name: 'ssl_certificate_random_provider' primary_resource_id: 'default' external_providers: ["random", "time"] @@ -80,8 +87,26 @@ properties: The certificate in PEM format. The certificate chain must be no greater than 5 certs long. The chain must include at least one intermediate cert. - required: true + exactly_one_of: + - 'certificate' + - 'certificateWo' sensitive: true + - name: 'certificateWo' + type: String + description: 'The write-only certificate in PEM format.' + required_with: + - 'certificateWoVersion' + exactly_one_of: + - 'certificate' + - 'certificateWo' + write_only: true + - name: 'certificateWoVersion' + type: String + description: 'The write-only version of the certificate.' + immutable: true + ignore_read: true + required_with: + - 'certificateWo' - name: 'creationTimestamp' type: Time description: 'Creation timestamp in RFC3339 text format.' @@ -116,10 +141,29 @@ properties: function: 'verify.ValidateGCEName' - name: 'privateKey' type: String - description: 'The write-only private key in PEM format.' - required: true + description: 'The private key in PEM format.' + exactly_one_of: + - 'privateKey' + - 'privateKeyWo' immutable: true ignore_read: true sensitive: true diff_suppress_func: 'sha256DiffSuppress' custom_flatten: 'templates/terraform/custom_flatten/sha256.tmpl' + - name: 'privateKeyWo' + type: String + description: 'The write-only private key in PEM format.' + required_with: + - 'privateKeyWoVersion' + exactly_one_of: + - 'privateKey' + - 'privateKeyWo' + write_only: true + - name: 'privateKeyWoVersion' + type: String + description: 'The write-only version of the private key.' + immutable: true + ignore_read: true + required_with: + - 'privateKeyWo' + diff --git a/mmv1/templates/terraform/examples/ssl_certificate_basic_wo.tf.tmpl b/mmv1/templates/terraform/examples/ssl_certificate_basic_wo.tf.tmpl new file mode 100644 index 000000000000..bc3cc39a666e --- /dev/null +++ b/mmv1/templates/terraform/examples/ssl_certificate_basic_wo.tf.tmpl @@ -0,0 +1,11 @@ +resource "google_compute_ssl_certificate" "default" { + name_prefix = "my-certificate-" + description = "a description" + private_key_wo = file("path/to/private.key") + private_key_wo_version = 1 + certificate_wo = file("path/to/certificate.crt") + certificate_wo_version = 1 + lifecycle { + create_before_destroy = true + } +} diff --git a/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl b/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl new file mode 100644 index 000000000000..8a30fb102413 --- /dev/null +++ b/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl @@ -0,0 +1,18 @@ +{{/* + The license inside this block applies to this file + Copyright 2024 Google Inc. + 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. +*/ -}} + +// we remove this since they aren't present in the API request +delete(obj, "private_key_wo_version") +delete(obj, "certificate_wo_version") + +return obj, nil diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_ssl_certificate_test.go b/mmv1/third_party/terraform/services/compute/resource_compute_ssl_certificate_test.go index 01b7f423c448..e0e5c1db07dc 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_ssl_certificate_test.go +++ b/mmv1/third_party/terraform/services/compute/resource_compute_ssl_certificate_test.go @@ -37,6 +37,46 @@ func TestAccComputeSslCertificate_no_name(t *testing.T) { }) } +func TestAccComputeSslCertificate_update_wo(t *testing.T) { + // Randomness + acctest.SkipIfVcr(t) + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeSslCertificateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeSslCertificate_wo(), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeSslCertificateExists( + t, "google_compute_ssl_certificate.foobar"), + ), + }, + { + ResourceName: "google_compute_ssl_certificate.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"private_key"}, + }, + { + Config: testAccComputeSslCertificate_update_wo(), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeSslCertificateExists( + t, "google_compute_ssl_certificate.foobar"), + ), + }, + { + ResourceName: "google_compute_ssl_certificate.foobar", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"private_key"}, + }, + }, + }) +} + func TestUnitComputeManagedSslCertificate_AbsoluteDomainSuppress(t *testing.T) { cases := map[string]struct { Old, New string @@ -114,3 +154,27 @@ resource "google_compute_ssl_certificate" "foobar" { } `) } + +func testAccComputeSslCertificate_wo() string { + return fmt.Sprintf(` +resource "google_compute_ssl_certificate" "foobar" { + description = "really descriptive" + private_key_wo = file("test-fixtures/test.key") + private_key_wo_version = 1 + certificate_wo = file("test-fixtures/test.crt") + certificate_wo_version = 1 +} +`) +} + +func testAccComputeSslCertificate_update_wo() string { + return fmt.Sprintf(` +resource "google_compute_ssl_certificate" "foobar" { + description = "really descriptive" + private_key_wo = file("test-fixtures/test.key") + private_key_wo_version = 2 + certificate_wo = file("test-fixtures/test.crt") + certificate_wo_version = 2 +} +`) +} From 85349918bbc769308314da8fba7b236cdfab467c Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 13:09:24 -0700 Subject: [PATCH 2/6] prevent flattener from generating when writeOnly is set on root fields --- mmv1/api/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mmv1/api/resource.go b/mmv1/api/resource.go index 8fd13845051b..486e351f2916 100644 --- a/mmv1/api/resource.go +++ b/mmv1/api/resource.go @@ -1223,7 +1223,7 @@ func (r Resource) InIdFormat(prop Type) bool { // Functions used to create slices of resource properties that could not otherwise be called from within generating templates. func (r Resource) ReadProperties() []*Type { return google.Reject(r.GettableProperties(), func(p *Type) bool { - return p.IgnoreRead + return p.IgnoreRead || p.WriteOnly }) } From 0caa48dc5794122b7c6b302c959bab2c7a4f48d2 Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 13:18:49 -0700 Subject: [PATCH 3/6] wrong directory --- mmv1/products/compute/SslCertificate.yaml | 2 +- .../terraform/encoders/ssl_certificate.go.tmpl | 4 ++++ .../update_encoder/ssl_certificate.tmpl | 18 ------------------ 3 files changed, 5 insertions(+), 19 deletions(-) create mode 100644 mmv1/templates/terraform/encoders/ssl_certificate.go.tmpl delete mode 100644 mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl diff --git a/mmv1/products/compute/SslCertificate.yaml b/mmv1/products/compute/SslCertificate.yaml index e5b43fc79e62..f3e2cc23ecd0 100644 --- a/mmv1/products/compute/SslCertificate.yaml +++ b/mmv1/products/compute/SslCertificate.yaml @@ -49,7 +49,7 @@ async: collection_url_key: 'items' custom_code: extra_schema_entry: 'templates/terraform/extra_schema_entry/ssl_certificate.tmpl' - encoder: 'templates/terraform/encoder/ssl_certificate.tmpl' + encoder: 'templates/terraform/encoders/ssl_certificate.go.tmpl' examples: - name: 'ssl_certificate_basic' primary_resource_id: 'default' diff --git a/mmv1/templates/terraform/encoders/ssl_certificate.go.tmpl b/mmv1/templates/terraform/encoders/ssl_certificate.go.tmpl new file mode 100644 index 000000000000..16f060277240 --- /dev/null +++ b/mmv1/templates/terraform/encoders/ssl_certificate.go.tmpl @@ -0,0 +1,4 @@ +// cannot include activate prop in the body +delete(obj, "certificate_wo_version") +delete(obj, "private_key_wo_version") +return obj, nil \ No newline at end of file diff --git a/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl b/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl deleted file mode 100644 index 8a30fb102413..000000000000 --- a/mmv1/templates/terraform/update_encoder/ssl_certificate.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -{{/* - The license inside this block applies to this file - Copyright 2024 Google Inc. - 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. -*/ -}} - -// we remove this since they aren't present in the API request -delete(obj, "private_key_wo_version") -delete(obj, "certificate_wo_version") - -return obj, nil From ed40e5e4d5e4fb5a3aaafd000686b8093e84c021 Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 13:21:44 -0700 Subject: [PATCH 4/6] fix yaml fmt --- mmv1/products/compute/SslCertificate.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/mmv1/products/compute/SslCertificate.yaml b/mmv1/products/compute/SslCertificate.yaml index f3e2cc23ecd0..1ff31bc422e9 100644 --- a/mmv1/products/compute/SslCertificate.yaml +++ b/mmv1/products/compute/SslCertificate.yaml @@ -166,4 +166,3 @@ properties: ignore_read: true required_with: - 'privateKeyWo' - From 5c8046e0322f79a02060ae0228760fcae3ab23d4 Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 14:23:17 -0700 Subject: [PATCH 5/6] provider_test fix --- mmv1/products/compute/SslCertificate.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mmv1/products/compute/SslCertificate.yaml b/mmv1/products/compute/SslCertificate.yaml index 1ff31bc422e9..c0ec871169d8 100644 --- a/mmv1/products/compute/SslCertificate.yaml +++ b/mmv1/products/compute/SslCertificate.yaml @@ -105,8 +105,6 @@ properties: description: 'The write-only version of the certificate.' immutable: true ignore_read: true - required_with: - - 'certificateWo' - name: 'creationTimestamp' type: Time description: 'Creation timestamp in RFC3339 text format.' @@ -164,5 +162,3 @@ properties: description: 'The write-only version of the private key.' immutable: true ignore_read: true - required_with: - - 'privateKeyWo' From 83331829bd32ef45e6918f7e6a7590ca25691950 Mon Sep 17 00:00:00 2001 From: "alvarez.mauriciotm@gmail.com" Date: Fri, 4 Apr 2025 14:42:36 -0700 Subject: [PATCH 6/6] at_least_one_of --- mmv1/products/compute/SslCertificate.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mmv1/products/compute/SslCertificate.yaml b/mmv1/products/compute/SslCertificate.yaml index c0ec871169d8..73700243998d 100644 --- a/mmv1/products/compute/SslCertificate.yaml +++ b/mmv1/products/compute/SslCertificate.yaml @@ -87,7 +87,7 @@ properties: The certificate in PEM format. The certificate chain must be no greater than 5 certs long. The chain must include at least one intermediate cert. - exactly_one_of: + at_least_one_of: - 'certificate' - 'certificateWo' sensitive: true @@ -96,7 +96,7 @@ properties: description: 'The write-only certificate in PEM format.' required_with: - 'certificateWoVersion' - exactly_one_of: + at_least_one_of: - 'certificate' - 'certificateWo' write_only: true @@ -140,7 +140,7 @@ properties: - name: 'privateKey' type: String description: 'The private key in PEM format.' - exactly_one_of: + at_least_one_of: - 'privateKey' - 'privateKeyWo' immutable: true @@ -153,7 +153,7 @@ properties: description: 'The write-only private key in PEM format.' required_with: - 'privateKeyWoVersion' - exactly_one_of: + at_least_one_of: - 'privateKey' - 'privateKeyWo' write_only: true