diff --git a/internal/provider/common_cert.go b/internal/provider/common_cert.go index dfd9745f..4b639520 100644 --- a/internal/provider/common_cert.go +++ b/internal/provider/common_cert.go @@ -269,8 +269,8 @@ func setCertificateCommonSchema(s map[string]*schema.Schema) { Required: true, ForceNew: true, Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: validation.StringInSlice(supportedKeyUsages(), false), + Type: schema.TypeString, + ValidateDiagFunc: StringInSliceOrWarn(supportedKeyUsages(), false), }, Description: "List of key usages allowed for the issued certificate. " + "Values are defined in [RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280) " + @@ -529,3 +529,27 @@ func certificateToMap(cert *x509.Certificate) map[string]interface{} { "sha1_fingerprint": fmt.Sprintf("%x", sha1.Sum(cert.Raw)), } } + +// StringInSliceOrWarn returns a SchemaValidateFunc which tests if the provided value +// is of type string and matches the value of an element in the valid slice. +// +// Differently from validation.StringInSlice, if the element is not part of the valid slice, +// a warning is produced. +func StringInSliceOrWarn(valid []string, ignoreCase bool) schema.SchemaValidateDiagFunc { + return validation.ToDiagFunc(func(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %s to be string", k)) + return warnings, errors + } + + for _, str := range valid { + if v == str || (ignoreCase && strings.EqualFold(v, str)) { + return warnings, errors + } + } + + warnings = append(warnings, fmt.Sprintf("expected %s to be one of %v, got %s so will ignored", k, valid, v)) + return warnings, errors + }) +} diff --git a/internal/provider/resource_self_signed_cert_test.go b/internal/provider/resource_self_signed_cert_test.go index 78f3fe5d..cf38b29a 100644 --- a/internal/provider/resource_self_signed_cert_test.go +++ b/internal/provider/resource_self_signed_cert_test.go @@ -521,25 +521,6 @@ func TestAccSelfSignedCert_InvalidConfigs(t *testing.T) { r.UnitTest(t, r.TestCase{ Providers: testProviders, Steps: []r.TestStep{ - { - Config: ` - resource "tls_self_signed_cert" "test" { - subject { - common_name = "common test cert" - } - validity_period_hours = 1 - allowed_uses = [ - "not_valid" - ] - set_subject_key_id = true - private_key_pem = "does not matter" - } - output "cert_pem" { - value = tls_self_signed_cert.test.cert_pem - } - `, - ExpectError: regexp.MustCompile(`expected allowed_uses.0 to be one of \[.*\], got not_valid`), - }, { Config: ` resource "tls_self_signed_cert" "test" { @@ -624,6 +605,7 @@ func selfSignedCertConfig(validity, earlyRenewal uint32, setKeyAlgorithm bool) s "digital_signature", "server_auth", "client_auth", + "non_repudiation", ] %s