Skip to content

Commit

Permalink
Add resource google_privateca_certificate_authority
Browse files Browse the repository at this point in the history
In Certificate Authority Service (privateca).

See
https://cloud.google.com/certificate-authority-service/docs/reference/rest/v1beta1/projects.locations.certificateAuthorities
for resource documentation.

Notes:
- This change doesn't implement support for subordinate CAs, which require
  additional customization because they must be activated.

Customizations:
- Use POST :scheduleDelete to delete the resource (delete is not supported)
- On pre_delete, POST :disable to disable the resources (required for scheduling
  deletd)
- Check resource deletion by checking that status is DELETION_PENDING
  • Loading branch information
connorsmith-w committed Jan 11, 2021
1 parent 11aeb94 commit 978bbe0
Show file tree
Hide file tree
Showing 6 changed files with 387 additions and 0 deletions.
265 changes: 265 additions & 0 deletions products/privateca/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
# Copyright 2020 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Product
name: Privateca
display_name: Certificate Authority
versions:
- !ruby/object:Api::Product::Version
name: beta
base_url: https://privateca.googleapis.com/v1beta1/
scopes:
- https://www.googleapis.com/auth/cloud-platform
apis_required:
- !ruby/object:Api::Product::ApiReference
name: Certificate Authority API
url: https://console.cloud.google.com/apis/api/privateca.googleapis.com
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
base_url: '{{op_id}}'
path: 'name'
wait_ms: 1000
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: True
allowed:
- True
- False
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
objects:
# CertificateAuthority
- !ruby/object:Api::Resource
name: 'CertificateAuthority'
description: |
A CertificateAuthority represents an individual Certificate Authority. A
CertificateAuthority can be used to create Certificates.
base_url: projects/{{project}}/locations/{{location}}/certificateAuthorities
create_url: projects/{{project}}/locations/{{location}}/certificateAuthorities?certificateAuthorityId={{certificate_authority_id}}
self_link: projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority_id}}
min_version: beta
create_verb: :POST
delete_url: '{{name}}:scheduleDelete'
delete_verb: :POST
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation':
'https://cloud.google.com/certificate-authority-service'
api: 'https://https://cloud.google.com/certificate-authority-service/docs/reference/rest'
properties:
- !ruby/object:Api::Type::String
name: location
description: Location of the Certificate Authority.
required: true
url_param_only: true
- !ruby/object:Api::Type::String
name: certificateAuthorityId
description: GCP region of the Realm.
input: true
required: true
url_param_only: true
- !ruby/object:Api::Type::String
name: 'name'
description: |
The resource name for this CertificateAuthority in the format
projects/*/locations/*/certificateAuthorities/*.
output: true
- !ruby/object:Api::Type::Enum
name: 'type'
description: The Type of this CertificateAuthority.
input: true
values:
- :SELF_SIGNED
default_value: :SELF_SIGNED
- !ruby/object:Api::Type::Enum
name: 'tier'
description: The Tier of this CertificateAuthority.
input: true
values:
- :ENTERPRISE
- :DEVOPS
default_value: :ENTERPRISE
- !ruby/object:Api::Type::NestedObject
name: 'config'
description: The config used to create a self-signed X.509 certificate or CSR.
required: true
input: true
properties:
- !ruby/object:Api::Type::NestedObject
name: 'subjectConfig'
description: |
Specifies some of the values in a certificate that are related to the subject.
required: true
properties:
- !ruby/object:Api::Type::NestedObject
name: 'subject'
description: Contains distinguished name fields such as the location and organization.
properties:
- !ruby/object:Api::Type::String
name: 'countryCode'
description: The country code of the subject.
- !ruby/object:Api::Type::String
name: 'organization'
description: The organization of the subject.
- !ruby/object:Api::Type::String
name: 'organizationalUnit'
description: The organizational unit of the subject.
- !ruby/object:Api::Type::String
name: 'locality'
description: The locality or city of the subject.
- !ruby/object:Api::Type::String
name: 'province'
description: The province, territory, or regional state of the subject.
- !ruby/object:Api::Type::String
name: 'streetAddress'
description: The street address of the subject.
- !ruby/object:Api::Type::String
name: 'postalCode'
description: The postal code of the subject.
- !ruby/object:Api::Type::String
name: 'commonName'
description: The common name of the distinguished name.
- !ruby/object:Api::Type::NestedObject
name: 'subjectAltName'
description: The subject alternative name fields.
properties:
- !ruby/object:Api::Type::Array
name: 'dnsNames'
description: Contains only valid, fully-qualified host names.
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'uris'
description: Contains only valid RFC 3986 URIs.
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'emailAddresses'
description: Contains only valid RFC 2822 E-mail addresses.
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'ipAddresses'
description: Contains only valid 32-bit IPv4 addresses or RFC 4291 IPv6 addresses.
item_type: Api::Type::String
- !ruby/object:Api::Type::NestedObject
name: 'reusableConfig'
description: |
Specifies some of the values in a certificate that are related to the subject.
required: true
properties:
- !ruby/object:Api::Type::String
name: 'reusableConfig'
description: |
A resource path to a ReusableConfig in the format
projects/*/locations/*/reusableConfigs/*.
- !ruby/object:Api::Type::String
name: 'lifetime'
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_value: 315360000s # 10 years
- !ruby/object:Api::Type::NestedObject
name: 'keySpec'
description: |
Used when issuing certificates for this CertificateAuthority. If this CertificateAuthority
is a self-signed CertificateAuthority, this key is also used to sign the self-signed CA
certificate. Otherwise, it is used to sign a CSR.
required: true
properties:
- !ruby/object:Api::Type::Enum
name: 'algorithm'
description: |
The algorithm to use for creating a managed Cloud KMS key for a for a simplified
experience. All managed keys will be have their ProtectionLevel as HSM.
values:
- :SIGN_HASH_ALGORITHM_UNSPECIFIED
- :RSA_PSS_2048_SHA256
- :RSA_PSS_3072_SHA256
- :RSA_PSS_4096_SHA256
- :RSA_PKCS1_2048_SHA256
- :RSA_PKCS1_3072_SHA256
- :RSA_PKCS1_4096_SHA256
- :EC_P256_SHA256
- :EC_P384_SHA384
- !ruby/object:Api::Type::NestedObject
name: 'issuingOptions'
description: |
Options that affect all certificates issued by a CertificateAuthority.
properties:
- !ruby/object:Api::Type::Boolean
name: 'includeCaCertUrl'
description: |
When true, includes a URL to the issuing CA certificate in the "authority
information access" X.509 extension.
default_value: true
- !ruby/object:Api::Type::Boolean
name: 'includeCrlAccessUrl'
description: |
When true, includes a URL to the CRL corresponding to certificates issued from a
CertificateAuthority. CRLs will expire 7 days from their creation. However, we will
rebuild daily. CRLs are also rebuilt shortly after a certificate is revoked.
default_value: false
- !ruby/object:Api::Type::Enum
name: 'state'
description: The State for this CertificateAuthority.
output: true
values:
- :STATE_UNSPECIFIED
- :ENABLED
- :DISABLED
- :PENDING_ACTIVATION
- :PENDING_DELETION
- !ruby/object:Api::Type::Array
name: 'pemCaCertificates'
description: |
This CertificateAuthority's certificate chain, including the current
CertificateAuthority's certificate. Ordered such that the root issuer is the final
element (consistent with RFC 5246). For a self-signed CA, this will only list the current
CertificateAuthority's certificate.
item_type: Api::Type::String
output: true
- !ruby/object:Api::Type::String
name: 'gcsBucket'
description: |
The name of a Cloud Storage bucket where this CertificateAuthority will publish content,
such as the CA certificate and CRLs. This must be a bucket name, without any prefixes
(such as gs://) or suffixes (such as .googleapis.com). For example, to use a bucket named
my-bucket, you would simply specify my-bucket. If not specified, a managed bucket will be
created.
input: true
- !ruby/object:Api::Type::NestedObject
name: 'accessUrls'
description: |
Output only. URLs for accessing content published by this CA, such as the CA certificate
and CRLs.
output: true
properties:
- !ruby/object:Api::Type::String
name: 'caCertificateAccessUrl'
description: |
The URL where this CertificateAuthority's CA certificate is published. This will only be
set for CAs that have been activated.
output: true
- !ruby/object:Api::Type::String
name: 'crlAccessUrl'
description: |
The URL where this CertificateAuthority's CRLs are published. This will only be set for
CAs that have been activated.
output: true
- !ruby/object:Api::Type::KeyValuePairs
name: labels
description: Labels with user-defined metadata.

34 changes: 34 additions & 0 deletions products/privateca/terraform.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2020 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Provider::Terraform::Config
overrides: !ruby/object:Overrides::ResourceOverrides
CertificateAuthority: !ruby/object:Overrides::Terraform::ResourceOverride
autogen_async: true
import_format: ["projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority_id}}"]
examples:
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_authority_basic"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_authority_id: "my-certificate-authority"
- !ruby/object:Provider::Terraform::Examples
name: "privateca_certificate_authority_full"
min_version: "beta"
primary_resource_id: "default"
vars:
certificate_authority_id: "my-certificate-authority"
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/privateca_certificate_authority.go.erb
test_check_destroy: templates/terraform/custom_check_destroy/privateca_certificate_authority.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
config := googleProviderConfig(t)

url, err := replaceVarsForTest(config, rs, "{{PrivatecaBasePath}}projects/{{project}}/locations/{{location}}/certificateAuthorities/{{certificate_authority_id}}")
if err != nil {
return err
}

res, err := sendRequest(config, "GET", "", url, config.userAgent, nil)
if err != nil {
return nil
}

if s := res["state"]; s != "PENDING_DELETION" {
return fmt.Errorf("CertificateAuthority %s got %s, want PENDING_DELETION", url, s)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "google_privateca_certificate_authority" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
certificate_authority_id = "<%= ctx[:vars]["certificate_authority_id"] %>"
location = "us-central1"
config {
subject_config {
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"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
resource "google_privateca_certificate_authority" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta
certificate_authority_id = "<%= ctx[:vars]["certificate_authority_id"] %>"
location = "us-central1"
tier = "DEVOPS"
config {
subject_config {
subject {
country_code = "US"
organization = "HashiCorp"
organizational_unit = "Terraform"
locality = "San Francisco"
province = "CA"
street_address = "101 2nd St #700"
postal_code = "94105"
}
common_name = "my-certificate-authority"
subject_alt_name {
dns_names = ["hashicorp.com"]
email_addresses = ["[email protected]"]
ip_addresses = ["127.0.0.1"]
uris = ["http://www.ietf.org/rfc/rfc3986.txt"]
}
}
reusable_config {
reusable_config = "projects/568668481468/locations/us-central1/reusableConfigs/root-unconstrained"
}
}
lifetime = "86400s"
issuing_options {
include_ca_cert_url = true
include_crl_access_url = false
}
key_spec {
algorithm = "EC_P256_SHA256"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
log.Printf("[DEBUG] Disabling CertificateAuthority %q", d.Id())

disableURL, err := replaceVars(d, config, "{{PrivatecaBasePath}}{{name}}:disable")
if err != nil {
return err
}

disableRes, err := sendRequestWithTimeout(config, "POST", billingProject, disableURL, userAgent, obj, d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
}

err = privatecaOperationWaitTime(config, disableRes, project, "Disabling CertificateAuthority", userAgent, d.Timeout(schema.TimeoutDelete))
if err != nil {
return err
}

0 comments on commit 978bbe0

Please sign in to comment.