From 7d169f7c4c2ab2efc5dbeb69bb7eeb84a6421aa1 Mon Sep 17 00:00:00 2001 From: kevgliss Date: Mon, 3 Aug 2015 13:51:27 -0700 Subject: [PATCH] Fixing up some of the sync related code --- lemur/certificates/models.py | 2 +- lemur/certificates/service.py | 4 +- lemur/manage.py | 1 + lemur/notifications/service.py | 16 +++--- lemur/plugins/lemur_aws/iam.py | 10 ++-- lemur/plugins/lemur_aws/plugin.py | 13 ++--- lemur/sources/service.py | 50 +++++++++++++------ .../static/app/angular/dashboard/dashboard.js | 2 - .../notification/notification.js | 2 +- setup.py | 8 +-- 10 files changed, 66 insertions(+), 42 deletions(-) diff --git a/lemur/certificates/models.py b/lemur/certificates/models.py index ef7cbdc6..83f3f690 100644 --- a/lemur/certificates/models.py +++ b/lemur/certificates/models.py @@ -279,4 +279,4 @@ class Certificate(db.Model): @event.listens_for(Certificate.destinations, 'append') def update_destinations(target, value, initiator): destination_plugin = plugins.get(value.plugin_name) - destination_plugin.upload(target.body, target.private_key, target.chain, value.options) + destination_plugin.upload(target.name, target.body, target.private_key, target.chain, value.options) diff --git a/lemur/certificates/service.py b/lemur/certificates/service.py index 237f145f..886ef165 100644 --- a/lemur/certificates/service.py +++ b/lemur/certificates/service.py @@ -135,10 +135,10 @@ def import_certificate(**kwargs): """ from lemur.users import service as user_service from lemur.notifications import service as notification_service - cert = Certificate(kwargs['public_certificate']) + cert = Certificate(kwargs['public_certificate'], chain=kwargs['intermediate_certificate']) # TODO future source plugins might have a better understanding of who the 'owner' is we should support this - cert.owner = kwargs.get('owner', current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')) + cert.owner = kwargs.get('owner', current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL')[0]) cert.creator = kwargs.get('creator', user_service.get_by_email('lemur@nobody')) # NOTE existing certs may not follow our naming standard we will diff --git a/lemur/manage.py b/lemur/manage.py index 4f5794ac..3621159e 100755 --- a/lemur/manage.py +++ b/lemur/manage.py @@ -180,6 +180,7 @@ def sync_sources(labels, view): information it discovers. """ if view: + sys.stdout.write("Active", "Label", "Description") for source in source_service.get_all(): sys.stdout.write( "[{active}]\t{label}\t{description}!\n".format( diff --git a/lemur/notifications/service.py b/lemur/notifications/service.py index 9653f957..db40b53c 100644 --- a/lemur/notifications/service.py +++ b/lemur/notifications/service.py @@ -24,6 +24,12 @@ from lemur.certificates import service as cert_service from lemur.plugins.base import plugins +def get_options(name, options): + for o in options: + if o.get('name') == name: + return o + + def _get_message_data(cert): """ Parse our the certification information needed for our notification @@ -45,10 +51,8 @@ def _deduplicate(messages): """ roll_ups = [] for data, options in messages: - targets = [] - for o in options: - if o.get('name') == 'recipients': - targets = o['value'].split(',') + o = get_options('recipients', options) + targets = o['value'].split(',') for m, r, o in roll_ups: if r == targets: @@ -148,8 +152,8 @@ def _is_eligible_for_notifications(cert): days = (cert.not_after - now.naive).days for notification in cert.notifications: - interval = notification.options['interval'] - unit = notification.options['unit'] + interval = get_options('interval', notification.options)['value'] + unit = get_options('unit', notification.options)['value'] if unit == 'weeks': interval *= 7 diff --git a/lemur/plugins/lemur_aws/iam.py b/lemur/plugins/lemur_aws/iam.py index 9279c577..5e3bca0a 100644 --- a/lemur/plugins/lemur_aws/iam.py +++ b/lemur/plugins/lemur_aws/iam.py @@ -19,17 +19,17 @@ def get_name_from_arn(arn): return arn.split("/", 1)[1] -def upload_cert(account_number, cert, private_key, cert_chain=None): +def upload_cert(account_number, name, body, private_key, cert_chain=None): """ Upload a certificate to AWS :param account_number: - :param cert: + :param name: :param private_key: :param cert_chain: :return: """ - return assume_service(account_number, 'iam').upload_server_cert(cert.name, str(cert.body), str(private_key), + return assume_service(account_number, 'iam').upload_server_cert(name, str(body), str(private_key), cert_chain=str(cert_chain)) @@ -57,7 +57,7 @@ def get_all_server_certs(account_number): result = response['list_server_certificates_response']['list_server_certificates_result'] for cert in result['server_certificate_metadata_list']: - certs.append(cert) + certs.append(cert['arn']) if result['is_truncated'] == 'true': marker = result['marker'] @@ -72,7 +72,7 @@ def get_cert_from_arn(arn): :param arn: :return: """ - name = arn.split("/", 1)[1] + name = get_name_from_arn(arn) account_number = arn.split(":")[4] name = name.split("/")[-1] diff --git a/lemur/plugins/lemur_aws/plugin.py b/lemur/plugins/lemur_aws/plugin.py index 07b1f9a7..06c36d7f 100644 --- a/lemur/plugins/lemur_aws/plugin.py +++ b/lemur/plugins/lemur_aws/plugin.py @@ -13,7 +13,7 @@ from lemur.plugins import lemur_aws as aws def find_value(name, options): for o in options: - if o.get(name): + if o['name'] == name: return o['value'] @@ -41,8 +41,8 @@ class AWSDestinationPlugin(DestinationPlugin): # 'port': {'type': 'int'} # } - def upload(self, cert, private_key, cert_chain, options, **kwargs): - iam.upload_cert(find_value('accountNumber', options), cert, private_key, cert_chain=cert_chain) + def upload(self, name, body, private_key, cert_chain, options, **kwargs): + iam.upload_cert(find_value('accountNumber', options), name, body, private_key, cert_chain=cert_chain) e = find_value('elb', options) if e: @@ -68,14 +68,15 @@ class AWSSourcePlugin(SourcePlugin): }, ] - def get_certificates(self, **kwargs): + def get_certificates(self, options, **kwargs): certs = [] - arns = elb.get_all_server_certs(kwargs['account_number']) + arns = iam.get_all_server_certs(find_value('accountNumber', options)) for arn in arns: - cert_body = iam.get_cert_from_arn(arn) + cert_body, cert_chain = iam.get_cert_from_arn(arn) cert_name = iam.get_name_from_arn(arn) cert = dict( public_certificate=cert_body, + intermediate_certificate=cert_chain, name=cert_name ) certs.append(cert) diff --git a/lemur/sources/service.py b/lemur/sources/service.py index e3f53094..b097696e 100644 --- a/lemur/sources/service.py +++ b/lemur/sources/service.py @@ -11,6 +11,7 @@ from lemur import database from lemur.sources.models import Source from lemur.certificates.models import Certificate from lemur.certificates import service as cert_service +from lemur.destinations import service as destination_service from lemur.plugins.base import plugins @@ -19,7 +20,7 @@ def _disassociate_certs_from_source(current_certificates, found_certificates, so missing = [] for cc in current_certificates: for fc in found_certificates: - if fc.body == cc.body: + if fc['public_certificate'] == cc.body: break else: missing.append(cc) @@ -36,6 +37,34 @@ def _disassociate_certs_from_source(current_certificates, found_certificates, so c.sources.delete(s) +def sync_create(certificate, source): + cert = cert_service.import_certificate(**certificate) + cert.sources.append(source) + sync_update_destination(cert, source) + database.update(cert) + + +def sync_update(certificate, source): + for s in certificate.sources: + if s.label == source.label: + break + else: + certificate.sources.append(source) + + sync_update_destination(certificate, source) + database.update(certificate) + + +def sync_update_destination(certificate, source): + dest = destination_service.get_by_label(source.label) + if dest: + for d in certificate.destinations: + if d.label == source.label: + break + else: + certificate.destinations.append(dest) + + def sync(labels=None): new, updated = 0, 0 c_certificates = cert_service.get_all_certs() @@ -46,30 +75,21 @@ def sync(labels=None): if source.label not in labels: continue - current_app.logger.error("Retrieving certificates from {0}".format(source.title)) + current_app.logger.error("Retrieving certificates from {0}".format(source.label)) s = plugins.get(source.plugin_name) certificates = s.get_certificates(source.options) for certificate in certificates: - exists = cert_service.find_duplicates(certificate) + exists = cert_service.find_duplicates(certificate['public_certificate']) if not exists: - cert = cert_service.import_certificate(**certificate) - cert.sources.append(source) - database.update(cert) - + sync_create(certificate, source) new += 1 # check to make sure that existing certificates have the current source associated with it - if len(exists) == 1: - for s in cert.sources: - if s.label == source.label: - break - else: - cert.sources.append(source) - + elif len(exists) == 1: + sync_update(exists[0], source) updated += 1 - else: current_app.logger.warning( "Multiple certificates found, attempt to deduplicate the following certificates: {0}".format( diff --git a/lemur/static/app/angular/dashboard/dashboard.js b/lemur/static/app/angular/dashboard/dashboard.js index 630e0439..69cfd554 100644 --- a/lemur/static/app/angular/dashboard/dashboard.js +++ b/lemur/static/app/angular/dashboard/dashboard.js @@ -9,8 +9,6 @@ angular.module('lemur') }) .controller('DashboardController', function ($scope, $rootScope, $filter, $location, LemurRestangular) { - var baseAccounts = LemurRestangular.all('accounts'); - $scope.colours = [ { fillColor: 'rgba(41, 171, 224, 0.2)', diff --git a/lemur/static/app/angular/notifications/notification/notification.js b/lemur/static/app/angular/notifications/notification/notification.js index 5df01e04..9495b6ec 100644 --- a/lemur/static/app/angular/notifications/notification/notification.js +++ b/lemur/static/app/angular/notifications/notification/notification.js @@ -38,7 +38,7 @@ angular.module('lemur') if (plugin.slug === $scope.notification.pluginName) { plugin.pluginOptions = $scope.notification.notificationOptions; $scope.notification.plugin = plugin; - }; + } }); }); diff --git a/setup.py b/setup.py index 5b315241..b508687f 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ install_requires = [ 'pyopenssl==0.15.1', 'pyjwt==1.0.1', 'xmltodict==0.9.2', - 'lockfile=0.10.2' + 'lockfile==0.10.2' ] tests_require = [ @@ -136,10 +136,10 @@ setup( 'lemur.plugins': [ 'verisign_issuer = lemur.plugins.lemur_verisign.plugin:VerisignIssuerPlugin', 'cloudca_issuer = lemur.plugins.lemur_cloudca.plugin:CloudCAIssuerPlugin', - 'cloudca_source = lemur.plugins.lemur_cloudca.plugin:CloudCASourcePlugin' + 'cloudca_source = lemur.plugins.lemur_cloudca.plugin:CloudCASourcePlugin', 'aws_destination = lemur.plugins.lemur_aws.plugin:AWSDestinationPlugin', - 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin' - 'email_notification = lemur.plugins.lemur_email.plugin:EmailNotificationPlugin' + 'aws_source = lemur.plugins.lemur_aws.plugin:AWSSourcePlugin', + 'email_notification = lemur.plugins.lemur_email.plugin:EmailNotificationPlugin', ], }, classifiers=[