Skip to content

Commit 351608b

Browse files
feat: Adding code samples to self-managed SSL certificate registration. (GoogleCloudPlatform#7390)
Co-authored-by: Dan Lee <71398022+dandhlee@users.noreply.github.com>
1 parent 1229940 commit 351608b

File tree

9 files changed

+313
-0
lines changed

9 files changed

+313
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START compute_certificate_create]
16+
from pathlib import Path
17+
from pprint import pprint
18+
from typing import Union
19+
20+
from googleapiclient import discovery
21+
22+
23+
def create_certificate(
24+
project_id: str, certificate_file: Union[str, Path], private_key_file: Union[str, Path], certificate_name: str, description: str = "Certificate created from a code sample."
25+
) -> None:
26+
"""
27+
Create a global SSL self-signed certificate within your Google Cloud project.
28+
29+
Args:
30+
project_id: project ID or project number of the Cloud project you want to use.
31+
certificate_file: path to the file with the certificate you want to create in your project.
32+
private_key_file: path to the private key you used to sign the certificate with.
33+
certificate_name: name for the certificate once it's created in your project.
34+
description: description of the certificate.
35+
"""
36+
service = discovery.build("compute", "v1")
37+
38+
# Read the cert into memory
39+
with open(certificate_file) as f:
40+
_temp_cert = f.read()
41+
42+
# Read the private_key into memory
43+
with open(private_key_file) as f:
44+
_temp_key = f.read()
45+
46+
# Now that the certificate and private key are in memory, you can create the
47+
# certificate resource
48+
ssl_certificate_body = {
49+
"name": certificate_name,
50+
"description": description,
51+
"certificate": _temp_cert,
52+
"privateKey": _temp_key,
53+
}
54+
request = service.sslCertificates().insert(
55+
project=project_id, body=ssl_certificate_body
56+
)
57+
response = request.execute()
58+
pprint(response)
59+
60+
61+
# [END compute_certificate_create]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from pathlib import Path
16+
# [START compute_certificate_create_regional]
17+
from pprint import pprint
18+
from typing import Union
19+
20+
from googleapiclient import discovery
21+
22+
23+
def create_regional_certificate(
24+
project_id: str,
25+
region: str,
26+
certificate_file: Union[str, Path],
27+
private_key_file: Union[str, Path],
28+
certificate_name: str,
29+
description: str = "Certificate created from a code sample."
30+
) -> None:
31+
"""
32+
Create a regional SSL self-signed certificate within your Google Cloud project.
33+
34+
Args:
35+
project_id: project ID or project number of the Cloud project you want to use.
36+
region: name of the region you want to use.
37+
certificate_file: path to the file with the certificate you want to create in your project.
38+
private_key_file: path to the private key you used to sign the certificate with.
39+
certificate_name: name for the certificate once it's created in your project.
40+
description: description of the certificate.
41+
"""
42+
service = discovery.build("compute", "v1")
43+
44+
# Read the cert into memory
45+
with open(certificate_file) as f:
46+
_temp_cert = f.read()
47+
48+
# Read the private_key into memory
49+
with open(private_key_file) as f:
50+
_temp_key = f.read()
51+
52+
# Now that the certificate and private key are in memory, you can create the
53+
# certificate resource
54+
ssl_certificate_body = {
55+
"name": certificate_name,
56+
"description": description,
57+
"certificate": _temp_cert,
58+
"privateKey": _temp_key,
59+
}
60+
request = service.regionSslCertificates().insert(
61+
project=project_id, region=region, body=ssl_certificate_body
62+
)
63+
response = request.execute()
64+
pprint(response)
65+
66+
67+
# [END compute_certificate_create_regional]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==6.2.4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-api-python-client==2.34.0
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import os
15+
from pathlib import Path
16+
import time
17+
import uuid
18+
19+
from googleapiclient import discovery
20+
import pytest
21+
from pytest import fixture
22+
23+
from create_certificate import create_certificate
24+
from create_regional_certificate import create_regional_certificate
25+
26+
PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"]
27+
CERTIFICATE_FILE = Path(__file__).parent / "test_fixtures" / "certificate.pem"
28+
PRIVATE_KEY_FILE = Path(__file__).parent / "test_fixtures" / "test_key.pem"
29+
30+
31+
@fixture(scope="module")
32+
def api_service():
33+
service = discovery.build("compute", "v1")
34+
yield service
35+
36+
37+
@fixture
38+
def autodelete_certificate_name(api_service):
39+
cert_name = "test-certificate-" + uuid.uuid4().hex[:10]
40+
41+
yield cert_name
42+
43+
api_service.sslCertificates().delete(
44+
project=PROJECT_ID, sslCertificate=cert_name
45+
).execute()
46+
47+
48+
@fixture
49+
def autodelete_regional_certificate_name(api_service):
50+
cert_name = "test-certificate-" + uuid.uuid4().hex[:10]
51+
52+
yield cert_name, "europe-central2"
53+
54+
api_service.regionSslCertificates().delete(
55+
project=PROJECT_ID, sslCertificate=cert_name, region="europe-central2"
56+
).execute()
57+
58+
59+
def test_global_register(api_service, autodelete_certificate_name):
60+
create_certificate(
61+
PROJECT_ID, CERTIFICATE_FILE, PRIVATE_KEY_FILE, autodelete_certificate_name
62+
)
63+
time.sleep(2)
64+
certificates = api_service.sslCertificates().list(project=PROJECT_ID).execute()
65+
for certificate in certificates["items"]:
66+
if certificate["name"] == autodelete_certificate_name:
67+
break
68+
else:
69+
pytest.fail("Certificate wasn't created.")
70+
71+
72+
def test_regional_register(api_service, autodelete_regional_certificate_name):
73+
certificate_name, region_name = autodelete_regional_certificate_name
74+
75+
create_regional_certificate(
76+
PROJECT_ID, region_name, CERTIFICATE_FILE, PRIVATE_KEY_FILE, certificate_name
77+
)
78+
time.sleep(2)
79+
certificates = (
80+
api_service.regionSslCertificates()
81+
.list(project=PROJECT_ID, region=region_name)
82+
.execute()
83+
)
84+
for certificate in certificates["items"]:
85+
if certificate["name"] == certificate_name:
86+
break
87+
else:
88+
pytest.fail("Certificate wasn't created.")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIEKzCCAxOgAwIBAgIUBqe2Dqsf7G8nyLFLUt6AxeAzM8kwDQYJKoZIhvcNAQEL
3+
BQAwgacxCzAJBgNVBAYTAlBMMRQwEgYDVQQIDAtNYXpvd2llY2tpZTEPMA0GA1UE
4+
BwwGV2Fyc2F3MRwwGgYDVQQKDBNHb29nbGUgQ2xvdWQgUG9sYW5kMQ8wDQYDVQQL
5+
DAZEZXZSZWwxFTATBgNVBAMMDEdvb2dsZSBDbG91ZDErMCkGCSqGSIb3DQEJARYc
6+
ZG9udHdyaXRlaGVyZUBub3QtZ29vZ2xlLmNvbTAeFw0yMjAxMjAxNzEzMzlaFw0z
7+
MjAxMTgxNzEzMzlaMIGnMQswCQYDVQQGEwJQTDEUMBIGA1UECAwLTWF6b3dpZWNr
8+
aWUxDzANBgNVBAcMBldhcnNhdzEcMBoGA1UECgwTR29vZ2xlIENsb3VkIFBvbGFu
9+
ZDEPMA0GA1UECwwGRGV2UmVsMRUwEwYDVQQDDAxHb29nbGUgQ2xvdWQxKzApBgkq
10+
hkiG9w0BCQEWHGRvbnR3cml0ZWhlcmVAbm90LWdvb2dsZS5jb20wggEiMA0GCSqG
11+
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDX17w2+kv8o5xdwPN6iHpCbDyCpqCRDSE/
12+
WBfcnYgwCPLtJuL9DGNzJr0fCNVEGIxrw1omxZmHSrL1yy+6bEL1ZyXrU9jZpVXc
13+
t+12PcA/vfwczWX74HLfIuEq1So+LMgV8DCZrefhT/fy0bzIa2ZOlgOgvyCvIILB
14+
YamJUqiBSIah4g9kbIOptwfwDrpG6v3OV1F8EilLRt2V3mpFfu32orlLEPay5w8j
15+
jjhxQ0aD2kNFVZAzAyt7glwYHyEhmk4Cs0jq3WfeBRS8nvxu0kbszSePT4KQ7dme
16+
vTztgJ1ZA4TtSUOVd8DM1wIVZtPAMw7hHso4Z723hg6lWBkONArhAgMBAAGjTTBL
17+
MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMDEGA1UdEQQqMCiCEmV4YW1wbGUtZG9t
18+
YWluLmNvbYISZXhhbXBsZS1kb21haW4ubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAl
19+
/Pk5CKGSKgH9Ogd8KGcgJ/+ugiTt3t7GlHWyAHILJ7/71OzX+p/ixF1vTOuK8Efx
20+
20aqTo/cby72NGiXOI/tKaayS9lyOft27LocOZz8FUQS0FIoUZH0cH+rBgZSduEo
21+
OJhzn8z816r6wkfbZ+n8ndAw2OP0aE/L7PzYfHwRTfzhk1IpTtyBWKAWHxU8zHxi
22+
3vGaPi7Mwi+U4CaLMWVnF1xeG2yOxlVTjfN4znYawPwRGxATP+DY+UrtfNusKQ0b
23+
ilP7H5SlETPxzGcWI7M4MNRvm70C+wTp6rsbZAeDjM2GVRcJQVLQk3Sd7lG4eOhM
24+
KdJk8Pt391pfLNiFj00D
25+
-----END CERTIFICATE-----
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[req]
2+
default_bits = 2048
3+
req_extensions = extension_requirements
4+
distinguished_name = dn_requirements
5+
6+
[extension_requirements]
7+
basicConstraints = CA:FALSE
8+
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
9+
subjectAltName = @sans_list
10+
11+
[dn_requirements]
12+
countryName = Country Name (2 letter code)
13+
stateOrProvinceName = State or Province Name (full name)
14+
localityName = Locality Name (eg, city)
15+
0.organizationName = Organization Name (eg, company)
16+
organizationalUnitName = Organizational Unit Name (eg, section)
17+
commonName = Common Name (e.g. server FQDN or YOUR name)
18+
emailAddress = Email Address
19+
20+
[sans_list]
21+
DNS.1 = example-domain.com
22+
DNS.2 = example-domain.net
23+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE REQUEST-----
2+
MIIDSTCCAjECAQAwgacxCzAJBgNVBAYTAlBMMRQwEgYDVQQIDAtNYXpvd2llY2tp
3+
ZTEPMA0GA1UEBwwGV2Fyc2F3MRwwGgYDVQQKDBNHb29nbGUgQ2xvdWQgUG9sYW5k
4+
MQ8wDQYDVQQLDAZEZXZSZWwxFTATBgNVBAMMDEdvb2dsZSBDbG91ZDErMCkGCSqG
5+
SIb3DQEJARYcZG9udHdyaXRlaGVyZUBub3QtZ29vZ2xlLmNvbTCCASIwDQYJKoZI
6+
hvcNAQEBBQADggEPADCCAQoCggEBANfXvDb6S/yjnF3A83qIekJsPIKmoJENIT9Y
7+
F9ydiDAI8u0m4v0MY3MmvR8I1UQYjGvDWibFmYdKsvXLL7psQvVnJetT2NmlVdy3
8+
7XY9wD+9/BzNZfvgct8i4SrVKj4syBXwMJmt5+FP9/LRvMhrZk6WA6C/IK8ggsFh
9+
qYlSqIFIhqHiD2Rsg6m3B/AOukbq/c5XUXwSKUtG3ZXeakV+7faiuUsQ9rLnDyOO
10+
OHFDRoPaQ0VVkDMDK3uCXBgfISGaTgKzSOrdZ94FFLye/G7SRuzNJ49PgpDt2Z69
11+
PO2AnVkDhO1JQ5V3wMzXAhVm08AzDuEeyjhnvbeGDqVYGQ40CuECAwEAAaBcMFoG
12+
CSqGSIb3DQEJDjFNMEswCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwMQYDVR0RBCow
13+
KIISZXhhbXBsZS1kb21haW4uY29tghJleGFtcGxlLWRvbWFpbi5uZXQwDQYJKoZI
14+
hvcNAQELBQADggEBAKdC1y10fECmLFmXEtM1Lkb0IhjJosMKJ3OgBDujM9+S7STA
15+
YTvf05gEQtMhzbZ8ymRbXRFT4jQ6vdlILmZ/eDFwEnoIRQ29fZChNssv97YTv8wO
16+
Ej3JpxWu2BZQMNibbBl+wmmghgG3EHELZz7WRL0/qdPMKO3YK9Lgt5yTgbJBG+tM
17+
QTGHI1BjR0Ax0KdbC9F1pSkzobc6t6QiLWIKLvrOxp1XXBiOyY8n5t+h9hV0Mogz
18+
BfC5aEEobETGkcZWDybqVgG0I01PdqE/VJe76+xkNj+zV7v0szdcIGfXKrel78ew
19+
x1ClYyK7VAlB3da8cFPQeEbEY6NKMXIuvWBnCtg=
20+
-----END CERTIFICATE REQUEST-----
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEpAIBAAKCAQEA19e8NvpL/KOcXcDzeoh6Qmw8gqagkQ0hP1gX3J2IMAjy7Sbi
3+
/Qxjcya9HwjVRBiMa8NaJsWZh0qy9csvumxC9Wcl61PY2aVV3Lftdj3AP738HM1l
4+
++By3yLhKtUqPizIFfAwma3n4U/38tG8yGtmTpYDoL8gryCCwWGpiVKogUiGoeIP
5+
ZGyDqbcH8A66Rur9zldRfBIpS0bdld5qRX7t9qK5SxD2sucPI444cUNGg9pDRVWQ
6+
MwMre4JcGB8hIZpOArNI6t1n3gUUvJ78btJG7M0nj0+CkO3Znr087YCdWQOE7UlD
7+
lXfAzNcCFWbTwDMO4R7KOGe9t4YOpVgZDjQK4QIDAQABAoIBAQCqk9syE7MTsPV1
8+
fnStRMhiUAmuMyM4HwlEd0k8V972H0xksVO4Kh86NMZHjYKFs2TeEV/gvk7sBdPS
9+
vkY07TQpnt/vz67Tqn9l1JG83WZeubVRyd2sJiCCSZ1rbVVaF6f09oJiIXbcsIdC
10+
hhDMz1vmBVZOpl2dKXNMgvMqDIIQ0J3SYCC91f4OXzMY6cNq77iU6a8oAvHqV81U
11+
eZRVxcFF7jiHJCZCI9HeWyHxciKaeE/VHX7jB3S/Qlvwa6kv7gxaG3tEAfqrjRmK
12+
NR2sfTBvtFcnrczIdIqGNyRT/zdEmbeO24Qo1ZaIVm9iiIsMvmo2IughvNL8Pbk2
13+
06HHSKZFAoGBAOuEIKfkbZHrFh8EtWtVoRTBkfOJX1Fi/kQizsqMpK8pWcmcK/4m
14+
8mVk7Etqlow01Mspw6C/CWYyfiDh9yHWJaUdCzPXiYrfdYZAXvct3lacdUM5ITuJ
15+
u8SU5lZGw+gC+RhtXfyyU8C+bsXkg8WM51da24ZMsbDxS+JXYMc+rDtnAoGBAOqd
16+
kgR969YO+MPUDy4mGzVqz3rBg0UOhu3cRJntbFaJ3kY6n2jYONVeV75ajstRkn6K
17+
gi7L+ETnUAcFqPDW1xVZp2dAVIRtcVOFkF2VKcpW1ZJvZNulQiGjguQqF9JdpIsD
18+
bjXZDcBGfiSMyG+UwTJLdpMgC5NiixGgNFHuAWJ3AoGAU95HasJTqoTW6dDZchGa
19+
PTP5b4pZ4TepaEYk8chH1QCassrkd6sS4ryf0PNyDRe7N2X1/kZJaJVOiRMu2GPU
20+
IApJtPpqRoPw7A/8QXWaGam5sGilxvfzX7vOkqa8mOCGKAa6U4SFgrvN4rbPngfh
21+
UiBO0HJ7TJGA/mczVYCiAL0CgYA0sxo2ehZ8abaFPl/+jL612/0o5MjYvS+fxEeA
22+
j+0y7xsHiWl/QnpZqyxobK0AjJ0sYW5mlph42cCHI0VUe92qRQ4uSivx5yd6jFjm
23+
PHg7pA+rKexszg0xwynGmJHrRe+M7kNWQyAsnWj+SsVHExHmez7yQ1N2Ur9MQUEf
24+
WifjdwKBgQCy8OzFjh7u44T9KauHwEvtCNp3N/WCZH4AUHygYoa8wUrWBuGWG+hM
25+
7dW9qkJp7bUmH2KakKLDdYL+uOMvdYslBVgDFoN7osl2tjL7HIcOJVKH5VYzt9+c
26+
nml67R6p+DmTvR9IL/5s8pUk3Js+Cdjj6N0Qo5lqxr0tfHHYXBd6Xw==
27+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)