Additional work

This commit is contained in:
Curtis Castrapel
2018-04-30 10:48:48 -07:00
parent 48dde287d8
commit 3e64dd4653
8 changed files with 125 additions and 21 deletions

View File

@ -74,7 +74,14 @@ class CertificateInputSchema(CertificateCreationSchema):
dns_provider = fields.Nested(DnsProviderSchema, missing={}, required=False, allow_none=True)
csr = fields.String(validate=validators.csr)
key_type = fields.String(validate=validate.OneOf(['RSA2048', 'RSA4096']), missing='RSA2048')
key_type = fields.String(
validate=validate.OneOf(
['RSA2048', 'RSA4096', 'ECCPRIME192V1', 'ECCPRIME256V1', 'ECCSECP192R1', 'ECCSECP224R1',
'ECCSECP256R1', 'ECCSECP384R1', 'ECCSECP521R1', 'ECCSECP256K1','ECCSECT163K1', 'ECCSECT233K1',
'ECCSECT283K1', 'ECCSECT409K1', 'ECCSECT571K1', 'ECCSECT163R2', 'ECCSECT233R1', 'ECCSECT283R1',
'ECCSECT409R1', 'ECCSECT571R2']),
missing='RSA2048')
notify = fields.Boolean(default=True)
rotation = fields.Boolean()

View File

@ -2,17 +2,24 @@
.. module: lemur.pending_certificates.cli
.. moduleauthor:: James Chuong <jchuong@instartlogic.com>
.. moduleauthor:: Curtis Castrapel <ccastrapel@netflix.com>
"""
from flask_script import Manager
from multiprocessing import Pool
from lemur.pending_certificates import service as pending_certificate_service
from lemur.plugins.base import plugins
from lemur.users import service as user_service
manager = Manager(usage="Handles pending certificate related tasks.")
agents = 20
# Need to call this multiple times and store status of the cert in DB. If it is being worked on by a worker, and which
# worker.
# Then open up an arbitrary number of copies of this? every minute??
# Or instead how about you send in a list of all pending certificates, make all the dns changes at once, then loop
# through and wait for each one to complete?
@manager.option('-i', dest='ids', action='append', help='IDs of pending certificates to fetch')
def fetch(ids):
"""
@ -22,10 +29,10 @@ def fetch(ids):
ids: a list of ids of PendingCertificates (passed in by manager options when run as CLI)
`python manager.py pending_certs fetch -i 123 321 all`
"""
new = 0
failed = 0
pending_certs = pending_certificate_service.get_pending_certs(ids)
user = user_service.get_by_username('lemur')
new = 0
failed = 0
for cert in pending_certs:
authority = plugins.get(cert.authority.plugin_name)
@ -43,6 +50,40 @@ def fetch(ids):
print(
"[+] Certificates: New: {new} Failed: {failed}".format(
new=new,
failed=failed
failed=failed,
)
)
def fetch_all():
"""
Attempt to get full certificates for each pending certificate listed.
Args:
ids: a list of ids of PendingCertificates (passed in by manager options when run as CLI)
`python manager.py pending_certs fetch -i 123 321 all`
"""
pending_certs = pending_certificate_service.get_pending_certs('all')
user = user_service.get_by_username('lemur')
new = 0
failed = 0
certs = authority.get_ordered_certificates(pending_certs)
for cert in certs:
authority = plugins.get(cert.authority.plugin_name)
real_cert = authority.get_ordered_certificate(cert)
if real_cert:
# If a real certificate was returned from issuer, then create it in Lemur and delete
# the pending certificate
pending_certificate_service.create_certificate(cert, real_cert, user)
pending_certificate_service.delete(cert)
# add metrics to metrics extension
new += 1
else:
pending_certificate_service.increment_attempt(cert)
failed += 1
print(
"[+] Certificates: New: {new} Failed: {failed}".format(
new=new,
failed=failed,
)
)

View File

@ -236,6 +236,49 @@ class ACMEIssuerPlugin(IssuerPlugin):
}
return cert
def get_ordered_certificates(self, pending_certs):
pending = []
for pending_cert in pending_certs:
acme_client, registration = setup_acme_client(pending_cert.authority)
order_info = authorization_service.get(pending_cert.external_id)
dns_provider = dns_provider_service.get(pending_cert.dns_provider_id)
dns_provider_type = __import__(dns_provider.provider_type, globals(), locals(), [], 1)
authorizations = get_authorizations(
acme_client, order_info.account_number, order_info.domains, dns_provider_type)
pending.append({
"acme_client": acme_client,
"account_number": order_info.account_number,
"dns_provider_type": dns_provider_type,
"authorizations": authorizations,
"pending_cert": pending_cert,
})
certs = []
for entry in pending:
finalize_authorizations(
pending["acme_client"],
pending["account_number"],
pending["dns_provider_type"],
pending["authorizations"]
)
pem_certificate, pem_certificate_chain = request_certificate(
pending["acme_client"],
pending["authorizations"],
pending["pending_cert"].csr
)
cert = {
'body': "\n".join(str(pem_certificate).splitlines()),
'chain': "\n".join(str(pem_certificate_chain).splitlines()),
'external_id': str(pending_cert.external_id)
}
certs.append({
"cert": cert,
"pending_cert": pending_cert,
})
return certs
def create_certificate(self, csr, issuer_options):
"""
Creates an ACME certificate.