* Closes #372
This commit is contained in:
kevgliss 2016-07-04 14:32:46 -07:00 committed by GitHub
parent c8eca56690
commit 4ee1c21144
5 changed files with 67 additions and 34 deletions

View File

@ -12,8 +12,8 @@ from flask import request, current_app
from sqlalchemy.orm.collections import InstrumentedList from sqlalchemy.orm.collections import InstrumentedList
from marshmallow import Schema, post_dump, pre_load, pre_dump
from inflection import camelize, underscore from inflection import camelize, underscore
from marshmallow import Schema, post_dump, pre_load, pre_dump
class LemurSchema(Schema): class LemurSchema(Schema):

View File

@ -36,6 +36,14 @@ class IntegrityError(LemurException):
return repr(self.message) return repr(self.message)
class AssociatedObjectNotFound(LemurException):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
class InvalidListener(LemurException): class InvalidListener(LemurException):
def __str__(self): def __str__(self):
return repr("Invalid listener, ensure you select a certificate if you are using a secure protocol") return repr("Invalid listener, ensure you select a certificate if you are using a secure protocol")

View File

@ -244,27 +244,31 @@ def create_default_expiration_notifications(name, recipients):
def create(label, plugin_name, options, description, certificates): def create(label, plugin_name, options, description, certificates):
""" """
Creates a new destination, that can then be used as a destination for certificates. Creates a new notification.
:param label: Notification common name :param label: Notification label
:param plugin_name: :param plugin_name:
:param options: :param options:
:param description: :param description:
:param certificates:
:rtype : Notification :rtype : Notification
:return: :return:
""" """
notification = Notification(label=label, options=options, plugin_name=plugin_name, description=description) notification = Notification(label=label, options=options, plugin_name=plugin_name, description=description)
notification = database.update_list(notification, 'certificates', Certificate, certificates) notification.certificates = certificates
return database.create(notification) return database.create(notification)
def update(notification_id, label, options, description, active, certificates): def update(notification_id, label, options, description, active, certificates):
""" """
Updates an existing destination. Updates an existing notification.
:param label: Notification common name :param notification_id:
:param label: Notification label
:param options: :param options:
:param description: :param description:
:param active:
:param certificates:
:rtype : Notification :rtype : Notification
:return: :return:
""" """

View File

@ -27,7 +27,8 @@ def update(role_id, name, description, users):
role = get(role_id) role = get(role_id)
role.name = name role.name = name
role.description = description role.description = description
role = database.update_list(role, 'users', User, users) if users:
role.users = users
database.update(role) database.update(role)
return role return role
@ -44,10 +45,8 @@ def create(name, password=None, description=None, username=None, users=None):
:return: :return:
""" """
role = Role(name=name, description=description, username=username, password=password) role = Role(name=name, description=description, username=username, password=password)
if users: if users:
role = database.update_list(role, 'users', User, users) role.users = users
return database.create(role) return database.create(role)

View File

@ -7,17 +7,40 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
from marshmallow import fields, post_load, pre_load, post_dump, validates_schema from sqlalchemy.orm.exc import NoResultFound
from marshmallow import fields, post_load, pre_load, post_dump, validates_schema
from marshmallow.exceptions import ValidationError
from lemur.authorities.models import Authority
from lemur.certificates.models import Certificate
from lemur.common import validators from lemur.common import validators
from lemur.common.schema import LemurSchema, LemurInputSchema, LemurOutputSchema from lemur.common.schema import LemurSchema, LemurInputSchema, LemurOutputSchema
from lemur.destinations.models import Destination
from lemur.notifications.models import Notification
from lemur.plugins import plugins from lemur.plugins import plugins
from lemur.roles.models import Role from lemur.roles.models import Role
from lemur.users.models import User from lemur.users.models import User
from lemur.authorities.models import Authority
from lemur.certificates.models import Certificate
from lemur.destinations.models import Destination
from lemur.notifications.models import Notification
def fetch_object(model, field, value):
try:
return model.query.filter(getattr(model, field) == value).one()
except NoResultFound:
raise ValidationError('Unable to find {model} with {field}: {data}'.format(model=model, field=field, data=value))
def fetch_objects(model, field, values):
values = [v[field] for v in values]
items = model.query.filter(getattr(model, field).in_(values)).all()
found = [getattr(i, field) for i in items]
diff = set(values).symmetric_difference(set(found))
if diff:
raise ValidationError('Unable to locate {model} with {field} {diff}'.format(model=model, field=field, diff=",".join([list(diff)])))
return items
class AssociatedAuthoritySchema(LemurInputSchema): class AssociatedAuthoritySchema(LemurInputSchema):
@ -27,9 +50,10 @@ class AssociatedAuthoritySchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if data.get('id'): if data.get('id'):
return Authority.query.filter(Authority.id == data['id']).one() return fetch_object(Authority, 'id', data['id'])
elif data.get('name'): elif data.get('name'):
return Authority.query.filter(Authority.name == data['name']).one() return fetch_object(Authority, 'name', data['name'])
class AssociatedRoleSchema(LemurInputSchema): class AssociatedRoleSchema(LemurInputSchema):
@ -39,10 +63,9 @@ class AssociatedRoleSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if many: if many:
ids = [d['id'] for d in data] return fetch_objects(Role, 'id', data)
return Role.query.filter(Role.id.in_(ids)).all()
else: else:
return Role.query.filter(Role.id == data['id']).one() return fetch_object(Role, 'id', data['id'])
class AssociatedDestinationSchema(LemurInputSchema): class AssociatedDestinationSchema(LemurInputSchema):
@ -52,10 +75,9 @@ class AssociatedDestinationSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if many: if many:
ids = [d['id'] for d in data] return fetch_objects(Destination, 'id', data)
return Destination.query.filter(Destination.id.in_(ids)).all()
else: else:
return Destination.query.filter(Destination.id == data['id']).one() return fetch_object(Destination, 'id', data['id'])
class AssociatedNotificationSchema(LemurInputSchema): class AssociatedNotificationSchema(LemurInputSchema):
@ -64,10 +86,9 @@ class AssociatedNotificationSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if many: if many:
ids = [d['id'] for d in data] return fetch_objects(Notification, 'id', data)
return Notification.query.filter(Notification.id.in_(ids)).all()
else: else:
return Notification.query.filter(Notification.id == data['id']).one() return fetch_object(Notification, 'id', data['id'])
class AssociatedCertificateSchema(LemurInputSchema): class AssociatedCertificateSchema(LemurInputSchema):
@ -76,10 +97,9 @@ class AssociatedCertificateSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if many: if many:
ids = [d['id'] for d in data] return fetch_objects(Certificate, 'id', data)
return Certificate.query.filter(Certificate.id.in_(ids)).all()
else: else:
return Certificate.query.filter(Certificate.id == data['id']).one() return fetch_object(Certificate, 'id', data['id'])
class AssociatedUserSchema(LemurInputSchema): class AssociatedUserSchema(LemurInputSchema):
@ -88,10 +108,9 @@ class AssociatedUserSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
if many: if many:
ids = [d['id'] for d in data] return fetch_objects(User, 'id', data)
return User.query.filter(User.id.in_(ids)).all()
else: else:
return User.query.filter(User.id == data['id']).one() return fetch_object(User, 'id', data['id'])
class PluginInputSchema(LemurInputSchema): class PluginInputSchema(LemurInputSchema):
@ -102,8 +121,11 @@ class PluginInputSchema(LemurInputSchema):
@post_load @post_load
def get_object(self, data, many=False): def get_object(self, data, many=False):
try:
data['plugin_object'] = plugins.get(data['slug']) data['plugin_object'] = plugins.get(data['slug'])
return data return data
except Exception:
raise ValidationError('Unable to find plugin: {0}'.format(data['slug']))
class PluginOutputSchema(LemurOutputSchema): class PluginOutputSchema(LemurOutputSchema):