Skip to content

Commit

Permalink
migrate code from googleapis/python-security-private-ca (#9028)
Browse files Browse the repository at this point in the history
- feat(samples): private CA python samples
- chore(deps): update dependency google-cloud-private-ca to v1 (#89)
- chore(deps): update dependency google-cloud-kms to v2.4.1 (#88)
- chore(deps): update dependency google-cloud-kms to v2.4.2 (#93)
- chore(deps): update dependency google-auth to v1.33.1 (#87)
- chore(deps): update dependency google-auth to v1.34.0 (#94)
- chore(deps): update dependency google-cloud-kms to v2.4.3 (#96)
- chore(deps): update dependency google-cloud-private-ca to v1.0.3 (#97)
- feat(samples): add local generation for crypto keys (#98)
- chore(deps): update dependency google-cloud-kms to v2.5.0 (#101)
- chore: generate python samples templates in owlbot.py (#108)
- chore(deps): update dependency cryptography to v3.4.8 (#109)
- chore(deps): update dependency google-auth to v2 (#107)
- chore(deps): update dependency google-cloud-private-ca to v1.0.4 (#103)
- chore(deps): update dependency google-auth to v2.0.2 (#116)
- chore(deps): update dependency google-cloud-kms to v2.6.0 (#115)
- chore(deps): update dependency pytest to v6.2.5 (#114)
- chore: blacken samples noxfile template (#121)
- chore: fail samples nox session if python version is missing (#128)
- chore(python): Add kokoro configs for python 3.10 samples testing (#134)
- chore(deps): update dependency google-auth to v2.1.0 (#120)
- chore(deps): update all dependencies (#144)
- chore(deps): update all dependencies (#146)
- chore(deps): update dependency google-cloud-private-ca to v1.2.1 (#147)
- chore(python): run blacken session for all directories with a noxfile (#150)
- chore(deps): update dependency cryptography to v36 (#154)
- feat(samples): add subordinate CA samples
- chore(deps): update dependency cryptography to v36.0.1 (#158)
- chore(samples): Add check for tests in directory (#164)
- chore(python): Noxfile recognizes that tests can live in a folder (#169)
- docs(samples): add sample to filter certificates (#160)
- chore(deps): update dependency google-auth to v2.6.0 (#173)
- docs(samples): add template/monitoring samples (#174)
- chore(deps): update all dependencies (#178)
- chore(deps): update all dependencies (#186)
- chore: Adding support for pytest-xdist and pytest-parallel (#193)
- chore(deps): update all dependencies (#196)
- chore(deps): update dependency google-cloud-private-ca to v1.3.0 (#199)
- chore(deps): update dependency pytest to v7.1.0 (#200)
- chore(deps): update dependency cryptography to v36.0.2 (#201)
- chore(deps): update all dependencies (#202)
- chore(python): use black==22.3.0 (#204)
- chore(deps): update dependency google-auth to v2.6.3 (#211)
- chore(deps): update dependency google-auth to v2.6.4 (#215)
- chore(deps): update dependency google-auth to v2.6.5 (#217)
- chore(python): add nox session to sort python imports (#218)
- chore(deps): update dependency google-auth to v2.6.6 (#221)
- chore(deps): update dependency pytest to v7.1.2 (#222)
- chore(deps): update dependency cryptography to v37 (#223)
- chore(deps): update dependency cryptography to v37.0.1 (#225)
- chore(deps): update dependency cryptography to v37.0.2 (#226)
- chore(deps): update dependency google-cloud-private-ca to v1.3.1 (#230)
- fix: require python 3.7+ (#267)
- chore(deps): update all dependencies (#262)
- chore(deps): update all dependencies (#273)
- chore(deps): update all dependencies (#275)
- chore(deps): update all dependencies (#276)
- chore(deps): update dependency google-cloud-monitoring to v2.11.1 (#281)
- chore(deps): update all dependencies (#283)
- chore(deps): update dependency google-auth to v2.11.0 (#284)
- chore(deps): update dependency pytest to v7.1.3 (#294)
- chore: Bump gapic-generator-python version to 1.3.0 (#295)
- chore: detect samples tests in nested directories (#299)
- chore(deps): update dependency google-auth to v2.11.1 (#300)
- chore(deps): update dependency google-auth to v2.12.0 (#302)
- chore(deps): update all dependencies (#304)
- chore(deps): update all dependencies (#307)
- chore(deps): update dependency pytest to v7.2.0 (#308)
- chore(deps): update dependency google-auth to v2.14.0 (#310)
- chore(python): drop flake8-import-order in samples noxfile (#315)
- chore(deps): update all dependencies (#311)
- chore(deps): update dependency cryptography to v38.0.4 (#317)
- chore(deps): update dependency google-auth to v2.15.0 (#318)
- chore(deps): update all dependencies (#321)
- chore(deps): update dependency google-cloud-private-ca to v1.5.0 (#322)
- chore(deps): update dependency cryptography to v39 (#323)
- chore(python): add support for python 3.11 (#324)
- chore(deps): update dependency google-cloud-monitoring to v2.13.0 (#325)
- chore(deps): update dependency google-auth to v2.16.0 (#326)
- chore(deps): update all dependencies (#329)
- chore(deps): update dependency pytest to v7.2.1 (#330)

## Description

Sample Migration from googleapis/python-security-private-ca

Note: Before submitting a pull request, please open an issue for discussion if you are not associated with Google.

## Checklist
- [ ] I have followed [Sample Guidelines from AUTHORING_GUIDE.MD](https://togithub.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md)
- [ ] README is updated to include [all relevant information](https://togithub.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md#readme-file)
- [ ] **Tests** pass:   `nox -s py-3.9` (see [Test Environment Setup](https://togithub.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md#test-environment-setup))
- [ ] **Lint** pass:   `nox -s lint` (see [Test Environment Setup](https://togithub.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md#test-environment-setup))
- [ ] These samples need a new **API enabled** in testing projects to pass (let us know which ones)
- [ ] These samples need a new/updated **env vars** in testing projects set to pass (let us know which ones)
- [ ] Please **merge** this PR for me once it is approved.
- [ ] This sample adds a new sample directory, and I updated the [CODEOWNERS file](https://togithub.com/GoogleCloudPlatform/python-docs-samples/blob/main/.github/CODEOWNERS) with the codeowners for this sample
  • Loading branch information
rsamborski authored and telpirion committed Mar 13, 2023
1 parent 0013c10 commit 7116d06
Show file tree
Hide file tree
Showing 32 changed files with 2,196 additions and 0 deletions.
87 changes: 87 additions & 0 deletions privateca/snippets/activate_subordinate_ca.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python

# Copyright 2021 Google LLC
#
# 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.

# [START privateca_activate_subordinateca]
import google.cloud.security.privateca_v1 as privateca_v1


def activate_subordinate_ca(
project_id: str,
location: str,
ca_pool_name: str,
subordinate_ca_name: str,
pem_ca_certificate: str,
ca_name: str,
) -> None:
"""
Activate a subordinate Certificate Authority (CA).
*Prerequisite*: Get the Certificate Signing Resource (CSR) of the subordinate CA signed by another CA. Pass in the signed
certificate and (issuer CA's name or the issuer CA's Certificate chain).
*Post*: After activating the subordinate CA, it should be enabled before issuing certificates.
Args:
project_id: project ID or project number of the Cloud project you want to use.
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
ca_pool_name: set it to the CA Pool under which the CA should be created.
pem_ca_certificate: the signed certificate, obtained by signing the CSR.
subordinate_ca_name: the CA to be activated.
ca_name: The name of the certificate authority which signed the CSR.
If an external CA (CA not present in Google Cloud) was used for signing,
then use the CA's issuerCertificateChain.
"""

ca_service_client = privateca_v1.CertificateAuthorityServiceClient()

subordinate_ca_path = ca_service_client.certificate_authority_path(
project_id, location, ca_pool_name, subordinate_ca_name
)
ca_path = ca_service_client.certificate_authority_path(
project_id, location, ca_pool_name, ca_name
)

# Set CA subordinate config.
subordinate_config = privateca_v1.SubordinateConfig(
# Follow one of the below methods:
# Method 1: If issuer CA is in Google Cloud, set the Certificate Authority Name.
certificate_authority=ca_path,
# Method 2: If issuer CA is external to Google Cloud, set the issuer's certificate chain.
# The certificate chain of the CA (which signed the CSR) from leaf to root.
# pem_issuer_chain=privateca_v1.SubordinateConfig.SubordinateConfigChain(
# pem_certificates=issuer_certificate_chain,
# )
)

# Construct the "Activate CA Request".
request = privateca_v1.ActivateCertificateAuthorityRequest(
name=subordinate_ca_path,
# The signed certificate.
pem_ca_certificate=pem_ca_certificate,
subordinate_config=subordinate_config,
)

# Activate the CA
operation = ca_service_client.activate_certificate_authority(request=request)
result = operation.result()

print("Operation result:", result)

# The current state will be STAGED.
# The Subordinate CA has to be ENABLED before issuing certificates.
print(
f"Current state: {ca_service_client.get_certificate_authority(name=subordinate_ca_path).state}"
)


# [END privateca_activate_subordinateca]
83 changes: 83 additions & 0 deletions privateca/snippets/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright 2021 Google LLC
#
# 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.

import uuid

import google.auth
import pytest

from create_ca_pool import create_ca_pool
from create_certificate_authority import create_certificate_authority
from create_certificate_template import create_certificate_template
from delete_ca_pool import delete_ca_pool
from delete_certificate_authority import delete_certificate_authority
from delete_certificate_template import delete_certificate_template

PROJECT = google.auth.default()[1]
LOCATION = "us-central1"
COMMON_NAME = "COMMON_NAME"
ORGANIZATION = "ORGANIZATION"
CA_DURATION = 1000000


def generate_name() -> str:
return "test-" + uuid.uuid4().hex[:10]


@pytest.fixture
def ca_pool():
CA_POOL_NAME = generate_name()

create_ca_pool(PROJECT, LOCATION, CA_POOL_NAME)

yield CA_POOL_NAME

delete_ca_pool(PROJECT, LOCATION, CA_POOL_NAME)


@pytest.fixture
def certificate_authority(ca_pool):
CA_NAME = generate_name()

create_certificate_authority(
PROJECT, LOCATION, ca_pool, CA_NAME, COMMON_NAME, ORGANIZATION, CA_DURATION
)

yield ca_pool, CA_NAME

delete_certificate_authority(PROJECT, LOCATION, ca_pool, CA_NAME)


@pytest.fixture
def deleted_certificate_authority(ca_pool):
CA_NAME = generate_name()

create_certificate_authority(
PROJECT, LOCATION, ca_pool, CA_NAME, COMMON_NAME, ORGANIZATION, CA_DURATION
)

delete_certificate_authority(PROJECT, LOCATION, ca_pool, CA_NAME)

yield ca_pool, CA_NAME


@pytest.fixture
def certificate_template():
TEMPLATE_NAME = generate_name()

create_certificate_template(PROJECT, LOCATION, TEMPLATE_NAME)

yield TEMPLATE_NAME

delete_certificate_template(PROJECT, LOCATION, TEMPLATE_NAME)
53 changes: 53 additions & 0 deletions privateca/snippets/create_ca_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python

# Copyright 2021 Google LLC
#
# 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.

# [START privateca_create_ca_pool]
import google.cloud.security.privateca_v1 as privateca_v1


def create_ca_pool(project_id: str, location: str, ca_pool_name: str) -> None:
"""
Create a Certificate Authority pool. All certificates created under this CA pool will
follow the same issuance policy, IAM policies,etc.,
Args:
project_id: project ID or project number of the Cloud project you want to use.
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
ca_pool_name: a unique name for the ca pool.
"""

caServiceClient = privateca_v1.CertificateAuthorityServiceClient()

ca_pool = privateca_v1.CaPool(
# Set the tier (see: https://cloud.google.com/certificate-authority-service/docs/tiers).
tier=privateca_v1.CaPool.Tier.ENTERPRISE,
)
location_path = caServiceClient.common_location_path(project_id, location)

# Create the pool request.
request = privateca_v1.CreateCaPoolRequest(
parent=location_path,
ca_pool_id=ca_pool_name,
ca_pool=ca_pool,
)

# Create the CA pool.
operation = caServiceClient.create_ca_pool(request=request)

print("Operation result:", operation.result())


# [END privateca_create_ca_pool]
102 changes: 102 additions & 0 deletions privateca/snippets/create_certificate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python

# Copyright 2021 Google LLC
#
# 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.

# [START privateca_create_certificate]
import google.cloud.security.privateca_v1 as privateca_v1
from google.protobuf import duration_pb2


def create_certificate(
project_id: str,
location: str,
ca_pool_name: str,
ca_name: str,
certificate_name: str,
common_name: str,
domain_name: str,
certificate_lifetime: int,
public_key_bytes: bytes,
) -> None:
"""
Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
The key used to sign the certificate is created by the Cloud KMS.
Args:
project_id: project ID or project number of the Cloud project you want to use.
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
ca_pool_name: set a unique name for the CA pool.
ca_name: the name of the certificate authority which issues the certificate.
certificate_name: set a unique name for the certificate.
common_name: a title for your certificate.
domain_name: fully qualified domain name for your certificate.
certificate_lifetime: the validity of the certificate in seconds.
public_key_bytes: public key used in signing the certificates.
"""

caServiceClient = privateca_v1.CertificateAuthorityServiceClient()

# The public key used to sign the certificate can be generated using any crypto library/framework.
# Also you can use Cloud KMS to retrieve an already created public key.
# For more info, see: https://cloud.google.com/kms/docs/retrieve-public-key.

# Set the Public Key and its format.
public_key = privateca_v1.PublicKey(
key=public_key_bytes,
format_=privateca_v1.PublicKey.KeyFormat.PEM,
)

subject_config = privateca_v1.CertificateConfig.SubjectConfig(
subject=privateca_v1.Subject(common_name=common_name),
subject_alt_name=privateca_v1.SubjectAltNames(dns_names=[domain_name]),
)

# Set the X.509 fields required for the certificate.
x509_parameters = privateca_v1.X509Parameters(
key_usage=privateca_v1.KeyUsage(
base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
digital_signature=True,
key_encipherment=True,
),
extended_key_usage=privateca_v1.KeyUsage.ExtendedKeyUsageOptions(
server_auth=True,
client_auth=True,
),
),
)

# Create certificate.
certificate = privateca_v1.Certificate(
config=privateca_v1.CertificateConfig(
public_key=public_key,
subject_config=subject_config,
x509_config=x509_parameters,
),
lifetime=duration_pb2.Duration(seconds=certificate_lifetime),
)

# Create the Certificate Request.
request = privateca_v1.CreateCertificateRequest(
parent=caServiceClient.ca_pool_path(project_id, location, ca_pool_name),
certificate_id=certificate_name,
certificate=certificate,
issuing_certificate_authority_id=ca_name,
)
result = caServiceClient.create_certificate(request=request)

print("Certificate creation result:", result)


# [END privateca_create_certificate]
Loading

0 comments on commit 7116d06

Please sign in to comment.