Purging ELB and Listener specific models
This commit is contained in:
parent
abf21d2931
commit
46652ba117
|
@ -14,10 +14,8 @@ from lemur.users.views import mod as users_bp
|
|||
from lemur.roles.views import mod as roles_bp
|
||||
from lemur.auth.views import mod as auth_bp
|
||||
from lemur.domains.views import mod as domains_bp
|
||||
from lemur.elbs.views import mod as elbs_bp
|
||||
from lemur.destinations.views import mod as destinations_bp
|
||||
from lemur.authorities.views import mod as authorities_bp
|
||||
from lemur.listeners.views import mod as listeners_bp
|
||||
from lemur.certificates.views import mod as certificates_bp
|
||||
from lemur.status.views import mod as status_bp
|
||||
from lemur.plugins.views import mod as plugins_bp
|
||||
|
@ -30,10 +28,8 @@ LEMUR_BLUEPRINTS = (
|
|||
roles_bp,
|
||||
auth_bp,
|
||||
domains_bp,
|
||||
elbs_bp,
|
||||
destinations_bp,
|
||||
authorities_bp,
|
||||
listeners_bp,
|
||||
certificates_bp,
|
||||
status_bp,
|
||||
plugins_bp,
|
||||
|
|
|
@ -226,7 +226,6 @@ class Certificate(db.Model):
|
|||
destinations = relationship("Destination", secondary=certificate_destination_associations, backref='certificate')
|
||||
sources = relationship("Source", secondary=certificate_source_associations, backref='certificate')
|
||||
domains = relationship("Domain", secondary=certificate_associations, backref="certificate")
|
||||
elb_listeners = relationship("Listener", lazy='dynamic', backref='certificate')
|
||||
|
||||
def __init__(self, body, private_key=None, chain=None):
|
||||
self.body = body
|
||||
|
|
|
@ -30,8 +30,6 @@ from lemur.authorities.models import Authority # noqa
|
|||
from lemur.certificates.models import Certificate # noqa
|
||||
from lemur.destinations.models import Destination # noqa
|
||||
from lemur.domains.models import Domain # noqa
|
||||
from lemur.elbs.models import ELB # noqa
|
||||
from lemur.listeners.models import Listener # noqa
|
||||
from lemur.notifications.models import Notification # noqa
|
||||
from lemur.sources.models import Source # noqa
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ certificate_destination_associations = db.Table('certificate_destination_associa
|
|||
|
||||
certificate_source_associations = db.Table('certificate_source_associations',
|
||||
Column('source_id', Integer,
|
||||
ForeignKey('destinations.id', ondelete='cascade')),
|
||||
ForeignKey('sources.id', ondelete='cascade')),
|
||||
Column('certificate_id', Integer,
|
||||
ForeignKey('certificates.id', ondelete='cascade'))
|
||||
)
|
||||
|
|
|
@ -35,7 +35,7 @@ angular.module('lemur')
|
|||
PluginService.getByType('notification').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
_.each($scope.plugins, function (plugin) {
|
||||
if (plugin.slug == $scope.notification.pluginName) {
|
||||
if (plugin.slug === $scope.notification.pluginName) {
|
||||
plugin.pluginOptions = $scope.notification.notificationOptions;
|
||||
$scope.notification.plugin = plugin;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
'use strict';
|
||||
angular.module('lemur')
|
||||
.service('SourceApi', function (LemurRestangular) {
|
||||
return LemurRestangular.all('sources');
|
||||
})
|
||||
.service('SourceService', function ($location, SourceApi, PluginService, toaster) {
|
||||
var SourceService = this;
|
||||
SourceService.findSourcesByName = function (filterValue) {
|
||||
return SourceApi.getList({'filter[label]': filterValue})
|
||||
.then(function (sources) {
|
||||
return sources;
|
||||
});
|
||||
};
|
||||
|
||||
SourceService.create = function (source) {
|
||||
return SourceApi.post(source).then(
|
||||
function () {
|
||||
toaster.pop({
|
||||
type: 'success',
|
||||
title: source.label,
|
||||
body: 'Successfully created!'
|
||||
});
|
||||
$location.path('sources');
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: source.label,
|
||||
body: 'Was not created! ' + response.data.message
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SourceService.update = function (source) {
|
||||
return source.put().then(
|
||||
function () {
|
||||
toaster.pop({
|
||||
type: 'success',
|
||||
title: source.label,
|
||||
body: 'Successfully updated!'
|
||||
});
|
||||
$location.path('sources');
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: source.label,
|
||||
body: 'Was not updated! ' + response.data.message
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SourceService.getPlugin = function (source) {
|
||||
return PluginService.getByName(source.pluginName).then(function (plugin) {
|
||||
source.plugin = plugin;
|
||||
});
|
||||
};
|
||||
return SourceService;
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('lemur')
|
||||
|
||||
.controller('SourcesCreateController', function ($scope, $modalInstance, PluginService, SourceService, LemurRestangular){
|
||||
$scope.source = LemurRestangular.restangularizeElement(null, {}, 'sources');
|
||||
|
||||
PluginService.getByType('source').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
});
|
||||
|
||||
$scope.save = function (source) {
|
||||
SourceService.create(source).then(function () {
|
||||
$modalInstance.close();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
})
|
||||
|
||||
.controller('SourcesEditController', function ($scope, $modalInstance, SourceService, SourceApi, PluginService, editId) {
|
||||
SourceApi.get(editId).then(function (source) {
|
||||
$scope.source = source;
|
||||
});
|
||||
|
||||
PluginService.getByType('source').then(function (plugins) {
|
||||
$scope.plugins = plugins;
|
||||
_.each($scope.plugins, function (plugin) {
|
||||
if (plugin.slug === $scope.source.pluginName) {
|
||||
plugin.pluginOptions = $scope.source.sourceOptions;
|
||||
$scope.source.plugin = plugin;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$scope.save = function (source) {
|
||||
SourceService.update(source).then(function () {
|
||||
$modalInstance.close();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.cancel = function () {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
});
|
|
@ -0,0 +1,56 @@
|
|||
<div class="modal-header">
|
||||
<div class="modal-title">
|
||||
<h3 class="modal-header"><span ng-show="!source.fromServer">Create</span><span ng-show="source.fromServer">Edit</span> Source <span class="text-muted"><small>oh the places you will go!</small></span></h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form name="createForm" class="form-horizontal" role="form" novalidate>
|
||||
<div class="form-group"
|
||||
ng-class="{'has-error': createForm.label.$invalid, 'has-success': !createForm.label.$invalid&&createForm.label.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
Label
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="label" ng-model="source.label" placeholder="Label" class="form-control" required/>
|
||||
<p ng-show="createForm.label.$invalid && !createForm.label.$pristine" class="help-block">You must enter an source label</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Description
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<textarea name="comments" ng-model="source.description" placeholder="Something elegant" class="form-control" ></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-2">
|
||||
Plugin
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<select class="form-control" ng-model="source.plugin" ng-options="plugin.title for plugin in plugins" required></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-repeat="item in source.plugin.pluginOptions">
|
||||
<ng-form name="subForm" class="form-horizontal" role="form" novalidate>
|
||||
<div ng-class="{'has-error': subForm.sub.$invalid, 'has-success': !subForm.sub.$invalid&&subForm.sub.$dirty}">
|
||||
<label class="control-label col-sm-2">
|
||||
{{ item.name | titleCase }}
|
||||
</label>
|
||||
<div class="col-sm-10">
|
||||
<input name="sub" ng-if="item.type == 'int'" type="number" ng-pattern="/^[0-9]{12,12}$/" class="form-control" ng-model="item.value"/>
|
||||
<select name="sub" ng-if="item.type == 'select'" class="form-control" ng-options="i for i in item.available" ng-model="item.value"></select>
|
||||
<input name="sub" ng-if="item.type == 'bool'" class="form-control" type="checkbox" ng-model="item.value">
|
||||
<input name="sub" ng-if="item.type == 'str'" type="text" class="form-control" ng-model="item.value"/>
|
||||
<p ng-show="subForm.sub.$invalid && !subForm.sub.$pristine" class="help-block">{{ item.helpMessage }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</ng-form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button ng-click="save(source)" type="submit" ng-disabled="createForm.$invalid" class="btn btn-primary">Save</button>
|
||||
<button ng-click="cancel()" class="btn btn-danger">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
'use strict';
|
||||
|
||||
angular.module('lemur')
|
||||
|
||||
.config(function config($routeProvider) {
|
||||
$routeProvider.when('/sources', {
|
||||
templateUrl: '/angular/sources/view/view.tpl.html',
|
||||
controller: 'SourcesViewController'
|
||||
});
|
||||
})
|
||||
|
||||
.controller('SourcesViewController', function ($scope, $modal, SourceApi, SourceService, ngTableParams, toaster) {
|
||||
$scope.filter = {};
|
||||
$scope.sourcesTable = new ngTableParams({
|
||||
page: 1, // show first page
|
||||
count: 10, // count per page
|
||||
sorting: {
|
||||
id: 'desc' // initial sorting
|
||||
},
|
||||
filter: $scope.filter
|
||||
}, {
|
||||
total: 0, // length of data
|
||||
getData: function ($defer, params) {
|
||||
SourceApi.getList(params.url()).then(
|
||||
function (data) {
|
||||
_.each(data, function (source) {
|
||||
SourceService.getPlugin(source);
|
||||
});
|
||||
params.total(data.total);
|
||||
$defer.resolve(data);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.remove = function (source) {
|
||||
source.remove().then(
|
||||
function () {
|
||||
$scope.sourcesTable.reload();
|
||||
},
|
||||
function (response) {
|
||||
toaster.pop({
|
||||
type: 'error',
|
||||
title: 'Opps',
|
||||
body: 'I see what you did there' + response.data.message
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.edit = function (sourceId) {
|
||||
var modalInstance = $modal.open({
|
||||
animation: true,
|
||||
templateUrl: '/angular/sources/source/source.tpl.html',
|
||||
controller: 'SourcesEditController',
|
||||
size: 'lg',
|
||||
resolve: {
|
||||
editId: function () {
|
||||
return sourceId;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modalInstance.result.then(function () {
|
||||
$scope.sourcesTable.reload();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.create = function () {
|
||||
var modalInstance = $modal.open({
|
||||
animation: true,
|
||||
controller: 'SourcesCreateController',
|
||||
templateUrl: '/angular/sources/source/source.tpl.html',
|
||||
size: 'lg'
|
||||
});
|
||||
|
||||
modalInstance.result.then(function () {
|
||||
$scope.sourcesTable.reload();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
$scope.toggleFilter = function (params) {
|
||||
params.settings().$scope.show_filter = !params.settings().$scope.show_filter;
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h2 class="featurette-heading">Sources
|
||||
<span class="text-muted"><small>where are you from?</small></span></h2>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="btn-group pull-right">
|
||||
<button ng-click="create()" class="btn btn-primary">Create</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button ng-click="toggleFilter(sourcesTable)" class="btn btn-default">Filter</button>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table ng-table="sourcesTable" class="table table-striped" show-filter="false" template-pagination="angular/pager.html" >
|
||||
<tbody>
|
||||
<tr ng-repeat="source in $data track by $index">
|
||||
<td data-title="'Label'" sortable="'label'" filter="{ 'label': 'text' }">
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ source.label }}</li>
|
||||
<li><span class="text-muted">{{ source.description }}</span></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="'Plugin'">
|
||||
<ul class="list-unstyled">
|
||||
<li>{{ source.plugin.title }}</li>
|
||||
<li><span class="text-muted">{{ source.plugin.description }}</span></li>
|
||||
</ul>
|
||||
</td>
|
||||
<td data-title="''">
|
||||
<div class="btn-group-vertical pull-right">
|
||||
<button tooltip="Edit Source" ng-click="edit(source.id)" class="btn btn-sm btn-info">
|
||||
Edit
|
||||
</button>
|
||||
<button tooltip="Delete Source" ng-click="remove(source)" type="button" class="btn btn-sm btn-danger pull-left">
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,134 @@
|
|||
from lemur.sources.service import * # noqa
|
||||
from lemur.sources.views import * # noqa
|
||||
|
||||
from json import dumps
|
||||
|
||||
|
||||
def test_crud(session):
|
||||
source = create('testdest', 'aws-source', {}, description='source1')
|
||||
assert source.id > 0
|
||||
|
||||
source = update(source.id, 'testdest2', {}, 'source2')
|
||||
assert source.label == 'testdest2'
|
||||
|
||||
assert len(get_all()) == 1
|
||||
|
||||
delete(1)
|
||||
assert len(get_all()) == 0
|
||||
|
||||
|
||||
def test_source_get(client):
|
||||
assert client.get(api.url_for(Sources, source_id=1)).status_code == 401
|
||||
|
||||
|
||||
def test_source_post(client):
|
||||
assert client.post(api.url_for(Sources, source_id=1), data={}).status_code == 405
|
||||
|
||||
|
||||
def test_source_put(client):
|
||||
assert client.put(api.url_for(Sources, source_id=1), data={}).status_code == 401
|
||||
|
||||
|
||||
def test_source_delete(client):
|
||||
assert client.delete(api.url_for(Sources, source_id=1)).status_code == 401
|
||||
|
||||
|
||||
def test_source_patch(client):
|
||||
assert client.patch(api.url_for(Sources, source_id=1), data={}).status_code == 405
|
||||
|
||||
|
||||
VALID_USER_HEADER_TOKEN = {
|
||||
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyMzMzNjksInN1YiI6MSwiZXhwIjoxNTIxNTQ2OTY5fQ.1qCi0Ip7mzKbjNh0tVd3_eJOrae3rNa_9MCVdA4WtQI'}
|
||||
|
||||
|
||||
def test_auth_source_get(client):
|
||||
assert client.get(api.url_for(Sources, source_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 200
|
||||
|
||||
|
||||
def test_auth_source_post_(client):
|
||||
assert client.post(api.url_for(Sources, source_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 405
|
||||
|
||||
|
||||
def test_auth_source_put(client):
|
||||
assert client.put(api.url_for(Sources, source_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 403
|
||||
|
||||
|
||||
def test_auth_source_delete(client):
|
||||
assert client.delete(api.url_for(Sources, source_id=1), headers=VALID_USER_HEADER_TOKEN).status_code == 403
|
||||
|
||||
|
||||
def test_auth_source_patch(client):
|
||||
assert client.patch(api.url_for(Sources, source_id=1), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 405
|
||||
|
||||
|
||||
VALID_ADMIN_HEADER_TOKEN = {
|
||||
'Authorization': 'Basic ' + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MzUyNTAyMTgsInN1YiI6MiwiZXhwIjoxNTIxNTYzODE4fQ.6mbq4-Ro6K5MmuNiTJBB153RDhlM5LGJBjI7GBKkfqA'}
|
||||
|
||||
|
||||
def test_admin_source_get(client):
|
||||
assert client.get(api.url_for(Sources, source_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
||||
|
||||
|
||||
def test_admin_source_post(client):
|
||||
assert client.post(api.url_for(Sources, source_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405
|
||||
|
||||
|
||||
def test_admin_source_put(client):
|
||||
assert client.put(api.url_for(Sources, source_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400
|
||||
|
||||
|
||||
def test_admin_source_delete(client):
|
||||
assert client.delete(api.url_for(Sources, source_id=1), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
||||
|
||||
|
||||
def test_admin_source_patch(client):
|
||||
assert client.patch(api.url_for(Sources, source_id=1), data={}, headers=VALID_ADMIN_HEADER_TOKEN).status_code == 405
|
||||
|
||||
|
||||
def test_sources_get(client):
|
||||
assert client.get(api.url_for(SourcesList)).status_code == 401
|
||||
|
||||
|
||||
def test_sources_post(client):
|
||||
assert client.post(api.url_for(SourcesList), data={}).status_code == 401
|
||||
|
||||
|
||||
def test_sources_put(client):
|
||||
assert client.put(api.url_for(SourcesList), data={}).status_code == 405
|
||||
|
||||
|
||||
def test_sources_delete(client):
|
||||
assert client.delete(api.url_for(SourcesList)).status_code == 405
|
||||
|
||||
|
||||
def test_sources_patch(client):
|
||||
assert client.patch(api.url_for(SourcesList), data={}).status_code == 405
|
||||
|
||||
|
||||
def test_auth_sources_get(client):
|
||||
assert client.get(api.url_for(SourcesList), headers=VALID_USER_HEADER_TOKEN).status_code == 200
|
||||
|
||||
|
||||
def test_auth_sources_post(client):
|
||||
assert client.post(api.url_for(SourcesList), data={}, headers=VALID_USER_HEADER_TOKEN).status_code == 403
|
||||
|
||||
|
||||
def test_admin_sources_get(client):
|
||||
resp = client.get(api.url_for(SourcesList), headers=VALID_ADMIN_HEADER_TOKEN)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json == {'items': [], 'total': 0}
|
||||
|
||||
|
||||
def test_admin_sources_crud(client):
|
||||
assert client.post(api.url_for(SourcesList), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 400
|
||||
data = {'plugin': {'slug': 'aws-source', 'pluginOptions': {}}, 'label': 'test', 'description': 'test'}
|
||||
resp = client.post(api.url_for(SourcesList), data=dumps(data), content_type='application/json', headers=VALID_ADMIN_HEADER_TOKEN)
|
||||
assert resp.status_code == 200
|
||||
assert client.get(api.url_for(Sources, source_id=resp.json['id']), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
||||
resp = client.get(api.url_for(SourcesList), headers=VALID_ADMIN_HEADER_TOKEN)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json['items'][0]['description'] == 'test'
|
||||
assert client.delete(api.url_for(Sources, source_id=2), headers=VALID_ADMIN_HEADER_TOKEN).status_code == 200
|
||||
resp = client.get(api.url_for(SourcesList), headers=VALID_ADMIN_HEADER_TOKEN)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json == {'items': [], 'total': 0}
|
Loading…
Reference in New Issue