Merge branch 'master' into 'dma-type'

# Conflicts:
#   scripts/run-shellcheck.sh
This commit is contained in:
fnux 2021-01-12 07:10:10 +01:00
commit bf90e55137
111 changed files with 4576 additions and 12 deletions

View file

@ -1,14 +1,29 @@
stages: stages:
- test - test
- doc
image: code.ungleich.ch:5050/ungleich-public/cdist/cdist-ci:latest image: code.ungleich.ch:5050/ungleich-public/cdist-contrib/ci-container:latest
shellcheck: shellcheck:
stage: test stage: test
script: script:
- ./scripts/run-shellcheck.sh - make lint
manpages: manpages:
stage: test stage: test
script: script:
- ./scripts/run-manpage-checks.sh - make check-manpages
docs:
stage: doc
only:
- master
before_script:
- eval $(ssh-agent -s)
- echo "$CD_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- echo "$CD_SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- make html
- sftp fnux@staticwebhosting.ungleich.ch:public_html/cdist-contrib <<< "put -r docs/dist/html/*"

View file

@ -1,3 +0,0 @@
# cdist-contrib changes
* 2020-04-28: New type: __find_exec (Ander Punnar)

70
Makefile Normal file
View file

@ -0,0 +1,70 @@
.PHONY: help
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo "man build only man user documentation"
@echo "html build only html user documentation"
@echo "docs build both man and html user documentation"
@echo "check-manpages check for manpage in types"
@echo "lint run shellcheck on types"
@echo "check run both type manpage checks and linting"
@echo "clean clean"
DOCS_SRC_DIR=./docs/src
TYPEDIR=./type
SPHINXM=make -C $(DOCS_SRC_DIR) man
SPHINXH=make -C $(DOCS_SRC_DIR) html
SPHINXC=make -C $(DOCS_SRC_DIR) clean
################################################################################
# Manpages
#
MAN7DSTDIR=$(DOCS_SRC_DIR)/man7
# Use shell / ls to get complete list - $(TYPEDIR)/*/man.rst does not work
# Using ls does not work if no file with given pattern exist, so use wildcard
MANTYPESRC=$(wildcard $(TYPEDIR)/*/man.rst)
MANTYPEPREFIX=$(subst $(TYPEDIR)/,$(MAN7DSTDIR)/cdist-type,$(MANTYPESRC))
MANTYPES=$(subst /man.rst,.rst,$(MANTYPEPREFIX))
# Link manpage: do not create man.html but correct named file
$(MAN7DSTDIR)/cdist-type%.rst: $(TYPEDIR)/%/man.rst
mkdir -p $(MAN7DSTDIR)
ln -sf "../../../$^" $@
DOCSINDEX=$(MAN7DSTDIR)/index.rst
DOCSINDEXH=$(DOCS_SRC_DIR)/index.rst.sh
$(DOCSINDEX): $(DOCSINDEXH)
$(DOCSINDEXH)
# Manpages: .cdist Types
DOT_CDIST_PATH=${HOME}/.cdist
DOTMAN7DSTDIR=$(MAN7DSTDIR)
DOTTYPEDIR=$(DOT_CDIST_PATH)/type
# Link manpage: do not create man.html but correct named file
$(DOTMAN7DSTDIR)/cdist-type%.rst: $(DOTTYPEDIR)/%/man.rst
ln -sf "$^" $@
man: $(MANTYPES) $(DOCSINDEX)
$(SPHINXM)
html: $(MANTYPES) $(DOCSINDEX)
$(SPHINXH)
docs: man html
check-manpages:
./scripts/run-manpage-checks.sh
lint:
./scripts/run-shellcheck.sh
check: check-manpages lint
clean:
$(SPHINXC)
rm -f docs/src/index.rst
rm -rf docs/src/man7/
rm -rf docs/src/__pycache__/

View file

@ -5,8 +5,9 @@ tool with community-maitained types which are either too specific to fit/be
maintained in cdist itself or were not accepted in code cdist but could still maintained in cdist itself or were not accepted in code cdist but could still
be useful. be useful.
This project does not have releases and is continously updated: see This project does not have releases and is continously updated: see git history
`CHANGELOG.md` for details. for change log. You will find HTML documentation at
[contrib.cdi.st](https://contrib.cdi.st).
## Using cdist-contrib ## Using cdist-contrib
@ -32,14 +33,11 @@ And you would run [cdist][cdist] from the same directory as follows:
## Participating in the [cdist][cdist] community ## Participating in the [cdist][cdist] community
Join us on [#cdist:ungleich.ch][cdistmatrix] on matrix or on Join us on [#cdist:ungleich.ch][cdistmatrix] on matrix!
[#cdist over mattermost][cdistmattermost].
[cdist]: https://www.cdi.st/ [cdist]: https://www.cdi.st/
[cdistconfig]: https://www.cdi.st/manual/latest/cdist-configuration.html [cdistconfig]: https://www.cdi.st/manual/latest/cdist-configuration.html
[cdistmatrix]: https://matrix.to/#/#cdist:ungleich.ch [cdistmatrix]: https://matrix.to/#/#cdist:ungleich.ch
[cdistmattermost]: https://chat.ungleich.ch/ungleich/channels/cdist
## Contributing ## Contributing
@ -53,3 +51,11 @@ Every type in cdist-contrib must:
* Have a `man.rst` documentation page. * Have a `man.rst` documentation page.
* Pass [shellcheck](http://shellcheck.net/) without errors. * Pass [shellcheck](http://shellcheck.net/) without errors.
## Other resources
Some people/organizations are known to keep some cdist types that might be of
interest to others:
* [cdist-evilham](https://git.sr.ht/~evilham/cdist-evilham): Evilham's cdist-types
* [cdist-recycledcloud](https://code.recycled.cloud/e-Durable/cdist-recycledcloud): e-Durable SA / Recycled Cloud public types

235
docs/src/Makefile Normal file
View file

@ -0,0 +1,235 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
PAPER ?=
BUILDDIR ?= ../dist
# for cache, etc.
_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
help:
@echo "Please use \`make <target>' where <target> 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 " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " epub3 to make an epub3"
@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)"
@echo " dummy to check syntax errors of document sources"
.PHONY: clean
clean:
rm -rf $(BUILDDIR)/*
rm -rf $(_BUILDDIR)/*
.PHONY: html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
.PHONY: dirhtml
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
.PHONY: singlehtml
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
.PHONY: pickle
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
.PHONY: json
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
.PHONY: htmlhelp
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."
.PHONY: qthelp
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/cdist-docs.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/cdist-docs.qhc"
.PHONY: applehelp
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
.PHONY: devhelp
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/cdist-docs"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/cdist-docs"
@echo "# devhelp"
.PHONY: epub
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
.PHONY: epub3
epub3:
$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
@echo
@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
.PHONY: latex
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)."
.PHONY: latexpdf
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."
.PHONY: latexpdfja
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."
.PHONY: text
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
.PHONY: man
man:
$(SPHINXBUILD) -b cman $(ALLSPHINXOPTS) $(BUILDDIR)/man
mkdir -p $(BUILDDIR)/man/man7
mv -f $(BUILDDIR)/man/*.7 $(BUILDDIR)/man/man7/
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
.PHONY: texinfo
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)."
.PHONY: info
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."
.PHONY: gettext
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
.PHONY: changes
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
.PHONY: linkcheck
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."
.PHONY: doctest
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
.PHONY: coverage
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
.PHONY: xml
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
.PHONY: pseudoxml
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
.PHONY: dummy
dummy:
$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
@echo
@echo "Build finished. Dummy builder generates no files."

101
docs/src/conf.py Normal file
View file

@ -0,0 +1,101 @@
#!/usr/bin/env python3
import sys
import os
import sphinx_rtd_theme
from datetime import date
# 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('.'))
sys.path.insert(0, os.path.abspath(os.path.join(
os.path.dirname(os.path.realpath(__file__)), "..", "..")))
# -- 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 = [
'docs.src.manpage',
'sphinx.ext.extlinks',
]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
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 = 'cdist-contrib'
copyright = 'cdist-contrib contributors'
# 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.
version = str(date.today())
release = os.popen('git rev-parse HEAD').read()
# 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
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = 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 = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Output file base name for HTML help builder.
htmlhelp_basename = 'cdistcontribdoc'
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
root_mandir = os.path.dirname(os.path.realpath(__file__))
mandirs = []
for mansubdir in ('man7',):
mandirs.append((os.path.join(root_mandir, mansubdir), mansubdir[-1]))
man_pages = []
for mandir, section in mandirs:
for root, dirs, files in os.walk(mandir):
for fname in files:
froot, fext = os.path.splitext(fname)
if fext == '.rst':
man_page = (os.path.join('man' + str(section), froot),
froot, '', [], section)
man_pages.append(man_page)
# man_pages = [
# ('cdist-type', 'cdist-type', 'cdist-type documentation',
# [author], 1),
# ('man7/cdist-type__file', 'cdist-type__file',
# '', [], 1),
# ('cdist-type__directory', 'cdist-type__directory',
# 'cdist-type__directory documentation', [author], 1),
# ]
# If true, show URL addresses after external links.
# man_show_urls = False

40
docs/src/index.rst.sh Executable file
View file

@ -0,0 +1,40 @@
#!/bin/sh
__cdist_pwd="$(pwd -P)"
__cdist_mydir="${0%/*}";
__cdist_abs_mydir="$(cd "$__cdist_mydir" && pwd -P)"
__cdist_myname=${0##*/};
__cdist_abs_myname="$__cdist_abs_mydir/$__cdist_myname"
filename="${__cdist_myname%.sh}"
dest="$__cdist_abs_mydir/$filename"
if ! command -v pandoc > /dev/null; then
echo "Pandoc is required to generate HTML index from README." >&2
exit 1
fi
cd "$__cdist_abs_mydir"
exec > "$dest"
pandoc -f markdown -t rst ../../README.md
cat << EOF
.. toctree::
:hidden:
EOF
# If there is no such file then ls prints error to stderr,
# so redirect stderr to /dev/null.
for type in $(ls man7/cdist-type__*.rst 2>/dev/null | LC_ALL=C sort); do
no_dir="${type#man7/}";
no_type="${no_dir#cdist-type}";
name="${no_type%.rst}";
manref="${no_dir%.rst}"
man="${manref}(7)"
echo " $name" "<man7/${manref}>"
done

87
docs/src/manpage.py Normal file
View file

@ -0,0 +1,87 @@
import sphinx.builders.manpage
import sphinx.writers.manpage
from docutils.frontend import OptionParser
from sphinx.util.console import bold, darkgreen
from six import string_types
from docutils.io import FileOutput
from os import path
from sphinx.util.nodes import inline_all_toctrees
from sphinx import addnodes
from sphinx.util import logging
"""
Extension based on sphinx builtin manpage.
It does not write its own .SH NAME based on config,
but leaves everything to actual reStructuredText file content.
"""
logger = logging.getLogger(__name__)
class ManualPageTranslator(sphinx.writers.manpage.ManualPageTranslator):
def header(self):
tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\""
" \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n")
return tmpl % self._docinfo
class ManualPageWriter(sphinx.writers.manpage.ManualPageWriter):
def __init__(self, builder):
super().__init__(builder)
self.translator_class = (
self.builder.get_translator_class() or ManualPageTranslator)
class ManualPageBuilder(sphinx.builders.manpage.ManualPageBuilder):
name = 'cman'
default_translator_class = ManualPageTranslator
def write(self, *ignored):
docwriter = ManualPageWriter(self)
docsettings = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
logger.info(bold('writing... '), nonl=True)
for info in self.config.man_pages:
docname, name, description, authors, section = info
if isinstance(authors, string_types):
if authors:
authors = [authors]
else:
authors = []
targetname = '%s.%s' % (name, section)
logger.info(darkgreen(targetname) + ' { ', nonl=True)
destination = FileOutput(
destination_path=path.join(self.outdir, targetname),
encoding='utf-8')
tree = self.env.get_doctree(docname)
docnames = set()
largetree = inline_all_toctrees(self, docnames, docname, tree,
darkgreen, [docname])
logger.info('} ', nonl=True)
self.env.resolve_references(largetree, docname, self)
# remove pending_xref nodes
for pendingnode in largetree.traverse(addnodes.pending_xref):
pendingnode.replace_self(pendingnode.children)
largetree.settings = docsettings
largetree.settings.title = name
largetree.settings.subtitle = description
largetree.settings.authors = authors
largetree.settings.section = section
docwriter.write(largetree, destination)
logger.info("")
def setup(app):
app.add_builder(ManualPageBuilder)

View file

@ -0,0 +1,7 @@
# This image is used in the cdist-contrib CI for linting and generating the
# documentation.
FROM fedora:latest
MAINTAINER Timothée Floure <fnux@ungleich.ch>
RUN dnf install -y git findutils make python3-sphinx python3-sphinx_rtd_theme \
ShellCheck openssh-clients pandoc

View file

@ -0,0 +1,36 @@
#!/bin/sh
passphrase=
appendonly=
case "$(cat "${__object:?}/parameter/encryption")" in
none)
enc=none
;;
repokey)
enc=repokey
if [ -f "${__object:?}/parameter/passphrase" ];
then
passphrase="$(cat "${__object:?}/parameter/passphrase")"
else
echo "__borg_repo cannot use repokey encryption with no passphrase. Aborting." >&2;
exit 1;
fi
;;
*)
echo "$enc is not a known encryption mode for __borg_repo. Aborting." >&2
exit 1;
esac
if [ -f "${__object:?}/parameter/append-only" ];
then
appendonly='--append-only'
fi
cat <<- EOF
if ! borg check --repository-only 1>&2 2>/dev/null "/${__object_id:?}";
then
BORG_NEW_PASSPHRASE=$passphrase borg init -e ${enc:?} $appendonly /${__object_id:?}
fi
EOF

43
type/__borg_repo/man.rst Normal file
View file

@ -0,0 +1,43 @@
cdist-type__borg_repo(7)
========================
NAME
----
cdist-type__borg_repo - Configure a borg repository on host
DESCRIPTION
-----------
Initializes a borg repository at the location specified in the
`${__object_id}`. Nothing is done if the repository already exists.
Currently, only `none` and `repokey` are supported as encryption modes;
`repokey` requires the `passphrase` argument to be given. The default is
`none`.
REQUIRED PARAMETERS
-------------------
encryption
The encryption to use.
OPTIONAL PARAMETERS
-------------------
passphrase
The passphrase to encrypt the keyfile with.
BOOLEAN PARAMETERS
------------------
append-only
If the repository is append-only
AUTHORS
-------
Joachim Desroches <joachim.desroches@epfl.ch>
COPYING
-------
Copyright \(C) 2020 Joachim Desroches. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

14
type/__borg_repo/manifest Normal file
View file

@ -0,0 +1,14 @@
#!/bin/sh
os="$(cat "${__global:?}"/explorer/os)"
case "$os" in
"alpine")
borg_package=borgbackup
;;
*)
echo "__borg_repo is not yet implemented for os $os. Aborting." >&2;
exit 1;
esac
__package "$borg_package"

View file

@ -0,0 +1 @@
append-only

View file

@ -0,0 +1 @@
none

View file

@ -0,0 +1 @@
passphrase

View file

@ -0,0 +1 @@
encryption

View file

@ -0,0 +1,90 @@
#!/bin/sh
#
# Upstream configuration guide/documentation:
# https://github.com/vector-im/riot-web/blob/develop/docs/config.md
generate_embedded_pages () {
if [ "$EMBED_HOMEPAGE" != "" ]; then
cat << EOF
"embeddedPages": {
"homeUrl": "home.html"
},
EOF
fi
}
generate_jitsi_config () {
if [ "$JITSI_DOMAIN" != "" ]; then
cat << EOF
"jitsi": {
"preferredDomain": "$JITSI_DOMAIN"
},
EOF
fi
}
generate_branding () {
echo '"branding": {'
if [ "$BRANDING_AUTH_HEADER_LOGO_URL" != "" ]; then
cat << EOF
"authHeaderLogoUrl": "$BRANDING_AUTH_HEADER_LOGO_URL",
EOF
fi
if [ "$BRANDING_AUTH_FOOTER_LINKS" != "" ]; then
cat << EOF
"authFooterLinks": "$BRANDING_AUTH_FOOTER_LINKS",
EOF
fi
cat << EOF
"welcomeBackgroundUrl": "themes/element/img/backgrounds/lake.jpg"
EOF
echo '},'
}
cat << EOF
{
"default_server_config": {
"m.homeserver": {
"base_url": "$DEFAULT_SERVER_URL",
"server_name": "$DEFAULT_SERVER_NAME"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"brand": "$BRAND",
$(generate_branding)
"defaultCountryCode": "$DEFAULT_COUNTRY_CODE",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"roomDirectory": {
"servers": [
$ROOM_DIRECTORY_SERVERS
]
},
"disable_custom_urls": "$DISABLE_CUSTOM_URLS",
$(generate_embedded_pages)
$(generate_jitsi_config)
"terms_and_conditions_links": [
{
"url": "$PRIVACY_POLICY_URL",
"text": "Privacy Policy"
},
{
"url": "$COOKIE_POLICY_URL",
"text": "Cookie Policy"
}
]
}
EOF

View file

@ -0,0 +1,69 @@
#!/bin/sh -e
#
# 2019 Timothée Floure (timothee.floure@ungleich.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
VERSION=$(cat "$__object/parameter/version")
INSTALL_DIR=$(cat "$__object/parameter/install_dir")
OWNER=$(cat "$__object/parameter/owner")
src="riot-v$VERSION"
archive="$src.tar.gz"
url="https://github.com/vector-im/riot-web/releases/download/v$VERSION/$archive"
# tar and curl are installed by the __matrix-riot manifest. mktemp is usually
# provided by coreutils and assumed installed.
cat << EOF
set -e
# Ensure that coreutils is installed.
if [ ! -x \$(which mktemp) ]; then
echo "mktemp is not available on the remote host." >&2
exit 1
fi
# Create temporary working directory.
tmpdir=\$(mktemp -d)
custom_files_dir="\$tmpdir/custom_files"
cd \$tmpdir
# Download and extract sources.
curl -L '$url' > $archive
tar xf $archive
# Backup files deployed by __matrix_element.
mkdir -p \$custom_files_dir
for file in $INSTALL_DIR/cdist/*; do
cp "\$file" "\$custom_files_dir"
done
# Deploy sources and restore configuration.
rm -r '$INSTALL_DIR'
mv '$src' '$INSTALL_DIR'
for file in \$custom_files_dir/*; do
cp "\$file" '$INSTALL_DIR'
done
# Chown deployed files to requested owner.
chown -R '$OWNER' '$INSTALL_DIR'
# Remove temporary working directory.
cd /
rm -r \$tmpdir
EOF

View file

@ -0,0 +1,87 @@
cdist-type__matrix_element(7)
=============================
NAME
----
cdist-type__matrix_element - Install and configure Element, a web Matrix client.
DESCRIPTION
-----------
This type install and configure the Element web client.
REQUIRED PARAMETERS
-------------------
install_dir
Root directory of Element's static files.
version
Release of Element to install.
OPTIONAL PARAMETERS
-------------------
default_server_name
Name of matrix homeserver to connect to, defaults to 'matrix.org'.
default_server_url
URL of matrix homeserver to connect to, defaults to 'https://matrix-client.matrix.org'.
owner
Owner of the deployed files, passed to `chown`. Defaults to 'root'.
brand
Web UI branding, defaults to 'Element'.
default_country_code
ISO 3166 alpha2 country code to use when showing country selectors, such as
phone number inputs. Defaults to GB.
privacy_policy_url
Defaults to 'https://element.io/privacy'.
cookie_policy_url
Defaults to 'https://matrix.org/docs/guides/element_im_cookie_policy'.
jitsi_domain
Domain name of preferred Jitsi instance (default is jitsi.element.im). This is
used whenever a user clicks on the voice/video call buttons.
homepage
Path to custom homepage, displayed once logged in.
welcomepage
Path to custom welcome (= login) page.
custom_asset
Serve a file a the top-level directory (e.g. /my-custom-logo.svg). Can be specified multiple times.
BOOLEAN PARAMETERS
-------------------
disable_custom_urls
Disallow the user to change the default homeserver when signing up or logging in.
EXAMPLES
--------
.. code-block:: sh
__matrix_element my-element --install_dir /var/www/element-web --version 1.5.6
SEE ALSO
--------
- `cdist-type__matrix_synapse(7) <cdist-type__matrix_synapse.html>`_
AUTHORS
-------
Timothée Floure <timothee.floure@ungleich.ch>
COPYING
-------
Copyright \(C) 2019 Timothée Floure. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

106
type/__matrix_element/manifest Executable file
View file

@ -0,0 +1,106 @@
#!/bin/sh -e
#
# 2019 Timothée Floure (timothee.floure@ungleich.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
# Ignore "Declare and assign separately to avoid masking return values. [SC2155]"
# => not relevant for the type arguments.
# shellcheck disable=SC2155
INSTALL_DIR=$(cat "$__object/parameter/install_dir")
export DEFAULT_SERVER_NAME=$(cat "$__object/parameter/default_server_name")
export DEFAULT_SERVER_URL=$(cat "$__object/parameter/default_server_url")
export BRAND=$(cat "$__object/parameter/brand")
export DEFAULT_COUNTRY_CODE=$(cat "$__object/parameter/default_country_code")
export ROOM_DIRECTORY_SERVERS=$(cat "$__object/parameter/room_directory_servers")
export PRIVACY_POLICY_URL=$(cat "$__object/parameter/privacy_policy_url")
export COOKIE_POLICY_URL=$(cat "$__object/parameter/cookie_policy_url")
if [ -f "$__object/parameter/jitsi_domain" ]; then
export JITSI_DOMAIN=$(cat "$__object/parameter/jitsi_domain")
fi
if [ -f "$__object/parameter/branding_auth_header_logo_url" ]; then
export BRANDING_AUTH_HEADER_LOGO_URL=$(cat "$__object/parameter/branding_auth_header_logo_url")
fi
if [ -f "$__object/parameter/branding_auth_footer_links" ]; then
export BRANDING_AUTH_FOOTER_LINKS=$(cat "$__object/parameter/branding_auth_footer_links")
fi
if [ -f "$__object/parameter/homepage" ]; then
export EMBED_HOMEPAGE=1
homepage=$(cat "$__object/parameter/homepage")
fi
if [ -f "$__object/parameter/welcomepage" ]; then
export EMBED_WELCOMEPAGE=1
welcomepage=$(cat "$__object/parameter/welcomepage")
fi
if [ -f "$__object/parameter/custom_asset" ]; then
"$__object/parameter/custom_asset" | while IFS= read -r file; do
require="__directory/$INSTALL_DIR/cdist" __file "$INSTALL_DIR/cdist/$(basename "$file")" \
--source "$file" \
--mode 0664 \
--state present
done
fi
if [ -f "$__object/parameter/disable_custom_urls" ]; then
export DISABLE_CUSTOM_URLS='true'
else
export DISABLE_CUSTOM_URLS='false'
fi
# Owner of the uploaded files.
owner=$(cat "$__object/parameter/owner")
# Ensure that curl and tar are installed, as they will be required by the
# gencode-remote script.
__package curl --state present
__package tar --state present
# Generate and deploy configuration file.
mkdir -p "$__object/files"
"$__type/files/config.json.sh" > "$__object/files/config.json"
# Install the config.json configuration file. The application's sources are
# downloaded and deployed by gencode-remote.
__directory "$INSTALL_DIR/cdist" \
--owner "$owner" --mode 0755 --parents \
--state present
require="__directory/$INSTALL_DIR/cdist" __file "$INSTALL_DIR/cdist/config.json" \
--source "$__object/files/config.json" \
--mode 0664 \
--state present
if [ $EMBED_HOMEPAGE ]; then
require="__directory/$INSTALL_DIR/cdist" __file "$INSTALL_DIR/cdist/home.html" \
--source "$homepage" \
--mode 0664 \
--state present
fi
if [ $EMBED_WELCOMEPAGE ]; then
require="__directory/$INSTALL_DIR/cdist" __file "$INSTALL_DIR/cdist/welcome.html" \
--source "$welcomepage" \
--mode 0664 \
--state present
fi

View file

@ -0,0 +1 @@
disable_custom_urls

View file

@ -0,0 +1 @@
Element

View file

@ -0,0 +1 @@
https://matrix.org/docs/guides/riot_im_cookie_policy

View file

@ -0,0 +1 @@
GB

View file

@ -0,0 +1 @@
matrix.org

View file

@ -0,0 +1 @@
https://matrix-client.matrix.org

View file

@ -0,0 +1 @@
root

View file

@ -0,0 +1 @@
https://element.io/privacy

View file

@ -0,0 +1 @@
"matrix.org"

View file

@ -0,0 +1,13 @@
default_server_url
default_server_name
brand
default_country_code
privacy_policy_url
cookie_policy_url
room_directory_servers
owner
homepage
welcomepage
jitsi_domain
branding_auth_header_logo_url
branding_auth_footer_links

View file

@ -0,0 +1 @@
custom_asset

View file

@ -0,0 +1,2 @@
version
install_dir

View file

@ -0,0 +1,18 @@
#!/bin/sh
cat <<EOF
[Unit]
Description=IM bridging daemon
Wants=network-online.target
After=network-online.target
[Service]
User=$USER
Group=$GROUP
Type=simple
Restart=on-failure
ExecStart=$BINARY_PATH -conf=/etc/matterbridge/matterbridge.toml
[Install]
WantedBy=multi-user.target
EOF

View file

@ -0,0 +1,56 @@
cdist-type__matterbridge(7)
===========================
NAME
----
cdist-type__matterbridge - Install matterbridge from upstream binary
DESCRIPTION
-----------
This singleton type install a matterbridge service from binary.
REQUIRED PARAMETERS
-------------------
version
Release (git tag) to fetch from the project github's page.
config
Matterbridge configuration (TOML).
OPTIONAL PARAMETERS
-------------------
None.
BOOLEAN PARAMETERS
------------------
None.
EXAMPLES
--------
.. code-block:: sh
__matterbridge --version 1.16.3 --config - <<- EOF
[...]
EOF
SEE ALSO
--------
- `Matterbridge github repository <https://github.com/42wim/matterbridge>`_
AUTHORS
-------
Timothée Floure <timothee.floure@ungleich.ch>
COPYING
-------
Copyright \(C) 2020 Timothée Floure. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

98
type/__matterbridge/manifest Executable file
View file

@ -0,0 +1,98 @@
#!/bin/sh -e
#
# 2020 Timothée Floure (timothee.floure@ungleich.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
debian)
# This type assume systemd for service installation.
;;
*)
printf "Your operating system (%s) is currently not supported by this type (%s)\n" "$os" "${__type##*/}" >&2
printf "Please contribute an implementation for it if you can.\n" >&2
exit 1
;;
esac
# Required parameters.
VERSION=$(cat "$__object/parameter/version")
if [ -f "$__object/parameter/config" ]; then
CONFIG="$(cat "$__object/parameter/config")"
if [ "$CONFIG" = "-" ]; then
CONFIG=$(cat "$__object/stdin")
fi
fi
# Hardcoded values used in templates.
export BINARY_PATH=/usr/local/bin/matterbridge
export CONFIG_PATH=/etc/matterbridge/matterbridge.toml
export USER=matterbridge
export GROUP=$USER
# Internal variables.
artefact="matterbridge-$VERSION-linux-64bit"
checksum_file="checksums.txt"
release_download_url=https://github.com/42wim/matterbridge/releases/download
binary_url="$release_download_url/v$VERSION/$artefact"
checksum_file_url="$release_download_url/v$VERSION/$checksum_file"
config_dir=$(dirname $CONFIG_PATH)
systemd_unit_path='/etc/systemd/system/matterbridge.service'
# Check if curl is available.
if ! command -v curl; then
echo "curl is required for this type, but could not be found. Exiting." >&2
exit 1
fi
# Initialize working directory.
mkdir -p "$__object/files"
# Download and check matterbridge binary.
curl -L "$binary_url" -o "$__object/files/$artefact"
curl -Ls "$checksum_file_url" | grep "$artefact" > "$__object/files/$checksum_file"
if ! (cd "$__object/files"; sha256sum --check $checksum_file); then
echo "Matterbridge binary checksum failed." >&2
exit 1
fi
# Create service user.
__user $USER --home "/var/lib/$USER"
# Deploy matterbridge binary.
require="__user/$USER" __file "$BINARY_PATH" \
--source "$__object/files/$artefact" \
--owner "$USER" --mode 755
# Generate and deploy configuration file.
"$__type/files/matterbridge.service.sh" > "$__object/files/matterbridge.service"
require="__user/$USER" __directory "$config_dir" \
--owner "$USER" --mode 0755 --parents \
require="__directory/$config_dir" __file "$CONFIG_PATH" \
--owner "$USER" \
--mode 0640 \
--source "$CONFIG"
__file "$systemd_unit_path" \
--source "$__object/files/matterbridge.service"
# Deal with init system.
require="__file/$systemd_unit_path" __start_on_boot matterbridge
require="__file/$BINARY_PATH __file/$CONFIG_PATH __file/$systemd_unit_path" __service matterbridge --action restart

View file

@ -0,0 +1,2 @@
version
config

View file

View file

@ -0,0 +1,8 @@
#!/bin/sh -e
# Explorer will output the key if he exists.
secretkey="/opt/netbox/cdist/secretkey"
if [ -f "$secretkey" ]; then
cat "$secretkey"
fi

5
type/__netbox/explorer/version Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh -e
# output version if exist
version_path="/opt/netbox/cdist/version"
if [ -f "$version_path" ]; then cat "$version_path"; fi

View file

@ -0,0 +1,319 @@
#!/bin/sh
cat << EOF
#########################
# #
# Required settings #
# #
#########################
# This is a list of valid fully-qualified domain names (FQDNs) for the NetBox server. NetBox will not permit write
# access to the server via any other hostnames. The first FQDN in the list will be treated as the preferred name.
#
# Example: ALLOWED_HOSTS = ['netbox.example.com', 'netbox.internal.local']
ALLOWED_HOSTS = [$ALLOWED_HOSTS ]
# PostgreSQL database configuration. See the Django documentation for a complete list of available parameters:
# https://docs.djangoproject.com/en/stable/ref/settings/#databases
DATABASE = {
'NAME': '$DATABASE_NAME', # Database name
'USER': '$DATABASE_USER', # PostgreSQL username
'PASSWORD': '$DATABASE_PASSWORD', # PostgreSQL password
'HOST': '$DATABASE_HOST', # Database server
'PORT': '$DATABASE_PORT', # Database port (leave blank for default)
'CONN_MAX_AGE': 300, # Max database connection age
}
# Redis database settings. Redis is used for caching and for queuing background tasks such as webhook events. A separate
# configuration exists for each. Full connection details are required in both sections, and it is strongly recommended
# to use two separate database IDs.
REDIS = {
'tasks': {
'HOST': '$REDIS_HOST',
'PORT': $REDIS_PORT,
# Comment out \`HOST\` and \`PORT\` lines and uncomment the following if using Redis Sentinel
# 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
# 'SENTINEL_SERVICE': 'netbox',
'PASSWORD': '$REDIS_PASSWORD',
'DATABASE': $((REDIS_DBID_OFFSET + 0)),
'SSL': $REDIS_SSL,
},
'caching': {
'HOST': '$REDIS_HOST',
'PORT': $REDIS_PORT,
# Comment out \`HOST\` and \`PORT\` lines and uncomment the following if using Redis Sentinel
# 'SENTINELS': [('mysentinel.redis.example.com', 6379)],
# 'SENTINEL_SERVICE': 'netbox',
'PASSWORD': '$REDIS_PASSWORD',
'DATABASE': $((REDIS_DBID_OFFSET + 1)),
'SSL': $REDIS_SSL,
}
}
RQ_DEFAULT_TIMEOUT = 300
# This key is used for secure generation of random numbers and strings. It must never be exposed outside of this file.
# For optimal security, SECRET_KEY should be at least 50 characters in length and contain a mix of letters, numbers, and
# symbols. NetBox will not run without this defined. For more information, see
# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-SECRET_KEY
SECRET_KEY = '$SECRET_KEY'
#########################
# #
# Optional settings #
# #
#########################
# Specify one or more name and email address tuples representing NetBox administrators. These people will be notified of
# application errors (assuming correct email settings are provided).
ADMINS = [
# ['John Doe', 'jdoe@example.com'],
]
# URL schemes that are allowed within links in NetBox
ALLOWED_URL_SCHEMES = (
'file', 'ftp', 'ftps', 'http', 'https', 'irc', 'mailto', 'sftp', 'ssh', 'tel', 'telnet', 'tftp', 'vnc', 'xmpp',
)
# Optionally display a persistent banner at the top and/or bottom of every page. HTML is allowed. To display the same
# content in both banners, define BANNER_TOP and set BANNER_BOTTOM = BANNER_TOP.
BANNER_TOP = ''
BANNER_BOTTOM = ''
# Text to include on the login page above the login form. HTML is allowed.
BANNER_LOGIN = ''
# Base URL path if accessing NetBox within a directory. For example, if installed at http://example.com/netbox/, set:
# BASE_PATH = 'netbox/'
BASE_PATH = '$BASEPATH'
# Cache timeout in seconds. Set to 0 to dissable caching. Defaults to 900 (15 minutes)
CACHE_TIMEOUT = 900
# Maximum number of days to retain logged changes. Set to 0 to retain changes indefinitely. (Default: 90)
CHANGELOG_RETENTION = 90
# API Cross-Origin Resource Sharing (CORS) settings. If CORS_ORIGIN_ALLOW_ALL is set to True, all origins will be
# allowed. Otherwise, define a list of allowed origins using either CORS_ORIGIN_WHITELIST or
# CORS_ORIGIN_REGEX_WHITELIST. For more information, see https://github.com/ottoyiu/django-cors-headers
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = [
# 'https://hostname.example.com',
]
CORS_ORIGIN_REGEX_WHITELIST = [
# r'^(https?://)?(\w+\.)?example\.com$',
]
# Set to True to enable server debugging. WARNING: Debugging introduces a substantial performance penalty and may reveal
# sensitive information about your installation. Only enable debugging while performing testing. Never enable debugging
# on a production system.
DEBUG = False
# Email settings
EMAIL = {
'SERVER': '$SMTP_HOST',
'PORT': $SMTP_PORT,
'USERNAME': '$SMTP_USER',
'PASSWORD': '$SMTP_PASSWORD',
'USE_SSL': $SMTP_USE_SSL,
'USE_TLS': $SMTP_USE_TLS,
'TIMEOUT': 10, # seconds
'FROM_EMAIL': '$SMTP_FROM_EMAIL',
}
# Enforcement of unique IP space can be toggled on a per-VRF basis. To enforce unique IP space within the global table
# (all prefixes and IP addresses not assigned to a VRF), set ENFORCE_GLOBAL_UNIQUE to True.
ENFORCE_GLOBAL_UNIQUE = False
# Exempt certain models from the enforcement of view permissions. Models listed here will be viewable by all users and
# by anonymous users. List models in the form \`<app>.<model>\`. Add '*' to this list to exempt all models.
EXEMPT_VIEW_PERMISSIONS = [
# 'dcim.site',
# 'dcim.region',
# 'ipam.prefix',
]
EOF
if [ "$HTTP_PROXY" != "" ] || [ "$HTTPS_PROXY" != "" ]; then
cat << EOF
# HTTP proxies NetBox should use when sending outbound HTTP requests (e.g. for webhooks).
HTTP_PROXIES = {
EOF
if [ "$HTTP_PROXY" != "" ]; then
cat << EOF
'http': '$HTTP_PROXY',
EOF
fi
if [ "$HTTPS_PROXY" != "" ]; then
cat << EOF
'https': '$HTTPS_PROXY',
EOF
fi
cat << EOF
}
EOF
fi
cat << EOF
# IP addresses recognized as internal to the system. The debugging toolbar will be available only to clients accessing
# NetBox from an internal IP.
INTERNAL_IPS = ('127.0.0.1', '::1')
# Enable custom logging. Please see the Django documentation for detailed guidance on configuring custom logs:
# https://docs.djangoproject.com/en/stable/topics/logging/
LOGGING = {}
# Setting this to True will permit only authenticated users to access any part of NetBox. By default, anonymous users
# are permitted to access most data in NetBox (excluding secrets) but not make any changes.
LOGIN_REQUIRED = $LOGIN_REQUIRED
# The length of time (in seconds) for which a user will remain logged into the web UI before being prompted to
# re-authenticate. (Default: 1209600 [14 days])
LOGIN_TIMEOUT = None
# Setting this to True will display a "maintenance mode" banner at the top of every page.
MAINTENANCE_MODE = False
# An API consumer can request an arbitrary number of objects =by appending the "limit" parameter to the URL (e.g.
# "?limit=1000"). This setting defines the maximum limit. Setting it to 0 or None will allow an API consumer to request
# all objects by specifying "?limit=0".
MAX_PAGE_SIZE = 1000
EOF
if [ "$MEDIA_ROOT" != "" ]; then
cat << EOF
# The file path where uploaded media such as image attachments are stored. A trailing slash is not needed. Note that
# the default value of this setting is derived from the installed location.
MEDIA_ROOT = '$MEDIA_ROOT'
EOF
fi
cat << EOF
# By default uploaded media is stored on the local filesystem. Using Django-storages is also supported. Provide the
# class path of the storage driver in STORAGE_BACKEND and any configuration options in STORAGE_CONFIG. For example:
# STORAGE_BACKEND = 'storages.backends.s3boto3.S3Boto3Storage'
# STORAGE_CONFIG = {
# 'AWS_ACCESS_KEY_ID': 'Key ID',
# 'AWS_SECRET_ACCESS_KEY': 'Secret',
# 'AWS_STORAGE_BUCKET_NAME': 'netbox',
# 'AWS_S3_REGION_NAME': 'eu-west-1',
# }
# Expose Prometheus monitoring metrics at the HTTP endpoint '/metrics'
METRICS_ENABLED = False
# Credentials that NetBox will uses to authenticate to devices when connecting via NAPALM.
NAPALM_USERNAME = ''
NAPALM_PASSWORD = ''
# NAPALM timeout (in seconds). (Default: 30)
NAPALM_TIMEOUT = 30
# NAPALM optional arguments (see http://napalm.readthedocs.io/en/latest/support/#optional-arguments). Arguments must
# be provided as a dictionary.
NAPALM_ARGS = {}
# Determine how many objects to display per page within a list. (Default: 50)
PAGINATE_COUNT = 50
# Enable installed plugins. Add the name of each plugin to the list.
PLUGINS = []
# Plugins configuration settings. These settings are used by various plugins that the user may have installed.
# Each key in the dictionary is the name of an installed plugin and its value is a dictionary of settings.
# PLUGINS_CONFIG = {
# 'my_plugin': {
# 'foo': 'bar',
# 'buzz': 'bazz'
# }
# }
# When determining the primary IP address for a device, IPv6 is preferred over IPv4 by default. Set this to True to
# prefer IPv4 instead.
PREFER_IPV4 = False
# Rack elevation size defaults, in pixels. For best results, the ratio of width to height should be roughly 10:1.
RACK_ELEVATION_DEFAULT_UNIT_HEIGHT = 22
RACK_ELEVATION_DEFAULT_UNIT_WIDTH = 220
EOF
if [ "$USE_LDAP" ]; then
cat << EOF
# Remote authentication support with ldap
REMOTE_AUTH_ENABLED = True
REMOTE_AUTH_BACKEND = 'netbox.authentication.LDAPBackend'
EOF
else
cat << EOF
# Remote authentication support
REMOTE_AUTH_ENABLED = False
REMOTE_AUTH_BACKEND = 'netbox.authentication.RemoteUserBackend'
EOF
fi
cat << EOF
REMOTE_AUTH_HEADER = 'HTTP_REMOTE_USER'
REMOTE_AUTH_AUTO_CREATE_USER = True
REMOTE_AUTH_DEFAULT_GROUPS = []
REMOTE_AUTH_DEFAULT_PERMISSIONS = {}
# This determines how often the GitHub API is called to check the latest release of NetBox. Must be at least 1 hour.
RELEASE_CHECK_TIMEOUT = 24 * 3600
# This repository is used to check whether there is a new release of NetBox available. Set to None to disable the
# version check or use the URL below to check for release in the official NetBox repository.
EOF
if [ "$UPDATE_CHECK" != "" ]; then
cat << EOF
RELEASE_CHECK_URL = 'https://api.github.com/repos/netbox-community/netbox/releases'
EOF
else
cat << EOF
RELEASE_CHECK_URL = None
EOF
fi
if [ "$REPORTS_ROOT" != "" ]; then
cat << EOF
# The file path where custom reports will be stored. A trailing slash is not needed. Note that the default value of
# this setting is derived from the installed location.
REPORTS_ROOT = '$REPORTS_ROOT'
EOF
fi
if [ "$SCRIPTS_ROOT" != "" ]; then
cat << EOF
# The file path where custom scripts will be stored. A trailing slash is not needed. Note that the default value of
# this setting is derived from the installed location.
SCRIPTS_ROOT = '$SCRIPTS_ROOT'
EOF
fi
cat << EOF
# By default, NetBox will store session data in the database. Alternatively, a file path can be specified here to use
# local file storage instead. (This can be useful for enabling authentication on a standby instance with read-only
# database access.) Note that the user as which NetBox runs must have read and write permissions to this path.
SESSION_FILE_PATH = None
# Time zone (default: UTC)
TIME_ZONE = 'UTC'
# Date/time formatting. See the following link for supported formats:
# https://docs.djangoproject.com/en/stable/ref/templates/builtins/#date
DATE_FORMAT = 'N j, Y'
SHORT_DATE_FORMAT = 'Y-m-d'
TIME_FORMAT = 'g:i a'
SHORT_TIME_FORMAT = 'H:i:s'
DATETIME_FORMAT = 'N j, Y g:i a'
SHORT_DATETIME_FORMAT = 'Y-m-d H:i'
EOF

View file

@ -0,0 +1,82 @@
#!/bin/sh
# no configuration if there are no ldap parameters
if [ -z "$USE_LDAP" ]; then
# skip
cat << EOF
##############################
# LDAP-backed authentication #
##############################
# no options set
EOF
exit 0
fi
cat << EOF
##############################
# LDAP-backed authentication #
##############################
import ldap
from django_auth_ldap.config import LDAPSearch, PosixGroupType
# Server URI
AUTH_LDAP_SERVER_URI = "$LDAP_SERVER"
# Set the DN and password for the NetBox service account.
AUTH_LDAP_BIND_DN = "$LDAP_BIND_DN"
AUTH_LDAP_BIND_PASSWORD = "$LDAP_BIND_PASSWORD"
# Search for user entry.
AUTH_LDAP_USER_SEARCH = LDAPSearch("$LDAP_USER_BASE",
ldap.SCOPE_SUBTREE,
"(uid=%(user)s)")
# You can map user attributes to Django attributes as so.
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail"
}
EOF
if [ "$LDAP_GROUP_BASE" != "" ]; then
cat << EOF
# This search ought to return all groups to which the user belongs. django_auth_ldap uses this to determine group
# hierarchy.
AUTH_LDAP_GROUP_SEARCH = LDAPSearch("$LDAP_GROUP_BASE", ldap.SCOPE_SUBTREE,
"(objectClass=posixGroup)")
AUTH_LDAP_GROUP_TYPE = PosixGroupType()
# Mirror LDAP group assignments.
AUTH_LDAP_MIRROR_GROUPS = True
# For more granular permissions, map LDAP groups to Django groups.
AUTH_LDAP_FIND_GROUP_PERMS = True
EOF
if [ "$LDAP_REQUIRE_GROUP" != "" ]; then
cat << EOF
# Define a group required to login.
AUTH_LDAP_REQUIRE_GROUP = "$LDAP_REQUIRE_GROUP"
EOF
fi
cat << EOF
# Define special user types using groups. Exercise great caution when assigning superuser status.
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
EOF
# superuser
if [ "$LDAP_SUPERUSER_GROUP" != "" ]; then
echo " \"is_superuser\": \"$LDAP_SUPERUSER_GROUP\","
fi
# staff user
if [ "$LDAP_STAFF_GROUP" != "" ]; then
echo " \"is_staff\": \"$LDAP_STAFF_GROUP\","
fi
echo "}"
fi

View file

@ -0,0 +1,24 @@
[Unit]
Description=NetBox Request Queue Worker
Documentation=https://netbox.readthedocs.io/en/stable/
PartOf=netbox.service
Wants=network.target
After=netbox.service
After=network.target
After=redis-server.service postgresql.service
[Service]
Type=simple
User=netbox
Group=netbox
WorkingDirectory=/opt/netbox
ExecStart=/opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py rqworker
Restart=on-failure
RestartSec=30
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,13 @@
[Unit]
Description=NetBox Service Wrapper
Documentation=https://netbox.readthedocs.io/en/stable/
Wants=network.target
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/true
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,33 @@
#!/bin/sh -e
# __netbox/files/netbox.socket.sh
# This is shared between all WSGI-server types.
# Arguments:
# 1: File which list all sockets to listen on (sepearated by \n)
if [ $# -ne 1 ]; then
printf "netbox.socket.sh: argument \$1 missing or too much given!\n" >&2
exit 1
fi
cat << UNIT
[Unit]
Description=Socket for NetBox via $TYPE
[Socket]
UNIT
# read all sockets to listen to
while read -r line; do
printf "ListenStream=%s\n" "$line"
done < "$1"
cat << UNIT
SocketUser=netbox
SocketGroup=www-data
[Install]
WantedBy=sockets.target
UNIT

120
type/__netbox/gencode-remote Executable file
View file

@ -0,0 +1,120 @@
#!/bin/sh -e
old_version="$(cat "$__object/explorer/version")"
VERSION=$(cat "$__object/parameter/version")
src="netbox-$VERSION"
archive="v$VERSION.tar.gz"
url="https://github.com/netbox-community/netbox/archive/$archive"
install_dir=/opt/netbox/netbox
if [ "$VERSION" != "$old_version" ]; then
cat << EOF
# Ensure that coreutils is installed.
if [ ! -x \$(which mktemp) ]; then
echo "mktemp is not available on the remote host." >&2
exit 1
fi
# Create temporary working directory.
tmpdir=\$(mktemp -d)
cd "\$tmpdir"
# Download and extract sources.
curl -sS -L '$url' > '$archive'
tar xf '$archive'
# virtualenv is given already by __pyvenv, just using it
# backup requirement files
if [ -f /opt/netbox/requirements.txt ]; then
mv /opt/netbox/requirements.txt /opt/netbox/old-requirements.txt
else
# preseve file-not-found errors and warnings
touch /opt/netbox/old-requirements.txt
fi
cp '$src/requirements.txt' /opt/netbox/
# Uninstall packages not required anymore
# if versions not be shortend, they will be ignored by pip, but not by comm
# all of this could be done with grep, too, but it's still must be shortend with awk
awk -F== '{print \$1}' '/opt/netbox/requirements.txt' | sort > "\$tmpdir/curr-reqs.txt"
awk -F== '{print \$1}' '/opt/netbox/old-requirements.txt' | sort > "\$tmpdir/old-reqs.txt"
comm -23 "\$tmpdir/old-reqs.txt" "\$tmpdir/curr-reqs.txt" > "\$tmpdir/pip-uninstall.txt"
# only uninstall if something is available (to avoid errors cause of this)
if [ -s "\$tmpdir/pip-uninstall.txt" ]; then
/opt/netbox/venv/bin/pip3 uninstall -qy -r "\$tmpdir/pip-uninstall.txt"
fi
# Install python dependencies.
# avoid gunicorn, because it will be done in an other type
grep -v "^gunicorn==" "\$tmpdir/$src/requirements.txt" \
| xargs /opt/netbox/venv/bin/pip3 install -q
EOF
if [ -f "$__object/parameter/ldap-server" ]; then
echo "/opt/netbox/venv/bin/pip3 install -q django-auth-ldap"
else
echo "/opt/netbox/venv/bin/pip3 uninstall -qy django-auth-ldap"
fi
cat << EOF
# Deploy sources and restore configuration.
rm -rf '$install_dir'
cp -r '$src/netbox' '$install_dir'
# force links to the cdist directory
ln -fs /opt/netbox/cdist/configuration.py '$install_dir/netbox/configuration.py'
ln -fs /opt/netbox/cdist/ldap_config.py '$install_dir/netbox/ldap_config.py'
# Set final permissions.
chown -R netbox /opt/netbox
# NetBox manage scripts
# Run database migrations.
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py migrate
# Generate static assets.
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py collectstatic --no-input
# Delete any stale content types
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py remove_stale_contenttypes --no-input
# Delete any expired user sessions
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py clearsessions
# Clear all cached data
sudo -u netbox /opt/netbox/venv/bin/python3 /opt/netbox/netbox/manage.py invalidate all
# Remove temporary working directory.
cd /
rm -rf "\$tmpdir"
# Save version after successful installation
printf "%s\\n" "$VERSION" > /opt/netbox/cdist/version
EOF
# meta
printf "installed %s\n" "$VERSION" >> "$__messages_out"
changes=yes
fi
# check if configuration changed
if grep -q "^__file/opt/netbox/" "$__messages_in"; then
# meta
printf "configured\n" >> "$__messages_out"
changes=yes
fi
# Check for changes
if [ "$changes" = "yes" ]; then
# After the upstream upgrade.sh script, it's ok to migrate while the
# application is running ;)
# restarting after changes
cat << EOF
# Restart service. All required services are included with netbox.service.
systemctl restart netbox
EOF
fi

274
type/__netbox/man.rst Normal file
View file

@ -0,0 +1,274 @@
cdist-type__netbox(7)
=====================
NAME
----
cdist-type__netbox - Install and configure NetBox
DESCRIPTION
-----------
This (singleton) type installs and configures a NetBox instance, a web
application to help manage and document computer networks.
It installs it with the user ``netbox`` at ``/opt/netbox`` with `python-venv`.
It setup systemd unit files for the services `netbox` and `netbox-rq`. The
`netbox` service only wrap all netbox related services, e.g. restarting and
so one will be delegated to all related services.
The application is still not accessable because a WSGI server is required. To
access the application through WSGI, uWSGI or Gunicorn can be used. The setup
can be done via there own types `__netbox_gunicorn` and `__netbox_uwsgi`.
The Gunicorn setup is recommended from the NetBox documentation. Consult each
manual page to decide. The types must be called after the `__netbox` type.
REQUIRED PARAMETERS
-------------------
version
NetBox version to be installed. You can find the correct and newest version
on GitHub at the NetBox project page under
"`Releases <https://github.com/netbox-community/netbox/releases>`_".
database
PostgreSQL database name.
database-user
PostgreSQL database user.
database-password
PostgreSQL database password.
host
Hostname (domain or IP address) on which the application is served.
Multiple hostnames are possible; given as multiple arguments.
OPTIONAL PARAMETERS
-------------------
secret-key
Random secret key of at least 50 alphanumeric characters and symbols. This
key must be unique to this installation and must not be shared outside the
local system. If no secret key is given, the type generates an own 50 chars
long key and saves it on the remote host to remember it for the next run.
The secret, random string is used to assist in the creation new
cryptographic hashes for passwords and HTTP cookies. It is not directly
used for hasing user passwords or for encrpted storage. It can be changed
at any time, but will invalidate all existing sessions.
database-host
PostgreSQL database hostname. Defaults to ``localhost``.
database-port
PostgreSQL database port. Defaults to empty (uses the default port).
ldap-server
LDAP server URI. Enables LDAP-backed authentication if specified.
ldap-bind-dn
DN for the NetBox service account. Required for LDAP authentication.
ldap-bind-password
Password for the NetBox service account. Required for LDAP authentication.
ldap-user-base
Base used for searching user entries. Required for LDAP authentication.
ldap-group-base
Base used for searching group entries.
ldap-require-group
Group required to login.
ldap-staff-group
Make members of this group to "staff". This gives the users "Admin Access",
which means access to the "NetBox Administration" site.
ldap-superuser-group
Make members of this groups superusers.
redis-host
Redis database hostname. Defaults to ``localhost``.
redis-port
Redis database port. Defaults to ``6379``.
redis-password
Redis password. Defaults to empty password.
redis-dbid-offset
Offset to set the redis database id's. The `tasks` database id is
`offset + 0` and `caching` is `offset + 1`. The offset defaults to ``0``.
smtp-host
Host of the SMTP email server. Defaults to ``localhost``.
smtp-port
Port of the SMTP email server. Defaults to ``25``.
smtp-user
Username to access the SMTP email server. Defaults to empty.
smtp-password
Password to access the SMTP email server. Defaults to empty.
smtp-from-email
Email from which NetBox will be sent of. Defaults to empty.
basepath
Base URL path if accessing netbox within a directory instead of directly the
webroot ``/``. For example, if installed at https://example.com/netbox/, set
the value ``netbox/``.
https-proxy
Proxy which will be used with any HTTP request like webhooks.
data-root
This parameter set's the media, reports and scripts root to subdirectories
of the given directory. Values can be overwritten by special parameters like
`--media-root` for example. Use this option if you want to store persistant
data of netbox on an other partition. A trailing slash is not needed.
The data directories have following predefined sub-directory names:
media root:
``$data_root/media``
reports root:
``$data_root/reports``
scripts root:
``$data_root/scripts``
To preserve all data from installation upgrades - which just replace the
installation directory - the data will be kept in the netbox home directory
rather than the installation directory by default (``/opt/netbox/data/``).
This way, no data will be deleted after the installation directory
replacement because it remains outside of the installation directory.
media-root
The file path to where media files (like image attachments) are stored.
Change this path if you require to store data on an other partiotion.
A trailing slash is not needed. Defaults to ``$data_root/media``.
reports-root
The file path of where custom reports are kept. Change this path if you
require to store data on an other partition. A trailing slash is not
needed. Defaults to ``$data_root/reports``.
scripts-root
The file path of where custom scripts are kept. Change this path if you
require to store data on an other partition. A trailing slash is not
needed. Defaults to ``$data_root/scripts``.
BOOLEAN PARAMETERS
------------------
redis-ssl
Enables a secure TLS/SSL connection to the redis database. By default, ssl
is disabled.
smtp-use-tls
Uses TLS to connect to the SMTP email server. `See documentation
<https://docs.djangoproject.com/en/3.1/ref/settings/#email-use-tls>`__
for more information.
smtp-use-ssl
Uses implicit TLS with the SMTP email server. `See documentation
<https://docs.djangoproject.com/en/3.1/ref/settings/#email-use-ssl>`__
for more information.
login-required
Sets if a login is required to access all sites. By default, anonymous
users can see most data (excluding secrets) but not make any changes.
update-notify
Enables the NetBox version check for new upstream updates. It checks every
24 hours for new releases and notify the admin users in the gui if any.
MESSAGES
--------
installed $VERSION
Netbox was fresh installed or updated. The new version number is appended.
configured
Some configuration files got updated and therefore the service was
restarted. This message will not be echoed if configuration got updated due
a standard installation.
EXAMPLES
--------
.. code-block:: sh
__netbox --version 2.8.7 --database netbox \
--database-password "secretsecretsecret" \
--secret-key "secretsecretsecret" \
--host "${__target_host:?}" \
--host "cool-netbox.xyz" \
--ldap-server "ldaps://ldap.domain.tld" \
--ldap-bind-dn "uid=netbox,ou=services,dc=domain,dc=tld" \
--ldap-bind-password "secretsecretsecret" \
--ldap-user-base "ou=users,dc=domain,dc=tld" \
--ldap-group-base "ou=groups,dc=domain,dc=tld" \
--ldap-require-group "cn=netbox-login,ou=groups,dc=domain,dc=tld" \
--ldap-superuser-group "cn=netbox-admin,ou=groups,dc=domain,dc=tld"
# using recommended gunicorn setup
require="__netbox" __netbox_gunicorn
NOTES
-----
The configuration of NetBox contains more optional settings than that what can
be set with this type. If you think an important setting is missing or there
is a more good way to inject python code for dynamic configuration variables,
you are welcome to contribute!
- `Possible optional settings
<https://netbox.readthedocs.io/en/stable/configuration/optional-settings/>`_
If you not setup ldap authentification, you may be interested into how to
`setting up a super user
<https://netbox.readthedocs.io/en/stable/installation/3-netbox/#create-a-super-user>`_
directly on the machine to be able to access and use NetBox.
You may also be interested of writing a own type which handles the creation of
the super user. To do this non-interactivly, see the ansible role as `reference
<https://github.com/lae/ansible-role-netbox/blob/18f46a3345f100936c5116abe716c480e1886676/vars/main.yml#L15>`_.
If you change the secret key while the netbox instance is running, there is a
time frame where the access to the application corrupts the whole database.
Then, you need to restore a backup or wipe the database.
Currently, the cause is not clear, but it should work if you do not touch
netbox while the configuration is done (do not shut it down, too). It only
applies for changes of the secret key, which not happen normally.
Maybe the `--restart` flag for the `__systemd_unit` types is not the best idea,
but avoids that the changes will not be applied. It could be solved if the type
would send messages from his actions.
SEE ALSO
--------
`NetBox documentation <https://netbox.readthedocs.io/en/stable/>`_
:strong:`cdist-type__netbox_gunicorn`\ (7)
:strong:`cdist-type__netbox_uwsgi`\ (7)
AUTHORS
-------
Timothée Floure <t.floure@e-durable.ch>
Matthias Stecher <matthiasstecher@gmx.de>
COPYING
-------
Copyright \(C) 2020 Timothée Floure.
Copyright \(C) 2020 Matthias Stecher.
You can redistribute it and/or modify it under the terms of the GNU
General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.

226
type/__netbox/manifest Executable file
View file

@ -0,0 +1,226 @@
#!/bin/sh -e
os=$(cat "$__global/explorer/os")
case "$os" in
debian|ubuntu)
# Install netbox dependencies.
for pkg in python3-pip python3-venv python3-dev build-essential libxml2-dev \
libxslt1-dev libffi-dev libpq-dev libssl-dev zlib1g-dev curl sudo; do
__package $pkg
done
if [ -f "$__object/parameter/ldap-server" ]; then
for pkg in libldap2-dev libsasl2-dev libssl-dev; do
__package $pkg
done
fi
;;
*)
printf "Your operating system (%s) is currently not supported by this type (%s)\n" "$os" "${__type##*/}" >&2
printf "Please contribute an implementation for it if you can.\n" >&2
exit 1
;;
esac
DATABASE_NAME=$(cat "$__object/parameter/database")
export DATABASE_NAME
DATABASE_USER="$(cat "$__object/parameter/database-user")"
export DATABASE_USER
DATABASE_PASSWORD=$(cat "$__object/parameter/database-password")
export DATABASE_PASSWORD
DATABASE_HOST="$(cat "$__object/parameter/database-host")"
export DATABASE_HOST
DATABASE_PORT="$(cat "$__object/parameter/database-port")"
export DATABASE_PORT
# list of hosts
ALLOWED_HOSTS=""
while read -r hostname; do
# shellcheck disable=SC2089
ALLOWED_HOSTS="$ALLOWED_HOSTS '$hostname',"
done < "$__object/parameter/host"
# shellcheck disable=SC2090
export ALLOWED_HOSTS
if [ -f "$__object/parameter/secret-key" ]; then
SECRET_KEY=$(cat "$__object/parameter/secret-key")
elif [ -s "$__object/explorer/secretkey" ]; then
# take the key that is already used
SECRET_KEY="$(cat "$__object/explorer/secretkey")"
else
# Can be done over netbox/generate_secret_key.py too, but it can't be
# generated right now where it's required (only if it's preloaded for
# this type to execute it now).
# Generates a 50-character long key with the same character set like
# the helper script. Must escape the '-' to be no character range.
SECRET_KEY="$(tr -cd '!@#$%^&*(\-_=+)[:alnum:]' < /dev/urandom | head -c50)"
fi
export SECRET_KEY
if [ -f "$__object/parameter/ldap-server" ]; then
LDAP_SERVER=$(cat "$__object/parameter/ldap-server")
USE_LDAP=yes
export LDAP_SERVER
fi
if [ -f "$__object/parameter/ldap-bind-dn" ]; then
LDAP_BIND_DN=$(cat "$__object/parameter/ldap-bind-dn")
USE_LDAP=yes
export LDAP_BIND_DN
fi
if [ -f "$__object/parameter/ldap-bind-password" ]; then
LDAP_BIND_PASSWORD=$(cat "$__object/parameter/ldap-bind-password")
USE_LDAP=yes
export LDAP_BIND_PASSWORD
fi
if [ -f "$__object/parameter/ldap-user-base" ]; then
LDAP_USER_BASE=$(cat "$__object/parameter/ldap-user-base")
USE_LDAP=yes
export LDAP_USER_BASE
fi
if [ -f "$__object/parameter/ldap-group-base" ]; then
LDAP_GROUP_BASE=$(cat "$__object/parameter/ldap-group-base")
export LDAP_GROUP_BASE
fi
if [ -f "$__object/parameter/ldap-require-group" ]; then
LDAP_REQUIRE_GROUP=$(cat "$__object/parameter/ldap-require-group")
export LDAP_REQUIRE_GROUP
fi
if [ -f "$__object/parameter/ldap-superuser-group" ]; then
LDAP_SUPERUSER_GROUP=$(cat "$__object/parameter/ldap-superuser-group")
export LDAP_SUPERUSER_GROUP
fi
if [ -f "$__object/parameter/ldap-staff-group" ]; then
LDAP_STAFF_GROUP="$(cat "$__object/parameter/ldap-staff-group")"
export LDAP_STAFF_GROUP
fi
# export if base ldap parameters are used
export USE_LDAP
# have default values
REDIS_HOST="$(cat "$__object/parameter/redis-host")"
export REDIS_HOST
REDIS_PORT="$(cat "$__object/parameter/redis-port")"
export REDIS_PORT
REDIS_PASSWORD="$(cat "$__object/parameter/redis-password")"
export REDIS_PASSWORD
REDIS_DBID_OFFSET="$(cat "$__object/parameter/redis-dbid-offset")"
export REDIS_DBID_OFFSET
if [ -f "$__object/parameter/redis-ssl" ]; then
REDIS_SSL="True"
else
REDIS_SSL="False"
fi
export REDIS_SSL
SMTP_HOST="$(cat "$__object/parameter/smtp-host")"
export SMTP_HOST
SMTP_PORT="$(cat "$__object/parameter/smtp-port")"
export SMTP_PORT
SMTP_USER="$(cat "$__object/parameter/smtp-user")"
export SMTP_USER
SMTP_PASSWORD="$(cat "$__object/parameter/smtp-password")"
export SMTP_PASSWORD
SMTP_FROM_EMAIL="$(cat "$__object/parameter/smtp-from-email")"
export SMTP_FROM_EMAIL
if [ -f "$__object/parameter/smtp-use-ssl" ]; then
SMTP_USE_SSL="True"
else
SMTP_USE_SSL="False"
fi
export SMTP_USE_SSL
if [ -f "$__object/parameter/smtp-use-tls" ]; then
if [ "$SMTP_USE_SSL" = "True" ]; then
echo "options --smtp-use-ssl and --smtp-use-tls are not compatible" >&2
exit 2
fi
SMTP_USE_TLS="True"
else
SMTP_USE_TLS="False"
fi
export SMTP_USE_TLS
BASEPATH="$(cat "$__object/parameter/basepath")"
export BASEPATH
if [ -f "$__object/parameter/http-proxy" ]; then
HTTP_PROXY=$(cat "$__object/parameter/http-proxy")
export HTTP_PROXY
fi
if [ -f "$__object/parameter/https-proxy" ]; then
HTTPS_PROXY=$(cat "$__object/parameter/https-proxy")
export HTTPS_PROXY
fi
if [ -f "$__object/parameter/login-required" ]; then
LOGIN_REQUIRED="True"
else
LOGIN_REQUIRED="False"
fi
export LOGIN_REQUIRED
data_root="$(cat "$__object/parameter/data-root")"
MEDIA_ROOT="$data_root/media"
REPORTS_ROOT="$data_root/reports"
SCRIPTS_ROOT="$data_root/scripts"
if [ -f "$__object/parameter/media-root" ]; then
MEDIA_ROOT="$(cat "$__object/parameter/media-root")"
fi
export MEDIA_ROOT
if [ -f "$__object/parameter/reports-root" ]; then
REPORTS_ROOT="$(cat "$__object/parameter/reports-root")"
fi
export REPORTS_ROOT
if [ -f "$__object/parameter/scripts-root" ]; then
SCRIPTS_ROOT="$(cat "$__object/parameter/scripts-root")"
fi
export SCRIPTS_ROOT
if [ -f "$__object/parameter/update-notify" ]; then
UPDATE_CHECK="yes"
export UPDATE_CHECK
fi
# Create system user used to run netbox.
__user netbox --system --home /opt/netbox --create-home
# Generate python environment (user will be set by gencode-remote)
require="__user/netbox" __pyvenv /opt/netbox/venv/
# Generate and upload netbox configuration.
mkdir -p "$__object/files"
"$__type/files/configuration.py.sh" > "$__object/files/configuration.py"
"$__type/files/ldap_config.py.sh" > "$__object/files/ldap_config.py"
require="__user/netbox" __directory /opt/netbox/cdist
require="__directory/opt/netbox/cdist" __file \
/opt/netbox/cdist/configuration.py --mode 640 --owner netbox \
--source "$__object/files/configuration.py"
if [ -f "$__object/parameter/ldap-server" ]; then
require="__directory/opt/netbox/cdist" __file \
/opt/netbox/cdist/ldap_config.py --mode 640 --owner netbox \
--source "$__object/files/ldap_config.py"
else
require="__directory/opt/netbox/cdist" __file \
/opt/netbox/cdist/ldap_config.py --state absent
fi
# save secret
require="__directory/opt/netbox/cdist" __file /opt/netbox/cdist/secretkey \
--mode 400 --owner netbox --source - << SECRET
$SECRET_KEY
SECRET
# Upload systemd unit for worker and wsgi service
# does not restart netbox on change cause it only restart all other services
__systemd_unit netbox.service \
--source "$__type/files/netbox.service" \
--enablement-state enabled
__systemd_unit netbox-rq.service \
--source "$__type/files/netbox-rq.service" \
--enablement-state enabled --restart

View file

@ -0,0 +1,5 @@
redis-ssl
smtp-use-ssl
smtp-use-tls
login-required
update-notify

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
/opt/netbox/data

View file

@ -0,0 +1 @@
localhost

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
0

View file

@ -0,0 +1 @@
localhost

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
6379

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
localhost

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
25

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,27 @@
secret-key
database-host
database-port
ldap-server
ldap-bind-dn
ldap-bind-password
ldap-user-base
ldap-group-base
ldap-require-group
ldap-staff-group
ldap-superuser-group
redis-host
redis-port
redis-password
redis-dbid-offset
smtp-host
smtp-port
smtp-user
smtp-password
smtp-from-email
basepath
http-proxy
https-proxy
data-root
media-root
reports-root
scripts-root

View file

@ -0,0 +1,4 @@
version
database
database-user
database-password

View file

@ -0,0 +1 @@
host

0
type/__netbox/singleton Normal file
View file

View file

@ -0,0 +1,4 @@
#!/bin/sh -e
# print version if available
/opt/netbox/venv/bin/pip3 show gunicorn | awk '/Version:/{print $2}'

View file

@ -0,0 +1,3 @@
#!/bin/sh -e
awk -v FS="==" '$1 ~ /gunicorn/{print $2}' /opt/netbox/requirements.txt

View file

@ -0,0 +1,31 @@
#!/bin/sh -e
# Generates gunicorn config
# see https://docs.gunicorn.org/en/stable/settings.html
# fix missing $__explorer
# see https://code.ungleich.ch/ungleich-public/cdist/-/issues/834
__explorer="$__global/explorer"
# size workes by cpu
cores="$(cat "$__explorer/cpu_cores")"
cat << EOF
# The IP address (typically localhost) and port that the Netbox WSGI process should listen on
#bind = done via systemd socket 'gunicorn-netbox.socket'
# Number of gunicorn workers to spawn. This should typically be 2n+1, where
# n is the number of CPU cores present.
workers = $(( 2*cores + 1 ))
# Number of threads per worker process
threads = 3
# Timeout (in seconds) for a request to complete
timeout = 120
# The maximum number of requests a worker can handle before being respawned
max_requests = 5000
max_requests_jitter = 500
EOF

View file

@ -0,0 +1,29 @@
[Unit]
Description=NetBox Gunicorn WSGI Service
Documentation=https://netbox.readthedocs.io/en/stable/
PartOf=netbox.service
Requires=netbox-rq.service
Requires=gunicorn-netbox.socket
Wants=network.target
After=netbox.service
After=network.target
After=redis-server.service postgresql.service
[Service]
Type=notify
User=netbox
Group=netbox
WorkingDirectory=/opt/netbox
ExecStart=/opt/netbox/venv/bin/gunicorn --pythonpath /opt/netbox/netbox --config /opt/netbox/gunicorn.py netbox.wsgi
# signals: https://docs.gunicorn.org/en/stable/signals.html
ExecReload=kill -HUP $MAINPID
ExecStop=kill -TERM $MAINPID
KillSignal=SIGQUIT
Restart=on-failure
RestartSec=30
[Install]
WantedBy=netbox.service

View file

@ -0,0 +1 @@
../../__netbox/files/netbox.socket.sh

View file

@ -0,0 +1,50 @@
#!/bin/sh -e
# control state
state="$(cat "$__object/parameter/state")"
case "$state" in
# install gunicorn
enabled|disabled)
curr_installed="$(cat "$__object/explorer/installed")"
should_installed="$(cat "$__object/explorer/should_installed")"
# gunicorn version change
if [ "$curr_installed" != "$should_installed" ]; then
# (re)installing gunicorn
echo "/opt/netbox/venv/bin/pip3 install 'gunicorn==$should_installed'"
if [ "$curr_installed" != "" ]; then
printf "updated %s to %s\n" "$curr_installed" "$should_installed" \
>> "$__messages_out"
else
printf "installed\n" >> "$__messages_out"
fi
do_restart=yes
fi
# configuration changes
if grep -q "^__file/opt/netbox/gunicorn.py:" "$__messages_in"; then
do_restart=yes
printf "configured\n" >> "$__messages_out"
fi
# restart gunicorn
if [ "$do_restart" ] && [ "$state" != "disabled" ]; then
cat << EOF
# Restart service
systemctl restart gunicorn-netbox
EOF
fi
;;
# uninstall
absent)
# check if installed
if [ -s "$__object/explorer/installed" ]; then
# service already disabled
echo "/opt/netbox/venv/bin/pip3 uninstall -y gunicorn"
printf "uninstalled\n" >> "$__messages_out"
fi
esac

View file

@ -0,0 +1,117 @@
cdist-type__netbox_gunicorn(7)
==============================
NAME
----
cdist-type__netbox_gunicorn - Run NetBox with Gunicorn
DESCRIPTION
-----------
This (singleton) type installs Gunicorn into the NetBox `python-venv` to host
the NetBox WSGI application. It provides the application as HTTP over the given
sockets. Static content must be served independent of Gunicorn. The Gunicorn
daemon is available as the `gunicorn-netbox` systemd service, but also
available via the `netbox` wrapper service.
It will use systemd socket activation to listen to the given sockets. This
should allow to bind to privileaged ports (all below 1024) and hot reloads.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
state
Represents the state of the Gunciron application. Defaults to ``enabled``.
enabled
The Gunicorn service is enabled and running.
disabled
The Gunicorn service is installed, but disabled.
absent
The uWSGI service is not installed and all configuration removed.
This type does not guarantee anything about the running state of the
service. To be sure about the service is stopped or not, use the type
:strong:`cdist-type__systemd_service`\ (7) after this execution.
bind-to
The hosts the gunicorn socket should be bind to. Formats are `IP`,
`IP:PORT`, `PATH` or anything other that systemd socket units will
understand as stream. Parameter can be set multiple times. Defaults
to ``127.0.0.1:8001``.
BOOLEAN PARAMETERS
------------------
None.
MESSAGES
--------
installed
The software was installed.
upgraded $old to $new
The version of the gunicorn software was updated from `$old` to `$new`.
configured
Configuration for gunicorn changed.
uninstalled
The Gunicorn application was removed.
In all cases where the application is still present, it restarts the service to
use the up-to-date version.
EXAMPLES
--------
.. code-block:: sh
# simple
__netbox $args
require="__netbox" __netbox_gunicorn
# with arguments
__netbox $args
require="__netbox" __netbox_gunicorn \
--bind-to 0.0.0.0:8001 \
--bind-to 1.2.3.4:5678
# replace uwsgi with gunicorn
__netbox $args
require="__netbox" __netbox_uwsgi --state absent
# it should depend on __netbox_uwsgi if they use the same socket
require="__netbox_uwsgi" __netbox_gunicorn --state enabled
# be sure the service is disabled
__netbox $args
require="__netbox" __netbox_gunicorn --state disabled
require="__netbox_gunicorn" __systemd_service gunicorn-netbox --state stopped
SEE ALSO
--------
`Gunicorn Documentation <https://docs.gunicorn.org/en/stable/>`_
:strong:`cdist-type__netbox`\ (7)
:strong:`cdist-type__netbox_uwsgi`\ (7)
AUTHORS
-------
Matthias Stecher <matthiasstecher@gmx.de>
COPYING
-------
Copyright \(C) 2020 Matthias Stecher. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

57
type/__netbox_gunicorn/manifest Executable file
View file

@ -0,0 +1,57 @@
#!/bin/sh -e
# __netbox_gunicorn/manifest
# Check states
state=""
unit_state=""
param_state="$(cat "$__object/parameter/state")"
case "$param_state" in
enabled|disabled)
state="present"
unit_state="$param_state"
;;
absent)
state="absent"
unit_state="disabled"
;;
*)
# does not exist
printf "The state '%s' does not exist, can't continue!\n" "$param_state" >&2
exit 2
;;
esac
mkdir "$__object/files"
if [ "$state" = "present" ]; then
# process template
"$__type/files/gunicorn.py.sh" > "$__object/files/gunicorn.py"
# gunicorn config file
__file /opt/netbox/gunicorn.py \
--mode 644 --owner netbox \
--source "$__object/files/gunicorn.py"
else
# absent config file
__file /opt/netbox/gunicorn.py --state absent
fi
TYPE="Gunicorn"
export TYPE
"$__type/files/netbox.socket.sh" "$__object/parameter/bind-to" \
> "$__object/files/netbox.socket"
# install systemd files
__systemd_unit gunicorn-netbox.socket \
--state "$state" --enablement-state "$unit_state" \
--source "$__object/files/netbox.socket" --restart
__systemd_unit gunicorn-netbox.service \
--state "$state" --enablement-state "$unit_state" \
--source "$__type/files/netbox.service" --restart

View file

@ -0,0 +1 @@
127.0.0.1:8001

View file

@ -0,0 +1 @@
enabled

View file

@ -0,0 +1 @@
state

View file

@ -0,0 +1 @@
bind-to

View file

View file

@ -0,0 +1,12 @@
#!/bin/sh -e
# explorer/bind-capablility
# Checks if the uWSGI binary have the capability to bind to privileaged ports
# as a non-root user. It's required if no systemd sockets are used (cause of
# the use of multiple protocols etc.)
binary="/opt/netbox/venv/bin/uwsgi"
# -v verifies if capability is set
if setcap -q -v CAP_NET_BIND_SERVICE+ep "$binary"; then
echo set
fi

View file

@ -0,0 +1,4 @@
#!/bin/sh -e
# print version if available
/opt/netbox/venv/bin/pip3 show uwsgi | awk '/Version:/{print $2}'

View file

@ -0,0 +1,4 @@
#!/bin/sh -e
# print latest version if availble
/opt/netbox/venv/bin/pip3 list --outdated | awk '$1 == "uwsgi" {print $3}'

View file

@ -0,0 +1,40 @@
#!/bin/sh -e
cat << EOF
[Unit]
Description=Netbox uWSGI WSGI Service
Documentation=https://netbox.readthedocs.io/en/stable/
PartOf=netbox.service
Requires=netbox-rq.service
EOF
# Add dependency to own socket
if [ "$(cat "$__object/files/systemd_socket")" = "yes" ]; then
echo "Requires=uwsgi-netbox.socket"
fi
cat << EOF
Wants=network.target
After=netbox.service
After=network.target
After=redis-server.service postgresql.service
[Service]
Type=notify
User=netbox
Group=netbox
WorkingDirectory=/opt/netbox
ExecStart=/opt/netbox/venv/bin/uwsgi --master --chdir /opt/netbox/netbox --module netbox.wsgi uwsgi.ini
# signals: https://uwsgi-docs.readthedocs.io/en/latest/Management.html#signals-for-controlling-uwsgi
ExecReload=kill -HUP \$MAINPID
ExecStop=kill -INT \$MAINPID
KillSignal=SIGQUIT
Restart=on-failure
RestartSec=30
[Install]
WantedBy=netbox.service
EOF

View file

@ -0,0 +1 @@
../../__netbox/files/netbox.socket.sh

View file

@ -0,0 +1,60 @@
#!/bin/sh -e
# Generates uwsgi config
# see https://uwsgi-docs.readthedocs.io/en/latest/Options.html
# or https://uwsgi-docs-additions.readthedocs.io/en/latest/Options.html
# params:
# 1: parameter name
# 2: parameter value file
#
# output: the lines for the configuration option
multi_options() {
while read -r line; do
printf "%s = %s\n" "$1" "$line"
done < "$2"
}
# fix missing $__explorer
# see https://code.ungleich.ch/ungleich-public/cdist/-/issues/834
__explorer="$__global/explorer"
# size workes by cpu
cores="$(cat "$__explorer/cpu_cores")"
cat << EOF
[uwsgi]
; socket(s) to bind
EOF
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
# special protocol to bind
find "$__object/parameter/" -maxdepth 1 -name "*-bind" -print \
| while read -r param; do
multi_options "$(basename "$param" | awk -F'-' '{print $1}')-socket" "$param"
done
else
# else, systemd will offer socket
echo "; sockets managed via 'uwsgi-netbox.socket'"
printf "protocol = %s\n" "$PROTOCOL"
fi
# multi-process settings
cat << EOF
; processes and threads
processes = $(( 2*cores + 1 ))
threads = 2
EOF
# optional mapping of static content
if [ "$STATIC_MAP" != "" ]; then
cat << EOF
; map static content
static-map = /static=/opt/netbox/netbox/static
EOF
fi

View file

@ -0,0 +1,101 @@
#!/bin/sh -e
# control state
state="$(cat "$__object/parameter/state")"
# Set capabilities to aquire privileaged ports as netbox user. Two modes are
# available to efficiently set capabilites. Assumes libcap-bin is installed as
# default on debian systems.
#
# Arguments:
# 1: mode to detect if capabilites are required to set ('set' or 'correct')
set_bind_cap() {
cap_mode="" # reset variable from the execution before
# check if capabilites are required after given mode
case "$1" in
# assumes capabilites are not set (cause of new binaries)
set)
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
cap_mode="+ep"
fi
;;
# check if capabilities have changed
correct)
if [ -s "$__object/explorer/bind-capability" ]; then
# capabilites are set
if [ "$SYSTEMD_SOCKET" = "yes" ]; then
cap_mode="-ep" # unset
fi
else
# capabilities are unset
if [ "$SYSTEMD_SOCKET" != "yes" ]; then
cap_mode="+ep" # set
fi
fi
;;
# faulty mode
*)
echo "called set_bind_cap incorrect (\$1 missing)" >&2
;;
esac
# set capabilities if any
if [ "$cap_mode" ]; then
printf "setcap -q CAP_NET_BIND_SERVICE%s /opt/netbox/venv/bin/uwsgi\n" "$cap_mode"
fi
}
SYSTEMD_SOCKET="$(cat "$__object/files/systemd_socket")"
case "$state" in
# install uwsgi
enabled|disabled)
# not installed
if ! [ -s "$__object/explorer/installed" ]; then
echo "/opt/netbox/venv/bin/pip3 install -q uwsgi"
set_bind_cap set
do_restart=yes
printf "installed\n" >> "$__messages_out"
# updates available
elif [ -s "$__object/explorer/upgradeable" ]; then
echo "/opt/netbox/venv/bin/pip3 install -q --upgrade uwsgi"
set_bind_cap set
do_restart=yes
printf "upgraded\n" >> "$__messages_out"
fi
# changed configuration
if grep -q "^__file/opt/netbox/uwsgi.ini:" "$__messages_in"; then
do_restart=yes
printf "configured\n" >> "$__messages_out"
fi
# if no capabilities were set yet, check if any are required
if [ -z "$cap_mode" ]; then
set_bind_cap correct
fi
# restart uwsgi
if [ "$do_restart" ] && [ "$state" != "disabled" ]; then
cat << EOF
# Restart service
systemctl restart uwsgi-netbox
EOF
fi
;;
# uninstall
absent)
# check if installed
if [ -s "$__object/explorer/installed" ]; then
# service already disabled
echo "/opt/netbox/venv/bin/pip3 uninstall -qy uwsgi"
printf "uninstalled\n" >> "$__messages_out"
fi
;;
esac

183
type/__netbox_uwsgi/man.rst Normal file
View file

@ -0,0 +1,183 @@
cdist-type__netbox_uwsgi(7)
===========================
NAME
----
cdist-type__netbox_uwsgi - Run NetBox with uWSGI
DESCRIPTION
-----------
This (singleton) type installs uWSGI into the NetBox `python-venv`. It hosts
the NetBox WSGI application via the WSGI protocol. A further server must be
installed to provide it as HTTP and serve static content. It supports multiple
protocols like uwsgi, fastcgi or HTTP to comunicate with the proxy server. This
application is available via the `uwsgi-netbox` systemd service. It is
controllable via the `netbox` wrapper service, too.
**As uWSGI will be started as netbox user, it does not have privileges to
bind to a privileaged port (all ports below 1024).** Because uWSGI will
drop privileages anyway before binding to a port, solutions are to use
the systemd sockets to activate the ports as root or set linux kernel
capabilites to bind to such a privileaged port.
As systemd sockets (or uwsgi itself) do not allow to distinguish multiple
sockets if different protocols are used for different sockets, this type does
not use systemd sockets if it is requested from the user. Using the
``--bind-to`` and ``--protocol`` parameters, it uses the systemd socket
activation. Else, it set the different sockets and protocols natively to uwsgi
and add kernel capabilities to be able to listen to privileaged ports.
REQUIRED PARAMETERS
-------------------
None.
OPTIONAL PARAMETERS
-------------------
state
Represents the state of the uWSGI application. Defaults to ``enabled``.
enabled
The uWSGI service is enabled and running.
disabled
The uWSGI service is installed, but disabled.
absent
The uWSGI service is not installed and all configuration removed.
This type does not guarantee anything about the running state of the
service. To be sure about the service is stopped or not, use the type
:strong:`cdist-type__systemd_service`\ (7) after this execution.
bind-to
The socket uwsgi should bind to. Must be UNIX/TCP (or anything that
systemd sockets accept as stream). Defaults to ``127.0.0.1:3031``. Can be
set multiple times. The used protocol is defined by ``--protocol``.
**By setting up the socket via this parameter, it uses systemd sockets to
handle these.** This parameter will be ignored if a more detailed paramter
is given (``--$proto-bind``).
protocol
The protocol which should be used for the socket given by the ``--bind-to``
parameter. Possible values are ``uwsgi``, ``http``, ``fastcgi`` and
``scgi``. If nothing given, it defaults to ``uwsgi``.
scgi-bind, uwsgi-bind, http-bind, fastcgi-bind
Bind the application to a specific protocol instead of implicit uwsgi via
``--bind-to``. If such parameter given, ``--bind-to`` will be ignored. Must
be a UNIX/TCP socket. Can be set multiple times.
**By using such parameters instead of ``--bind-to``, no systemd sockets
will be used because it can not handle sockets for multiple protocols.**
Instead, the native socket binding will be used. It will add kernel
capabilites to bind to privileaged ports, too. This allow binds to ports
like 80 as netbox user.
BOOLEAN PARAMETERS
------------------
serve-static
Setup uWSGI to serve the static content, too. This is generally not
recommended for real production setups, as it is the job of the reverse
proxy server, who will thread it as static cachable content. This option
is only recommended for small setups or direct usage of the uWSGI socket
like using it as standalone HTTP server for NetBox.
**Hint**: This parameter does not work in junction with the `__netbox`
parameter ``--basepath``. It is because this type does not know the
parameter value and this case is very unlikly to happen; although an
implementation is not difficult.
MESSAGES
--------
installed
The uwsgi service was installed.
upgraded
The uwsgi service was upgraded.
configured
The uwsgi configuration got updated.
uninstalled
The uWSGI application was removed.
In all cases where the application is still present, it restarts the service to
use the up-to-date version.
EXAMPLES
--------
.. code-block:: sh
# simple
__netbox $args
require="__netbox" __netbox_uwsgi
# with multiple binds
__netbox $args
require="__netbox" __netbox_uwsgi --bind-to 0.0.0.0:3032 \
--bind-to 0.0.0.0:3033
# with multiple protocols
# parameter `--bind-to` will be ignored
# avoids systemd sockets, but can handle multiple protocols
__netbox $args
require="__netbox" __netbox_uwsgi --uwsgi-bind 0.0.0.0:3031 \
--http-bind 0.0.0.0:8080 \
--fastcgi-bind 1.2.3.4:5678
# as standalone server
__netbox $args
require="__netbox" __netbox_uwsgi --serve-static --http-bind 0.0.0.0:80
# replace gunicorn with uwsgi
__netbox $args
require="__netbox" __netbox_gunicorn --state absent
# it should depend on __netbox_gunicorn if they use the same socket
require="__netbox_gunicorn" __netbox_uwsgi --state enabled
# be sure the service is disabled
__netbox $args
require="__netbox" __netbox_uwsgi --state disabled
require="__netbox_uwsgi" __systemd_service uwsgi-netbox --state stopped
NOTES
-----
If systemd sockets are used, uwsgi can not be reloaded because it does not
handle the socket correctly. It works by completly restarting uwsgi (because
it is near the same cause of the systemd socket) or tweaking the service unit
with the line ``StandardInput=socket``, which limits you to only one address
to bind to (else, the service will not start).
Maybe someone is interested in enabling log files, because the "log to stdout"
is not the fanciest approach (because it is shown in the journal). See the
`uwsgi documentation <https://uwsgi.readthedocs.io/en/latest/Logging.html>` for
reference.
SEE ALSO
--------
`uWSGI Documentation <https://uwsgi-docs.readthedocs.io/en/latest/>`_
:strong:`cdist-type__netbox`\ (7)
:strong:`cdist-type__netbox_gunicorn`\ (7)
AUTHORS
-------
Matthias Stecher <matthiasstecher@gmx.de>
COPYING
-------
Copyright \(C) 2020 Matthias Stecher. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

86
type/__netbox_uwsgi/manifest Executable file
View file

@ -0,0 +1,86 @@
#!/bin/sh -e
# __netbox_uwsgi/manifest
# Check states
state=""
unit_state=""
param_state="$(cat "$__object/parameter/state")"
case "$param_state" in
enabled|disabled)
state="present"
unit_state="$param_state"
;;
absent)
state="absent"
unit_state="disabled"
;;
*)
# does not exist
printf "The state '%s' does not exist, can't continue!\n" "$param_state" >&2
exit 2
;;
esac
mkdir "$__object/files"
# check if systemd sockets will be used
if [ -f "$__object/parameter/bind-to" ]; then
SYSTEMD_SOCKET="yes"
fi
if find "$__object/parameter/" -maxdepth 1 -name "*-bind" -print -quit | grep -q .; then
SYSTEMD_SOCKET="no"
fi
echo "$SYSTEMD_SOCKET" > "$__object/files/systemd_socket"
if [ "$state" = "present" ]; then
# already checked outside this if-clause
export SYSTEMD_SOCKET
PROTOCOL="$(cat "$__object/parameter/protocol")"
export PROTOCOL
if [ -f "$__object/parameter/serve-static" ]; then
STATIC_MAP="yes"
export STATIC_MAP
fi
# process template
"$__type/files/uwsgi.ini.sh" > "$__object/files/uwsgi.ini"
# uwsgi config file
# TODO maybe patching with __key_value cause of .ini ?
__file /opt/netbox/uwsgi.ini \
--mode 644 --owner netbox \
--source "$__object/files/uwsgi.ini"
else
# absent config file
__file /opt/netbox/uwsgi.ini --state absent
fi
# handle the systemd socket
if [ "$SYSTEMD_SOCKET" = "yes" ]; then
TYPE="uWSGI"
export TYPE
# generate and set the socket unit
"$__type/files/netbox.socket.sh" "$__object/parameter/bind-to" \
> "$__object/files/netbox.socket"
__systemd_unit uwsgi-netbox.socket \
--state "$state" --enablement-state "$unit_state" \
--source "$__object/files/netbox.socket" --restart
else
# remove the systemd socket unit
__systemd_unit uwsgi-netbox.socket --state absent
fi
# install service file
"$__type/files/netbox.service.sh" > "$__object/files/netbox.service"
__systemd_unit uwsgi-netbox.service \
--state "$state" --enablement-state "$unit_state" \
--source "$__object/files/netbox.service" --restart

View file

@ -0,0 +1 @@
serve-static

View file

@ -0,0 +1 @@
127.0.0.1:3031

View file

@ -0,0 +1 @@
uwsgi

View file

@ -0,0 +1 @@
enabled

View file

@ -0,0 +1,2 @@
state
protocol

View file

@ -0,0 +1,5 @@
bind-to
uwsgi-bind
http-bind
fastcgi-bind
scgi-bind

View file

File diff suppressed because it is too large Load diff

16
type/__unbound/gencode-remote Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
UNBOUND_CERTS_DIR=/etc/unbound
if [ -f "$__object/parameter/enable_rc" ]; then
echo "unbound-control-setup -d $UNBOUND_CERTS_DIR"
echo "chown unbound:unbound $UNBOUND_CERTS_DIR/*.pem $UNBOUND_CERTS_DIR/*.key"
fi
cat << EOF
if pgrep unbound; then
service unbound reload
else
service unbound start
fi
EOF

84
type/__unbound/man.rst Normal file
View file

@ -0,0 +1,84 @@
cdist-type__unbound(7)
===============================
NAME
----
cdist-type__ungleich_unbound - unbound server deployment for ungleich
DESCRIPTION
-----------
This unbound (dns resolver and cache) deployment provides DNS64 and fetch
answers from specified upstrean DNS server. This is a singleton type.
REQUIRED PARAMETERS
-------------------
dns64_prefix
IPv6 prefix used for DNS64.
forward_addr
DNS servers used to lookup names, can be provided multiple times. It can be
either an IPv4 or IPv6 address but no domain name.
OPTIONAL PARAMETERS
-------------------
interface
Interface to listen on, can be provided multiple times. Defaults to
'127.0.0.1' and '::1'.
access_control
Controls which clients are allowed queries to the unbound service (everything
but localhost is refused by default), can be provided multiple times. The
format is described in unbound.conf(5).
rc_interface
Address or path to socket used for remote control (see `--enable_control`. Defaults to `127.0.0.1`).
local_data
Configure local data, which is served in reply to queries for it. Can be
specified multiple times.
BOOLEAN PARAMETERS
------------------
disable-ip4
Do not answer or issue queries over IPv4. Cannot be used alongside the
`--disable-ip6` flag.
disable-ip6
Do not answer or issue queries over IPv6. Cannot be used alongside the
`--disable-ip4` flag.
enable_rc
Enable remote control (see `unbound-control(8)`).
EXAMPLES
--------
.. code-block:: sh
__ungleich_unbound \
--interface '::0' \
--dns64_prefix '2a0a:e5c0:2:10::/96' \
--forward_addr '2a0a:e5c0:2:1::5' \
--forward_addr '2a0a:e5c0:2:1::6' \
--access_control '::0/0 deny' \
--access_control '2a0a:e5c0::/29 allow' \
--access_control '2a09:2940::/29 allow' \
--ip6
SEE ALSO
--------
- `unbound.conf(5) <https://nlnetlabs.nl/documentation/unbound/unbound.conf/>`_
AUTHORS
-------
Timothée Floure <timothee.floure@ungleich.ch>
COPYING
-------
Copyright \(C) 2020 Timothée Floure. You can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

102
type/__unbound/manifest Executable file
View file

@ -0,0 +1,102 @@
#!/bin/sh -e
#
# 2020 Timothée Floure (timothee.floure@ungleich.ch)
#
# This file is part of cdist.
#
# cdist is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cdist is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see <http://www.gnu.org/licenses/>.
#
os=$(cat "$__global/explorer/os")
case "$os" in
alpine)
__package unbound --state present
;;
*)
printf "Your operating system (%s) is currently not supported by this type (%s)\n" "$os" "${__type##*/}" >&2
printf "Please contribute an implementation for it if you can.\n" >&2
exit 1
;;
esac
# Required parameters:
DNS64_PREFIX=$(cat "$__object/parameter/dns64_prefix")
export DNS64_PREFIX
FORWARD_ADDRS=$(cat "$__object/parameter/forward_addr")
export FORWARD_ADDRS
# Optional parameters:
if [ -f "$__object/parameter/interface" ]; then
INTERFACES=$(cat "$__object/parameter/interface")
export INTERFACES
fi
if [ -f "$__object/parameter/access_control" ]; then
ACCESS_CONTROLS=$(cat "$__object/parameter/access_control")
export ACCESS_CONTROLS
fi
if [ -f "$__object/parameter/rc_interface" ]; then
RC_INTERFACE=$(cat "$__object/parameter/rc_interface")
export RC_INTERFACE
fi
if [ -f "$__object/parameter/local_data" ]; then
LOCAL_DATA=$(cat "$__object/parameter/local_data")
export LOCAL_DATA
fi
# Boolean parameters:
if [ -f "$__object/parameter/disable_ip4" ] && \
[ -f "$__object/parameter/disable_ip6" ]; then
echo "--disable-ip4 and --disable-ip6 cannot be used at the same time." >&2
exit 1
fi
if [ -f "$__object/parameter/disable_ip4" ]; then
export DO_IP4='no'
else
export DO_IP4='yes'
fi
if [ -f "$__object/parameter/disable_ip6" ]; then
export DO_IP6='no'
else
export DO_IP6='yes'
fi
if [ -f "$__object/parameter/enable_rc" ]; then
export RC_ENABLE='yes'
else
export RC_ENABLE='no'
fi
# Certs for remote control:
export RC_SERVER_KEY_FILE='/etc/unbound/unbound_server.key'
export RC_SERVER_CERT_FILE='/etc/unbound/unbound_server.pem'
export RC_CONTROL_KEY_FILE='/etc/unbound/unbound_control.key'
export RC_CONTROL_CERT_FILE='/etc/unbound/unbound_control.pem'
# Generate and deploy configuration files.
source_file="$__object/files/unbound.conf"
target_file="/etc/unbound/unbound.conf"
mkdir -p "$__object/files"
"$__type/files/unbound.conf.sh" > "$source_file"
require="__package/unbound" __file "$target_file" \
--source "$source_file" \
--owner root \
--mode 644

View file

@ -0,0 +1,3 @@
disable_ip6
disable_ip4
enable_rc

View file

@ -0,0 +1 @@
127.0.0.1

Some files were not shown because too many files have changed in this diff Show more