commit
541d5420bb
|
@ -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 *~
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
|
||||||
|
|
|
@ -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')
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"})
|
|
7
setup.py
7
setup.py
|
@ -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': [
|
||||||
|
|
Loading…
Reference in New Issue