From 453f966fb7f80b8c1b69b4436504a6847fc75cc5 Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Sun, 23 Jan 2022 15:02:44 +0300 Subject: [PATCH] docs(samples): add sample to filter certificates (#160) docs(samples): add sample to undelete certificate authority * samples(security): add filter/undelete certs * add fixture for a deleted CA Co-authored-by: Anthonios Partheniou --- privateca/snippets/conftest.py | 13 ++++ privateca/snippets/filter_certificates.py | 48 +++++++++++++ .../snippets/test_certificate_authorities.py | 15 ++-- privateca/snippets/test_certificates.py | 13 +++- .../undelete_certificate_authority.py | 68 +++++++++++++++++++ 5 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 privateca/snippets/filter_certificates.py create mode 100644 privateca/snippets/undelete_certificate_authority.py diff --git a/privateca/snippets/conftest.py b/privateca/snippets/conftest.py index e3cc338a5039..6c11fc7cadcd 100644 --- a/privateca/snippets/conftest.py +++ b/privateca/snippets/conftest.py @@ -56,3 +56,16 @@ def certificate_authority(ca_pool): 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 diff --git a/privateca/snippets/filter_certificates.py b/privateca/snippets/filter_certificates.py new file mode 100644 index 000000000000..8ee7aac050d6 --- /dev/null +++ b/privateca/snippets/filter_certificates.py @@ -0,0 +1,48 @@ +#!/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_filter_certificate] +import google.cloud.security.privateca_v1 as privateca_v1 + + +def filter_certificates( + project_id: str, location: str, ca_pool_name: str, filter_condition: str +) -> None: + """ + Filter certificates based on a condition and list them. + + 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: name of the CA pool which contains the certificates to be listed. + """ + + caServiceClient = privateca_v1.CertificateAuthorityServiceClient() + + ca_pool_path = caServiceClient.ca_pool_path(project_id, location, ca_pool_name) + + # Create the certificate request and set the filter condition. + request = privateca_v1.ListCertificatesRequest( + parent=ca_pool_path, filter=filter_condition, + ) + + # Retrieve and print the certificate names. + print("Available certificates: ") + for cert in caServiceClient.list_certificates(request=request): + print(f"- {cert.name}") + + +# [END privateca_filter_certificate] diff --git a/privateca/snippets/test_certificate_authorities.py b/privateca/snippets/test_certificate_authorities.py index 4ef01f97b62d..128cf7e79868 100644 --- a/privateca/snippets/test_certificate_authorities.py +++ b/privateca/snippets/test_certificate_authorities.py @@ -24,6 +24,7 @@ from delete_certificate_authority import delete_certificate_authority from disable_certificate_authority import disable_certificate_authority from enable_certificate_authority import enable_certificate_authority +from undelete_certificate_authority import undelete_certificate_authority PROJECT = google.auth.default()[1] @@ -71,17 +72,15 @@ def test_enable_and_disable_certificate_authority( assert re.search(f"Disabled Certificate Authority: {CA_NAME}", out,) -def test_delete_certificate_authority(capsys: typing.Any) -> None: - CA_POOL_NAME = generate_name() - CA_NAME = generate_name() +def test_undelete_certificate_authority( + deleted_certificate_authority, capsys: typing.Any +) -> None: + CA_POOL_NAME, CA_NAME = deleted_certificate_authority - create_ca_pool(PROJECT, LOCATION, CA_POOL_NAME) - create_certificate_authority( - PROJECT, LOCATION, CA_POOL_NAME, CA_NAME, COMMON_NAME, ORGANIZATION, CA_DURATION - ) + undelete_certificate_authority(PROJECT, LOCATION, CA_POOL_NAME, CA_NAME) delete_certificate_authority(PROJECT, LOCATION, CA_POOL_NAME, CA_NAME) delete_ca_pool(PROJECT, LOCATION, CA_POOL_NAME) out, _ = capsys.readouterr() - + assert re.search(f"Successfully undeleted Certificate Authority: {CA_NAME}", out,) assert re.search(f"Successfully deleted Certificate Authority: {CA_NAME}", out,) diff --git a/privateca/snippets/test_certificates.py b/privateca/snippets/test_certificates.py index 85d707f46b71..3d129bfa1bf0 100644 --- a/privateca/snippets/test_certificates.py +++ b/privateca/snippets/test_certificates.py @@ -13,6 +13,7 @@ # limitations under the License. +import re import time import typing import uuid @@ -28,6 +29,7 @@ from create_certificate import create_certificate from disable_certificate_authority import disable_certificate_authority from enable_certificate_authority import enable_certificate_authority +from filter_certificates import filter_certificates from revoke_certificate import revoke_certificate @@ -74,6 +76,11 @@ def test_create_and_revoke_certificate_authority( public_key_bytes, ) + FILTER_CONDITION = ( + f"certificate_description.subject_description.subject.common_name={COMMON_NAME}" + ) + filter_certificates(PROJECT, LOCATION, CA_POOL_NAME, FILTER_CONDITION) + revoke_certificate( PROJECT, LOCATION, CA_POOL_NAME, CERT_NAME, ) @@ -81,6 +88,10 @@ def test_create_and_revoke_certificate_authority( disable_certificate_authority(PROJECT, LOCATION, CA_POOL_NAME, CA_NAME) out, _ = capsys.readouterr() - assert "Certificate creation result:" in out + assert "Available certificates:" in out + assert re.search( + f"- projects/.*/locations/{LOCATION}/caPools/{CA_POOL_NAME}/certificates/{CERT_NAME}", + out, + ) assert "Certificate revoke result:" in out diff --git a/privateca/snippets/undelete_certificate_authority.py b/privateca/snippets/undelete_certificate_authority.py new file mode 100644 index 000000000000..f436f891cd38 --- /dev/null +++ b/privateca/snippets/undelete_certificate_authority.py @@ -0,0 +1,68 @@ +#!/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_undelete_ca] +import google.cloud.security.privateca_v1 as privateca_v1 + + +def undelete_certificate_authority( + project_id: str, location: str, ca_pool_name: str, ca_name: str +) -> None: + """ + Restore a deleted CA, if still within the grace period of 30 days. + + 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: the name of the CA pool under which the deleted CA is present. + ca_name: the name of the CA to be restored (undeleted). + """ + + caServiceClient = privateca_v1.CertificateAuthorityServiceClient() + ca_path = caServiceClient.certificate_authority_path( + project_id, location, ca_pool_name, ca_name + ) + + # Confirm if the CA is in DELETED stage. + ca_state = caServiceClient.get_certificate_authority(name=ca_path).state + if ca_state != privateca_v1.CertificateAuthority.State.DELETED: + print("CA is not deleted !") + return + + # Create the Request. + request = privateca_v1.UndeleteCertificateAuthorityRequest(name=ca_path) + + # Undelete the CA. + operation = caServiceClient.undelete_certificate_authority(request=request) + result = operation.result() + + print("Operation result", result) + + # Get the current CA state. + ca_state = caServiceClient.get_certificate_authority(name=ca_path).state + + # CA state changes from DELETED to DISABLED if successfully restored. + # Confirm if the CA is DISABLED. + if ca_state == privateca_v1.CertificateAuthority.State.DISABLED: + print("Successfully undeleted Certificate Authority:", ca_name) + else: + print( + "Unable to restore the Certificate Authority! Please try again! Current state:", + ca_state, + ) + + +# [END privateca_undelete_ca]