diff --git a/.changelog/4449.txt b/.changelog/4449.txt new file mode 100644 index 0000000000..2d26114746 --- /dev/null +++ b/.changelog/4449.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +`google_privateca_certificate` +``` diff --git a/google-beta/provider.go b/google-beta/provider.go index 3145e246d4..394da9f75f 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -799,9 +799,9 @@ func Provider() *schema.Provider { return provider } -// Generated resources: 207 +// Generated resources: 208 // Generated IAM resources: 108 -// Total generated resources: 315 +// Total generated resources: 316 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -1076,6 +1076,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_privateca_certificate_authority_iam_binding": ResourceIamBinding(PrivatecaCertificateAuthorityIamSchema, PrivatecaCertificateAuthorityIamUpdaterProducer, PrivatecaCertificateAuthorityIdParseFunc), "google_privateca_certificate_authority_iam_member": ResourceIamMember(PrivatecaCertificateAuthorityIamSchema, PrivatecaCertificateAuthorityIamUpdaterProducer, PrivatecaCertificateAuthorityIdParseFunc), "google_privateca_certificate_authority_iam_policy": ResourceIamPolicy(PrivatecaCertificateAuthorityIamSchema, PrivatecaCertificateAuthorityIamUpdaterProducer, PrivatecaCertificateAuthorityIdParseFunc), + "google_privateca_certificate": resourcePrivatecaCertificate(), "google_pubsub_topic": resourcePubsubTopic(), "google_pubsub_topic_iam_binding": ResourceIamBinding(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), "google_pubsub_topic_iam_member": ResourceIamMember(PubsubTopicIamSchema, PubsubTopicIamUpdaterProducer, PubsubTopicIdParseFunc), diff --git a/google-beta/resource_privateca_certificate.go b/google-beta/resource_privateca_certificate.go new file mode 100644 index 0000000000..0b475e9ad4 --- /dev/null +++ b/google-beta/resource_privateca_certificate.go @@ -0,0 +1,1898 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourcePrivatecaCertificate() *schema.Resource { + return &schema.Resource{ + Create: resourcePrivatecaCertificateCreate, + Read: resourcePrivatecaCertificateRead, + Delete: resourcePrivatecaCertificateDelete, + + Importer: &schema.ResourceImporter{ + State: resourcePrivatecaCertificateImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "certificate_authority": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Certificate Authority name.`, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `Location of the CertificateAuthority. A full list of valid locations can be found by +running 'gcloud beta privateca locations list'.`, + }, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name for this Certificate .`, + }, + "config": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `The config used to create a self-signed X.509 certificate or CSR.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_key": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Description: `A PublicKey describes a public key.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{"KEY_TYPE_UNSPECIFIED", "PEM_RSA_KEY", "PEM_EC_KEY"}, false), + Description: `Types of public keys that are supported. At a minimum, we support RSA and ECDSA, for the key sizes or curves listed: https://cloud.google.com/kms/docs/algorithms#asymmetric_signing_algorithms Possible values: ["KEY_TYPE_UNSPECIFIED", "PEM_RSA_KEY", "PEM_EC_KEY"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `Required. A public key. When this is specified in a request, the padding and encoding can be any of the options described by the respective 'KeyType' value. When this is generated by the service, it will always be an RFC 5280 SubjectPublicKeyInfo structure containing an algorithm identifier and a key. A base64-encoded string.`, + }, + }, + }, + }, + "reusable_config": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Description: `Specifies some of the values in a certificate that are related to the subject.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "reusable_config": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `A resource path to a ReusableConfig in the format +'projects/*/locations/*/reusableConfigs/*'.`, + }, + }, + }, + }, + "subject_config": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Description: `Specifies some of the values in a certificate that are related to the subject.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "common_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The common name of the distinguished name.`, + }, + "subject": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Description: `Contains distinguished name fields such as the location and organization.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "organization": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The organization of the subject.`, + }, + "country_code": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The country code of the subject.`, + }, + "locality": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The locality or city of the subject.`, + }, + "organizational_unit": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The organizational unit of the subject.`, + }, + "postal_code": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The postal code of the subject.`, + }, + "province": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The province, territory, or regional state of the subject.`, + }, + "street_address": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The street address of the subject.`, + }, + }, + }, + }, + "subject_alt_name": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `The subject alternative name fields.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "dns_names": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Contains only valid, fully-qualified host names.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + AtLeastOneOf: []string{"config.0.subject_config.0.subject_alt_name.0.dns_names", "config.0.subject_config.0.subject_alt_name.0.uris", "config.0.subject_config.0.subject_alt_name.0.email_addresses", "config.0.subject_config.0.subject_alt_name.0.ip_addresses"}, + }, + "email_addresses": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Contains only valid RFC 2822 E-mail addresses.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + AtLeastOneOf: []string{"config.0.subject_config.0.subject_alt_name.0.dns_names", "config.0.subject_config.0.subject_alt_name.0.uris", "config.0.subject_config.0.subject_alt_name.0.email_addresses", "config.0.subject_config.0.subject_alt_name.0.ip_addresses"}, + }, + "ip_addresses": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Contains only valid 32-bit IPv4 addresses or RFC 4291 IPv6 addresses.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + AtLeastOneOf: []string{"config.0.subject_config.0.subject_alt_name.0.dns_names", "config.0.subject_config.0.subject_alt_name.0.uris", "config.0.subject_config.0.subject_alt_name.0.email_addresses", "config.0.subject_config.0.subject_alt_name.0.ip_addresses"}, + }, + "uris": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `Contains only valid RFC 3986 URIs.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + AtLeastOneOf: []string{"config.0.subject_config.0.subject_alt_name.0.dns_names", "config.0.subject_config.0.subject_alt_name.0.uris", "config.0.subject_config.0.subject_alt_name.0.email_addresses", "config.0.subject_config.0.subject_alt_name.0.ip_addresses"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ExactlyOneOf: []string{"pem_csr", "config"}, + }, + "labels": { + Type: schema.TypeMap, + Optional: true, + ForceNew: true, + Description: `Labels with user-defined metadata to apply to this resource.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "lifetime": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The desired lifetime of the CA certificate. Used to create the "notBeforeTime" and +"notAfterTime" fields inside an X.509 certificate. A duration in seconds with up to nine +fractional digits, terminated by 's'. Example: "3.5s".`, + Default: "315360000s", + }, + "pem_csr": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `Immutable. A pem-encoded X.509 certificate signing request (CSR).`, + ExactlyOneOf: []string{"pem_csr", "config"}, + }, + "certificate_description": { + Type: schema.TypeList, + Computed: true, + Description: `Output only. Details regarding the revocation of this Certificate. This Certificate is considered revoked if and only if this field is present.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "public_key": { + Type: schema.TypeList, + Required: true, + Description: `A PublicKey describes a public key.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"KEY_TYPE_UNSPECIFIED", "PEM_RSA_KEY", "PEM_EC_KEY"}, false), + Description: `Types of public keys that are supported. At a minimum, we support RSA and ECDSA, for the key sizes or curves listed: https://cloud.google.com/kms/docs/algorithms#asymmetric_signing_algorithms Possible values: ["KEY_TYPE_UNSPECIFIED", "PEM_RSA_KEY", "PEM_EC_KEY"]`, + }, + "key": { + Type: schema.TypeString, + Optional: true, + Description: `Required. A public key. When this is specified in a request, the padding and encoding can be any of the options described by the respective 'KeyType' value. When this is generated by the service, it will always be an RFC 5280 SubjectPublicKeyInfo structure containing an algorithm identifier and a key. A base64-encoded string.`, + }, + }, + }, + }, + "aia_issuing_certificate_urls": { + Type: schema.TypeList, + Optional: true, + Description: `Describes lists of issuer CA certificate URLs that appear in the "Authority Information Access" extension in the certificate.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "authority_key_id": { + Type: schema.TypeList, + Optional: true, + Description: `Identifies the subjectKeyId of the parent certificate, per https://tools.ietf.org/html/rfc5280#section-4.2.1.1`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_id": { + Type: schema.TypeString, + Optional: true, + Description: `Optional. The value of this KeyId encoded in lowercase hexadecimal. This is most likely the 160 bit SHA-1 hash of the public key.`, + }, + }, + }, + }, + "cert_fingerprint": { + Type: schema.TypeList, + Optional: true, + Description: `The hash of the x.509 certificate.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "sha256_hash": { + Type: schema.TypeString, + Optional: true, + Description: `The SHA 256 hash, encoded in hexadecimal, of the DER x509 certificate.`, + }, + }, + }, + }, + "config_values": { + Type: schema.TypeList, + Optional: true, + Description: `Describes some of the technical fields in a certificate.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_usage": { + Type: schema.TypeList, + Optional: true, + Description: `Optional. Indicates the intended use for keys that correspond to a certificate.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unknown_extended_key_usages": { + Type: schema.TypeList, + Required: true, + Description: `An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "obect_id": { + Type: schema.TypeList, + Required: true, + Description: `Required. Describes how some of the technical fields in a certificate should be populated.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "object_id_path": { + Type: schema.TypeList, + Required: true, + Description: `An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages.`, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + }, + }, + }, + "base_key_usage": { + Type: schema.TypeList, + Optional: true, + Description: `Describes high-level ways in which a key may be used.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_usage_options": { + Type: schema.TypeList, + Optional: true, + Description: `Describes high-level ways in which a key may be used.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cert_sign": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used to sign certificates.`, + }, + "content_commitment": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used for cryptographic commitments. Note that this may also be referred to as "non-repudiation".`, + }, + "crl_sign": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used sign certificate revocation lists.`, + }, + "data_encipherment": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used to encipher data.`, + }, + "decipher_only": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used to decipher only.`, + }, + "digital_signature": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used for digital signatures.`, + }, + "encipher_only": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used to encipher only.`, + }, + "key_agreement": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used in a key agreement protocol.`, + }, + "key_encipherment": { + Type: schema.TypeBool, + Optional: true, + Description: `The key may be used to encipher other keys.`, + }, + }, + }, + }, + }, + }, + }, + "extended_key_usage": { + Type: schema.TypeList, + Optional: true, + Description: `Describes high-level ways in which a key may be used.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_auth": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.2. Officially described as "TLS WWW client authentication", though regularly used for non-WWW TLS.`, + }, + "code_signing": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.3. Officially described as "Signing of downloadable executable code client authentication".`, + }, + "email_protection": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.4. Officially described as "Email protection".`, + }, + "ocsp_signing": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.9. Officially described as "Signing OCSP responses".`, + }, + "server_auth": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.1. Officially described as "TLS WWW server authentication", though regularly used for non-WWW TLS.`, + }, + "time_stamping": { + Type: schema.TypeBool, + Optional: true, + Description: `Corresponds to OID 1.3.6.1.5.5.7.3.8. Officially described as "Binding the hash of an object to a time".`, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + "crl_distribution_points": { + Type: schema.TypeList, + Optional: true, + Description: `Describes a list of locations to obtain CRL information, i.e. the DistributionPoint.fullName described by https://tools.ietf.org/html/rfc5280#section-4.2.1.13`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "subject_description": { + Type: schema.TypeList, + Optional: true, + Description: `Describes some of the values in a certificate that are related to the subject and lifetime.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "common_name": { + Type: schema.TypeString, + Optional: true, + Description: `The "common name" of the distinguished name.`, + }, + "hex_serial_number": { + Type: schema.TypeString, + Optional: true, + Description: `The serial number encoded in lowercase hexadecimal.`, + }, + "lifetime": { + Type: schema.TypeString, + Optional: true, + Description: `For convenience, the actual lifetime of an issued certificate. Corresponds to 'notAfterTime' - 'notBeforeTime'.`, + }, + "not_after_time": { + Type: schema.TypeString, + Optional: true, + Description: `The time at which the certificate expires.`, + }, + "not_before_time": { + Type: schema.TypeString, + Optional: true, + Description: `The time at which the certificate becomes valid.`, + }, + "subject": { + Type: schema.TypeList, + Optional: true, + Description: `Required. Contains distinguished name fields such as the location and organization.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "country_code": { + Type: schema.TypeString, + Optional: true, + Description: `The country code of the subject.`, + }, + "locality": { + Type: schema.TypeString, + Optional: true, + Description: `The locality or city of the subject.`, + }, + "organization": { + Type: schema.TypeString, + Optional: true, + Description: `The organization of the subject.`, + }, + "organizational_unit": { + Type: schema.TypeString, + Optional: true, + Description: `The organizationalUnit of the subject.`, + }, + "postal_code": { + Type: schema.TypeString, + Optional: true, + Description: `The postalCode or city of the subject.`, + }, + "province": { + Type: schema.TypeString, + Optional: true, + Description: `The province of the subject.`, + }, + "street_address": { + Type: schema.TypeString, + Optional: true, + Description: `The streetAddress or city of the subject.`, + }, + }, + }, + }, + "subject_alt_name": { + Type: schema.TypeList, + Optional: true, + Description: `Optional. The subject alternative name fields.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "custom_sans": { + Type: schema.TypeList, + Required: true, + Description: `Contains additional subject alternative name values.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "critical": { + Type: schema.TypeBool, + Required: true, + Description: `Required. Indicates whether or not this extension is critical (i.e., if the client does not know how to handle this extension, the client should consider this to be an error).`, + }, + "obect_id": { + Type: schema.TypeList, + Required: true, + Description: `Required. Describes how some of the technical fields in a certificate should be populated.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "object_id_path": { + Type: schema.TypeList, + Required: true, + Description: `An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages.`, + Elem: &schema.Schema{ + Type: schema.TypeInt, + }, + }, + }, + }, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `Required. The value of this X.509 extension.`, + }, + }, + }, + }, + "dns_names": { + Type: schema.TypeList, + Optional: true, + Description: `Contains only valid, fully-qualified host names.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "email_addresses": { + Type: schema.TypeList, + Optional: true, + Description: `Contains only valid RFC 2822 E-mail addresses.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "ip_addresses": { + Type: schema.TypeList, + Optional: true, + Description: `Contains only valid 32-bit IPv4 addresses or RFC 4291 IPv6 addresses.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "uris": { + Type: schema.TypeList, + Optional: true, + Description: `Contains only valid RFC 3986 URIs.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + "subject_key_id": { + Type: schema.TypeList, + Optional: true, + Description: `Provides a means of identifiying certificates that contain a particular public key, per https://tools.ietf.org/html/rfc5280#section-4.2.1.2.`, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "key_id": { + Type: schema.TypeString, + Optional: true, + Description: `Optional. The value of this KeyId encoded in lowercase hexadecimal. This is most likely the 160 bit SHA-1 hash of the public key.`, + }, + }, + }, + }, + }, + }, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `The time that this resource was created on the server. +This is in RFC3339 text format.`, + }, + "pem_certificate": { + Type: schema.TypeString, + Computed: true, + Description: `Output only. The pem-encoded, signed X.509 certificate.`, + }, + "pem_certificates": { + Type: schema.TypeList, + Computed: true, + Description: `Required. Expected to be in leaf-to-root order according to RFC 5246.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "revocation_details": { + Type: schema.TypeList, + Computed: true, + Description: `Output only. Details regarding the revocation of this Certificate. This Certificate is +considered revoked if and only if this field is present.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "revocation_state": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"REVOCATION_REASON_UNSPECIFIED", "KEY_COMPROMISE", "CERTIFICATE_AUTHORITY_COMPROMISE", "AFFILIATION_CHANGED", "SUPERSEDED", "CESSATION_OF_OPERATION", "CERTIFICATE_HOLD", "PRIVILEGE_WITHDRAWN", "ATTRIBUTE_AUTHORITY_COMPROMISE", ""}, false), + Description: `Indicates why a Certificate was revoked. Possible values: ["REVOCATION_REASON_UNSPECIFIED", "KEY_COMPROMISE", "CERTIFICATE_AUTHORITY_COMPROMISE", "AFFILIATION_CHANGED", "SUPERSEDED", "CESSATION_OF_OPERATION", "CERTIFICATE_HOLD", "PRIVILEGE_WITHDRAWN", "ATTRIBUTE_AUTHORITY_COMPROMISE"]`, + }, + "revocation_time": { + Type: schema.TypeString, + Optional: true, + Description: `The time at which this Certificate was revoked.`, + }, + }, + }, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `Output only. The time at which this CertificateAuthority was updated. +This is in RFC3339 text format.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} + +func resourcePrivatecaCertificateCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + lifetimeProp, err := expandPrivatecaCertificateLifetime(d.Get("lifetime"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("lifetime"); !isEmptyValue(reflect.ValueOf(lifetimeProp)) && (ok || !reflect.DeepEqual(v, lifetimeProp)) { + obj["lifetime"] = lifetimeProp + } + labelsProp, err := expandPrivatecaCertificateLabels(d.Get("labels"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("labels"); !isEmptyValue(reflect.ValueOf(labelsProp)) && (ok || !reflect.DeepEqual(v, labelsProp)) { + obj["labels"] = labelsProp + } + pemCsrProp, err := expandPrivatecaCertificatePemCsr(d.Get("pem_csr"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("pem_csr"); !isEmptyValue(reflect.ValueOf(pemCsrProp)) && (ok || !reflect.DeepEqual(v, pemCsrProp)) { + obj["pemCsr"] = pemCsrProp + } + configProp, err := expandPrivatecaCertificateConfig(d.Get("config"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("config"); !isEmptyValue(reflect.ValueOf(configProp)) && (ok || !reflect.DeepEqual(v, configProp)) { + obj["config"] = configProp + } + + url, err := replaceVars(d, config, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates?certificateId={{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Certificate: %#v", obj) + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Certificate: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Certificate: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Certificate %q: %#v", d.Id(), res) + + return resourcePrivatecaCertificateRead(d, meta) +} + +func resourcePrivatecaCertificateRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Certificate: %s", err) + } + billingProject = project + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("PrivatecaCertificate %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + + if err := d.Set("lifetime", flattenPrivatecaCertificateLifetime(res["lifetime"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("revocation_details", flattenPrivatecaCertificateRevocationDetails(res["revocationDetails"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("pem_certificate", flattenPrivatecaCertificatePemCertificate(res["pemCertificate"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("certificate_description", flattenPrivatecaCertificateCertificateDescription(res["certificateDescription"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("pem_certificates", flattenPrivatecaCertificatePemCertificates(res["pemCertificates"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("create_time", flattenPrivatecaCertificateCreateTime(res["createTime"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("update_time", flattenPrivatecaCertificateUpdateTime(res["updateTime"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("labels", flattenPrivatecaCertificateLabels(res["labels"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("pem_csr", flattenPrivatecaCertificatePemCsr(res["pemCsr"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + if err := d.Set("config", flattenPrivatecaCertificateConfig(res["config"], d, config)); err != nil { + return fmt.Errorf("Error reading Certificate: %s", err) + } + + return nil +} + +func resourcePrivatecaCertificateDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + project, err := getProject(d, config) + if err != nil { + return fmt.Errorf("Error fetching project for Certificate: %s", err) + } + billingProject = project + + url, err := replaceVars(d, config, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}:revoke") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting Certificate %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "Certificate") + } + + log.Printf("[DEBUG] Finished deleting Certificate %q: %#v", d.Id(), res) + return nil +} + +func resourcePrivatecaCertificateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + if err := parseImportId([]string{ + "projects/(?P[^/]+)/locations/(?P[^/]+)/certificateAuthorities/(?P[^/]+)/certificates/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + "(?P[^/]+)/(?P[^/]+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenPrivatecaCertificateLifetime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateRevocationDetails(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["revocation_state"] = + flattenPrivatecaCertificateRevocationDetailsRevocationState(original["revocationState"], d, config) + transformed["revocation_time"] = + flattenPrivatecaCertificateRevocationDetailsRevocationTime(original["revocationTime"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateRevocationDetailsRevocationState(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateRevocationDetailsRevocationTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificatePemCertificate(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescription(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["subject_description"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescription(original["subjectDescription"], d, config) + transformed["config_values"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValues(original["configValues"], d, config) + transformed["public_key"] = + flattenPrivatecaCertificateCertificateDescriptionPublicKey(original["publicKey"], d, config) + transformed["subject_key_id"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectKeyId(original["subjectKeyId"], d, config) + transformed["authority_key_id"] = + flattenPrivatecaCertificateCertificateDescriptionAuthorityKeyId(original["authorityKeyId"], d, config) + transformed["crl_distribution_points"] = + flattenPrivatecaCertificateCertificateDescriptionCrlDistributionPoints(original["crlDistributionPoints"], d, config) + transformed["aia_issuing_certificate_urls"] = + flattenPrivatecaCertificateCertificateDescriptionAiaIssuingCertificateUrls(original["aiaIssuingCertificateUrls"], d, config) + transformed["cert_fingerprint"] = + flattenPrivatecaCertificateCertificateDescriptionCertFingerprint(original["certFingerprint"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescription(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["subject"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubject(original["subject"], d, config) + transformed["common_name"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionCommonName(original["commonName"], d, config) + transformed["subject_alt_name"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltName(original["subjectAltName"], d, config) + transformed["hex_serial_number"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionHexSerialNumber(original["hexSerialNumber"], d, config) + transformed["lifetime"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionLifetime(original["lifetime"], d, config) + transformed["not_before_time"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionNotBeforeTime(original["notBeforeTime"], d, config) + transformed["not_after_time"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionNotAfterTime(original["notAfterTime"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubject(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["country_code"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectCountryCode(original["countryCode"], d, config) + transformed["organization"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectOrganization(original["organization"], d, config) + transformed["organizational_unit"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectOrganizationalUnit(original["organizationalUnit"], d, config) + transformed["locality"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectLocality(original["locality"], d, config) + transformed["province"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectProvince(original["province"], d, config) + transformed["street_address"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectStreetAddress(original["streetAddress"], d, config) + transformed["postal_code"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectPostalCode(original["postalCode"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectCountryCode(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectOrganization(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectOrganizationalUnit(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectLocality(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectProvince(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectStreetAddress(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectPostalCode(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionCommonName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["dns_names"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameDnsNames(original["dnsNames"], d, config) + transformed["uris"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameUris(original["uris"], d, config) + transformed["email_addresses"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameEmailAddresses(original["emailAddresses"], d, config) + transformed["ip_addresses"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameIpAddresses(original["ipAddresses"], d, config) + transformed["custom_sans"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSans(original["customSans"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameDnsNames(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameUris(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameEmailAddresses(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameIpAddresses(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSans(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "obect_id": flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansObectId(original["obectId"], d, config), + "critical": flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansCritical(original["critical"], d, config), + "value": flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansValue(original["value"], d, config), + }) + } + return transformed +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansObectId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["object_id_path"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansObectIdObjectIdPath(original["objectIdPath"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansObectIdObjectIdPath(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansCritical(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionSubjectAltNameCustomSansValue(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionHexSerialNumber(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionLifetime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionNotBeforeTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectDescriptionNotAfterTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValues(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key_usage"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsage(original["keyUsage"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsage(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["base_key_usage"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsage(original["baseKeyUsage"], d, config) + transformed["extended_key_usage"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsage(original["extendedKeyUsage"], d, config) + transformed["unknown_extended_key_usages"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsages(original["unknownExtendedKeyUsages"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsage(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key_usage_options"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptions(original["keyUsageOptions"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptions(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["digital_signature"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDigitalSignature(original["digitalSignature"], d, config) + transformed["content_commitment"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsContentCommitment(original["contentCommitment"], d, config) + transformed["key_encipherment"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsKeyEncipherment(original["keyEncipherment"], d, config) + transformed["data_encipherment"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDataEncipherment(original["dataEncipherment"], d, config) + transformed["key_agreement"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsKeyAgreement(original["keyAgreement"], d, config) + transformed["cert_sign"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsCertSign(original["certSign"], d, config) + transformed["crl_sign"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsCrlSign(original["crlSign"], d, config) + transformed["encipher_only"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsEncipherOnly(original["encipherOnly"], d, config) + transformed["decipher_only"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDecipherOnly(original["decipherOnly"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDigitalSignature(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsContentCommitment(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsKeyEncipherment(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDataEncipherment(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsKeyAgreement(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsCertSign(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsCrlSign(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsEncipherOnly(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageBaseKeyUsageKeyUsageOptionsDecipherOnly(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsage(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["server_auth"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageServerAuth(original["serverAuth"], d, config) + transformed["client_auth"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageClientAuth(original["clientAuth"], d, config) + transformed["code_signing"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageCodeSigning(original["codeSigning"], d, config) + transformed["email_protection"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageEmailProtection(original["emailProtection"], d, config) + transformed["time_stamping"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageTimeStamping(original["timeStamping"], d, config) + transformed["ocsp_signing"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageOcspSigning(original["ocspSigning"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageServerAuth(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageClientAuth(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageCodeSigning(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageEmailProtection(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageTimeStamping(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageExtendedKeyUsageOcspSigning(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsages(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "obect_id": flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsagesObectId(original["obectId"], d, config), + }) + } + return transformed +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsagesObectId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["object_id_path"] = + flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsagesObectIdObjectIdPath(original["objectIdPath"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionConfigValuesKeyUsageUnknownExtendedKeyUsagesObectIdObjectIdPath(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionPublicKey(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key"] = + flattenPrivatecaCertificateCertificateDescriptionPublicKeyKey(original["key"], d, config) + transformed["type"] = + flattenPrivatecaCertificateCertificateDescriptionPublicKeyType(original["type"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionPublicKeyKey(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionPublicKeyType(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionSubjectKeyId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key_id"] = + flattenPrivatecaCertificateCertificateDescriptionSubjectKeyIdKeyId(original["keyId"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionSubjectKeyIdKeyId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionAuthorityKeyId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key_id"] = + flattenPrivatecaCertificateCertificateDescriptionAuthorityKeyIdKeyId(original["keyId"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionAuthorityKeyIdKeyId(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionCrlDistributionPoints(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionAiaIssuingCertificateUrls(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCertificateDescriptionCertFingerprint(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["sha256_hash"] = + flattenPrivatecaCertificateCertificateDescriptionCertFingerprintSha256Hash(original["sha256Hash"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateCertificateDescriptionCertFingerprintSha256Hash(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificatePemCertificates(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateCreateTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateUpdateTime(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateLabels(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificatePemCsr(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["subject_config"] = + flattenPrivatecaCertificateConfigSubjectConfig(original["subjectConfig"], d, config) + transformed["reusable_config"] = + flattenPrivatecaCertificateConfigReusableConfig(original["reusableConfig"], d, config) + transformed["public_key"] = + flattenPrivatecaCertificateConfigPublicKey(original["publicKey"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigSubjectConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["subject"] = + flattenPrivatecaCertificateConfigSubjectConfigSubject(original["subject"], d, config) + transformed["common_name"] = + flattenPrivatecaCertificateConfigSubjectConfigCommonName(original["commonName"], d, config) + transformed["subject_alt_name"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectAltName(original["subjectAltName"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigSubjectConfigSubject(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["country_code"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectCountryCode(original["countryCode"], d, config) + transformed["organization"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectOrganization(original["organization"], d, config) + transformed["organizational_unit"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectOrganizationalUnit(original["organizationalUnit"], d, config) + transformed["locality"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectLocality(original["locality"], d, config) + transformed["province"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectProvince(original["province"], d, config) + transformed["street_address"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectStreetAddress(original["streetAddress"], d, config) + transformed["postal_code"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectPostalCode(original["postalCode"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigSubjectConfigSubjectCountryCode(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectOrganization(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectOrganizationalUnit(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectLocality(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectProvince(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectStreetAddress(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectPostalCode(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigCommonName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectAltName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["dns_names"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameDnsNames(original["dnsNames"], d, config) + transformed["uris"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameUris(original["uris"], d, config) + transformed["email_addresses"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameEmailAddresses(original["emailAddresses"], d, config) + transformed["ip_addresses"] = + flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameIpAddresses(original["ipAddresses"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameDnsNames(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameUris(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameEmailAddresses(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigSubjectConfigSubjectAltNameIpAddresses(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigReusableConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["reusable_config"] = + flattenPrivatecaCertificateConfigReusableConfigReusableConfig(original["reusableConfig"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigReusableConfigReusableConfig(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigPublicKey(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["key"] = + flattenPrivatecaCertificateConfigPublicKeyKey(original["key"], d, config) + transformed["type"] = + flattenPrivatecaCertificateConfigPublicKeyType(original["type"], d, config) + return []interface{}{transformed} +} +func flattenPrivatecaCertificateConfigPublicKeyKey(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenPrivatecaCertificateConfigPublicKeyType(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandPrivatecaCertificateLifetime(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) { + if v == nil { + return map[string]string{}, nil + } + m := make(map[string]string) + for k, val := range v.(map[string]interface{}) { + m[k] = val.(string) + } + return m, nil +} + +func expandPrivatecaCertificatePemCsr(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSubjectConfig, err := expandPrivatecaCertificateConfigSubjectConfig(original["subject_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSubjectConfig); val.IsValid() && !isEmptyValue(val) { + transformed["subjectConfig"] = transformedSubjectConfig + } + + transformedReusableConfig, err := expandPrivatecaCertificateConfigReusableConfig(original["reusable_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReusableConfig); val.IsValid() && !isEmptyValue(val) { + transformed["reusableConfig"] = transformedReusableConfig + } + + transformedPublicKey, err := expandPrivatecaCertificateConfigPublicKey(original["public_key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPublicKey); val.IsValid() && !isEmptyValue(val) { + transformed["publicKey"] = transformedPublicKey + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigSubjectConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedSubject, err := expandPrivatecaCertificateConfigSubjectConfigSubject(original["subject"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSubject); val.IsValid() && !isEmptyValue(val) { + transformed["subject"] = transformedSubject + } + + transformedCommonName, err := expandPrivatecaCertificateConfigSubjectConfigCommonName(original["common_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCommonName); val.IsValid() && !isEmptyValue(val) { + transformed["commonName"] = transformedCommonName + } + + transformedSubjectAltName, err := expandPrivatecaCertificateConfigSubjectConfigSubjectAltName(original["subject_alt_name"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSubjectAltName); val.IsValid() && !isEmptyValue(val) { + transformed["subjectAltName"] = transformedSubjectAltName + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubject(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedCountryCode, err := expandPrivatecaCertificateConfigSubjectConfigSubjectCountryCode(original["country_code"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedCountryCode); val.IsValid() && !isEmptyValue(val) { + transformed["countryCode"] = transformedCountryCode + } + + transformedOrganization, err := expandPrivatecaCertificateConfigSubjectConfigSubjectOrganization(original["organization"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOrganization); val.IsValid() && !isEmptyValue(val) { + transformed["organization"] = transformedOrganization + } + + transformedOrganizationalUnit, err := expandPrivatecaCertificateConfigSubjectConfigSubjectOrganizationalUnit(original["organizational_unit"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedOrganizationalUnit); val.IsValid() && !isEmptyValue(val) { + transformed["organizationalUnit"] = transformedOrganizationalUnit + } + + transformedLocality, err := expandPrivatecaCertificateConfigSubjectConfigSubjectLocality(original["locality"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedLocality); val.IsValid() && !isEmptyValue(val) { + transformed["locality"] = transformedLocality + } + + transformedProvince, err := expandPrivatecaCertificateConfigSubjectConfigSubjectProvince(original["province"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedProvince); val.IsValid() && !isEmptyValue(val) { + transformed["province"] = transformedProvince + } + + transformedStreetAddress, err := expandPrivatecaCertificateConfigSubjectConfigSubjectStreetAddress(original["street_address"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedStreetAddress); val.IsValid() && !isEmptyValue(val) { + transformed["streetAddress"] = transformedStreetAddress + } + + transformedPostalCode, err := expandPrivatecaCertificateConfigSubjectConfigSubjectPostalCode(original["postal_code"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedPostalCode); val.IsValid() && !isEmptyValue(val) { + transformed["postalCode"] = transformedPostalCode + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectCountryCode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectOrganization(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectOrganizationalUnit(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectLocality(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectProvince(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectStreetAddress(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectPostalCode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigCommonName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectAltName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedDnsNames, err := expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameDnsNames(original["dns_names"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedDnsNames); val.IsValid() && !isEmptyValue(val) { + transformed["dnsNames"] = transformedDnsNames + } + + transformedUris, err := expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameUris(original["uris"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedUris); val.IsValid() && !isEmptyValue(val) { + transformed["uris"] = transformedUris + } + + transformedEmailAddresses, err := expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameEmailAddresses(original["email_addresses"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedEmailAddresses); val.IsValid() && !isEmptyValue(val) { + transformed["emailAddresses"] = transformedEmailAddresses + } + + transformedIpAddresses, err := expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameIpAddresses(original["ip_addresses"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedIpAddresses); val.IsValid() && !isEmptyValue(val) { + transformed["ipAddresses"] = transformedIpAddresses + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameDnsNames(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameUris(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameEmailAddresses(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigSubjectConfigSubjectAltNameIpAddresses(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigReusableConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedReusableConfig, err := expandPrivatecaCertificateConfigReusableConfigReusableConfig(original["reusable_config"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedReusableConfig); val.IsValid() && !isEmptyValue(val) { + transformed["reusableConfig"] = transformedReusableConfig + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigReusableConfigReusableConfig(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigPublicKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + if len(l) == 0 || l[0] == nil { + return nil, nil + } + raw := l[0] + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedKey, err := expandPrivatecaCertificateConfigPublicKeyKey(original["key"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedKey); val.IsValid() && !isEmptyValue(val) { + transformed["key"] = transformedKey + } + + transformedType, err := expandPrivatecaCertificateConfigPublicKeyType(original["type"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedType); val.IsValid() && !isEmptyValue(val) { + transformed["type"] = transformedType + } + + return transformed, nil +} + +func expandPrivatecaCertificateConfigPublicKeyKey(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandPrivatecaCertificateConfigPublicKeyType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google-beta/resource_privateca_certificate_generated_test.go b/google-beta/resource_privateca_certificate_generated_test.go new file mode 100644 index 0000000000..0e9498bfbe --- /dev/null +++ b/google-beta/resource_privateca_certificate_generated_test.go @@ -0,0 +1,213 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccPrivatecaCertificate_privatecaCertificateConfigExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project": getTestProjectFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProvidersOiCS, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": {}, + }, + CheckDestroy: testAccCheckPrivatecaCertificateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccPrivatecaCertificate_privatecaCertificateConfigExample(context), + }, + }, + }) +} + +func testAccPrivatecaCertificate_privatecaCertificateConfigExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_privateca_certificate_authority" "test-ca" { + provider = google-beta + certificate_authority_id = "tf-test-my-certificate-authority%{random_suffix}" + location = "us-central1" + tier = "ENTERPRISE" + config { + subject_config { + subject { + organization = "HashiCorp" + } + common_name = "my-certificate-authority" + subject_alt_name { + dns_names = ["hashicorp.com"] + } + } + reusable_config { + reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained" + } + } + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } + disable_on_delete = true +} + + +resource "google_privateca_certificate" "default" { + provider = google-beta + project = "%{project}" + location = "us-central1" + certificate_authority = google_privateca_certificate_authority.test-ca.certificate_authority_id + lifetime = "860s" + name = "tf-test-my-certificate%{random_suffix}" + config { + reusable_config { + reusable_config= "projects/568668481468/locations/us-central1/reusableConfigs/leaf-server-tls" + } + subject_config { + common_name = "san1.example.com" + subject { + country_code = "us" + organization = "google" + organizational_unit = "enterprise" + locality = "mountain view" + province = "california" + street_address = "1600 amphitheatre parkway" + postal_code = "94109" + } + subject_alt_name { + dns_names = ["hashicorp.com"] + email_addresses = ["email@example.com"] + ip_addresses = ["127.0.0.1"] + uris = ["http://www.ietf.org/rfc/rfc3986.txt"] + } + } + + public_key { + type = "PEM_RSA_KEY" + key = filebase64("test-fixtures/rsa_public.pem") + } + } +} +`, context) +} + +func TestAccPrivatecaCertificate_privatecaCertificateCsrExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "project": getTestProjectFromEnv(), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProvidersOiCS, + ExternalProviders: map[string]resource.ExternalProvider{ + "random": {}, + }, + CheckDestroy: testAccCheckPrivatecaCertificateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccPrivatecaCertificate_privatecaCertificateCsrExample(context), + }, + }, + }) +} + +func testAccPrivatecaCertificate_privatecaCertificateCsrExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_privateca_certificate_authority" "test-ca" { + provider = google-beta + certificate_authority_id = "tf-test-my-certificate-authority%{random_suffix}" + location = "us-central1" + tier = "ENTERPRISE" + config { + subject_config { + subject { + organization = "HashiCorp" + } + common_name = "my-certificate-authority" + subject_alt_name { + dns_names = ["hashicorp.com"] + } + } + reusable_config { + reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained" + } + } + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } + disable_on_delete = true +} + + + + +resource "google_privateca_certificate" "default" { + provider = google-beta + project = "%{project}" + location = "us-central1" + certificate_authority = google_privateca_certificate_authority.test-ca.certificate_authority_id + lifetime = "860s" + name = "tf-test-my-certificate%{random_suffix}" + pem_csr = file("test-fixtures/rsa_csr.pem") +} +`, context) +} + +func testAccCheckPrivatecaCertificateDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_privateca_certificate" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}") + + if err != nil { + return err + } + + res, err := sendRequest(config, "GET", "", url, config.userAgent, nil) + if err != nil { + return err + } + + if _, ok := res["revocationDetails"]; !ok { + return fmt.Errorf("CertificateAuthority.Certificate Revocation expected %s got %s, want revocationDetails.revocationTime", url, s) + } + + return nil + } + + return nil + } +} diff --git a/google-beta/test-fixtures/rsa_csr.pem b/google-beta/test-fixtures/rsa_csr.pem new file mode 100644 index 0000000000..acb70eb670 --- /dev/null +++ b/google-beta/test-fixtures/rsa_csr.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIDETCCAfkCAQAwVDELMAkGA1UEBhMCVVMxDzANBgNVBAoMBkdvb2dsZTETMBEG +A1UECwwKRW50ZXJwcmlzZTEfMB0GA1UEAwwWc2VydmVyLmVzb2RlbW9hcHAyLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMZThbWkUvD8wxzP/v/t +918Z0fhDYgSrow75G1kIbUf5Z3qG+l0AyLadIo3SqN3ENQYf2+O1VP9Hk90tyvCS +iGqjXJLCLXdrwLLqHoqFDxwm3bQ0/AlOIpmilS++BdHUew0HfqZq9lJOFPAF3EtL +LPaE0eRbA2HguHe4q/7jIIr999vYuafCtetrzIBI8ke9+S2VvPPw+ni2KZvmTb1+ +DnIqq7QX/t92Y9RW1UgeXqvc/LbYwnIfSyCpea1IvHILup+eQ/R2aeIgzFrDbuS4 +ULrxdJrMu4UXXPJMbw7xSOAdhJoX+uky08bR3pbUbt6wNwwjuDLNLBIdlYZK6seL +QRsCAwEAAaB4MHYGCSqGSIb3DQEJDjFpMGcwDgYDVR0PAQH/BAQDAgeAMBMGA1Ud +JQQMMAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQ/ZBWqbeL7spn5xkS9awVgZ5L1ITAh +BgNVHREEGjAYghZzZXJ2ZXIuZXNvZGVtb2FwcDIuY29tMA0GCSqGSIb3DQEBBQUA +A4IBAQAJoFccsGUrdoPRuhjvhrtjnj2D8hEAA0bt+numzT5E26Cte7HHRg2Jn2f7 +5qxNunesf86FBjOtg/dr3tKIAPAQ7H6yojq/XFFrKkbDpYodigdxeD4pQ2NaZxPU +2FJZoGyoxoUMb7wozROTJDRI0hAmkVUtUgta3UHtDuVXLYTwpKCBHqFi6Nshv8jO +XTHsr7G/a0ky0nnbzYvhilyzZQS7k1F2pQIhzTFZtvwzM9JvpWyzS7I8W8QX5YqG +bqDgRvIy7MHu0sWjOPvSKtU5ivW+wawEytspDxdEapivIAzY7wvMH27ixm0sfCxN +tRlgsGSzkSXGk9c4MHDtmGFFfD0U +-----END CERTIFICATE REQUEST----- diff --git a/website/docs/r/privateca_certificate.html.markdown b/website/docs/r/privateca_certificate.html.markdown new file mode 100644 index 0000000000..b9726769ac --- /dev/null +++ b/website/docs/r/privateca_certificate.html.markdown @@ -0,0 +1,658 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Certificate Authority Service" +layout: "google" +page_title: "Google: google_privateca_certificate" +sidebar_current: "docs-google-privateca-certificate" +description: |- + A Certificate corresponds to a signed X. +--- + +# google\_privateca\_certificate + +A Certificate corresponds to a signed X.509 certificate issued by a CertificateAuthority. + + +~> **Note:** The Certificate Authority that is referenced by this resource **must** be +`tier = "ENTERPRISE"` + +~> **Warning:** Please remember that all resources created during preview (via the terraform-provider-google-beta) +will be deleted when CA service transitions to General Availability (GA). Relying on these +certificate authorities for production traffic is discouraged. + +~> **Warning:** This resource is in beta, and should be used with the terraform-provider-google-beta provider. +See [Provider Versions](https://terraform.io/docs/providers/google/guides/provider_versions.html) for more details on beta resources. + + + +## Example Usage - Privateca Certificate Config + + +```hcl +resource "google_privateca_certificate_authority" "test-ca" { + provider = google-beta + certificate_authority_id = "my-certificate-authority" + location = "us-central1" + tier = "ENTERPRISE" + config { + subject_config { + subject { + organization = "HashiCorp" + } + common_name = "my-certificate-authority" + subject_alt_name { + dns_names = ["hashicorp.com"] + } + } + reusable_config { + reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained" + } + } + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } + disable_on_delete = true +} + + +resource "google_privateca_certificate" "default" { + provider = google-beta + project = "my-project-name" + location = "us-central1" + certificate_authority = google_privateca_certificate_authority.test-ca.certificate_authority_id + lifetime = "860s" + name = "my-certificate" + config { + reusable_config { + reusable_config= "projects/568668481468/locations/us-central1/reusableConfigs/leaf-server-tls" + } + subject_config { + common_name = "san1.example.com" + subject { + country_code = "us" + organization = "google" + organizational_unit = "enterprise" + locality = "mountain view" + province = "california" + street_address = "1600 amphitheatre parkway" + postal_code = "94109" + } + subject_alt_name { + dns_names = ["hashicorp.com"] + email_addresses = ["email@example.com"] + ip_addresses = ["127.0.0.1"] + uris = ["http://www.ietf.org/rfc/rfc3986.txt"] + } + } + + public_key { + type = "PEM_RSA_KEY" + key = filebase64("test-fixtures/rsa_public.pem") + } + } +} +``` + +## Example Usage - Privateca Certificate Csr + + +```hcl +resource "google_privateca_certificate_authority" "test-ca" { + provider = google-beta + certificate_authority_id = "my-certificate-authority" + location = "us-central1" + tier = "ENTERPRISE" + config { + subject_config { + subject { + organization = "HashiCorp" + } + common_name = "my-certificate-authority" + subject_alt_name { + dns_names = ["hashicorp.com"] + } + } + reusable_config { + reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained" + } + } + key_spec { + algorithm = "RSA_PKCS1_4096_SHA256" + } + disable_on_delete = true +} + + + + +resource "google_privateca_certificate" "default" { + provider = google-beta + project = "my-project-name" + location = "us-central1" + certificate_authority = google_privateca_certificate_authority.test-ca.certificate_authority_id + lifetime = "860s" + name = "my-certificate" + pem_csr = file("test-fixtures/rsa_csr.pem") +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `name` - + (Required) + The name for this Certificate . + +* `location` - + (Required) + Location of the CertificateAuthority. A full list of valid locations can be found by + running `gcloud beta privateca locations list`. + +* `certificate_authority` - + (Required) + Certificate Authority name. + + +- - - + + +* `lifetime` - + (Optional) + The desired lifetime of the CA certificate. Used to create the "notBeforeTime" and + "notAfterTime" fields inside an X.509 certificate. A duration in seconds with up to nine + fractional digits, terminated by 's'. Example: "3.5s". + +* `labels` - + (Optional) + Labels with user-defined metadata to apply to this resource. + +* `pem_csr` - + (Optional) + Immutable. A pem-encoded X.509 certificate signing request (CSR). + +* `config` - + (Optional) + The config used to create a self-signed X.509 certificate or CSR. + Structure is documented below. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +The `config` block supports: + +* `subject_config` - + (Required) + Specifies some of the values in a certificate that are related to the subject. + Structure is documented below. + +* `reusable_config` - + (Required) + Specifies some of the values in a certificate that are related to the subject. + Structure is documented below. + +* `public_key` - + (Required) + A PublicKey describes a public key. + Structure is documented below. + + +The `subject_config` block supports: + +* `subject` - + (Required) + Contains distinguished name fields such as the location and organization. + Structure is documented below. + +* `common_name` - + (Required) + The common name of the distinguished name. + +* `subject_alt_name` - + (Optional) + The subject alternative name fields. + Structure is documented below. + + +The `subject` block supports: + +* `country_code` - + (Optional) + The country code of the subject. + +* `organization` - + (Required) + The organization of the subject. + +* `organizational_unit` - + (Optional) + The organizational unit of the subject. + +* `locality` - + (Optional) + The locality or city of the subject. + +* `province` - + (Optional) + The province, territory, or regional state of the subject. + +* `street_address` - + (Optional) + The street address of the subject. + +* `postal_code` - + (Optional) + The postal code of the subject. + +The `subject_alt_name` block supports: + +* `dns_names` - + (Optional) + Contains only valid, fully-qualified host names. + +* `uris` - + (Optional) + Contains only valid RFC 3986 URIs. + +* `email_addresses` - + (Optional) + Contains only valid RFC 2822 E-mail addresses. + +* `ip_addresses` - + (Optional) + Contains only valid 32-bit IPv4 addresses or RFC 4291 IPv6 addresses. + +The `reusable_config` block supports: + +* `reusable_config` - + (Required) + A resource path to a ReusableConfig in the format + `projects/*/locations/*/reusableConfigs/*`. + +The `public_key` block supports: + +* `key` - + (Optional) + Required. A public key. When this is specified in a request, the padding and encoding can be any of the options described by the respective 'KeyType' value. When this is generated by the service, it will always be an RFC 5280 SubjectPublicKeyInfo structure containing an algorithm identifier and a key. A base64-encoded string. + +* `type` - + (Required) + Types of public keys that are supported. At a minimum, we support RSA and ECDSA, for the key sizes or curves listed: https://cloud.google.com/kms/docs/algorithms#asymmetric_signing_algorithms + Possible values are `KEY_TYPE_UNSPECIFIED`, `PEM_RSA_KEY`, and `PEM_EC_KEY`. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}}` + +* `revocation_details` - + Output only. Details regarding the revocation of this Certificate. This Certificate is + considered revoked if and only if this field is present. + Structure is documented below. + +* `pem_certificate` - + Output only. The pem-encoded, signed X.509 certificate. + +* `certificate_description` - + Output only. Details regarding the revocation of this Certificate. This Certificate is considered revoked if and only if this field is present. + Structure is documented below. + +* `pem_certificates` - + Required. Expected to be in leaf-to-root order according to RFC 5246. + +* `create_time` - + The time that this resource was created on the server. + This is in RFC3339 text format. + +* `update_time` - + Output only. The time at which this CertificateAuthority was updated. + This is in RFC3339 text format. + + +The `revocation_details` block contains: + +* `revocation_state` - + (Optional) + Indicates why a Certificate was revoked. + Possible values are `REVOCATION_REASON_UNSPECIFIED`, `KEY_COMPROMISE`, `CERTIFICATE_AUTHORITY_COMPROMISE`, `AFFILIATION_CHANGED`, `SUPERSEDED`, `CESSATION_OF_OPERATION`, `CERTIFICATE_HOLD`, `PRIVILEGE_WITHDRAWN`, and `ATTRIBUTE_AUTHORITY_COMPROMISE`. + +* `revocation_time` - + (Optional) + The time at which this Certificate was revoked. + +The `certificate_description` block contains: + +* `subject_description` - + (Optional) + Describes some of the values in a certificate that are related to the subject and lifetime. + Structure is documented below. + +* `config_values` - + (Optional) + Describes some of the technical fields in a certificate. + Structure is documented below. + +* `public_key` - + (Required) + A PublicKey describes a public key. + Structure is documented below. + +* `subject_key_id` - + (Optional) + Provides a means of identifiying certificates that contain a particular public key, per https://tools.ietf.org/html/rfc5280#section-4.2.1.2. + Structure is documented below. + +* `authority_key_id` - + (Optional) + Identifies the subjectKeyId of the parent certificate, per https://tools.ietf.org/html/rfc5280#section-4.2.1.1 + Structure is documented below. + +* `crl_distribution_points` - + (Optional) + Describes a list of locations to obtain CRL information, i.e. the DistributionPoint.fullName described by https://tools.ietf.org/html/rfc5280#section-4.2.1.13 + +* `aia_issuing_certificate_urls` - + (Optional) + Describes lists of issuer CA certificate URLs that appear in the "Authority Information Access" extension in the certificate. + +* `cert_fingerprint` - + (Optional) + The hash of the x.509 certificate. + Structure is documented below. + + +The `subject_description` block supports: + +* `subject` - + (Optional) + Required. Contains distinguished name fields such as the location and organization. + Structure is documented below. + +* `common_name` - + (Optional) + The "common name" of the distinguished name. + +* `subject_alt_name` - + (Optional) + Optional. The subject alternative name fields. + Structure is documented below. + +* `hex_serial_number` - + (Optional) + The serial number encoded in lowercase hexadecimal. + +* `lifetime` - + (Optional) + For convenience, the actual lifetime of an issued certificate. Corresponds to 'notAfterTime' - 'notBeforeTime'. + +* `not_before_time` - + (Optional) + The time at which the certificate becomes valid. + +* `not_after_time` - + (Optional) + The time at which the certificate expires. + + +The `subject` block supports: + +* `country_code` - + (Optional) + The country code of the subject. + +* `organization` - + (Optional) + The organization of the subject. + +* `organizational_unit` - + (Optional) + The organizationalUnit of the subject. + +* `locality` - + (Optional) + The locality or city of the subject. + +* `province` - + (Optional) + The province of the subject. + +* `street_address` - + (Optional) + The streetAddress or city of the subject. + +* `postal_code` - + (Optional) + The postalCode or city of the subject. + +The `subject_alt_name` block supports: + +* `dns_names` - + (Optional) + Contains only valid, fully-qualified host names. + +* `uris` - + (Optional) + Contains only valid RFC 3986 URIs. + +* `email_addresses` - + (Optional) + Contains only valid RFC 2822 E-mail addresses. + +* `ip_addresses` - + (Optional) + Contains only valid 32-bit IPv4 addresses or RFC 4291 IPv6 addresses. + +* `custom_sans` - + (Required) + Contains additional subject alternative name values. + Structure is documented below. + + +The `custom_sans` block supports: + +* `obect_id` - + (Required) + Required. Describes how some of the technical fields in a certificate should be populated. + Structure is documented below. + +* `critical` - + (Required) + Required. Indicates whether or not this extension is critical (i.e., if the client does not know how to handle this extension, the client should consider this to be an error). + +* `value` - + (Optional) + Required. The value of this X.509 extension. + + +The `obect_id` block supports: + +* `object_id_path` - + (Required) + An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages. + +The `config_values` block supports: + +* `key_usage` - + (Optional) + Optional. Indicates the intended use for keys that correspond to a certificate. + Structure is documented below. + + +The `key_usage` block supports: + +* `base_key_usage` - + (Optional) + Describes high-level ways in which a key may be used. + Structure is documented below. + +* `extended_key_usage` - + (Optional) + Describes high-level ways in which a key may be used. + Structure is documented below. + +* `unknown_extended_key_usages` - + (Required) + An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages. + Structure is documented below. + + +The `base_key_usage` block supports: + +* `key_usage_options` - + (Optional) + Describes high-level ways in which a key may be used. + Structure is documented below. + + +The `key_usage_options` block supports: + +* `digital_signature` - + (Optional) + The key may be used for digital signatures. + +* `content_commitment` - + (Optional) + The key may be used for cryptographic commitments. Note that this may also be referred to as "non-repudiation". + +* `key_encipherment` - + (Optional) + The key may be used to encipher other keys. + +* `data_encipherment` - + (Optional) + The key may be used to encipher data. + +* `key_agreement` - + (Optional) + The key may be used in a key agreement protocol. + +* `cert_sign` - + (Optional) + The key may be used to sign certificates. + +* `crl_sign` - + (Optional) + The key may be used sign certificate revocation lists. + +* `encipher_only` - + (Optional) + The key may be used to encipher only. + +* `decipher_only` - + (Optional) + The key may be used to decipher only. + +The `extended_key_usage` block supports: + +* `server_auth` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.1. Officially described as "TLS WWW server authentication", though regularly used for non-WWW TLS. + +* `client_auth` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.2. Officially described as "TLS WWW client authentication", though regularly used for non-WWW TLS. + +* `code_signing` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.3. Officially described as "Signing of downloadable executable code client authentication". + +* `email_protection` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.4. Officially described as "Email protection". + +* `time_stamping` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.8. Officially described as "Binding the hash of an object to a time". + +* `ocsp_signing` - + (Optional) + Corresponds to OID 1.3.6.1.5.5.7.3.9. Officially described as "Signing OCSP responses". + +The `unknown_extended_key_usages` block supports: + +* `obect_id` - + (Required) + Required. Describes how some of the technical fields in a certificate should be populated. + Structure is documented below. + + +The `obect_id` block supports: + +* `object_id_path` - + (Required) + An ObjectId specifies an object identifier (OID). These provide context and describe types in ASN.1 messages. + +The `public_key` block supports: + +* `key` - + (Optional) + Required. A public key. When this is specified in a request, the padding and encoding can be any of the options described by the respective 'KeyType' value. When this is generated by the service, it will always be an RFC 5280 SubjectPublicKeyInfo structure containing an algorithm identifier and a key. A base64-encoded string. + +* `type` - + (Required) + Types of public keys that are supported. At a minimum, we support RSA and ECDSA, for the key sizes or curves listed: https://cloud.google.com/kms/docs/algorithms#asymmetric_signing_algorithms + Possible values are `KEY_TYPE_UNSPECIFIED`, `PEM_RSA_KEY`, and `PEM_EC_KEY`. + +The `subject_key_id` block supports: + +* `key_id` - + (Optional) + Optional. The value of this KeyId encoded in lowercase hexadecimal. This is most likely the 160 bit SHA-1 hash of the public key. + +The `authority_key_id` block supports: + +* `key_id` - + (Optional) + Optional. The value of this KeyId encoded in lowercase hexadecimal. This is most likely the 160 bit SHA-1 hash of the public key. + +The `cert_fingerprint` block supports: + +* `sha256_hash` - + (Optional) + The SHA 256 hash, encoded in hexadecimal, of the DER x509 certificate. + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + + +Certificate can be imported using any of these accepted formats: + +``` +$ terraform import google_privateca_certificate.default projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority}}/certificates/{{name}} +$ terraform import google_privateca_certificate.default {{project}}/{{location}}/{{certificate_authority}}/{{name}} +$ terraform import google_privateca_certificate.default {{location}}/{{certificate_authority}}/{{name}} +``` + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/google.erb b/website/google.erb index a496b308b3..a965319847 100644 --- a/website/google.erb +++ b/website/google.erb @@ -362,6 +362,10 @@ Resources