Merge pull request #73 from kevgliss/cleanup

Cleanup
This commit is contained in:
kevgliss 2015-09-08 08:43:56 -07:00
commit 541d5420bb
19 changed files with 110 additions and 111 deletions

4
MANIFEST.in Normal file
View File

@ -0,0 +1,4 @@
include setup.py package.json bower.json gulpfile.js README.rst MANIFEST.in LICENSE AUTHORS
recursive-include lemur/plugins/lemur_email/templates *
recursive-include lemur/static *
global-exclude *~

View File

@ -17,7 +17,7 @@ from lemur.domains.views import mod as domains_bp
from lemur.destinations.views import mod as destinations_bp from lemur.destinations.views import mod as destinations_bp
from lemur.authorities.views import mod as authorities_bp from lemur.authorities.views import mod as authorities_bp
from lemur.certificates.views import mod as certificates_bp from lemur.certificates.views import mod as certificates_bp
from lemur.status.views import mod as status_bp from lemur.defaults.views import mod as defaults_bp
from lemur.plugins.views import mod as plugins_bp from lemur.plugins.views import mod as plugins_bp
from lemur.notifications.views import mod as notifications_bp from lemur.notifications.views import mod as notifications_bp
from lemur.sources.views import mod as sources_bp from lemur.sources.views import mod as sources_bp
@ -31,7 +31,7 @@ LEMUR_BLUEPRINTS = (
destinations_bp, destinations_bp,
authorities_bp, authorities_bp,
certificates_bp, certificates_bp,
status_bp, defaults_bp,
plugins_bp, plugins_bp,
notifications_bp, notifications_bp,
sources_bp sources_bp

View File

@ -7,7 +7,7 @@
""" """
from builtins import str from builtins import str
from flask import Blueprint, current_app, make_response, jsonify from flask import Blueprint, make_response, jsonify
from flask.ext.restful import reqparse, Api, fields from flask.ext.restful import reqparse, Api, fields
from cryptography import x509 from cryptography import x509
@ -668,58 +668,9 @@ class NotificationCertificatesList(AuthenticatedResource):
return service.render(args) return service.render(args)
class CertificatesDefaults(AuthenticatedResource):
""" Defineds the 'certificates' defaults endpoint """
def __init__(self):
super(CertificatesDefaults)
def get(self):
"""
.. http:get:: /certificates/defaults
Returns defaults needed to generate CSRs
**Example request**:
.. sourcecode:: http
GET /certificates/defaults HTTP/1.1
Host: example.com
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"country": "US",
"state": "CA",
"location": "Los Gatos",
"organization": "Netflix",
"organizationalUnit": "Operations"
}
:reqheader Authorization: OAuth token to authenticate
:statuscode 200: no error
:statuscode 403: unauthenticated
"""
return dict(
country=current_app.config.get('LEMUR_DEFAULT_COUNTRY'),
state=current_app.config.get('LEMUR_DEFAULT_STATE'),
location=current_app.config.get('LEMUR_DEFAULT_LOCATION'),
organization=current_app.config.get('LEMUR_DEFAULT_ORGANIZATION'),
organizationalUnit=current_app.config.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT')
)
api.add_resource(CertificatesList, '/certificates', endpoint='certificates') api.add_resource(CertificatesList, '/certificates', endpoint='certificates')
api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate') api.add_resource(Certificates, '/certificates/<int:certificate_id>', endpoint='certificate')
api.add_resource(CertificatesStats, '/certificates/stats', endpoint='certificateStats') api.add_resource(CertificatesStats, '/certificates/stats', endpoint='certificateStats')
api.add_resource(CertificatesUpload, '/certificates/upload', endpoint='certificateUpload') api.add_resource(CertificatesUpload, '/certificates/upload', endpoint='certificateUpload')
api.add_resource(CertificatePrivateKey, '/certificates/<int:certificate_id>/key', endpoint='privateKeyCertificates') api.add_resource(CertificatePrivateKey, '/certificates/<int:certificate_id>/key', endpoint='privateKeyCertificates')
api.add_resource(NotificationCertificatesList, '/notifications/<int:notification_id>/certificates', endpoint='notificationCertificates') api.add_resource(NotificationCertificatesList, '/notifications/<int:notification_id>/certificates', endpoint='notificationCertificates')
api.add_resource(CertificatesDefaults, '/certificates/defaults', endpoint='certificatesDefault')

63
lemur/defaults/views.py Normal file
View File

@ -0,0 +1,63 @@
"""
.. module: lemur.status.views
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
"""
from flask import current_app, Blueprint
from flask.ext.restful import Api
from lemur.auth.service import AuthenticatedResource
mod = Blueprint('default', __name__)
api = Api(mod)
class LemurDefaults(AuthenticatedResource):
""" Defines the 'defaults' endpoint """
def __init__(self):
super(LemurDefaults)
def get(self):
"""
.. http:get:: /defaults
Returns defaults needed to generate CSRs
**Example request**:
.. sourcecode:: http
GET /defaults HTTP/1.1
Host: example.com
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"country": "US",
"state": "CA",
"location": "Los Gatos",
"organization": "Netflix",
"organizationalUnit": "Operations"
}
:reqheader Authorization: OAuth token to authenticate
:statuscode 200: no error
:statuscode 403: unauthenticated
"""
return dict(
country=current_app.config.get('LEMUR_DEFAULT_COUNTRY'),
state=current_app.config.get('LEMUR_DEFAULT_STATE'),
location=current_app.config.get('LEMUR_DEFAULT_LOCATION'),
organization=current_app.config.get('LEMUR_DEFAULT_ORGANIZATION'),
organizationalUnit=current_app.config.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT')
)
api.add_resource(LemurDefaults, '/defaults', endpoint='default')

View File

@ -569,11 +569,11 @@ class ProvisionELB(Command):
'authority': authority, 'authority': authority,
'owner': owner, 'owner': owner,
# defaults: # defaults:
'organization': u'Netflix, Inc.', 'organization': current_app.config.get('LEMUR_DEFAULT_ORGANIZATION'),
'organizationalUnit': u'Operations', 'organizationalUnit': current_app.config.get('LEMUR_DEFAULT_ORGANIZATIONAL_UNIT'),
'country': u'US', 'country': current_app.config.get('LEMUR_DEFAULT_COUNTRY'),
'state': u'California', 'state': current_app.config.get('LEMUR_DEFAULT_STATE'),
'location': u'Los Gatos' 'location': current_app.config.get('LEMUR_DEFAULT_LOCATION')
} }
return options return options

View File

@ -53,7 +53,7 @@
<hr /> <hr />
</div> </div>
<p> <p>
Lemur, Netflix's SSL management portal has noticed that the following certificates are expiring soon, if you rely on these certificates Lemur, has noticed that the following certificates are expiring soon, if you rely on these certificates
you should create new certificates to replace the certificates that are expiring. you should create new certificates to replace the certificates that are expiring.
</p> </p>
<p> <p>

View File

@ -60,6 +60,15 @@ lemur.controller('datePickerController', function ($scope, $timeout){
}; };
}); });
lemur.service('DefaultService', function (LemurRestangular) {
var DefaultService = this;
DefaultService.get = function () {
return LemurRestangular.all('defaults').customGET().then(function (defaults) {
return defaults;
});
};
});
lemur.factory('LemurRestangular', function (Restangular, $location, $auth) { lemur.factory('LemurRestangular', function (Restangular, $location, $auth) {
return Restangular.withConfig(function (RestangularConfigurer) { return Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('http://localhost:5000/api/1'); RestangularConfigurer.setBaseUrl('http://localhost:5000/api/1');

View File

@ -30,6 +30,9 @@ angular.module('lemur')
.controller('AuthorityCreateController', function ($scope, $modalInstance, AuthorityService, LemurRestangular, RoleService, PluginService, WizardHandler) { .controller('AuthorityCreateController', function ($scope, $modalInstance, AuthorityService, LemurRestangular, RoleService, PluginService, WizardHandler) {
$scope.authority = LemurRestangular.restangularizeElement(null, {}, 'authorities'); $scope.authority = LemurRestangular.restangularizeElement(null, {}, 'authorities');
// set the defaults
AuthorityService.getDefaults($scope.authority);
$scope.loading = false; $scope.loading = false;
$scope.create = function (authority) { $scope.create = function (authority) {
WizardHandler.wizard().context.loading = true; WizardHandler.wizard().context.loading = true;

View File

@ -10,7 +10,7 @@
Owner Owner
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="email" name="owner" ng-model="authority.owner" placeholder="owner@netflix.com" <input type="email" name="owner" ng-model="authority.owner" placeholder="owner@example.com"
class="form-control" required/> class="form-control" required/>
<p ng-show="editForm.owner.$invalid && !editForm.owner.$pristine" class="help-block">Enter a valid <p ng-show="editForm.owner.$invalid && !editForm.owner.$pristine" class="help-block">Enter a valid

View File

@ -16,7 +16,7 @@
Owner Owner
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="email" name="ownerEmail" ng-model="authority.ownerEmail" placeholder="TeamDL@netflix.com" tooltip="This is the authorities team distribution list or the main point of contact for this authority" class="form-control" required/> <input type="email" name="ownerEmail" ng-model="authority.ownerEmail" placeholder="TeamDL@example.com" tooltip="This is the authorities team distribution list or the main point of contact for this authority" class="form-control" required/>
<p ng-show="trackingForm.ownerEmail.$invalid && !trackingForm.ownerEmail.$pristine" class="help-block">You must enter an Certificate Authority owner</p> <p ng-show="trackingForm.ownerEmail.$invalid && !trackingForm.ownerEmail.$pristine" class="help-block">You must enter an Certificate Authority owner</p>
</div> </div>
</div> </div>

View File

@ -56,7 +56,7 @@ angular.module('lemur')
}); });
return LemurRestangular.all('authorities'); return LemurRestangular.all('authorities');
}) })
.service('AuthorityService', function ($location, AuthorityApi, toaster) { .service('AuthorityService', function ($location, AuthorityApi, DefaultService, toaster) {
var AuthorityService = this; var AuthorityService = this;
AuthorityService.findAuthorityByName = function (filterValue) { AuthorityService.findAuthorityByName = function (filterValue) {
return AuthorityApi.getList({'filter[name]': filterValue}) return AuthorityApi.getList({'filter[name]': filterValue})
@ -117,6 +117,16 @@ angular.module('lemur')
}); });
}; };
AuthorityService.getDefaults = function (authority) {
return DefaultService.get().then(function (defaults) {
authority.caDN.country = defaults.country;
authority.caDN.state = defaults.state;
authority.caDN.location = defaults.location;
authority.caDN.organization = defaults.organization;
authority.caDN.organizationalUnit = defaults.organizationalUnit;
});
};
AuthorityService.getRoles = function (authority) { AuthorityService.getRoles = function (authority) {
return authority.getList('roles').then(function (roles) { return authority.getList('roles').then(function (roles) {
authority.roles = roles; authority.roles = roles;

View File

@ -4,7 +4,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="certificate.selectedDestination" placeholder="AWS, TheSecret..." <input type="text" ng-model="certificate.selectedDestination" placeholder="AWS..."
typeahead="destination.label for destination in destinationService.findDestinationsByName($viewValue)" typeahead-loading="loadingDestinations" typeahead="destination.label for destination in destinationService.findDestinationsByName($viewValue)" typeahead-loading="loadingDestinations"
class="form-control input-md" typeahead-on-select="certificate.attachDestination($item)" typeahead-min-wait="50" class="form-control input-md" typeahead-on-select="certificate.attachDestination($item)" typeahead-min-wait="50"
tooltip="Lemur can upload certificates to any pre-defined destination" tooltip="Lemur can upload certificates to any pre-defined destination"

View File

@ -6,7 +6,7 @@
Owner Owner
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="email" name="ownerEmail" ng-model="certificate.owner" placeholder="TeamDL@netflix.com" tooltip="This is the certificates team distribution list or main point of contact" class="form-control" required/> <input type="email" name="ownerEmail" ng-model="certificate.owner" placeholder="TeamDL@example.com" tooltip="This is the certificates team distribution list or main point of contact" class="form-control" required/>
<p ng-show="trackingForm.ownerEmail.$invalid && !trackingForm.ownerEmail.$pristine" class="help-block">You must enter an Certificate owner</p> <p ng-show="trackingForm.ownerEmail.$invalid && !trackingForm.ownerEmail.$pristine" class="help-block">You must enter an Certificate owner</p>
</div> </div>
</div> </div>

View File

@ -11,7 +11,7 @@
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="email" name="owner" ng-model="certificate.owner" placeholder="owner@netflix.com" <input type="email" name="owner" ng-model="certificate.owner" placeholder="owner@example.com"
class="form-control" required/> class="form-control" required/>
<p ng-show="uploadForm.owner.$invalid && !uploadForm.owner.$pristine" class="help-block">Enter a valid <p ng-show="uploadForm.owner.$invalid && !uploadForm.owner.$pristine" class="help-block">Enter a valid
@ -24,7 +24,7 @@
Custom Name <span class="glyphicon glyphicon-question-sign"></span> Custom Name <span class="glyphicon glyphicon-question-sign"></span>
</label> </label>
<div class="col-sm-10"> <div class="col-sm-10">
<input name="name" ng-model="certificate.name" placeholder="example.netflix.net-SymantecCorporation-20150828-20160830" class="form-control"/> <input name="name" ng-model="certificate.name" placeholder="the.example.net-SymantecCorporation-20150828-20160830" class="form-control"/>
</div> </div>
</div> </div>
<div class="form-group" <div class="form-group"

View File

@ -89,7 +89,7 @@ angular.module('lemur')
}); });
return LemurRestangular.all('certificates'); return LemurRestangular.all('certificates');
}) })
.service('CertificateService', function ($location, CertificateApi, LemurRestangular, toaster) { .service('CertificateService', function ($location, CertificateApi, LemurRestangular, DefaultService, toaster) {
var CertificateService = this; var CertificateService = this;
CertificateService.findCertificatesByName = function (filterValue) { CertificateService.findCertificatesByName = function (filterValue) {
return CertificateApi.getList({'filter[name]': filterValue}) return CertificateApi.getList({'filter[name]': filterValue})
@ -207,7 +207,7 @@ angular.module('lemur')
}; };
CertificateService.getDefaults = function (certificate) { CertificateService.getDefaults = function (certificate) {
return certificate.customGET('defaults').then(function (defaults) { return DefaultService.get().then(function (defaults) {
certificate.country = defaults.country; certificate.country = defaults.country;
certificate.state = defaults.state; certificate.state = defaults.state;
certificate.location = defaults.location; certificate.location = defaults.location;

View File

@ -8,12 +8,5 @@
<div class="row featurette"> <div class="row featurette">
<div class="col-md-10"> <div class="col-md-10">
<h2 class="featurette-heading">SSL In The Cloud <span class="text-muted">Encrypt it all </span></h2> <h2 class="featurette-heading">SSL In The Cloud <span class="text-muted">Encrypt it all </span></h2>
<p class="lead">The Security Operations team manages all of the SSL certificate generation at Netflix. This
portal was created to serve as both a self service application so that application owners can provision
their own certificates and to help enforce some key naming and security conventions, in order provide
Netflix with scalable and manageable SSL security.</p>
<p>See <a href="http://go/ssl">go/ssl</a> for more info.</p>
</div> </div>
</div> </div>

View File

@ -1,33 +0,0 @@
"""
.. module: lemur.status.views
:copyright: (c) 2015 by Netflix Inc., see AUTHORS for more
:license: Apache, see LICENSE for more details.
"""
import os
from flask import app, Blueprint, jsonify
from flask.ext.restful import Api
from lemur.auth.service import AuthenticatedResource
mod = Blueprint('status', __name__)
api = Api(mod)
class Status(AuthenticatedResource):
""" Defines the 'accounts' endpoint """
def __init__(self):
super(Status, self).__init__()
def get(self):
if not os.path.isdir(os.path.join(app.config.get("KEY_PATH"), "decrypted")):
return jsonify({
'environment': app.config.get('ENVIRONMENT'),
'status': 'degraded',
'message': "This Lemur instance is in a degraded state and is unable to issue certificates, please alert secops@netflix.com"})
else:
return jsonify({
'environment': app.config.get('ENVIRONMENT'),
'status': 'healthy',
'message': "This Lemur instance is healthy"})

View File

@ -16,7 +16,7 @@ from distutils.core import Command
from setuptools.command.develop import develop from setuptools.command.develop import develop
from setuptools.command.install import install from setuptools.command.install import install
from setuptools.command.sdist import sdist from setuptools.command.sdist import sdist
from setuptools import setup from setuptools import setup, find_packages
from subprocess import check_output from subprocess import check_output
ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__))) ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__)))
@ -110,11 +110,11 @@ class BuildStatic(Command):
setup( setup(
name='lemur', name='lemur',
version='0.1', version='0.1.3',
author='Kevin Glisson', author='Kevin Glisson',
author_email='kglisson@netflix.com', author_email='kglisson@netflix.com',
long_description=open(os.path.join(ROOT, 'README.rst')).read(), long_description=open(os.path.join(ROOT, 'README.rst')).read(),
packages=['lemur'], packages=find_packages(),
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
install_requires=install_requires, install_requires=install_requires,
@ -127,7 +127,6 @@ setup(
'build_static': BuildStatic, 'build_static': BuildStatic,
'sdist': SdistWithBuildStatic, 'sdist': SdistWithBuildStatic,
'install': SmartInstall 'install': SmartInstall
}, },
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [