Modules
=======

The repository for the Puppet role/profile module is
`<https://git.psi.ch/linux-infra/puppet>`_.

The general roles structure is::

  role::generic_server
  role::generic_desktop
  ...
  role::daas::compute
  role::daas::login
  ...
  role::sls::console
  role::sls::boot_server

So we have some roles that are generic PSI-wide (eg. ``generic_server``) while
some roles that are specific to some projects and have a dedicated namespace.

For the profiles section we have the following::
  
  profile::ssh_client
  profile::afs_client
  profile::log_client
  profile::mysql_server

For profiles maybe we will not need namespace areas dedicated to
specific projects, since profiles should be generic enough to be
reusable.


How to write modules
--------------------

The structure of a module depends on the type of module to some extent.
Currently, we distinguish three kinds of modules:

- roles
- profiles
- components


Parameter validation
~~~~~~~~~~~~~~~~~~~~

The first thing every module must do is parameter and environment validation. In
particular, a module should check that

- its arguments have the correct type
- it supports the OS of the client system

A typical module could start like this::

  class profile::logging (
    $forward_to,
    $persistent_journal,
  )
  {
    validate_array($forward_to)
    validate_bool($target)

    check_os('RedHat 7', 'RedHat 8')
  }

This would make sure that ``$forward_to`` is an array, ``$persistent_journal``
is a boolean, and that the client runs RHEL 7 or (a hypothetical) RHEL 8.

Arguments should be checked first, in the order that they are passed.

Checking the OS will ease porting efforts to newer releases of RHEL, other
distributions (e.g. Ubuntu), or other operating systems (e.g. BSD), should the
need arise.


Hiera queries
~~~~~~~~~~~~~

Only profiles and roles query Hiera. Components should take all their inputs as
parameters or facts.

In profiles, Hiera queries must generally be done as default arguments to
parameters, **not** inside the modules body::

  class profile::logging (
    $forward_to=hiera('...'),
    $persistent_journal=hiera('...'),
  )
  {

The reason is that this allows a role to enforce certain parameters and disable
the corresponding Hiera query.


Layout
~~~~~~

Roles and profiles are usually implemented in a single file, e.g.
``psi/manifests/profile/logging.pp``. Components on the other hand follow the
standard Puppet layout, i.e.
``auditd/manifests/{init,install,config,service}.pp``.

Files and templates
~~~~~~~~~~~~~~~~~~~

Every file or template should be used by only one class and its path inside the
module should reflect this. Eg. if the template ``sshd_config.erb`` is used by
the ``profile::ssh_server`` module, it will be places inside the
``templates/profile/ssh_server`` directory.

Furthermore, on top of every file managed by puppet, a header like the
following should be present: ::

  ########################################################################
  #
  # THIS FILE IS MANAGED BY PUPPET - DO NOT MODIFY!
  #
  # profile::ssh_server
  # sshd_config.erb
  #
  ########################################################################

The last two lines should be:

  - the puppet class using the file;
  - the name of the file/template.

Debugging templates
~~~~~~~~~~~~~~~~~~~

You can use the ``erb`` tool to test the variable interpolation. One easy way is to prepare a file with the variable values and pipe it together with the template through erb. Define the variables in a file ``test-vars.erb`` like in this example::

  <%
  @partitions = {'a' => 'aa', 'b' => 'bb', 'c' => 'cc'}
  @group_whitelist = ['groupA', 'groupB']
  @port = 8000
  %>

and then use a commmand line like the following to pipe it through ``erb``::

  erb <(cat /tmp/test-vars.erb /tmp/my-template.erb)

The output will contain the variable substituted template. If you want to check your
template for syntax errors, you can just use the following command::

  erb -P -x -T '-' jupyterhub_config.py.erb | ruby -c

Roles
-----

.. toctree::
   :maxdepth: 1

   roles/base
   roles/bootpc
   roles/console
   roles/daq_buffer
   roles/dcache_t3_pools
   roles/desktop
   roles/ganglia_server
   roles/grafana
   roles/hpc/ces
   roles/hpc/cn
   roles/hpc/database
   roles/hpc/ui
   roles/hpc/server
   roles/influxdb
   roles/jupyterserver
   roles/log_server
   roles/login_server
   roles/media_station
   roles/nomachine_proxy
   roles/reverse_proxy
   roles/server
   roles/slurm_client
   roles/slurm_compute
   roles/slurm_server
   roles/softioc
   roles/web_server
   roles/workstation
   roles/zookeeper


Profiles
--------

.. toctree::
   :maxdepth: 1

   profiles/aaa
   profiles/afs_client
   profiles/autofs
   profiles/custom_timers
   profiles/epics
   profiles/filecopy
   profiles/files
   profiles/ganglia_client
   profiles/ganglia_server
   profiles/gnome
   profiles/gpfs
   profiles/grafana
   profiles/icewm
   profiles/icinga/client
   profiles/icinga/nrpe
   profiles/icinga/checks/gpfs
   profiles/icinga/checks/nvidia
   profiles/icinga/checks/puppet_client
   profiles/icinga/checks/service
   profiles/icinga/checks/slurm
   profiles/icinga/checks/hp/smart_array
   profiles/infiniband
   profiles/jupyterhub
   profiles/kdump_client
   profiles/local_accounts
   profiles/log_client
   profiles/log_server
   profiles/mkresource/files
   profiles/mounter
   profiles/mta
   profiles/multipath
   profiles/nomachine
   profiles/nomachine/desktop
   profiles/nomachine/license
   profiles/nomachine/repository
   profiles/nomachine/service
   profiles/nomachine/terminal
   profiles/nomachine/workstation
   profiles/networking
   profiles/nfs_server
   profiles/ntp_client
   profiles/nvidia
   profiles/package_list
   profiles/platform
   profiles/platform/hewlett_packard
   profiles/pmodules
   profiles/print_client
   profiles/puppet_client
   profiles/repository
   profiles/repository_list
   profiles/rpm_repos
   profiles/serial_console
   profiles/ssh_client
   profiles/ssh_server.rst
   profiles/sysinfo
   profiles/telegraf
   profiles/vgroot
   profiles/web_server


Components
----------

.. toctree::
   :maxdepth: 1

   components/grub2
   components/logrotate
   components/selinux
   components/sudo
   components/systemd
   components/sysctl
   components/updatedb
   components/utils
