certbot-oci-certs 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- certbot_oci_certs/__init__.py +1 -0
- certbot_oci_certs/installer.py +313 -0
- certbot_oci_certs-0.1.0.dist-info/METADATA +186 -0
- certbot_oci_certs-0.1.0.dist-info/RECORD +8 -0
- certbot_oci_certs-0.1.0.dist-info/WHEEL +5 -0
- certbot_oci_certs-0.1.0.dist-info/entry_points.txt +2 -0
- certbot_oci_certs-0.1.0.dist-info/licenses/LICENSE.txt +35 -0
- certbot_oci_certs-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1 @@
|
|
1
|
+
"""Certbot plug-in for Oracle Cloud Infrastructure (OCI) Certs Management Service."""
|
@@ -0,0 +1,313 @@
|
|
1
|
+
"""Certbot Installer for OCI Certificates service."""
|
2
|
+
import logging
|
3
|
+
from distutils.command.config import config
|
4
|
+
from itertools import chain
|
5
|
+
|
6
|
+
from certbot import errors
|
7
|
+
from certbot import interfaces
|
8
|
+
from certbot.plugins import common
|
9
|
+
|
10
|
+
import oci
|
11
|
+
|
12
|
+
from certbot.errors import PluginError, Error
|
13
|
+
from pycparser.ply.yacc import resultlimit
|
14
|
+
|
15
|
+
#import oci.certificates_management.CertificatesManagementClient
|
16
|
+
|
17
|
+
logger = logging.getLogger(__name__)
|
18
|
+
# import sys
|
19
|
+
# logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
|
20
|
+
|
21
|
+
class OCIInstaller(common.Plugin, interfaces.Installer):
|
22
|
+
description = "OCI Certificates Service installer. Uploads the acquired certificate into the OCI Certificates Service - either as a new certificate or as a new certificate version."
|
23
|
+
certificate_main_domain = None
|
24
|
+
certificate_name = None
|
25
|
+
certificate_id = None
|
26
|
+
compartment_id = None
|
27
|
+
|
28
|
+
# I will wind up refactoring this later but for now I'm copy/pasting this from the DNS plug-in. And it uses self.credentials". So so do I here
|
29
|
+
credentials = None
|
30
|
+
|
31
|
+
# later on I won't save the credentials / config and instead just hang on to the client handle
|
32
|
+
certificates_client = None
|
33
|
+
certificates_management_client = None
|
34
|
+
|
35
|
+
@classmethod
|
36
|
+
def add_parser_arguments(cls, add):
|
37
|
+
add("compartment-id",help="Compartment OCID")
|
38
|
+
add("certificate-id",help="Certificate OCID")
|
39
|
+
add("certificate-name",help="Certificate Name")
|
40
|
+
|
41
|
+
add('auth-mode', help='Authentication mode - one of "configfile", "instance", "cloudshell"',
|
42
|
+
**{
|
43
|
+
"default": "configfile",
|
44
|
+
"choices": ['configfile', 'instance', 'cloudshell']
|
45
|
+
}
|
46
|
+
)
|
47
|
+
|
48
|
+
add('configfile', help="OCI CLI Configuration file (for authmode=configfile).")
|
49
|
+
add('profile', help="OCI configuration profile (in OCI configuration file)",**{"default":"DEFAULT"})
|
50
|
+
|
51
|
+
|
52
|
+
def __init__(self, *args, **kwargs):
|
53
|
+
super(OCIInstaller, self).__init__(*args, **kwargs)
|
54
|
+
|
55
|
+
# then initialize the SDK
|
56
|
+
match self.conf('auth-mode'):
|
57
|
+
case "configfile":
|
58
|
+
self.credentials = {
|
59
|
+
"config": oci.config.from_file(profile_name=self.conf('profile')),
|
60
|
+
"signer": None,
|
61
|
+
}
|
62
|
+
case "instance":
|
63
|
+
self.credentials = {
|
64
|
+
"config": None,
|
65
|
+
"signer": oci.auth.signers.InstancePrincipalsSecurityTokenSigner(),
|
66
|
+
}
|
67
|
+
|
68
|
+
case "cloudshell":
|
69
|
+
import os
|
70
|
+
self.credentials = {
|
71
|
+
"config": oci.config.from_file(
|
72
|
+
file_location=os.getenv("OCI_CLI_CONFIG_FILE"),
|
73
|
+
profile_name="DEFAULT"
|
74
|
+
# I am fairly certain that DEFAULT is always the right profile for cloud shell
|
75
|
+
# if not then this is the relevant code
|
76
|
+
# profile_name=self.conf('profile')
|
77
|
+
),
|
78
|
+
# "signer": oci.auth.signers.SecurityTokenSigner(),
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
# i may or may not need this
|
83
|
+
identity_client = None
|
84
|
+
|
85
|
+
if self.credentials["signer"]:
|
86
|
+
signer = self.credentials["signer"]
|
87
|
+
identity_client = oci.identity.IdentityClient(self.credentials["config"], signer=signer)
|
88
|
+
self.certificates_client = oci.certificates.CertificatesClient(self.credentials["config"], signer=signer)
|
89
|
+
self.certificates_management_client = oci.certificates_management.CertificatesManagementClient(self.credentials["config"], signer=signer)
|
90
|
+
else:
|
91
|
+
identity_client = oci.identity.IdentityClient(self.credentials["config"])
|
92
|
+
self.certificates_management_client = oci.certificates_management.CertificatesManagementClient(self.credentials["config"])
|
93
|
+
|
94
|
+
# since we bothered to create an identity client let's use it to check that we can even talk to OCI control plane
|
95
|
+
# compartments are not subject to access control so just ask for the tenancy compartment
|
96
|
+
try:
|
97
|
+
identity_client.get_compartment(self.credentials["config"]["tenancy"])
|
98
|
+
except Exception as e:
|
99
|
+
logger.error("Failed to retrieve tenancy information. Check your configuration")
|
100
|
+
logger(e)
|
101
|
+
raise errors.PluginError(Exception("OCI configuration not valid"))
|
102
|
+
|
103
|
+
# copy these for convenience
|
104
|
+
compartment_id = self.conf("compartment-id")
|
105
|
+
certificate_id = self.conf("certificate-id")
|
106
|
+
certificate_name = self.conf("certificate-name")
|
107
|
+
|
108
|
+
|
109
|
+
# before we try to do anything we need to figure out the current situation vis a vis the cert in certs service
|
110
|
+
# possible cases:
|
111
|
+
# 1. they provided the certificate OCID
|
112
|
+
# 2. they provided the compartment OCID but no name for the certificate
|
113
|
+
# 3. they provided the compartment OCID and a name for the certificate
|
114
|
+
|
115
|
+
# Case by case
|
116
|
+
# 1. they provided the certificate OCID
|
117
|
+
if certificate_id:
|
118
|
+
logger.info("Certificate ID {} provided".format(certificate_id))
|
119
|
+
|
120
|
+
# if they provide a certificate ID then the other fields should be ignored
|
121
|
+
# using assert here will wind up raising a fatal exception
|
122
|
+
# TODO: decide if I want to do that
|
123
|
+
assert compartment_id == None
|
124
|
+
assert certificate_name == None
|
125
|
+
|
126
|
+
# NOTE: this means that we need certbot to run with permission to get the existing certificate.
|
127
|
+
# This seems OK to me at this point. But I am willing to be convinced otherwise.
|
128
|
+
# If you are reading this and have an opinion you know how to find me.
|
129
|
+
logger.debug("Looking for existing certificate with OCID {}".format(certificate_id))
|
130
|
+
response = self.certificates_management_client.get_certificate(certificate_id)
|
131
|
+
logger.debug("Returned from getting certificate.")
|
132
|
+
|
133
|
+
if len(response.data.items) != 1:
|
134
|
+
import json
|
135
|
+
logger.error("Failed to locate certificate. Response data: {}".format(json.dumps(oci.util.to_dict(response.data))))
|
136
|
+
raise PluginError(Exception("Failure attempting to locate certificate with specified OCID {}".format(certificate_id)))
|
137
|
+
|
138
|
+
# NOTE: we don't set self.compartment_id or self.certificate_name because we're ***NOT***
|
139
|
+
# going to move the existing certificate or change its name.
|
140
|
+
self.certificate_id = certificate_id
|
141
|
+
|
142
|
+
# 2. they provided the compartment OCID (but no name for the certificate)
|
143
|
+
# in which case we're going to make one up
|
144
|
+
# 3. they provided the compartment OCID and a name for the certificate
|
145
|
+
# in which case we have to go find the existing cert with that name.
|
146
|
+
# Q: should we scold them and tell them to use the OCID because that's more performant?
|
147
|
+
if compartment_id:
|
148
|
+
self.compartment_id = compartment_id
|
149
|
+
if not certificate_name:
|
150
|
+
# NOTE: I was going to let this fall through and list certificates in the compartment.
|
151
|
+
# But there exists a possibility, however remote, that someone might allow certbot to INSTALL
|
152
|
+
# a certificate, but not list existing ones in the compartment.
|
153
|
+
logger.debug("NO certificate name provided as argument. One will be automatically generated for you.")
|
154
|
+
|
155
|
+
|
156
|
+
else:
|
157
|
+
logger.info("Certificate name '{}' provided".format(certificate_name))
|
158
|
+
|
159
|
+
try:
|
160
|
+
# Try to find a certificate with that name
|
161
|
+
# NOTE: we may ot may find one with that name. A response with **EITHER** 0 or 1 items is A-OK
|
162
|
+
logger.info("Listing certificates in compartment {} with name '{}'".format(compartment_id,certificate_name))
|
163
|
+
response = self.certificates_management_client.list_certificates(compartment_id=compartment_id, name=certificate_name)
|
164
|
+
logger.debug("Returned from listing certificates")
|
165
|
+
|
166
|
+
# there had better be either zero or only one!
|
167
|
+
if len(response.data.items) == 0:
|
168
|
+
logger.info("Did not find certificate with name '{}'. The certificate will be uploaded as a new certificate to compartment {} with that name".format(certificate_name,compartment_id))
|
169
|
+
|
170
|
+
elif len(response.data.items) == 1:
|
171
|
+
logger.debug("Getting certificate OCID from response data")
|
172
|
+
self.certificate_id = response.data.items[0].id
|
173
|
+
logger.info("Existing certificate with name {} in compartment {} found. Certificate OCID is {}".format(certificate_name, compartment_id, certificate_id))
|
174
|
+
|
175
|
+
else:
|
176
|
+
# This should NOT happen because certificate names (OCI names, not domain name or whatever) are unique within a single compartment!
|
177
|
+
# But good programmers look both ways before crossing a one way street.
|
178
|
+
# So...
|
179
|
+
# also I could just do this with an assert. I should probably start doing that.
|
180
|
+
import json
|
181
|
+
raise PluginError(Exception("Expected one matching certificate but response data contained {}: {}".format(len(response.data.items), json.dumps(oci.util.to_dict(response.data)))))
|
182
|
+
|
183
|
+
except Exception as e:
|
184
|
+
logger.error("Exception occurred attempting to list existing certificates in compartment {}".format(compartment_id))
|
185
|
+
raise PluginError(Exception("Exception encountered trying to locate certificate with name {} in compartment {}".format(certificate_name,compartment_id)))
|
186
|
+
|
187
|
+
|
188
|
+
else:
|
189
|
+
raise PluginError(Error("At a minimum you must provided either (A) the OCID for an existing certificate (via --oci-certificate-id) or (B) the OCID of a compartment"))
|
190
|
+
|
191
|
+
logger.info("Plugin initialized")
|
192
|
+
|
193
|
+
def prepare(self):
|
194
|
+
pass
|
195
|
+
|
196
|
+
def more_info(self):
|
197
|
+
return "This plug-in installs the certificate into OCI Certificates Service"
|
198
|
+
|
199
|
+
def get_all_names(self):
|
200
|
+
# from the docs: "Returns all names that may be authenticated."
|
201
|
+
# what does that mean?
|
202
|
+
# ¯\_(ツ)_/¯
|
203
|
+
return []
|
204
|
+
|
205
|
+
def deploy_cert(self, domain, cert_path, key_path, chain_path, fullchain_path):
|
206
|
+
"""
|
207
|
+
Actually upload Certificate to OCI Certificates service
|
208
|
+
"""
|
209
|
+
|
210
|
+
def readFile(file):
|
211
|
+
with open(file) as f:
|
212
|
+
return (f.read())
|
213
|
+
|
214
|
+
# this code is cribbed from the CLI
|
215
|
+
# TODO: change this to use UpdateCertificateByImportingConfigDetails
|
216
|
+
# i.e.:
|
217
|
+
# from oci.certificates_management.models import UpdateCertificateByImportingConfigDetails
|
218
|
+
|
219
|
+
_details = {}
|
220
|
+
_details['certificateConfig'] = {}
|
221
|
+
_details['certificateConfig']['configType'] = 'IMPORTED'
|
222
|
+
_details['certificateConfig']['certChainPem'] = readFile(chain_path)
|
223
|
+
_details['certificateConfig']['privateKeyPem'] = readFile(key_path)
|
224
|
+
_details['certificateConfig']['certificatePem'] = readFile(cert_path)
|
225
|
+
|
226
|
+
response = None
|
227
|
+
|
228
|
+
if self.certificate_id:
|
229
|
+
logger.info("Preparing certificate as new version of existing certificate with OCID {}".format(self.certificate_id))
|
230
|
+
|
231
|
+
response = self.certificates_management_client.update_certificate(
|
232
|
+
certificate_id=self.certificate_id,
|
233
|
+
update_certificate_details=_details,
|
234
|
+
**{}
|
235
|
+
)
|
236
|
+
|
237
|
+
logger.debug("Back from update call")
|
238
|
+
|
239
|
+
else:
|
240
|
+
# if there's no name then make one
|
241
|
+
# NOTE: we waited until now (instead of doing it during the init) because you don't have the cert name then
|
242
|
+
|
243
|
+
# the domain here is /probably/ a good name for the certificate in OCI Certs.
|
244
|
+
|
245
|
+
# TODO: think about whether we should do another search to see if a cert with that name exists
|
246
|
+
# Reasons to do that: that's probably what they want
|
247
|
+
# Reasons to not: if that's what they wanted they would have told us that
|
248
|
+
|
249
|
+
# this code tacks on a timestamp. I decided NOT to do that
|
250
|
+
# I'm leaving the code here but commented out:
|
251
|
+
# (1) as a reminder that I changed my mind about this
|
252
|
+
# (2) as a warning to others that I changed my mind once about this already
|
253
|
+
# (3) in case I change my mind again
|
254
|
+
# from datetime import datetime
|
255
|
+
# name = "certbot-imported-cert-" + domain + datetime.now().strftime("-%Y%m%dT%H%M%S")
|
256
|
+
|
257
|
+
# name = "certbot-imported-cert-" + domain
|
258
|
+
|
259
|
+
name = domain
|
260
|
+
logger.debug("Automatically generated certificate name '{}'.".format(name))
|
261
|
+
|
262
|
+
_details['name'] = name
|
263
|
+
_details['compartmentId'] = self.compartment_id
|
264
|
+
_details['description'] = "Certificate created via import using the certbot OCI Certificate Installer plugin"
|
265
|
+
|
266
|
+
response = self.certificates_management_client.create_certificate(
|
267
|
+
create_certificate_details=_details,
|
268
|
+
**{}
|
269
|
+
)
|
270
|
+
logger.debug("Back from create certificate call")
|
271
|
+
|
272
|
+
import json
|
273
|
+
logger.debug("Response data: {}".format(json.dumps(oci.util.to_dict(response.data))))
|
274
|
+
|
275
|
+
def enhance(self, domain, enhancement, options=None): # pylint: disable=missing-docstring,no-self-use
|
276
|
+
pass # pragma: no cover
|
277
|
+
|
278
|
+
def supported_enhancements(self): # pylint: disable=missing-docstring,no-self-use
|
279
|
+
return [] # pragma: no cover
|
280
|
+
|
281
|
+
def get_all_certs_keys(self): # pylint: disable=missing-docstring,no-self-use
|
282
|
+
pass # pragma: no cover
|
283
|
+
|
284
|
+
|
285
|
+
def save(self, title=None, temporary=False):
|
286
|
+
pass
|
287
|
+
|
288
|
+
def rollback_checkpoints(self, rollback=1):
|
289
|
+
pass
|
290
|
+
|
291
|
+
def recovery_routine(self):
|
292
|
+
pass
|
293
|
+
|
294
|
+
def view_config_changes(self):
|
295
|
+
pass
|
296
|
+
|
297
|
+
def config_test(self):
|
298
|
+
pass
|
299
|
+
|
300
|
+
def restart(self):
|
301
|
+
pass
|
302
|
+
|
303
|
+
def renew_deploy(self, lineage, *args, **kwargs): # pylint: disable=missing-docstring,no-self-use
|
304
|
+
"""
|
305
|
+
Renew certificates when calling `certbot renew`
|
306
|
+
"""
|
307
|
+
|
308
|
+
# Run deploy_cert with the lineage params
|
309
|
+
self.deploy_cert(lineage.names()[0], lineage.cert_path, lineage.key_path, lineage.chain_path, lineage.fullchain_path)
|
310
|
+
|
311
|
+
return
|
312
|
+
|
313
|
+
interfaces.RenewDeployer.register(OCIInstaller)
|
@@ -0,0 +1,186 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: certbot_oci_certs
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: OCI Certs Management Service plugin for Certbot
|
5
|
+
Home-page: https://github.com/therealcmj/certbot-oci-certs
|
6
|
+
Author: Chris Johnson
|
7
|
+
Author-email: christopher.johnson@oracle.com
|
8
|
+
License: Apache License 2.0
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
10
|
+
Classifier: Environment :: Plugins
|
11
|
+
Classifier: Intended Audience :: System Administrators
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
14
|
+
Classifier: Programming Language :: Python
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
17
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
18
|
+
Classifier: Topic :: Security
|
19
|
+
Classifier: Topic :: System :: Installation/Setup
|
20
|
+
Classifier: Topic :: System :: Networking
|
21
|
+
Classifier: Topic :: System :: Systems Administration
|
22
|
+
Classifier: Topic :: Utilities
|
23
|
+
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
|
24
|
+
Description-Content-Type: text/x-rst
|
25
|
+
License-File: LICENSE.txt
|
26
|
+
Requires-Dist: acme>=1.7.0
|
27
|
+
Requires-Dist: certbot>=1.7.0
|
28
|
+
Requires-Dist: setuptools
|
29
|
+
Requires-Dist: mock
|
30
|
+
Requires-Dist: oci
|
31
|
+
Dynamic: author
|
32
|
+
Dynamic: author-email
|
33
|
+
Dynamic: classifier
|
34
|
+
Dynamic: description
|
35
|
+
Dynamic: description-content-type
|
36
|
+
Dynamic: home-page
|
37
|
+
Dynamic: license
|
38
|
+
Dynamic: license-file
|
39
|
+
Dynamic: requires-dist
|
40
|
+
Dynamic: requires-python
|
41
|
+
Dynamic: summary
|
42
|
+
|
43
|
+
certbot-oci-certs
|
44
|
+
=================
|
45
|
+
|
46
|
+
Oracle Cloud Infrastructure (OCI) Installer plugin for Certbot.
|
47
|
+
|
48
|
+
This plugin automates the process of installing a certificate acquired by certbot
|
49
|
+
into OCI Certificates Management Service.
|
50
|
+
|
51
|
+
For more information on the OCI Certificates service pleae see the official documentation at
|
52
|
+
https://docs.oracle.com/en-us/iaas/Content/certificates/home.htm
|
53
|
+
|
54
|
+
Configuration:
|
55
|
+
--------------
|
56
|
+
|
57
|
+
Install and configure the OCI CLI. See https://docs.cloud.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm
|
58
|
+
for details.
|
59
|
+
|
60
|
+
To use this installer you will need:
|
61
|
+
|
62
|
+
* an OCI account with adequate permission to Create / Update / Delete certificates stored in the Certificates Management Service
|
63
|
+
|
64
|
+
Installation
|
65
|
+
------------
|
66
|
+
|
67
|
+
I haven't published this in PyPI yet. So for the time being you need to install from source.
|
68
|
+
|
69
|
+
::
|
70
|
+
|
71
|
+
git clone git@github.com:therealcmj/certbot-oci-certs.git
|
72
|
+
cd certbot-oci-certs
|
73
|
+
pip install .
|
74
|
+
|
75
|
+
|
76
|
+
or
|
77
|
+
|
78
|
+
::
|
79
|
+
|
80
|
+
git clone git@github.com:therealcmj/certbot-oci-certs.git
|
81
|
+
pip install ./certbot-oci-certs
|
82
|
+
|
83
|
+
|
84
|
+
Development
|
85
|
+
-----------
|
86
|
+
|
87
|
+
If you want to work on the code you should create a virtual environment and install it there:
|
88
|
+
|
89
|
+
::
|
90
|
+
|
91
|
+
git clone git@github.com:therealcmj/certbot-oci-certs.git
|
92
|
+
cd certbot-oci-certs
|
93
|
+
virtualenv dev
|
94
|
+
. ./dev/bin/activate
|
95
|
+
pip install -e .
|
96
|
+
|
97
|
+
You can then use your IDE as normal on the live code.
|
98
|
+
|
99
|
+
To use the debugger be sure to choose the correct virtual environment. For PyCharm go to Debug, Edit Configurations
|
100
|
+
and then update the Interpreter to point to the newly created Virtual Environment.
|
101
|
+
|
102
|
+
Arguments
|
103
|
+
---------
|
104
|
+
|
105
|
+
As of this writing this plug-in supports the following arguments on certbot's command line:
|
106
|
+
|
107
|
+
::
|
108
|
+
|
109
|
+
--oci-certificate-id OCI_CERTIFICATE_ID
|
110
|
+
Certificate OCID (default: None)
|
111
|
+
--oci-certificate-name OCI_CERTIFICATE_NAME
|
112
|
+
Certificate Name (default: None)
|
113
|
+
--oci-compartment-id OCI_COMPARTMENT_ID
|
114
|
+
Compartment OCID (default: None)
|
115
|
+
--oci-auth-mode {configfile,instance,cloudshell}
|
116
|
+
Authentication mode - one of "configfile", "instance", "cloudshell" (default: configfile)
|
117
|
+
--oci-configfile OCI_CONFIGFILE
|
118
|
+
OCI CLI Configuration file (for authmode=configfile). (default: None)
|
119
|
+
--oci-profile OCI_PROFILE
|
120
|
+
OCI configuration profile (in OCI configuration file) (default: DEFAULT)
|
121
|
+
|
122
|
+
|
123
|
+
You can always get a list of the available arguments by running
|
124
|
+
|
125
|
+
::
|
126
|
+
|
127
|
+
certbot installer -h oci
|
128
|
+
|
129
|
+
Examples
|
130
|
+
--------
|
131
|
+
|
132
|
+
Assuming you have previously acquired a certificate for demosite.ociateam.com
|
133
|
+
(perhaps using the certbot-dns-oci plug-in)
|
134
|
+
you can install it via:
|
135
|
+
|
136
|
+
|
137
|
+
::
|
138
|
+
|
139
|
+
certbot install \
|
140
|
+
--logs-dir logs --work-dir work --config-dir config \
|
141
|
+
--installer oci \
|
142
|
+
--oci-compartment $MYOCICOMPARTMENT \
|
143
|
+
--cert-path demosite.ociateam.com/cert.pem \
|
144
|
+
--key-path demosite.ociateam.com/privkey.pem \
|
145
|
+
--chain-path demosite.ociateam.com/chain.pem \
|
146
|
+
-d demosite.ociateam.com
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
If you want to acquire a certificate AND install it in one go using both of my plug-ins you can do that too...
|
151
|
+
|
152
|
+
::
|
153
|
+
|
154
|
+
CERTNAME=demo$$.ociateam.com ; \
|
155
|
+
certbot run \
|
156
|
+
--test-cert \
|
157
|
+
--logs-dir logs --work-dir work --config-dir config \
|
158
|
+
--authenticator dns-oci \
|
159
|
+
--installer oci \
|
160
|
+
--oci-compartment $MYOCICOMPARTMENT \
|
161
|
+
--oci-certificate-name $CERTNAME \
|
162
|
+
--debug \
|
163
|
+
-d $CERTNAME
|
164
|
+
|
165
|
+
|
166
|
+
And to renew (just that one certificate) later it's just:
|
167
|
+
|
168
|
+
::
|
169
|
+
|
170
|
+
CERTNAME=demo$$.ociateam.com ; \
|
171
|
+
certbot renew \
|
172
|
+
--test-cert \
|
173
|
+
--logs-dir logs --work-dir work --config-dir config \
|
174
|
+
--debug \
|
175
|
+
--cert-name $CERTNAME
|
176
|
+
|
177
|
+
|
178
|
+
CAUTION:
|
179
|
+
--------
|
180
|
+
|
181
|
+
Please do remember tat "certbot renew" tries to renew all certs nearing expiration. If you use the
|
182
|
+
--oci-certificate-name command line argument when running "certbot renew" you're going to make a mess of things.
|
183
|
+
So be cautious and renew certs one by one OR remember to leave that command line argument off!
|
184
|
+
|
185
|
+
YOU HAVE BEEN WARNED.
|
186
|
+
|
@@ -0,0 +1,8 @@
|
|
1
|
+
certbot_oci_certs/__init__.py,sha256=4I8n0MnRbQlnqCMmSJLAoN8OCipmTRk0KS7RqGUbVmY,86
|
2
|
+
certbot_oci_certs/installer.py,sha256=QeSW4Br746T2v8CJ5PY_gWg0U_czJFNoP0Qju3xYVRE,14601
|
3
|
+
certbot_oci_certs-0.1.0.dist-info/licenses/LICENSE.txt,sha256=1KQsyLaCuLy7_mruVDbako7EHDMf2ykPJLA3a1_xM8g,1867
|
4
|
+
certbot_oci_certs-0.1.0.dist-info/METADATA,sha256=cyDWnEFkMy2R9Oi1JBFgEuIYW9WH86OAo6tLWHHOyjw,5428
|
5
|
+
certbot_oci_certs-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
+
certbot_oci_certs-0.1.0.dist-info/entry_points.txt,sha256=PT3jR9PsuzhraJQdy630GQ8NJsJAZRLZYluGtPVGEnI,65
|
7
|
+
certbot_oci_certs-0.1.0.dist-info/top_level.txt,sha256=oks_XOIzKufM11BNZ3h6v43736th6im0aMB2ECH2unQ,18
|
8
|
+
certbot_oci_certs-0.1.0.dist-info/RECORD,,
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Copyright (c) 2018, 2024 Oracle and/or its affiliates. All rights reserved.
|
2
|
+
|
3
|
+
The Universal Permissive License (UPL), Version 1.0
|
4
|
+
|
5
|
+
Subject to the condition set forth below, permission is hereby granted to any
|
6
|
+
person obtaining a copy of this software, associated documentation and/or data
|
7
|
+
(collectively the "Software"), free of charge and under any and all copyright
|
8
|
+
rights in the Software, and any and all patent rights owned or freely
|
9
|
+
licensable by each licensor hereunder covering either (i) the unmodified
|
10
|
+
Software as contributed to or provided by such licensor, or (ii) the Larger
|
11
|
+
Works (as defined below), to deal in both
|
12
|
+
|
13
|
+
(a) the Software, and
|
14
|
+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
|
15
|
+
one is included with the Software (each a "Larger Work" to which the Software
|
16
|
+
is contributed by such licensors),
|
17
|
+
|
18
|
+
without restriction, including without limitation the rights to copy, create
|
19
|
+
derivative works of, display, perform, and distribute the Software and make,
|
20
|
+
use, sell, offer for sale, import, export, have made, and have sold the
|
21
|
+
Software and the Larger Work(s), and to sublicense the foregoing rights on
|
22
|
+
either these or other terms.
|
23
|
+
|
24
|
+
This license is subject to the following condition:
|
25
|
+
The above copyright notice and either this complete permission notice or at
|
26
|
+
a minimum a reference to the UPL must be included in all copies or
|
27
|
+
substantial portions of the Software.
|
28
|
+
|
29
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
30
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
31
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
32
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
33
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
34
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
35
|
+
SOFTWARE.
|
@@ -0,0 +1 @@
|
|
1
|
+
certbot_oci_certs
|