diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 628a589..ce80d2b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,42 @@ Changelog ######### +This is the changelog for Puppetboard. + +0.0.3 +===== +This release introduces a few big changes. The most obvious one is the +revamped Overview page which has received significant love. Most of the work +was done by Julius Härtl. The Nodes tab has been given a slight face-lift +too. + +Other changes: + +* This release depends on the new pypuppetdb 0.1.0. Because of this the SSL + configuration options have been changed: + + * ``PUPPETDB_SSL`` is gone and replaced by ``PUPPETDB_SSL_VERIFY`` which + now defaults to ``True``. This only affects connections to PuppetDB that + happen over SSL. + * SSL is automatically enabled if both ``PUPPETDB_CERT`` and + ``PUPPETDB_KEY`` are provided. + +* Display of deeply nested metrics and query results have been fixed. +* Average resources per node metric is now displayed as a natural number. +* A link back to the node has been added to the reports. +* A few issues with reports have been fixed. +* A new setting called ``UNRESPONSIVE_HOURS`` has been added which denotes + the amount of hours after which Puppetboard will display the node as + unreported if it hasn't checked in. We default to ``2`` hours. +* The event message can now be viewed by clicking on the event. + +Puppetboard is now neatly packaged up and available on PyPi. This should +significantly help reduce the convoluted installation instructions people had +to follow. + +Updated installation instructions have been added on how to install from PyPi +and how to configure your HTTPD. + 0.0.2 ===== In this release we've introduced a few new things. First of all we now require diff --git a/README.rst b/README.rst index f823845..16fe85f 100644 --- a/README.rst +++ b/README.rst @@ -40,17 +40,88 @@ this might throw at you. Installation ============ -Currently you can only run from source: +Puppetboard is now packaged and available on PyPi. + +Production +---------- + +To install it simply issue the following command: + +.. code-block:: bash + + $ pip install puppetboard + +This will install Puppetboard and take care of the dependencies. If you +do this Puppetboard will be installed in the so called site-packages or +dist-packages of your Python distribution. + +The complete path on Debian systems would be: +``/usr/local/lib/python2.X/lib/dist-packages/puppetboard``. + +You will need this path in order to configure your HTTPD and WSGI-capable +application server. + +Development +----------- + +If you wish to hack on Puppetboard you should fork/clone the Github repository +and then install the requirements through: .. code-block:: bash - $ git clone https://github.com/nedap/puppetboard $ pip install -r requirements.txt -This will install all the requirements for Puppetboard. +You're advised to do this inside a virtualenv specifically created to work on +Puppetboard as to not pollute your global Python installation. -Run it -====== +Configuration +============= +The following instructions will help you configure Puppetboard and your HTTPD. + +Settings +-------- +Puppetboard will look for a file pointed at by the ``PUPPETBOARD_SETTINGS`` +environment variable. The file has to be identical to ``default_settings.py`` +but should only override the settings you need changed. + +You can grab a copy of ``default_settings.py`` from the path where pip +installed Puppetboard to or by looking in the source checkout. + +If you run PuppetDB and Puppetboard on the same machine the default settings +provided will be enough to get you started and you won't need a custom +settings file. + +Assuming your webserver and PuppetDB machine are not identical you will at +least have to change the following settings: + +* ``PUPPETDB_HOST`` +* ``PUPPETDB_PORT`` + +By default PuppetDB requires SSL to be used when a non-local client wants to +connect. Therefor you'll also have to supply the following settings: + +* ``PUPPETDB_KEY = /path/to/private/keyfile.pem`` +* ``PUPPETDB_CERT = /path/to/public/keyfile.crt`` + +For information about how to generate the correct keys please refer to the +`pypuppetdb documentation`_. + +Other settings that might be interesting: + +* ``PUPPETDB_TIMEOUT``: Defaults to 20 seconds but you might need to increase + this value. It depends on how big the results are when querying PuppetDB. + This behaviour will change in a future release when pagination will be + introduced. +* ``UNRESPONSIVE_HOURS``: The amount of hours since the last check-in after + which a node is considered unresponsive. +* ``LOGLEVEL``: A string representing the loglevel. It defaults to ``'info'`` + but can be changed to ``'warning'`` or ``'critical'`` for less verbose + logging or ``'debug'`` for more information. +* ``ENABLE_QUERY``: Defaults to ``True`` causing a Query tab to show up in the + web interface allowing users to write and execute arbitrary queries against + a set of endpoints in PuppetDB. Change this to ``False`` to disable this. + +.. _pypuppetdb documentation: http://pypuppetdb.readthedocs.org/en/v0.1.0/quickstart.html#ssl Development ----------- @@ -61,67 +132,265 @@ You can run it in development mode by simply executing: $ python dev.py +Use ``PUPPETBOARD_SETTINGS`` to change the different settings or patch +``default_settings.py`` directly. Take care not to include your local +changes on that file when submitting patches for Puppetboard. + Production ---------- -For WSGI capable webservers a ``wsgi.py`` is provided which ``mod_wsgi`` -and ``uwsgi`` can deal with. +To run Puppetboard in production we provide instructions for the following +scenarios: - * Apache mod_wsgi configuration: http://flask.pocoo.org/docs/deploying/mod_wsgi/ - * uwsgi configuration: ``uwsgi --http :9090 --wsgi-file /path/to/puppetboard/wsgi.py`` - * Passenger +* Apache + mod_wsgi +* Apache + mod_passenger +* uwsgi + nginx -In the case of uwsgi you'll of course need something like nginx in front of it to -proxy the requests to it. +If you deploy Puppetboard through a different setup we'd welcome a pull +request that adds the instructions to this section. -Don't forget that you also need to serve the ``static/`` folder on the -``/static`` URL of your vhost. (I'm considering embedding the little additional -Javascript and CSS this application has so no one has to bother with that). +Apache + mod_wsgi +^^^^^^^^^^^^^^^^^ -Passenger -^^^^^^^^^ -From within the Puppetboard checkout: +First we need to create the necessary directories: .. code-block:: bash - mkdir public - mkdir tmp - ln -s wsgi.py passenger_wsgi.py + $ mkdir -p /var/www/puppetboard + $ chown www-data:www-data /var/www/puppetboard -The apache vhost configuration: +Copy Puppetboard's ``default_settings.py`` to the newly created puppetboard +directory and name the file ``settings.py``. This file will be available +at the path Puppetboard was installed, for example: +``/usr/local/lib/python2.X/lib/dist-packages/puppetboard/default_settings.py``. + +Change the settings that need changing to match your environment and delete +or comment with a ``#`` the rest of the entries. + +If you don't need to change any settings you can skip the creation of the +``settings.py`` file entirely. + +Now create a ``wsgi.py`` with the following content in the newly created +puppetboard directory: + +.. code-block:: + + from __future__ import absolute_import + import os + + # Needed if a settings.py file exists + os.environ['PUPPETBOARD_SETTINGS'] = '/var/www/puppetboard/settings.py' + from puppetboard.app import app as application + +Make sure this file is owned by the user and group the webserver runs as. + +The last thing we need to do is configure Apache: + +.. code-block:: + + + ServerName puppetboard.example.tld + WSGIDaemonProcess puppetboard user=www-data group=www-data threads=5 + WSGIScriptAlias / /var/www/puppetboard/wsgi.py + ErrorLog /var/log/apache2/puppetboard.error.log + CustomLog /var/log/apache2/puppetboard.access.log combined + + Alias /static /usr/local/lib/python2.X/dist-packages/puppetboard/static + + + WSGIProcessGroup puppetboard + WSGIApplicationGroup %{GLOBAL} + Order deny,allow + Allow from all + + + +Note the directory path, it's the path to where pip installed Puppetboard. We +also alias the ``/static`` path so that Apache will serve the static files +like the included CSS and Javascript. + +Apache + mod_passenger +^^^^^^^^^^^^^^^^^^^^^^ + +It is possible to run Python applications through Passenger. Passenger has +supported this since version 3 but it's considered experimental. Since the +release of Passenger 4 it's a 'core' feature of the product. + +Performance wise it also leaves something to be desired compared to the +mod_wsgi powered solution. Application start up is noticeably slower and +loading pages takes a fraction longer. + +First we need to create the necessary directories: + +.. code-block:: bash + + $ mkdir -p /var/www/puppetboard/{tmp,public} + $ chown -R www-data:www-data /var/www/puppetboard + +Copy Puppetboard's ``default_settings.py`` to the newly created puppetboard +directory and name the file ``settings.py``. This file will be available +at the path Puppetboard was installed, for example: +``/usr/local/lib/python2.X/lib/dist-packages/puppetboard/default_settings.py``. + +Change the settings that need changing to match your environment and delete +or comment with a ``#`` the rest of the entries. + +If you don't need to change any settings you can skip the creation of the +``settings.py`` file entirely. + +Now create a ``passenger_wsgi.py`` with the following content in the newly +created puppetboard directory: + +.. code-block:: + + from __future__ import absolute_import + import os + import logging + + logging.basicConfig(filename=/path/to/file/for/logging, level=logging.INFO) + + # Needed if a settings.py file exists + os.environ['PUPPETBOARD_SETTINGS'] = '/var/www/puppetboard/settings.py' + + try: + from puppetboard.app import app as application + except Exception, inst: + logging.exception("Error: %s", str(type(inst))) + +Unfortunately due to the way Passenger works we also need to configure logging +inside ``passenger_wsgi.py`` else application start up issues won't be logged. + +This means that even though ``LOGLEVEL`` might be set in your ``settings.py`` +this setting will take precedence over it. + +Now the only thing left to do is configure Apache: .. code-block:: ServerName puppetboard.example.tld - DocumentRoot /path/to/puppetboard/public + DocumentRoot /var/www/puppetboard/public + ErrorLog /var/log/apache2/puppetboard.error.log + CustomLog /var/log/apache2/puppetboard.access.log combined RackAutoDetect On - Alias /static /path/to/puppetboard/static - - Options None - Order allow,deny - allow from all - + Alias /static /usr/local/lib/python2.X/dist-packages/puppetboard/static -Configuration -============= +Note the ``/static`` alias path, it's the path to where pip installed +Puppetboard. This is needed so that Apache will serve the static files like +the included CSS and Javascript. -Puppetboard has some configuration settings, their defaults can -be viewed in ``puppetboard/default_settings.py``. +nginx + uwsgi +^^^^^^^^^^^^^ +A common Python deployment scenario is to use the uwsgi application server +(which can also serve rails/rack, PHP, Perl and other applications) and proxy +to it through something like nginx or perhaps even HAProxy. -Additionally Puppetboard will look for an environment variable -called ``PUPPETBOARD_SETTINGS`` pointing to a file with identical -markup as ``default_settings.py``. Any setting defined in -``PUPPETBOARD_SETTINGS`` will override the defaults. +uwsgi has a feature that every instance can run as its own user. In this +example we'll use the ``www-data`` user but you can create a separate user +solely for running Puppetboard and use that instead. -Experimental ------------- -Pypuppetdb and Puppetboard can query and display information from -PuppetDB's experimental API endpoints. +First we need to create the necessary directories: -However, if you haven't enabled them for Puppet it isn't particularily -useful to enable them here as there will be no data to retrieve. +.. code-block:: bash + + $ mkdir -p /var/www/puppetboard + $ chown www-data:www-data /var/www/puppetboard + +Copy Puppetboard's ``default_settings.py`` to the newly created puppetboard +directory and name the file ``settings.py``. This file will be available +at the path Puppetboard was installed, for example: +``/usr/local/lib/python2.X/lib/dist-packages/puppetboard/default_settings.py``. + +Change the settings that need changing to match your environment and delete +or comment with a ``#`` the rest of the entries. + +If you don't need to change any settings you can skip the creation of the +``settings.py`` file entirely. + +Now create a ``wsgi.py`` with the following content in the newly created +puppetboard directory: + +.. code-block:: + + from __future__ import absolute_import + import os + + # Needed if a settings.py file exists + os.environ['PUPPETBOARD_SETTINGS'] = '/var/www/puppetboard/settings.py' + from puppetboard.app import app as application + +Make sure this file is owned by the user and group the uwsgi instance will run +as. + +Now we need to start uwsgi: + +.. code-block:: bash + + $ uwsgi --http :9090 --wsgi-file /var/www/puppetboard/wsgi.py + +Feel free to change the port to something other than ``9090``. + +The last thing we need to do is configure nginx to proxy the requests: + +.. code-block:: + + upstream puppetboard { + server 127.0.0.1:9090; + } + + server { + listen 80; + server_name puppetboard.example.tld; + charset utf-8; + + location /static { + alias /usr/local/lib/python2.X/dist-packages/puppetboard/static; + } + + location / { + uwsgi_pass puppetboard; + include /path/to/uwsgi_params/probably/etc/nginx/uwsgi_params; + } + } + +If all went well you should now be able to access to Puppetboard. Note the +``/static`` location block to make nginx serve static files like the included +CSS and Javascript. + +Because nginx natively supports the uwsgi protocol we use ``uwsgi_pass`` +instead of the traditional ``proxy_pass``. + +Security +-------- + +If you wish to make users authenticate before getting access to Puppetboard +you can use one of the following configuration snippets. + +Apache +^^^^^^ + +Inside the ``VirtualHost``: + +.. code-block:: + + + AuthType Basic + AuthName "Puppetboard" + Require valid-user + AuthBasicProvider file + AuthUserFile /path/to/a/file.htpasswd + + +nginx +^^^^^ + +Inside the ``location / {}`` block that has the ``uwsgi_pass`` directive: + +.. code-block:: + + auth_basic "Puppetboard"; + auth_basic_user_file /path/to/a/file.htpasswd; Getting Help ============