diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..69fa449dd --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 000000000..415eebca1 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,183 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " coverage to run coverage check of the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/LetsEncrypt.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/LetsEncrypt.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/LetsEncrypt" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/LetsEncrypt" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +coverage: + $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage + @echo "Testing of coverage in the sources finished, look at the " \ + "results in $(BUILDDIR)/coverage/python.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/api/client/CONFIG.rst b/docs/api/client/CONFIG.rst new file mode 100644 index 000000000..9ed190768 --- /dev/null +++ b/docs/api/client/CONFIG.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.CONFIG` +-------------------------------- + +.. automodule:: letsencrypt.client.CONFIG + :members: diff --git a/docs/api/client/acme.rst b/docs/api/client/acme.rst new file mode 100644 index 000000000..7773fae04 --- /dev/null +++ b/docs/api/client/acme.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.acme` +------------------------------ + +.. automodule:: letsencrypt.client.acme + :members: diff --git a/docs/api/client/apache_configurator.rst b/docs/api/client/apache_configurator.rst new file mode 100644 index 000000000..76818e05a --- /dev/null +++ b/docs/api/client/apache_configurator.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.apache_configurator` +--------------------------------------------- + +.. automodule:: letsencrypt.client.apache_configurator + :members: diff --git a/docs/api/client/augeas_configurator.rst b/docs/api/client/augeas_configurator.rst new file mode 100644 index 000000000..6b8ca4d83 --- /dev/null +++ b/docs/api/client/augeas_configurator.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.augeas_configurator` +--------------------------------------------- + +.. automodule:: letsencrypt.client.augeas_configurator + :members: diff --git a/docs/api/client/challenge.rst b/docs/api/client/challenge.rst new file mode 100644 index 000000000..c46e1b053 --- /dev/null +++ b/docs/api/client/challenge.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.challenge` +----------------------------------- + +.. automodule:: letsencrypt.client.challenge + :members: diff --git a/docs/api/client/client.rst b/docs/api/client/client.rst new file mode 100644 index 000000000..ac68c2764 --- /dev/null +++ b/docs/api/client/client.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.client` +-------------------------------- + +.. automodule:: letsencrypt.client.client + :members: diff --git a/docs/api/client/configurator.rst b/docs/api/client/configurator.rst new file mode 100644 index 000000000..7331f35ec --- /dev/null +++ b/docs/api/client/configurator.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.configurator` +-------------------------------------- + +.. automodule:: letsencrypt.client.configurator + :members: diff --git a/docs/api/client/crypto_util.rst b/docs/api/client/crypto_util.rst new file mode 100644 index 000000000..1b47cd151 --- /dev/null +++ b/docs/api/client/crypto_util.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.crypto_util` +------------------------------------- + +.. automodule:: letsencrypt.client.crypto_util + :members: diff --git a/docs/api/client/display.rst b/docs/api/client/display.rst new file mode 100644 index 000000000..5dde8b66d --- /dev/null +++ b/docs/api/client/display.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.display` +--------------------------------- + +.. automodule:: letsencrypt.client.display + :members: diff --git a/docs/api/client/errors.rst b/docs/api/client/errors.rst new file mode 100644 index 000000000..40f0ae6c7 --- /dev/null +++ b/docs/api/client/errors.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.errors` +-------------------------------- + +.. automodule:: letsencrypt.client.errors + :members: diff --git a/docs/api/client/index.rst b/docs/api/client/index.rst new file mode 100644 index 000000000..7fe44df50 --- /dev/null +++ b/docs/api/client/index.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client` +------------------------- + +.. automodule:: letsencrypt.client + :members: diff --git a/docs/api/client/interactive_challenge.rst b/docs/api/client/interactive_challenge.rst new file mode 100644 index 000000000..38f14f115 --- /dev/null +++ b/docs/api/client/interactive_challenge.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.interactive_challenge` +----------------------------------------------- + +.. automodule:: letsencrypt.client.interactive_challenge + :members: diff --git a/docs/api/client/le_util.rst b/docs/api/client/le_util.rst new file mode 100644 index 000000000..537e90546 --- /dev/null +++ b/docs/api/client/le_util.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.le_util` +--------------------------------- + +.. automodule:: letsencrypt.client.le_util + :members: diff --git a/docs/api/client/logger.rst b/docs/api/client/logger.rst new file mode 100644 index 000000000..8225c306c --- /dev/null +++ b/docs/api/client/logger.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.logger` +-------------------------------- + +.. automodule:: letsencrypt.client.logger + :members: diff --git a/docs/api/client/nginx_configurator.rst b/docs/api/client/nginx_configurator.rst new file mode 100644 index 000000000..efcef3ffe --- /dev/null +++ b/docs/api/client/nginx_configurator.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.nginx_configurator` +-------------------------------------------- + +.. automodule:: letsencrypt.client.nginx_configurator + :members: diff --git a/docs/api/client/recovery_contact_challenge.rst b/docs/api/client/recovery_contact_challenge.rst new file mode 100644 index 000000000..3b6e12a0f --- /dev/null +++ b/docs/api/client/recovery_contact_challenge.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.recovery_contact_challenge` +---------------------------------------------------- + +.. automodule:: letsencrypt.client.recovery_contact_challenge + :members: diff --git a/docs/api/client/recovery_token_challenge.rst b/docs/api/client/recovery_token_challenge.rst new file mode 100644 index 000000000..68fbdc6e1 --- /dev/null +++ b/docs/api/client/recovery_token_challenge.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.recovery_token_challenge` +-------------------------------------------------- + +.. automodule:: letsencrypt.client.recovery_token_challenge + :members: diff --git a/docs/api/client/validator.rst b/docs/api/client/validator.rst new file mode 100644 index 000000000..7f990e2a4 --- /dev/null +++ b/docs/api/client/validator.rst @@ -0,0 +1,5 @@ +:mod:`letsencrypt.client.validator` +----------------------------------- + +.. automodule:: letsencrypt.client.validator + :members: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..fd089d14b --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,289 @@ +# -*- coding: utf-8 -*- +# +# Let's Encrypt documentation build configuration file, created by +# sphinx-quickstart on Sun Nov 23 20:35:21 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Let\'s Encrypt' +copyright = u'2014, Let\'s Encrypt Project' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'LetsEncryptdoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'LetsEncrypt.tex', u'Let\'s Encrypt Documentation', + u'Let\'s Encrypt Project', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'letsencrypt', u'Let\'s Encrypt Documentation', + [u'Let\'s Encrypt Project'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'LetsEncrypt', u'Let\'s Encrypt Documentation', + u'Let\'s Encrypt Project', 'LetsEncrypt', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} + +todo_include_todos = True diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..c636507df --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,24 @@ +.. Let's Encrypt documentation master file, created by + sphinx-quickstart on Sun Nov 23 20:35:21 2014. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Let's Encrypt's documentation! +========================================= + +API documentation +----------------- + +.. toctree:: + :glob: + + api/** + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 000000000..e83ba8cb5 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,263 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + echo. coverage to run coverage check of the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 2> nul +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\LetsEncrypt.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\LetsEncrypt.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %~dp0 + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "coverage" ( + %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage + if errorlevel 1 exit /b 1 + echo. + echo.Testing of coverage in the sources finished, look at the ^ +results in %BUILDDIR%/coverage/python.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/letsencrypt/client/CONFIG.py b/letsencrypt/client/CONFIG.py index 1c11510c1..1c2fd496c 100644 --- a/letsencrypt/client/CONFIG.py +++ b/letsencrypt/client/CONFIG.py @@ -1,62 +1,83 @@ +"""Config for Let's Encrypt.""" import os.path -# CA hostname -# If you create your own server... change this line -# Note: the server certificate must be trusted in order to avoid -# further modifications to the client + ACME_SERVER = "letsencrypt-demo.org" -# Apache server root directory +"""CA hostname. + +If you create your own server... change this line + +Note: the server certificate must be trusted in order to avoid +further modifications to the client.""" + SERVER_ROOT = "/etc/apache2/" -# Configuration file directory for letsencrypt +"""Apache server root directory""" + CONFIG_DIR = "/etc/letsencrypt/" -# Working directory for letsencrypt +"""Configuration file directory for letsencrypt""" + WORK_DIR = "/var/lib/letsencrypt/" -# Directory where configuration backups are stored +"""Working directory for letsencrypt""" + BACKUP_DIR = os.path.join(WORK_DIR, "backups/") -# Replaces MODIFIED_FILES, directory where temp checkpoint is created +"""Directory where configuration backups are stored""" + TEMP_CHECKPOINT_DIR = os.path.join(WORK_DIR, "temp_checkpoint/") -# Directory used before a permanent checkpoint is finalized +"""Replaces MODIFIED_FILES, directory where temp checkpoint is created""" + IN_PROGRESS_DIR = os.path.join(BACKUP_DIR, "IN_PROGRESS/") -# Directory where all certificates/keys are stored - used for easy revocation +"""Directory used before a permanent checkpoint is finalized""" + CERT_KEY_BACKUP = os.path.join(WORK_DIR, "keys-certs/") -# Where all keys should be stored +"""Directory where all certificates/keys are stored. + +Used for easy revocation""" + KEY_DIR = os.path.join(SERVER_ROOT, "ssl/") -# Certificate storage +"""Where all keys should be stored""" + CERT_DIR = os.path.join(SERVER_ROOT, "certs/") +"""Certificate storage""" -# Contains standard Apache SSL directives OPTIONS_SSL_CONF = os.path.join(CONFIG_DIR, "options-ssl.conf") -# Let's Encrypt SSL vhost configuration extension +"""Contains standard Apache SSL directives""" + LE_VHOST_EXT = "-le-ssl.conf" -# Temporary file for challenge virtual hosts +"""Let's Encrypt SSL vhost configuration extension""" + APACHE_CHALLENGE_CONF = os.path.join(CONFIG_DIR, "le_dvsni_cert_challenge.conf") +"""Temporary file for challenge virtual hosts""" -# Byte size of S and Nonce S_SIZE = 32 +"""Byte size of S""" + NONCE_SIZE = 16 +"""byte size of Nonce""" -# Key Sizes RSA_KEY_SIZE = 2048 +"""Key size""" -# bits of hashcash to generate DIFFICULTY = 23 +"""bits of hashcash to generate""" -# Let's Encrypt cert and chain files CERT_PATH = CERT_DIR + "cert-letsencrypt.pem" +"""Let's Encrypt cert file.""" + CHAIN_PATH = CERT_DIR + "chain-letsencrypt.pem" +"""Let's Encrypt chain file.""" -# Invalid Extension INVALID_EXT = ".acme.invalid" +"""Invalid Extension""" -# Challenge Preferences Dict for currently supported challenges CHALLENGE_PREFERENCES = ["dvsni", "recoveryToken"] +"""Challenge Preferences Dict for currently supported challenges""" -# Mutually Exclusive Challenges - only solve 1 EXCLUSIVE_CHALLENGES = [frozenset(["dvsni", "simpleHttps"])] +"""Mutually Exclusive Challenges - only solve 1""" -# These are challenges that must be solved by a Configurator object CONFIG_CHALLENGES = frozenset(["dvsni", "simpleHttps"]) +"""These are challenges that must be solved by a Configurator object""" -# Rewrite rule arguments used for redirections to https vhost REWRITE_HTTPS_ARGS = [ "^.*$", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,R=permanent]"] +"""Rewrite rule arguments used for redirections to https vhost""" diff --git a/letsencrypt/client/acme.py b/letsencrypt/client/acme.py index 58dd0bc9b..50ab26e8b 100644 --- a/letsencrypt/client/acme.py +++ b/letsencrypt/client/acme.py @@ -29,12 +29,10 @@ SCHEMATA = dict([ def acme_object_validate(json_string, schemata=None): """Validate a JSON string against the ACME protocol using JSON Schema. - :param json_string: Well-formed input JSON string. - :type json_string: str + :param str json_string: Well-formed input JSON string. - :param schemata: Mapping from type name to JSON Schema definition. - Useful for testing. - :type schemata: dict + :param dict schemata: Mapping from type name to JSON Schema + definition. Useful for testing. :returns: None if validation was successful. @@ -66,14 +64,12 @@ def pretty(json_string): def challenge_request(name): """Create ACME "challengeRequest message. - :param name: Domain name - :type name: unicode + :param unicode name: Domain name :returns: ACME "challengeRequest" message. :rtype: dict """ - return { "type": "challengeRequest", "identifier": name, @@ -84,19 +80,10 @@ def authorization_request(req_id, name, server_nonce, responses, key_file): """Create ACME "authorizationRequest" message. :param req_id: TODO - :type req_id: TODO - :param name: TODO - :type name: TODO - :param server_nonce: TODO - :type server_nonce: TODO - :param responses: TODO - :type response: TODO - :param key_file: TODO - :type key_file: TODO :returns: ACME "authorizationRequest" message. :rtype: dict @@ -115,11 +102,8 @@ def authorization_request(req_id, name, server_nonce, responses, key_file): def certificate_request(csr_der, key): """Create ACME "certificateRequest" message. - :param csr_der: DER encoded CSR. - :type csr_der: str - + :param str csr_der: DER encoded CSR. :param key: TODO - :type key: TODO :returns: ACME "certificateRequest" message. :rtype: dict @@ -135,12 +119,10 @@ def certificate_request(csr_der, key): def revocation_request(key_file, cert_der): """Create ACME "revocationRequest" message. - :param key_file: Path to a file containing RSA key. Accepted formats - are the same as for `Crypto.PublicKey.RSA.importKey`. - :type key_file: str + :param str key_file: Path to a file containing RSA key. Accepted + formats are the same as for `Crypto.PublicKey.RSA.importKey`. - :param cert_der: DER encoded certificate. - :type cert_der: str + :param str cert_der: DER encoded certificate. :returns: ACME "revocationRequest" message. :rtype: dict @@ -156,8 +138,7 @@ def revocation_request(key_file, cert_der): def status_request(token): """Create ACME "statusRequest" message. - :param token: Token provided in ACME "defer" message. - :type token: str + :param str token: Token provided in ACME "defer" message. :returns: ACME "statusRequest" message. :rtype: dict diff --git a/letsencrypt/client/apache_configurator.py b/letsencrypt/client/apache_configurator.py index 57b37c81c..78fced67c 100644 --- a/letsencrypt/client/apache_configurator.py +++ b/letsencrypt/client/apache_configurator.py @@ -44,6 +44,8 @@ from letsencrypt.client import logger # transactional due to the use of register_file_creation() class VH(object): + """Virtual host.""" + def __init__(self, filename_path, vh_path, vh_addrs, is_ssl, is_enabled): self.file = filename_path self.path = vh_path @@ -129,25 +131,22 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Deploys certificate to specified virtual host. Currently tries to find the last directives to deploy the cert in - the given virtualhost. If it can't find the directives, it searches - the "included" confs. The function verifies that it has located + the given virtualhost. If it can't find the directives, it searches + the "included" confs. The function verifies that it has located the three directives and finally modifies them to point to the correct destination - TODO: Make sure last directive is changed - TODO: Might be nice to remove chain directive if none exists - * This shouldn't happen within letsencrypt though + + .. todo:: Make sure last directive is changed + + .. todo:: Might be nice to remove chain directive if none exists + This shouldn't happen within letsencrypt though :param vhost: ssl vhost to deploy certificate - :type vhost: VH + :type vhost: :class:`VH` - :param cert: certificate filename - :type cert: str - - :param key: private key filename - :type key: str - - :param cert_chain: certificate chain filename - :type cert_chain: str + :param strcert: certificate filename + :param str key: private key filename + :param str cert_chain: certificate chain filename :returns: Success :rtype: bool @@ -196,13 +195,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def choose_virtual_host(self, name, ssl=True): """ Chooses a virtual host based on the given domain name. - TODO: This should maybe return list if no obvious answer is presented + .. todo:: This should maybe return list if no obvious answer is presented - :param name: domain name - :type name: str + :param str name: domain name :returns: ssl vhost associated with name - :rtype: VH + :rtype: :class:`VH` """ # Allows for domain names to be associated with a virtual host @@ -244,11 +242,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Helps to choose an appropriate vhost - :param domain: domain name to associate - :type domain: str + :param str domain: domain name to associate :param vhost: virtual host to associate with domain - :type vhost: VH + :type vhost: :class:`VH` """ self.assoc[domain] = vhost @@ -257,7 +254,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Returns all names found in the Apache Configuration. :returns: All ServerNames, ServerAliases, and reverse DNS entries for - virtual host addresses + virtual host addresses :rtype: set """ @@ -286,10 +283,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def _set_user_config_file(self, filename=''): """Set the appropriate user configuration file - TODO: This will have to be updated for other distros versions + .. todo:: This will have to be updated for other distros versions - :param filename: optional filename that will be used as the user config - :type filename: str + :param str filename: optional filename that will be used as the user config """ if filename: @@ -309,7 +305,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Helper function for get_virtual_hosts(). :param host: In progress vhost whose names will be added - :type host: VH + :type host: :class:`VH` """ nameMatch = self.aug.match(("%s//*[self::directive=~regexp('%s')] | " @@ -326,11 +322,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def _create_vhost(self, path): """Used by get_virtual_hosts to create vhost objects - :param path: Augeas path to virtual host - :type path: str + :param str path: Augeas path to virtual host :returns: newly created vhost - :rtype: VH + :rtype: :class:`VH` """ addrs = [] @@ -353,7 +348,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def get_virtual_hosts(self): """Returns list of virtual hosts found in the Apache configuration. - :returns: List of VH objects found in configuration + :returns: List of :class:`VH` objects found in configuration :rtype: list """ @@ -372,8 +367,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Checks if addr has a NameVirtualHost directive in the Apache config - :param addr: vhost address ie. *:443 - :type addr: str + :param str addr: vhost address ie. \*:443 :returns: Success :rtype: bool @@ -403,8 +397,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Directive is added to ports.conf unless the file doesn't exist It is added to httpd.conf as a backup - :param addr: Address that will be added as NameVirtualHost directive - :type addr: str + :param str addr: Address that will be added as NameVirtualHost directive """ aug_file_path = "/files%sports.conf" % self.server_root @@ -429,14 +422,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): an IfMod mod_ssl.c block. If the IfMod block does not exist in the file, it is created. - :param aug_conf_path: Desired Augeas config path to add directive - :type aug_conf_path: str - - :param directive: Directive you would like to add - :type directive: str - - :param val: Value of directive ie. Listen 443, 443 is the value - :type val: str + :param str aug_conf_path: Desired Augeas config path to add directive + :param str directive: Directive you would like to add + :param str val: Value of directive ie. Listen 443, 443 is the value """ # TODO: Add error checking code... does the path given even exist? @@ -451,13 +439,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def make_server_sni_ready(self, vhost, default_addr="*:443"): """Checks to see if the server is ready for SNI challenges. - TODO: This should largely depend on the version of Apache + .. todo:: This should largely depend on the version of Apache :param vhost: VHost to check SNI compatibility - :type vhost: VH + :type vhost: :class:`VH` - :param default_addr: TODO - investigate function further - :type default_addr: str + :param str default_addr: TODO - investigate function further """ # Check if mod_ssl is loaded @@ -498,11 +485,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): def get_ifmod(self, aug_conf_path, mod): """Returns the path to and creates one if it doesn't exist. - :param aug_conf_path: Augeas configuration path - :type aug_conf_path: str - - :param mod: module ie. mod_ssl.c - :type mod: str + :param str aug_conf_path: Augeas configuration path + :param str mod: module ie. mod_ssl.c """ ifMods = self.aug.match(("%s/IfModule/*[self::arg='%s']" % @@ -520,14 +504,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Note: Not added to AugeasConfigurator because it may depend on the lens - :param aug_conf_path: Augeas configuration path to add directive - :type aug_conf_path: str + :param str aug_conf_path: Augeas configuration path to add directive + :param str directive: Directive to add + :param str arg: Value of the directive. ie. Listen 443, 443 is arg - :param directive: Directive to add - :type directive: str - - :param arg: Value of the directive. ie. Listen 443, 443 is arg - :type arg: str """ self.aug.set(aug_conf_path + "/directive[last() + 1]", directive) @@ -544,7 +524,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Recursively searches through config files to find directives Directives should be in the form of a case insensitive regex currently - TODO: arg should probably be a list + + .. todo:: arg should probably be a list Note: Augeas is inherently case sensitive while Apache is case insensitive. Augeas 1.0 allows case insensitive regexes like @@ -553,15 +534,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): transformation by calling case_i() on everything to maintain compatibility. - :param directive: Directive to look for - :type directive: str + :param str directive: Directive to look for :param arg: Specific value direcitve must have, None if all should be considered :type arg: str or None - :param start: Beginning Augeas path to begin looking - :type start: str + :param str start: Beginning Augeas path to begin looking """ # Cannot place member variable in the definition of the function so... @@ -606,13 +585,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): Converts an Apache Include directive argument into an Augeas searchable path - TODO: convert to use os.path.join() - :param cur_dir: current working directory - :type cur_dir: str + .. todo:: convert to use os.path.join() - :param arg: Argument of Include directive - :type arg: str + :param str cur_dir: current working directory + + :param str arg: Argument of Include directive :returns: Augeas path string :rtype: str @@ -676,7 +654,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Checks to see if mod_ssl is loaded Currently uses apache2ctl to get loaded module list - TODO: This function is likely fragile to versions/distros + + .. todo:: This function is likely fragile to versions/distros :returns: If ssl_module is included and active in Apache :rtype: bool @@ -704,10 +683,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): New vhost will reside as (nonssl_vhost.path) + CONFIG.LE_VHOST_EXT :param nonssl_vhost: Valid VH that doesn't have SSLEngine on - :type nonssl_vhost: VH + :type nonssl_vhost: :class:`VH` :returns: SSL vhost - :rtype: VH + :rtype: :class:`VH` """ avail_fp = nonssl_vhost.file @@ -809,10 +788,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): The function then adds the directive :param ssl_vhost: Destination of traffic, an ssl enabled vhost - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: Success, general_vhost (HTTP vhost) - :rtype: bool, VH + :rtype: (bool, :class:`VH`) """ # TODO: Enable check to see if it is already there @@ -858,7 +837,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): -1 is also returned in case of no redirection/rewrite directives :param vhost: vhost to check - :type vhost: VH + :type vhost: :class:`VH` :returns: Success, code value... see documentation :rtype: bool, int @@ -889,10 +868,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): """Creates an http_vhost specifically to redirect for the ssl_vhost. :param ssl_vhost: ssl vhost - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: Success, vhost - :rtype: bool, VH + :rtype: (bool, :class:`VH`) """ # Consider changing this to a dictionary check @@ -973,7 +952,7 @@ LogLevel warn \n\ if not conflict: returns space separated list of new host addrs :param ssl_vhost: SSL Vhost to check for possible port 80 redirection - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: TODO :rtype: TODO @@ -1012,10 +991,10 @@ LogLevel warn \n\ Consider changing this into a dict check :param ssl_vhost: ssl vhost to check - :type ssl_vhost: VH + :type ssl_vhost: :class:`VH` :returns: HTTP vhost or None if unsuccessful - :rtype: VH or None + :rtype: :class:`VH` or None """ # _default_:443 check @@ -1090,8 +1069,7 @@ LogLevel warn \n\ Takes in Augeas path and returns the file name - :param vhost_path: Augeas virtual host path - :type vhost_path: str + :param str vhost_path: Augeas virtual host path :returns: filename of vhost :rtype: str @@ -1116,10 +1094,9 @@ LogLevel warn \n\ def is_site_enabled(self, avail_fp): """Checks to see if the given site is enabled. - TODO: fix hardcoded sites-enabled + .. todo:: fix hardcoded sites-enabled - :param avail_fp: Complete file path of available site - :type avail_fp: str + :param str avail_fp: Complete file path of available site :returns: Success :rtype: bool @@ -1135,11 +1112,12 @@ LogLevel warn \n\ def enable_site(self, vhost): """Enables an available site, Apache restart required. - TODO: This function should number subdomains before the domain vhost - TODO: Make sure link is not broken... + .. todo:: This function should number subdomains before the domain vhost + + .. todo:: Make sure link is not broken... :param vhost: vhost to enable - :type vhost: VH + :type vhost: :class:`VH` :returns: Success :rtype: bool @@ -1164,8 +1142,7 @@ LogLevel warn \n\ Both enables and restarts Apache so module is active. - :param mod_name: Name of the module to enable - :type mod_name: str + :param str mod_name: Name of the module to enable """ try: @@ -1185,8 +1162,7 @@ LogLevel warn \n\ def fnmatch_to_re(self, clean_fn_match): """Method converts Apache's basic fnmatch to regular expression. - :param clean_fn_match: Apache style filename match, similar to globs - :type clean_fn_match: str + :param str clean_fn_match: Apache style filename match, similar to globs :returns: regex suitable for augeas :rtype: str @@ -1212,8 +1188,7 @@ LogLevel warn \n\ Checks to see if file_path is parsed by Augeas If file_path isn't parsed, the file is added and Augeas is reloaded - :param file_path: Apache config file path - :type file_path: str + :param str file_path: Apache config file path """ # Test if augeas included file for Httpd.lens @@ -1313,8 +1288,7 @@ LogLevel warn \n\ This function will correctly add a transform to augeas The existing augeas.add_transform in python is broken. - :param incl: TODO - :type incl: str + :param str incl: TODO """ lastInclude = self.aug.match("/augeas/load/Httpd/incl [last()]") @@ -1354,8 +1328,7 @@ LogLevel warn \n\ def perform(self, chall_dict): """Perform the configuration related challenge. - :param chall_dict: Dictionary representing a challenge. - :type chall_dict: dict + :param dict chall_dict: Dictionary representing a challenge. """ @@ -1366,13 +1339,16 @@ LogLevel warn \n\ def dvsni_perform(self, chall_dict): """Peform a DVSNI challenge. - Composed of - listSNITuple: List of tuples with form (addr, r, nonce) - addr (string), r (base64 string), nonce (hex string) - dvsni_key: string - File path to key + Composed of: - :param chall_dict: dvsni challenge - see documentation - :type chall_dict: dict + listSNITuple + List of tuples with form (addr, r, nonce) + addr (string), r (base64 string), nonce (hex string) + + dvsni_key + string - File path to key + + :param dict chall_dict: dvsni challenge - see documentation """ # Save any changes to the configuration as a precaution @@ -1437,8 +1413,7 @@ LogLevel warn \n\ def dvsni_get_cert_file(self, nonce): """Returns standardized name for challenge certificate. - :param nonce: hex form of nonce - :type nonce: str + :param str nonce: hex form of nonce :returns: certificate file name :rtype: str @@ -1449,14 +1424,9 @@ LogLevel warn \n\ def _get_config_text(self, nonce, ip_addrs, key): """Chocolate virtual server configuration text - :param nonce: hex form of nonce - :type nonce: str - - :param ip_addrs: addresses of challenged domain - :type ip_addrs: str - - :param key: file path to key - :type key: str + :param str nonce: hex form of nonce + :param str ip_addrs: addresses of challenged domain + :param str key: file path to key :returns: virtual host configuration text :rtype: str @@ -1483,18 +1453,14 @@ LogLevel warn \n\ Result: Apache config includes virtual servers for issued challs - :param mainConfig: file path to Apache user config file - :type mainConfig: str + :param str mainConfig: file path to Apache user config file - :param listSNITuple: list of tuples with the form (addr, y, nonce) - addr (string), y (byte array), nonce (hex string) - :type listSNITuple: lsit + :param list listSNITuple: list of tuples with the form (addr, y, nonce) + addr (string), y (byte array), nonce (hex string) - :param dvsni_key: file path to key - :type dvsni_key: str + :param str dvsni_key: file path to key - :param listlistAddrs: list of list of addresses to apply - :type listlistAddrs: list + :param list listlistAddrs: list of list of addresses to apply """ # WARNING: THIS IS A POTENTIAL SECURITY VULNERABILITY @@ -1527,8 +1493,7 @@ LogLevel warn \n\ Adds DVSNI challenge include file if it does not already exist within mainConfig - :param mainConfig: file path to main user apache config file - :type mainConfig: str + :param str mainConfig: file path to main user apache config file """ if len(self.find_directive( @@ -1542,11 +1507,8 @@ LogLevel warn \n\ Certificate created at dvsni_get_cert_file(nonce) - :param nonce: hex form of nonce - :type nonce: str - - :param key_file: absolute path to key file - :type key: str + :param str nonce: hex form of nonce + :param str key_file: absolute path to key file """ try: @@ -1567,11 +1529,8 @@ LogLevel warn \n\ def dvsni_gen_ext(self, r, s): """Generates z extension to be placed in certificate extension. - :param r: DVSNI r value - :type r: byte array - - :param s: DVSNI s value - :type s: byte array + :param bytearray r: DVSNI r value + :param bytearray s: DVSNI s value result: returns z + CONFIG.INVALID_EXT @@ -1592,8 +1551,7 @@ def case_i(string): May be replaced by a more proper /i once augeas 1.0 is widely supported. - :param string: string to make case i regex - :type string: str + :param str string: string to make case i regex """ return "".join(["["+c.upper()+c.lower()+"]" @@ -1603,10 +1561,10 @@ def case_i(string): def strip_dir(path): """Returns directory of file path. - TODO: Replace this with Python standard function + .. todo:: Replace this with Python standard function - :param path: path is a file path. not an augeas section or directive path - :type path: str + :param str path: path is a file path. not an augeas section or + directive path :returns: directory :rtype: str diff --git a/letsencrypt/client/augeas_configurator.py b/letsencrypt/client/augeas_configurator.py index 8bfd4c1ff..e304966c2 100644 --- a/letsencrypt/client/augeas_configurator.py +++ b/letsencrypt/client/augeas_configurator.py @@ -12,6 +12,7 @@ from letsencrypt.client import logger class AugeasConfigurator(configurator.Configurator): + """Augeas configurator.""" def __init__(self): super(AugeasConfigurator, self).__init__() @@ -24,8 +25,7 @@ class AugeasConfigurator(configurator.Configurator): def check_parsing_errors(self, lens): """Verify Augeas can parse all of the lens files. - :param lens: lens to check for errors - :type lens: str + :param str lens: lens to check for errors """ error_files = self.aug.match("/augeas//error") @@ -48,14 +48,12 @@ class AugeasConfigurator(configurator.Configurator): all configuration changes made will be saved. According to the function parameters. - :param title: The title of the save. If a title is given, the - configuration will be saved as a new checkpoint - and put in a timestamped directory. - :type title: str + :param str title: The title of the save. If a title is given, the + configuration will be saved as a new checkpoint and put in a + timestamped directory. - :param temporary: Indicates whether the changes made will be quickly - reversed in the future (ie. challenges) - :type temporary: bool + :param bool temporary: Indicates whether the changes made will + be quickly reversed in the future (ie. challenges) """ save_state = self.aug.get("/augeas/save") @@ -141,8 +139,7 @@ class AugeasConfigurator(configurator.Configurator): def rollback_checkpoints(self, rollback=1): """Revert 'rollback' number of configuration checkpoints. - :param rollback: Number of checkpoints to reverse - :type rollback: int + :param int rollback: Number of checkpoints to reverse """ try: @@ -222,8 +219,7 @@ class AugeasConfigurator(configurator.Configurator): Adds title to cp_dir CHANGES_SINCE Move cp_dir to Backups directory and rename with timestamp - :param cp_dir: "IN PROGRESS" directory - :type cp_dir: str + :param str cp_dir: "IN PROGRESS" directory :returns: Success :rtype: bool @@ -250,11 +246,8 @@ class AugeasConfigurator(configurator.Configurator): def add_to_checkpoint(self, cp_dir, save_files): """Add save files to checkpoint directory. - :param cp_dir: Checkpoint directory filepath - :type cp_dir: str - - :param save_files: set of files to save - :type save_files: set + :param str cp_dir: Checkpoint directory filepath + :param set save_files: set of files to save """ le_util.make_or_verify_dir(cp_dir, 0o755) @@ -289,8 +282,7 @@ class AugeasConfigurator(configurator.Configurator): Recover a specific checkpoint provided by cp_dir Note: this function does not reload augeas. - :param cp_dir: checkpoint directory file path - :type cp_dir: str + :param str cp_dir: checkpoint directory file path :returns: 0 success, 1 Unable to revert, -1 Unable to delete :rtype: int @@ -322,8 +314,7 @@ class AugeasConfigurator(configurator.Configurator): def check_tempfile_saves(self, save_files): """Verify save isn't overwriting any temporary files. - :param save_files: Set of files about to be saved. - :type save_files: set + :param set save_files: Set of files about to be saved. :returns: Success, error message :rtype: bool, str @@ -347,12 +338,10 @@ class AugeasConfigurator(configurator.Configurator): file will be cleaned up if the program exits unexpectedly. (Before a save occurs) - :param temporary: If the file creation registry is for a temp or - permanent save. - :type temporary: bool + :param bool temporary: If the file creation registry is for + a temp or permanent save. - :param *files: file paths to be registered - :type *files: str + :param \*files: file paths (str) to be registered """ if temporary: @@ -395,8 +384,7 @@ class AugeasConfigurator(configurator.Configurator): def _remove_contained_files(self, file_list): """Erase all files contained within file_list. - :param file_list: file containing list of file paths to be deleted - :type file_list: str + :param str file_list: file containing list of file paths to be deleted :returns: Success :rtype: bool diff --git a/letsencrypt/client/challenge.py b/letsencrypt/client/challenge.py index 0f44f7af9..6eaee82f7 100644 --- a/letsencrypt/client/challenge.py +++ b/letsencrypt/client/challenge.py @@ -23,18 +23,16 @@ class Challenge(object): def gen_challenge_path(challenges, combos=None): """Generate a plan to get authority over the identity. - TODO: Make sure that the challenges are feasible... - Example: Do you have the recovery key? + .. todo:: Make sure that the challenges are feasible... + Example: Do you have the recovery key? - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :param combos: A collection of sets of challenges from ACME - "challenge" server message ("combinations"), - each of which would be sufficient to prove - possession of the identifier. + "challenge" server message ("combinations"), each of which would + be sufficient to prove possession of the identifier. :type combos: list or None :returns: List of indices from `challenges`. @@ -49,19 +47,17 @@ def gen_challenge_path(challenges, combos=None): def _find_smart_path(challenges, combos): """ - Can be called if combinations is included + Can be called if combinations is included Function uses a simple ranking system to choose the combo with the lowest cost - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :param combos: A collection of sets of challenges from ACME - "challenge" server message ("combinations"), - each of which would be sufficient to prove - possession of the identifier. + "challenge" server message ("combinations"), each of which would + be sufficient to prove possession of the identifier. :type combos: list or None :returns: List of indices from `challenges`. @@ -102,10 +98,9 @@ def _find_dumb_path(challenges): This function returns the best path that does not contain multiple mutually exclusive challenges - :param challanges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challanges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. :returns: List of indices from `challenges`. :rtype: list diff --git a/letsencrypt/client/client.py b/letsencrypt/client/client.py index 285cbf976..70395c771 100644 --- a/letsencrypt/client/client.py +++ b/letsencrypt/client/client.py @@ -36,20 +36,11 @@ class Client(object): private_key=None, private_key_file=None, use_curses=True): """ - :param ca_server: Certificate authority server - :type ca_server: str - - :param cert_signing_request: Contents of the CSR - :type cert_signing_request: str - - :param private_key: Contents of the private key - :type private_key: str - - :param private_key_file: absolute path to private_key - :type private_key_file: str - - :param use_curses: Use curses UI - :type use_curses: bool + :param str ca_server: Certificate authority server + :param str cert_signing_request: Contents of the CSR + :param str private_key: Contents of the private key + :param str private_key_file: absolute path to private_key + :param bool use_curses: Use curses UI """ self.curses = use_curses @@ -80,14 +71,12 @@ class Client(object): def authenticate(self, domains=None, redirect=None, eula=False): """ - :param domains: List of domains - :type domains: list + :param list domains: List of domains :param redirect: - :type redirect: bool|None + :type redirect: bool or None - :param eula: EULA accepted - :type eula: bool + :param bool eula: EULA accepted :raises errors.LetsEncryptClientError: CSR does not contain one of the specified names. @@ -157,9 +146,12 @@ class Client(object): def acme_challenge(self): """Handle ACME "challenge" phase. - TODO: Handle more than one domain name in self.names + + .. todo:: Handle more than one domain name in self.names + :returns: ACME "challenge" message. :rtype: dict + """ return self.send_and_receive_expected( acme.challenge_request(self.names[0]), "challenge") @@ -167,14 +159,10 @@ class Client(object): def acme_authorization(self, challenge_msg, chal_objs, responses): """Handle ACME "authorization" phase. - :param challenge_msg: ACME "challenge" message. - :type challenge_msg: dict + :param dict challenge_msg: ACME "challenge" message. :param chal_objs: TODO - :type chal_objs: TODO - :param responses: TODO - :type responses: TODO :returns: ACME "authorization" message. :rtype: dict @@ -196,8 +184,7 @@ class Client(object): def acme_certificate(self, csr_der): """Handle ACME "certificate" phase. - :param csr_der: CSR in DER format. - :type csr_der: str + :param str csr_der: CSR in DER format. :returns: ACME "certificate" message. :rtype: dict @@ -210,8 +197,7 @@ class Client(object): def acme_revocation(self, cert): """Handle ACME "revocation" phase. - :param cert: TODO - :type cert: dict + :param dict cert: TODO :returns: ACME "revocation" message. :rtype: dict @@ -235,8 +221,7 @@ class Client(object): def send(self, msg): """Send ACME message to server. - :param msg: ACME message (JSON serializable). - :type msg: dict + :param dict msg: ACME message (JSON serializable). :returns: Server response message. :rtype: dict @@ -274,11 +259,8 @@ class Client(object): def send_and_receive_expected(self, msg, expected): """Send ACME message to server and return expected message. - :param msg: ACME message (JSON serializable). - :type msg: dict - - :param expected: Name of the expected response ACME message type. - :type expected: str + :param dict msg: ACME message (JSON serializable). + :param str expected: Name of the expected response ACME message type. :returns: ACME response message of expected type. :rtype: dict @@ -296,19 +278,15 @@ class Client(object): def is_expected_msg(self, response, expected, delay=3, rounds=20): """Is reponse expected ACME message? - :param response: ACME response message from server. - :type response: dict + :param dict response: ACME response message from server. - :param expected: Name of the expected response ACME message type. - :type expected: str + :param str expected: Name of the expected response ACME message type. - :param delay: Number of seconds to delay before next round in case - of ACME "defer" response message. - :type delay: int + :param int delay: Number of seconds to delay before next round + in case of ACME "defer" response message. - :param rounds: Number of resend attempts in case of ACME "defer" - reponse message. - :type rounds: int + :param int rounds: Number of resend attempts in case of ACME "defer" + reponse message. :returns: ACME response message from server. :rtype: dict @@ -387,8 +365,7 @@ class Client(object): def choose_certs(self, certs): """Display choose certificates menu. - :param certs: List of cert dicts. - :type certs: list + :param list certs: List of cert dicts. """ code, tag = display.display_certs(certs) @@ -478,8 +455,7 @@ class Client(object): def verify_identity(self, challenge_msg): """Verify identity. - :param challenge_msg: ACME "challenge" message. - :type challenge_msg: dict + :param dict challenge_msg: ACME "challenge" message. :returns: TODO :rtype: dict @@ -519,11 +495,9 @@ class Client(object): def store_cert_key(self, cert_file, encrypt=False): """Store certificate key. - :param cert_file: Path to a certificate file. - :type cert_file: str + :param str cert_file: Path to a certificate file. - :param encrypt: Should the certificate key be encrypted? - :type encrypt: bool + :param bool encrypt: Should the certificate key be encrypted? :returns: True if key file was stored successfully, False otherwise. :rtype: bool @@ -584,15 +558,12 @@ class Client(object): """ :param name: TODO - :type name: TODO - :param challenges: A list of challenges from ACME "challenge" - server message to be fulfilled by the client - in order to prove possession of the identifier. - :type challenges: list + :param list challenges: A list of challenges from ACME "challenge" + server message to be fulfilled by the client in order to prove + possession of the identifier. - :param path: List of indices from `challenges`. - :type path: list + :param list path: List of indices from `challenges`. :returns: A pair of TODO :rtype: tuple @@ -748,8 +719,7 @@ class Client(object): def remove_cert_key(cert): """Remove certificate key. - :param cert: - :type cert: dict + :param dict cert: """ list_file = os.path.join(CONFIG.CERT_KEY_BACKUP, "LIST") @@ -776,8 +746,7 @@ def remove_cert_key(cert): def sanity_check_names(names): """Make sure host names are valid. - :param names: List of host names - :type names: list + :param list names: List of host names """ for name in names: @@ -792,8 +761,7 @@ def is_hostname_sane(hostname): Do enough to avoid shellcode from the environment. There's no need to do more. - :param hostname: Host name to validate - :type hostname: str + :param str hostname: Host name to validate :returns: True if hostname is valid, otherwise false. :rtype: bool diff --git a/letsencrypt/client/configurator.py b/letsencrypt/client/configurator.py index 30972c0e8..5adec3a67 100644 --- a/letsencrypt/client/configurator.py +++ b/letsencrypt/client/configurator.py @@ -11,6 +11,13 @@ class Configurator(object): """ def deploy_cert(self, vhost, cert, key, cert_chain=None): + """Deploy certificate. + + :param vhost + :param str cert: CSR + :param str key: Private key + + """ raise NotImplementedError() def choose_virtual_host(self, name): @@ -53,12 +60,12 @@ class Configurator(object): intended to be permanent, but the save is not ready to be a full checkpoint - title: string - The title of the save. If a title is given, the - configuration will be saved as a new checkpoint - and put in a timestamped directory. - `title` has no effect if temporary is true. - temporary: boolean - Indicates whether the changes made will be - quickly reversed in the future (challenges) + :param str title: The title of the save. If a title is given, the + configuration will be saved as a new checkpoint and put in a + timestamped directory. `title` has no effect if temporary is true. + + :param bool temporary: Indicates whether the changes made will + be quickly reversed in the future (challenges) """ raise NotImplementedError() diff --git a/letsencrypt/client/crypto_util.py b/letsencrypt/client/crypto_util.py index f2bb4c6f7..a53edc85a 100644 --- a/letsencrypt/client/crypto_util.py +++ b/letsencrypt/client/crypto_util.py @@ -25,23 +25,21 @@ def b64_cert_to_pem(b64_der_cert): def create_sig(msg, key_str, nonce=None, nonce_len=CONFIG.NONCE_SIZE): """Create signature with nonce prepended to the message. - TODO: Change this over to M2Crypto... PKey - Protect against crypto unicode errors... is this sufficient? - Do I need to escape? + .. todo:: Change this over to M2Crypto... PKey - :param msg: Message to be signed - :type msg: Anything with __str__ method + .. todo::Protect against crypto unicode errors... is this sufficient? + Do I need to escape? - :param key_str: Key in string form. Accepted formats - are the same as for `Crypto.PublicKey.RSA.importKey`. - :type key_str: str + :param str key_str: Key in string form. Accepted formats + are the same as for `Crypto.PublicKey.RSA.importKey`. + + :param str msg: Message to be signed :param nonce: Nonce to be used. If None, nonce of `nonce_len` size will be randomly genereted. :type nonce: str or None - :param nonce_len: Size of the automaticaly generated nonce. - :type nonce_len: int + :param int nonce_len: Size of the automaticaly generated nonce. :returns: Signature. :rtype: dict @@ -176,8 +174,7 @@ def make_ss_cert(key_str, domains): def get_cert_info(filename): """Get certificate info. - :param filename: Name of file containing certificate in PEM format. - :type filename: str + :param str filename: Name of file containing certificate in PEM format. :rtype: dict @@ -213,8 +210,7 @@ def valid_csr(csr): Check if `csr` is a valid CSR for the given domains. - :param csr: CSR file contents - :type csr: str + :param str csr: CSR file contents :returns: Validity of CSR. :rtype: bool @@ -233,11 +229,9 @@ def csr_matches_names(csr, domains): M2Crypto currently does not expose the OpenSSL interface to also check the SAN extension. This is insufficient for full testing - :param csr: CSR file contents - :type csr: str + :param str csr: CSR file contents - :param domains: Domains the CSR should contain. - :type domains: list + :param list domains: Domains the CSR should contain. :returns: If the CSR subject contains one of the domains :rtype: bool @@ -253,8 +247,7 @@ def csr_matches_names(csr, domains): def valid_privkey(privkey): """Is valid RSA private key? - :param privkey: Private key file contents - :type privkey: str + :param str privkey: Private key file contents :returns: Validity of private key. :rtype: bool @@ -269,11 +262,8 @@ def valid_privkey(privkey): def csr_matches_pubkey(csr, privkey): """Does private key correspond to the subject public key in the CSR? - :param csr: CSR file contents - :type csr: str - - :param privkey: Private key file contents - :type privkey: str + :param str csr: CSR file contents + :param str privkey: Private key file contents :returns: Correspondence of private key to CSR subject public key. :rtype: bool diff --git a/letsencrypt/client/le_util.py b/letsencrypt/client/le_util.py index 4d76a5d21..75924e08b 100644 --- a/letsencrypt/client/le_util.py +++ b/letsencrypt/client/le_util.py @@ -10,14 +10,9 @@ from letsencrypt.client import errors def make_or_verify_dir(directory, mode=0o755, uid=0): """Make sure directory exists with proper permissions. - :param directory: Path to a directry. - :type directory: str - - :param mode: Diretory mode. - :type mode: int - - :param uid: Directory owner. - :type uid: int + :param str directory: Path to a directry. + :param int mode: Diretory mode. + :param int uid: Directory owner. :raises LetsEncryptClientError: if a directory already exists, but has wrong permissions or owner @@ -38,16 +33,12 @@ def make_or_verify_dir(directory, mode=0o755, uid=0): def check_permissions(filepath, mode, uid=0): """Check file or directory permissions. - :param filepath: Path to the tested file (or directory). - :type filepath: str + :param str filepath: Path to the tested file (or directory). + :param int mode: Expected file mode. + :param int uid: Expected file owner. - :param mode: Expected file mode. - :type mode: int - - :param uid: Expected file owner. - :type uid: int - - :returns: bool -- True if `mode` and `uid` match, False otherwise. + :returns: True if `mode` and `uid` match, False otherwise. + :rtype: bool """ file_stat = os.stat(filepath) @@ -57,11 +48,8 @@ def check_permissions(filepath, mode, uid=0): def unique_file(default_name, mode=0o777): """Safely finds a unique file for writing only (by default). - :param default_name: Default file name - :type default_name: str - - :param mode: File mode - :type mode: int + :param str default_name: Default file name + :param int mode: File mode :return: tuple of file object and file name @@ -94,11 +82,11 @@ def jose_b64encode(data): :param data: Data to be encoded. :type data: str or bytearray - :raises TypeError: if input is of incorrect type - :returns: JOSE Base64 string. :rtype: str + :raises TypeError: if `data` is of incorrect type + """ if not isinstance(data, str): raise TypeError('argument should be str or bytearray') @@ -112,11 +100,11 @@ def jose_b64decode(data): only ASCII characters are allowed. :type data: str or unicode + :returns: Decoded data. + :raises TypeError: if input is of incorrect type :raises ValueError: if unput is unicode with non-ASCII characters - :returns: Decoded data. - """ if isinstance(data, unicode): try: diff --git a/letsencrypt/client/logger.py b/letsencrypt/client/logger.py index 3a67aef9d..5444c3ce0 100644 --- a/letsencrypt/client/logger.py +++ b/letsencrypt/client/logger.py @@ -1,3 +1,4 @@ +"""Logger.""" import logger import textwrap import time diff --git a/letsencrypt/scripts/main.py b/letsencrypt/scripts/main.py index d38762925..fdd5746b1 100755 --- a/letsencrypt/scripts/main.py +++ b/letsencrypt/scripts/main.py @@ -100,8 +100,7 @@ def main(): def read_file(filename): """Returns the given file's contents with universal new line support. - :param filename: Filename - :type filename: str + :param str filename: Filename :returns: File contents :rtype: str @@ -119,10 +118,9 @@ def rollback(config, checkpoints): """Revert configuration the specified number of checkpoints. :param config: Configurator object - :type config: ApacheConfigurator + :type config: :class:`ApacheConfigurator` - :param checkpoints: Number of checkpoints to revert. - :type checkpoints: int + :param int checkpoints: Number of checkpoints to revert. """ config.rollback_checkpoints(checkpoints) @@ -133,7 +131,7 @@ def view_checkpoints(config): """View checkpoints and associated configuration changes. :param config: Configurator object - :type config: ApacheConfigurator + :type config: :class:`ApacheConfigurator` """ config.display_checkpoints() diff --git a/setup.cfg b/setup.cfg index 2b9124c06..677247955 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,6 +3,7 @@ zip_ok = false [aliases] dev = develop easy_install letsencrypt[testing] +docs = develop easy_install letsencrypt[docs] [nosetests] nocapture=1 diff --git a/setup.py b/setup.py index 93e22b4d9..a2a13fecf 100755 --- a/setup.py +++ b/setup.py @@ -12,6 +12,10 @@ install_requires = [ 'requests', ] +docs_extras = [ + 'Sphinx', +] + testing_extras = [ 'coverage', 'nose', @@ -36,6 +40,7 @@ setup( tests_require=install_requires, test_suite='letsencrypt', extras_require={ + 'docs': docs_extras, 'testing': testing_extras, }, entry_points={