Merge pull request #28 from kevgliss/docs

Adding additional plugin documentation
This commit is contained in:
kevgliss 2015-07-31 19:07:02 -07:00
commit 46c6b8f8a4
39 changed files with 866 additions and 286 deletions

View File

@ -1,7 +1,16 @@
Lemur
*****
=====
[![Build Status](https://magnum.travis-ci.com/Netflix/lemur.svg?token=i5tcyx3z4N7pEVTxTeuP&branch=master)](https://magnum.travis-ci.com/Netflix/lemur)
.. image:: https://img.shields.io/pypi/v/lemur.svg
:target: https://pypi.python.org/pypi/lemur/
:alt: Latest Version
.. image:: https://readthedocs.org/projects/lemur/badge/?version=latest
:target: https://lemur.readthedocs.org
:alt: Latest Docs
.. image:: https://magnum.travis-ci.com/Netflix/lemur.svg?branch=master
:target: https://magnum.travis-ci.com/Netflix/lemur
Lemur manages SSL certificate creation. It provides a central portal for developers to issuer their own SSL certificates with 'sane' defaults.

View File

@ -223,35 +223,17 @@ If you are not using PING you do not need to configure any of these options
AWS Configuration
=================
AWS Plugin Configuration
========================
In order for Lemur to manage it's own account and other accounts we must ensure it has the correct AWS permissions.
.. note:: AWS usage is completely optional. Lemur can upload, find and manage SSL certificates in AWS. But is not required to do so.
AWS Configuration Options
-------------------------
.. data:: AWS_ACCOUNT_MAPPINGS
:noindex:
Lemur maintains it's own internal table of AWS accounts with their alias and account numbers, this variable is used during setup to bootstrap
your particular enviroment.
Defaults to ``{}``.
::
AWS_ACCOUNT_MAPPINGS = {
'awsaccountalias': 111111111111
}
Setting up IAM roles
--------------------
Lemur uses boto heavily to talk to all the AWS resources it manages. By default it uses the on-instance credentials to make the necessary calls.
Lemur's aws plugin uses boto heavily to talk to all the AWS resources it manages. By default it uses the on-instance credentials to make the necessary calls.
In order to limit the permissions we will create a new two IAM roles for Lemur. You can name them whatever you would like but for example sake we will be calling them LemurInstanceProfile and Lemur.
@ -554,5 +536,3 @@ These permissions are applied to the user upon login and refreshed on every requ
.. seealso::
`Flask-Principal <https://pythonhosted.org/Flask-Principal>`_

View File

@ -178,6 +178,7 @@ Uncertain about how to write tests? Take a look at some existing tests that are
You can see a list of open pull requests (pending changes) by visiting https://github.com/netflix/lemur/pulls
Pull requests should be against **master** and pass all TravisCI checks
Plugins
=======

View File

@ -1,20 +0,0 @@
accounts Package
================
:mod:`models` Module
--------------------
.. automodule:: lemur.accounts.models
:members:
:undoc-members:
:show-inheritance:
:mod:`service` Module
---------------------
.. automodule:: lemur.accounts.service
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,11 +0,0 @@
analyze Package
===============
:mod:`service` Module
---------------------
.. automodule:: lemur.analyze.service
:members:
:undoc-members:
:show-inheritance:

View File

@ -5,6 +5,7 @@ auth Package
-------------------------
.. automodule:: lemur.auth.permissions
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,8 +14,16 @@ auth Package
---------------------
.. automodule:: lemur.auth.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.auth.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -5,6 +5,7 @@ authorities Package
--------------------
.. automodule:: lemur.authorities.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,8 +14,16 @@ authorities Package
---------------------
.. automodule:: lemur.authorities.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.authorities.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -5,6 +5,7 @@ certificates Package
------------------------
.. automodule:: lemur.certificates.exceptions
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,6 +14,7 @@ certificates Package
--------------------
.. automodule:: lemur.certificates.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -21,6 +23,7 @@ certificates Package
---------------------
.. automodule:: lemur.certificates.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -29,6 +32,7 @@ certificates Package
------------------
.. automodule:: lemur.certificates.sync
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -37,7 +41,16 @@ certificates Package
--------------------
.. automodule:: lemur.certificates.verify
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.certificates.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,18 +1,20 @@
common Package
==============
:mod:`crypto` Module
--------------------
.. automodule:: lemur.common.crypto
:members:
:undoc-members:
:show-inheritance:
:mod:`health` Module
--------------------
.. automodule:: lemur.common.health
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`managers` Module
----------------------
.. automodule:: lemur.common.managers
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -21,14 +23,7 @@ common Package
-------------------
.. automodule:: lemur.common.utils
:noindex:
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
lemur.common.services

View File

@ -1,35 +0,0 @@
aws Package
===========
:mod:`elb` Module
-----------------
.. automodule:: lemur.common.services.aws.elb
:members:
:undoc-members:
:show-inheritance:
:mod:`iam` Module
-----------------
.. automodule:: lemur.common.services.aws.iam
:members:
:undoc-members:
:show-inheritance:
:mod:`ses` Module
-----------------
.. automodule:: lemur.common.services.aws.ses
:members:
:undoc-members:
:show-inheritance:
:mod:`sts` Module
-----------------
.. automodule:: lemur.common.services.aws.sts
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,19 +0,0 @@
cloudca Package
===============
:mod:`cloudca` Module
---------------------
.. automodule:: lemur.common.services.issuers.plugins.cloudca.cloudca
:members:
:undoc-members:
:show-inheritance:
:mod:`constants` Module
-----------------------
.. automodule:: lemur.common.services.issuers.plugins.cloudca.constants
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,11 +0,0 @@
plugins Package
===============
Subpackages
-----------
.. toctree::
lemur.common.services.issuers.plugins.cloudca
lemur.common.services.issuers.plugins.verisign

View File

@ -1,19 +0,0 @@
verisign Package
================
:mod:`constants` Module
-----------------------
.. automodule:: lemur.common.services.issuers.plugins.verisign.constants
:members:
:undoc-members:
:show-inheritance:
:mod:`verisign` Module
----------------------
.. automodule:: lemur.common.services.issuers.plugins.verisign.verisign
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,26 +0,0 @@
issuers Package
===============
:mod:`issuer` Module
--------------------
.. automodule:: lemur.common.services.issuers.issuer
:members:
:undoc-members:
:show-inheritance:
:mod:`manager` Module
---------------------
.. automodule:: lemur.common.services.issuers.manager
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
lemur.common.services.issuers.plugins

View File

@ -1,11 +0,0 @@
services Package
================
Subpackages
-----------
.. toctree::
lemur.common.services.aws
lemur.common.services.issuers

View File

@ -1,10 +1,11 @@
listeners Package
=================
destinations Package
====================
:mod:`models` Module
--------------------
.. automodule:: lemur.listeners.models
.. automodule:: lemur.destinations.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -12,7 +13,8 @@ listeners Package
:mod:`service` Module
---------------------
.. automodule:: lemur.listeners.service
.. automodule:: lemur.destinations.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -20,8 +22,8 @@ listeners Package
:mod:`views` Module
-------------------
.. automodule:: lemur.listeners.views
.. automodule:: lemur.destinations.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -5,6 +5,7 @@ domains Package
--------------------
.. automodule:: lemur.domains.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,7 +14,16 @@ domains Package
---------------------
.. automodule:: lemur.domains.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.domains.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,10 +1,11 @@
elbs Package
============
notifications Package
=====================
:mod:`models` Module
--------------------
.. automodule:: lemur.elbs.models
.. automodule:: lemur.notifications.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -12,15 +13,8 @@ elbs Package
:mod:`service` Module
---------------------
.. automodule:: lemur.elbs.service
:members:
:undoc-members:
:show-inheritance:
:mod:`sync` Module
------------------
.. automodule:: lemur.elbs.sync
.. automodule:: lemur.notifications.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -28,8 +22,8 @@ elbs Package
:mod:`views` Module
-------------------
.. automodule:: lemur.elbs.views
.. automodule:: lemur.notifications.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,29 @@
base Package
============
:mod:`base` Package
-------------------
.. automodule:: lemur.plugins.base
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`manager` Module
---------------------
.. automodule:: lemur.plugins.base.manager
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`v1` Module
----------------
.. automodule:: lemur.plugins.base.v1
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,47 @@
bases Package
=============
:mod:`bases` Package
--------------------
.. automodule:: lemur.plugins.bases
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`destination` Module
-------------------------
.. automodule:: lemur.plugins.bases.destination
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`issuer` Module
--------------------
.. automodule:: lemur.plugins.bases.issuer
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`notification` Module
--------------------------
.. automodule:: lemur.plugins.bases.notification
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`source` Module
--------------------
.. automodule:: lemur.plugins.bases.source
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,47 @@
lemur_aws Package
=================
:mod:`lemur_aws` Package
------------------------
.. automodule:: lemur.plugins.lemur_aws
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`elb` Module
-----------------
.. automodule:: lemur.plugins.lemur_aws.elb
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`iam` Module
-----------------
.. automodule:: lemur.plugins.lemur_aws.iam
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`plugin` Module
--------------------
.. automodule:: lemur.plugins.lemur_aws.plugin
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`sts` Module
-----------------
.. automodule:: lemur.plugins.lemur_aws.sts
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,20 @@
lemur_cloudca Package
=====================
:mod:`lemur_cloudca` Package
----------------------------
.. automodule:: lemur.plugins.lemur_cloudca
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`plugin` Module
--------------------
.. automodule:: lemur.plugins.lemur_cloudca.plugin
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,27 @@
lemur_email Package
===================
:mod:`lemur_email` Package
--------------------------
.. automodule:: lemur.plugins.lemur_email
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`plugin` Module
--------------------
.. automodule:: lemur.plugins.lemur_email.plugin
:noindex:
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
lemur.plugins.lemur_email.templates

View File

@ -0,0 +1,11 @@
templates Package
=================
:mod:`config` Module
--------------------
.. automodule:: lemur.plugins.lemur_email.templates.config
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,29 @@
lemur_verisign Package
======================
:mod:`lemur_verisign` Package
-----------------------------
.. automodule:: lemur.plugins.lemur_verisign
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`constants` Module
-----------------------
.. automodule:: lemur.plugins.lemur_verisign.constants
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`plugin` Module
--------------------
.. automodule:: lemur.plugins.lemur_verisign.plugin
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -0,0 +1,32 @@
plugins Package
===============
:mod:`plugins` Package
----------------------
.. automodule:: lemur.plugins
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.plugins.views
:noindex:
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
lemur.plugins.base
lemur.plugins.bases
lemur.plugins.lemur_aws
lemur.plugins.lemur_cloudca
lemur.plugins.lemur_email
lemur.plugins.lemur_verisign

View File

@ -5,6 +5,7 @@ roles Package
--------------------
.. automodule:: lemur.roles.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,8 +14,16 @@ roles Package
---------------------
.. automodule:: lemur.roles.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.roles.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -1,7 +1,20 @@
lemur Package
=============
:mod:`lemur` Package
--------------------
.. automodule:: lemur.__init__
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`constants` Module
-----------------------
.. automodule:: lemur.constants
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -10,6 +23,7 @@
----------------------
.. automodule:: lemur.database
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -18,6 +32,7 @@
------------------------
.. automodule:: lemur.decorators
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -26,6 +41,7 @@
------------------------
.. automodule:: lemur.exceptions
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -34,6 +50,7 @@
------------------------
.. automodule:: lemur.extensions
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -42,6 +59,7 @@
---------------------
.. automodule:: lemur.factory
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -50,6 +68,7 @@
--------------------
.. automodule:: lemur.manage
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -58,14 +77,7 @@
--------------------
.. automodule:: lemur.models
:members:
:undoc-members:
:show-inheritance:
:mod:`notifications` Module
---------------------------
.. automodule:: lemur.notifications
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -75,13 +87,14 @@ Subpackages
.. toctree::
lemur.accounts
lemur.auth
lemur.authorities
lemur.certificates
lemur.common
lemur.destinations
lemur.domains
lemur.notifications
lemur.plugins
lemur.roles
lemur.status
lemur.users

View File

@ -5,7 +5,7 @@ status Package
-------------------
.. automodule:: lemur.status.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -5,6 +5,7 @@ users Package
--------------------
.. automodule:: lemur.users.models
:noindex:
:members:
:undoc-members:
:show-inheritance:
@ -13,7 +14,16 @@ users Package
---------------------
.. automodule:: lemur.users.service
:noindex:
:members:
:undoc-members:
:show-inheritance:
:mod:`views` Module
-------------------
.. automodule:: lemur.users.views
:noindex:
:members:
:undoc-members:
:show-inheritance:

View File

@ -6,6 +6,11 @@ Several interfaces exist for extending Lemur:
* Issuer (lemur.plugins.base.issuer)
* Destination (lemur.plugins.base.destination)
* Source (lemur.plugins.base.source)
* Notification (lemur.plugins.base.notification)
Each interface has its own function that will need to be defined in order for
your plugin to work correctly. See :ref:`Plugin Interfaces <PluginInterfaces>` for details.
Structure
---------
@ -54,44 +59,175 @@ And you'll register it via ``entry_points`` in your ``setup.py``::
},
)
You can potentially package multiple plugin types in one package, say you want to create a source and
destination plugins for the same third-party. To accomplish this simply alias the plugin in entry points to point
at multiple plugins within your package::
setup(
# ...
entry_points={
'lemur.plugins': [
'pluginnamesource = lemur_pluginname.plugin:PluginNameSource',
'pluginnamedestination = lemur_pluginname.plugin:PluginNameDestination'
],
},
)
That's it! Users will be able to install your plugin via ``pip install <package name>``.
Interfaces
==========
.. SeeAlso:: For more information about python packages see `Python Packaging <https://packaging.python.org/en/latest/distributing.html>`_
Lemur has several different plugin interfaces that are used to extend Lemur, each of them require
that you subclass and override their functions in order for your plugin to function.
.. _PluginInterfaces:
Plugin Interfaces
=================
In order to use the interfaces all plugins are required to inherit and override unimplemented functions
of the parent object.
Issuer
------
Issuer plugins are to be used when you want to allow Lemur to use external services to create certificates.
In the simple case this means that you have one Certificate Authority and you ask it for certificates given a
few parameters. In a more advanced case this could mean that this third party not only allows you to create certifcates
but also allows you to create Certificate Authorities and Sub Certificate Authorities.
Issuer plugins are used when you have an external service that creates certificates or authorities.
In the simple case the third party only issues certificates (Verisign, DigiCert, etc.).
The `IssuerPlugin` interface only required that you implement one function::
If you have a third party or internal service that creates authorities (CloudCA, EJBCA, etc.), Lemur has you covered,
it can treat any issuer plugin as both a source of creating new certificates as well as new authorities.
The `IssuerPlugin` exposes two functions::
def create_certificate(self, options):
# requests.get('a third party')
Lemur will pass a dictionary of all possible options for certificate creation. Including a valid CSR, and the raw options associated with the request.
Lemur will pass a dictionary of all possible options for certificate creation.
Optionally the `IssuerPlugin` exposes another function for authority create::
If you wish to be able to create new authorities implement the following function and ensure that the ROOT_CERTIFICATE and the INTERMEDIATE_CERTIFICATE (if any) for the new authority is returned::
def create_authority(self, options):
# request.get('a third party')
root_cert, intermediate_cert, username, password = request.get('a third party')
# if your provider creates specific credentials for each authority you can associated them with the role associated with the authority
# these credentials will be provided along with any other options when a certificate is created
role = dict(username=username, password=password, name='generatedAuthority')
return root_cert, intermediate_cert, [role]
If implemented this function will be used to allow users to create external Certificate Authorities. From this function
you are expected to return the ROOT certificate authority, any intermediates that Authority might provide and any roles
you wish to be associated with this authority.
.. Note::
Lemur uses PEM formatted certificates as it's internal standard, if you receive certificates in other formats convert them to PEM before returning.
.. Note:: You do not need to associate roles to the authority at creation time as they can always be associated after the
fact.
If instead you do not need need to generate authorities but instead use a static authority (Verisign, DigiCert), you can use publicly available constants::
def create_authority(self, options):
# optionally associate a role with authority to control who can use it
role = dict(username='', password='', name='exampleAuthority')
# username and password don't really matter here because we do no need to authenticate our authority against a third party
return EXAMPLE_ROOT_CERTIFICATE, EXAMPLE_INTERMEDIATE_CERTIFICATE, [role]
.. Note:: You do not need to associate roles to the authority at creation time as they can always be associated after the fact.
The `IssuerPlugin` doesn't have any options like Destination, Source, and Notification plugins. Essentially Lemur **should** already have
any fields you might need to submit a request to a third party. If there are additional options you need
in your plugin feel free to open an issue, or look into adding additional options to issuers yourself.
Destination
-----------
Destination plugins allow you to propagate certificates managed by Lemur to additional third parties. This provides flexibility when
different orchestration systems have their own way of manage certificates or there is an existing system you wish to integrate with Lemur.
The DestinationPlugin requires only one function to be implemented::
def upload(self, cert, private_key, cert_chain, options, **kwargs):
# request.post('a third party')
Additionally the DestinationPlugin allows the plugin author to add additional options
that can be used to help define sub-destinations.
For example, if we look at the aws-destination plugin we can see that it defines an `accountNumber` option::
options = [
{
'name': 'accountNumber',
'type': 'int',
'required': True,
'validation': '/^[0-9]{12,12}$/',
'helpMessage': 'Must be a valid AWS account number!',
}
]
By defining an `accountNumber` we can make this plugin handle many N number of AWS accounts instead of just one.
The schema for defining plugin options are pretty straightforward:
- **Name**: name of the variable you wish to present the user, snake case (snakeCase) is preferrred as Lemur
will parse these and create pretty variable titles
- **Type** there are currently four supported variable types
- **Int** creates an html integer box for the user to enter integers into
- **Str** creates a html text input box
- **Boolean** creates a checkbox for the user to signify truithyness
- **Select** creates a select box that gives the user a list of options
- When used a `available` key must be provided with a list of selectable options
- **Required** determines if this option is required, this **must be a boolean value**
- **Validation** simple JavaScript regular expression used to give the user an indication if the input value is valid
- **HelpMessage** simple string that provides more detail about the option
.. Note::
DestinationPlugin, NotificationPlugin and SourcePlugin all support the option
schema outlined above.
Notification
------------
Lemur includes the ability to create Email notifications by **default**. These notifications
currently come in the form of expiration noticies. Lemur periodically checks certifications expiration dates and
determines if a given certificate is eligible for notification. There are currently only two parameters used to
determine if a certificate is eligible; validity expiration (date the certificate is no longer valid) and the number
of days the current date (UTC) is from that expiration date.
There are currently two objects that available for notification plugins the first is `NotficationPlugin`. This is the base object for
any notification within Lemur. Currently the only support notification type is an certificate expiration notification. If you
are trying to create a new notification type (audit, failed logins, etc.) this would be the object to base your plugin on.
You would also then need to build additional code to trigger the new notification type.
The second is `ExpirationNotificationPlugin`, this object inherits from `NotificationPlugin` object.
You will most likely want to base your plugin on, if you want to add new channels for expiration notices (Slack, Hipcat, Jira, etc.). It adds default options that are required by
by all expiration notifications (interval, unit). This interface expects for the child to define the following function::
def send(self):
# request.post("some alerting infrastructure")
Source
------
When building Lemur we realized that although it would be nice if every certificate went through Lemur to get issued, but this is not
always be the case. Often times there are third parties that will issue certificates on your behalf and these can get deployed
to infrastructure without any interaction with Lemur. In an attempt to combat this and try to track every certificate, Lemur has a notion of
certificate **Sources**. Lemur will contact the source at periodic intervals and attempt to **sync** against the source. This means downloading or discovering any
certificate Lemur does not know about and adding the certificate to it's inventory to be tracked and alerted on.
The `SourcePlugin` object has one default option of `pollRate`. This controls the number of seconds which to get new certificates.
.. warning::
Lemur currently has a very basic polling system of running a cron job every 15min to see which source plugins need to be run.
This means special consideration needs to be taken such that running all `SourcePlugins` does not take >15min to run. It also means
that the minimum resolution of a source plugin poll rate is effectively 15min.
The `SourcePlugin` object requires implementation of one function::
def get_certificates(self, **kwargs):
# request.get("some source of certificates")
.. Note::
Often times to facilitate code re-use it makes sense put source and destination plugins into one package.
Testing
@ -165,5 +301,4 @@ Running tests follows the py.test standard. As long as your test files and metho
=========================== 1 passed in 0.35 seconds ============================
.. SeeAlso:: Lemur bundles several plugins that use the same interfaces mentioned above. View the source: #TODO
.. SeeAlso:: Lemur bundles several plugins that use the same interfaces mentioned above. View the source: # TODO

View File

@ -9,10 +9,18 @@ Authentication
:undoc-members:
:show-inheritance:
Accounts
--------
Destinations
------------
.. automodule:: lemur.accounts.views
.. automodule:: lemur.destinations.views
:members:
:undoc-members:
:show-inheritance:
Notifications
-------------
.. automodule:: lemur.notifications.views
:members:
:undoc-members:
:show-inheritance:
@ -56,5 +64,3 @@ Domains
:members:
:undoc-members:
:show-inheritance:

261
docs/generate_api.py Normal file
View File

@ -0,0 +1,261 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
sphinx-autopackage-script
This script parses a directory tree looking for python modules and packages and
creates ReST files appropriately to create code documentation with Sphinx.
It also creates a modules index (named modules.<suffix>).
"""
# Copyright 2008 Société des arts technologiques (SAT), http://www.sat.qc.ca/
# Copyright 2010 Thomas Waldmann <tw AT waldmann-edv DOT de>
# All rights reserved.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import optparse
# automodule options
OPTIONS = ['members',
'undoc-members',
# 'inherited-members', # disabled because there's a bug in sphinx
'show-inheritance',
]
INIT = '__init__.py'
def makename(package, module):
"""Join package and module with a dot."""
# Both package and module can be None/empty.
if package:
name = package
if module:
name += '.' + module
else:
name = module
return name
def write_file(name, text, opts):
"""Write the output file for module/package <name>."""
if opts.dryrun:
return
fname = os.path.join(opts.destdir, "%s.%s" % (name, opts.suffix))
if not opts.force and os.path.isfile(fname):
print 'File %s already exists, skipping.' % fname
else:
print 'Creating file %s.' % fname
f = open(fname, 'w')
f.write(text)
f.close()
def format_heading(level, text):
"""Create a heading of <level> [1, 2 or 3 supported]."""
underlining = ['=', '-', '~', ][level-1] * len(text)
return '%s\n%s\n\n' % (text, underlining)
def format_directive(module, package=None):
"""Create the automodule directive and add the options."""
directive = '.. automodule:: %s\n' % makename(package, module)
for option in OPTIONS:
directive += ' :%s:\n' % option
return directive
def create_module_file(package, module, opts):
"""Build the text of the file and write the file."""
text = format_heading(1, '%s Module' % module)
text += format_heading(2, ':mod:`%s` Module' % module)
text += format_directive(module, package)
write_file(makename(package, module), text, opts)
def create_package_file(root, master_package, subroot, py_files, opts, subs):
"""Build the text of the file and write the file."""
package = os.path.split(root)[-1]
text = format_heading(1, '%s Package' % package)
# add each package's module
for py_file in py_files:
if shall_skip(os.path.join(root, py_file)):
continue
is_package = py_file == INIT
py_file = os.path.splitext(py_file)[0]
py_path = makename(subroot, py_file)
if is_package:
heading = ':mod:`%s` Package' % package
else:
heading = ':mod:`%s` Module' % py_file
text += format_heading(2, heading)
text += format_directive(is_package and subroot or py_path, master_package)
text += '\n'
# build a list of directories that are packages (they contain an INIT file)
subs = [sub for sub in subs if os.path.isfile(os.path.join(root, sub, INIT))]
# if there are some package directories, add a TOC for theses subpackages
if subs:
text += format_heading(2, 'Subpackages')
text += '.. toctree::\n\n'
for sub in subs:
text += ' %s.%s\n' % (makename(master_package, subroot), sub)
text += '\n'
write_file(makename(master_package, subroot), text, opts)
def create_modules_toc_file(master_package, modules, opts, name='modules'):
"""
Create the module's index.
"""
text = format_heading(1, '%s Modules' % opts.header)
text += '.. toctree::\n'
text += ' :maxdepth: %s\n\n' % opts.maxdepth
modules.sort()
prev_module = ''
for module in modules:
# look if the module is a subpackage and, if yes, ignore it
if module.startswith(prev_module + '.'):
continue
prev_module = module
text += ' %s\n' % module
write_file(name, text, opts)
def shall_skip(module):
"""
Check if we want to skip this module.
"""
# skip it, if there is nothing (or just \n or \r\n) in the file
return os.path.getsize(module) < 3
def recurse_tree(path, excludes, opts):
"""
Look for every file in the directory tree and create the corresponding
ReST files.
"""
# use absolute path for root, as relative paths like '../../foo' cause
# 'if "/." in root ...' to filter out *all* modules otherwise
path = os.path.abspath(path)
# check if the base directory is a package and get is name
if INIT in os.listdir(path):
package_name = path.split(os.path.sep)[-1]
else:
package_name = None
toc = []
tree = os.walk(path, False)
for root, subs, files in tree:
# keep only the Python script files
py_files = sorted([f for f in files if os.path.splitext(f)[1] == '.py'])
if INIT in py_files:
py_files.remove(INIT)
py_files.insert(0, INIT)
# remove hidden ('.') and private ('_') directories
subs = sorted([sub for sub in subs if sub[0] not in ['.', '_']])
# check if there are valid files to process
# TODO: could add check for windows hidden files
if "/." in root or "/_" in root \
or not py_files \
or is_excluded(root, excludes):
continue
if INIT in py_files:
# we are in package ...
if (# ... with subpackage(s)
subs
or
# ... with some module(s)
len(py_files) > 1
or
# ... with a not-to-be-skipped INIT file
not shall_skip(os.path.join(root, INIT))
):
subroot = root[len(path):].lstrip(os.path.sep).replace(os.path.sep, '.')
create_package_file(root, package_name, subroot, py_files, opts, subs)
toc.append(makename(package_name, subroot))
elif root == path:
# if we are at the root level, we don't require it to be a package
for py_file in py_files:
if not shall_skip(os.path.join(path, py_file)):
module = os.path.splitext(py_file)[0]
create_module_file(package_name, module, opts)
toc.append(makename(package_name, module))
# create the module's index
if not opts.notoc:
create_modules_toc_file(package_name, toc, opts)
def normalize_excludes(rootpath, excludes):
"""
Normalize the excluded directory list:
* must be either an absolute path or start with rootpath,
* otherwise it is joined with rootpath
* with trailing slash
"""
sep = os.path.sep
f_excludes = []
for exclude in excludes:
if not os.path.isabs(exclude) and not exclude.startswith(rootpath):
exclude = os.path.join(rootpath, exclude)
if not exclude.endswith(sep):
exclude += sep
f_excludes.append(exclude)
return f_excludes
def is_excluded(root, excludes):
"""
Check if the directory is in the exclude list.
Note: by having trailing slashes, we avoid common prefix issues, like
e.g. an exlude "foo" also accidentally excluding "foobar".
"""
sep = os.path.sep
if not root.endswith(sep):
root += sep
for exclude in excludes:
if root.startswith(exclude):
return True
return False
def main():
"""
Parse and check the command line arguments.
"""
parser = optparse.OptionParser(usage="""usage: %prog [options] <package path> [exclude paths, ...]
Note: By default this script will not overwrite already created files.""")
parser.add_option("-n", "--doc-header", action="store", dest="header", help="Documentation Header (default=Project)", default="Project")
parser.add_option("-d", "--dest-dir", action="store", dest="destdir", help="Output destination directory", default="")
parser.add_option("-s", "--suffix", action="store", dest="suffix", help="module suffix (default=txt)", default="txt")
parser.add_option("-m", "--maxdepth", action="store", dest="maxdepth", help="Maximum depth of submodules to show in the TOC (default=4)", type="int", default=4)
parser.add_option("-r", "--dry-run", action="store_true", dest="dryrun", help="Run the script without creating the files")
parser.add_option("-f", "--force", action="store_true", dest="force", help="Overwrite all the files")
parser.add_option("-t", "--no-toc", action="store_true", dest="notoc", help="Don't create the table of content file")
(opts, args) = parser.parse_args()
if not args:
parser.error("package path is required.")
else:
rootpath, excludes = args[0], args[1:]
if os.path.isdir(rootpath):
# check if the output destination is a valid directory
if opts.destdir and os.path.isdir(opts.destdir):
excludes = normalize_excludes(rootpath, excludes)
recurse_tree(rootpath, excludes, opts)
else:
print '%s is not a valid output destination directory.' % opts.destdir
else:
print '%s is not a valid directory.' % rootpath
if __name__ == '__main__':
main()

View File

@ -1,10 +1,14 @@
Creating Certificates
=====================
Creating Users
==============
Creating Roles
==============
Creating Authorities
====================
Creating Certificates
=====================

View File

@ -64,17 +64,6 @@ You will benefit from having:
You must create a Nginx configuration file for Lemur. On GNU/Linux, they usually
go into /etc/nginx/conf.d/. Name it lemur.conf.
The minimal configuration file to run the site is::
server {
listen 80;
server_name www.yourwebsite.com;
location / {
proxy_pass http://127.0.0.1:5000;
}
}
`proxy_pass` just passes the external request to the Python process.
The port much match the one used by the 0bin process of course.
@ -106,7 +95,7 @@ You can make some adjustments to get a better user experience::
}
location / {
root /www/lemur/lemur/static/dist;
root /path/to/lemur/static/dist;
include mime.types;
index index.html;
}
@ -172,7 +161,7 @@ sensitive nature of Lemur and what it controls makes this essential. This is a s
}
location / {
root /www/lemur/lemur/static/dist;
root /path/to/lemur/static/dist;
include mime.types;
index index.html;
}
@ -180,6 +169,8 @@ sensitive nature of Lemur and what it controls makes this essential. This is a s
}
.. Note:: Some paths will have to be adjusted based on where you have choose to install Lemur.
Apache
------

View File

@ -2,6 +2,7 @@ Quickstart
**********
This guide will step you through setting up a Python-based virtualenv, installing the required packages, and configuring the basic web service.
This guide assumes a clean Ubuntu 14.04 instance, commands may differ based on the OS and configuration being used.
Dependencies
------------
@ -38,6 +39,20 @@ Finally, activate your virtualenv::
install into the virtualenv by default.
Installing build dependencies
-----------------------------
If installing Lemur on true bare Ubuntu OS you will need to grab the following packages so that Lemur can correctly build it's
dependencies.
$ sudo apt-get update
$ sudo apt-get install nodejs-legacy python-pip libpq-dev python-dev build-essential libssl-dev libffi-dev nginx git supervisor
And optionally if your database is going to be on the same host as the webserver.
$ sudo apt-get install postgres
Installing Lemur
----------------
@ -89,9 +104,34 @@ You can specify `-c` or `--config` to any Lemur command to specify the current e
you are working in. Lemur will also look under the environmental variable `LEMUR_CONF` should
that be easier to setup in your environment.
Update your configuration
-------------------------
Once created you will need to update the configuration file with information about your environment,
such as which database to talk to, where keys are stores etc..
.. Note:: If you are unVfamiliar with with the SQLALCHEMY_DATABASE_URI string it can be broken up like so:
postgresql://userame:password@databasefqdn:databaseport/databasename
Setup Postgres
--------------
For production a dedicated database is recommended, for this guide we will assume postgres has been installed and is on
the same machine that Lemur is installed on.
First, set a password for the postgres user. For this guide, we will use **lemur** as an example but you should use the database password generated for by Lemur.::
$ sudo -u postgres psql postgres
# \password postgres
Enter new password: lemur
Enter it again: lemur
Type CTRL-D to exit psql once you have changed the password.
Next, we will create our a new database::
$ sudo -u postgres createdb lemur
.. _InitializingLemur:
Initializing Lemur
@ -102,6 +142,8 @@ used by Lemur to help associate certificates that do not currently have an owner
Lemur has discovered certificates from a third party resource. This is also a default user that can be used to
administer Lemur.
**Make note of the password used as this will be use to first login to the Lemur UI**
.. code-block:: bash
$ lemur db init
@ -115,12 +157,6 @@ administer Lemur.
for them or be enrolled automatically through SSO. This can be done through the CLI or UI.
See :ref:`Creating Users <CreatingUsers>` and :ref:`Command Line Interface <CommandLineInterface>` for details
.. note::
This assumes you have already created a postgres database and have specified the right postgres URI in the
lemur configuration. See the `Postgres Documentation <http://www.postgresql.org/docs/9.0/static/tutorial-createdb.html>`_
for details.
Setup a Reverse Proxy
---------------------
@ -208,7 +244,7 @@ of Lemur, but we do our best to reconcile those changes.
.. code-block:: bash
$ crontab -e
* 3 * * * lemur sync
* 3 * * * lemur sync --all
* 3 * * * lemur check_revoked
Additional Utilities
@ -238,4 +274,3 @@ The above gets you going, but for production there are several different securit
remember Lemur is handling sensitive data and security is imperative.
See :doc:`../production/index` for more details on how to configure Lemur for production.

View File

@ -185,7 +185,7 @@ class CertificatesList(AuthenticatedResource):
Host: example.com
Accept: application/json, text/javascript
{
{
"country": "US",
"state": "CA",
"location": "A Place",
@ -225,7 +225,7 @@ class CertificatesList(AuthenticatedResource):
"commonName": "test",
"validityStart": "2015-06-05T07:00:00.000Z",
"validityEnd": "2015-06-16T07:00:00.000Z"
}
}
**Example response**:

View File

@ -12,8 +12,19 @@ from lemur.plugins.base import Plugin
class SourcePlugin(Plugin):
type = 'source'
default_options = [
{
'name': 'pollRate',
'type': 'int',
'required': False,
'helpMessage': 'Rate in seconds to poll source for new information.',
'default': '60',
}
]
def get_certificates(self):
raise NotImplemented
def get_options(self):
return {}
@property
def options(self):
return list(self.default_options) + self.additional_options

View File

@ -66,13 +66,6 @@ class AWSSourcePlugin(SourcePlugin):
'validation': '/^[0-9]{12,12}$/',
'helpMessage': 'Must be a valid AWS account number!',
},
{
'name': 'pollRate',
'type': 'int',
'required': False,
'helpMessage': 'Rate in seconds to poll source for new information.',
'default': '60',
}
]
def get_certificates(self, **kwargs):