From b9b7cc084104e8764248c37a9a12c471ef310891 Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Wed, 24 Apr 2019 18:18:44 +0200 Subject: [PATCH] feat(prometheus): basic setup based on template-formula --- pillar.example | 64 +++++++++++ prometheus/clean.sls | 7 ++ prometheus/config/clean.sls | 16 +++ prometheus/config/file.sls | 27 +++++ prometheus/config/init.sls | 5 + prometheus/defaults.yaml | 11 ++ prometheus/files/default/prometheus.yml.jinja | 6 ++ prometheus/init.sls | 7 ++ prometheus/libtofs.jinja | 100 ++++++++++++++++++ prometheus/map.jinja | 24 +++++ prometheus/osfamilymap.yaml | 40 +++++++ prometheus/osfingermap.yaml | 14 +++ prometheus/osmap.yaml | 25 +++++ prometheus/package/clean.sls | 16 +++ prometheus/package/init.sls | 5 + prometheus/package/install.sls | 10 ++ prometheus/service/clean.sls | 18 ++++ prometheus/service/init.sls | 5 + prometheus/service/running.sls | 43 ++++++++ 19 files changed, 443 insertions(+) create mode 100644 pillar.example create mode 100644 prometheus/clean.sls create mode 100644 prometheus/config/clean.sls create mode 100644 prometheus/config/file.sls create mode 100644 prometheus/config/init.sls create mode 100644 prometheus/defaults.yaml create mode 100644 prometheus/files/default/prometheus.yml.jinja create mode 100644 prometheus/init.sls create mode 100644 prometheus/libtofs.jinja create mode 100644 prometheus/map.jinja create mode 100644 prometheus/osfamilymap.yaml create mode 100644 prometheus/osfingermap.yaml create mode 100644 prometheus/osmap.yaml create mode 100644 prometheus/package/clean.sls create mode 100644 prometheus/package/init.sls create mode 100644 prometheus/package/install.sls create mode 100644 prometheus/service/clean.sls create mode 100644 prometheus/service/init.sls create mode 100644 prometheus/service/running.sls diff --git a/pillar.example b/pillar.example new file mode 100644 index 00000000..0e6a6e27 --- /dev/null +++ b/pillar.example @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +prometheus: + pkg: prometheus + config_file: /etc/prometheus/prometheus.yml + service: + name: prometheus + flags: --web.listen-address="0.0.0.0:9090" + + tofs: + # The files_switch key serves as a selector for alternative + # directories under the formula files directory. See TOFS pattern + # doc for more info. + # Note: Any value not evaluated by `config.get` will be used literally. + # This can be used to set custom paths, as many levels deep as required. + files_switch: + - any/path/can/be/used/here + - id + - osfinger + - os + - os_family + # All aspects of path/file resolution are customisable using the options below. + # This is unnecessary in most cases; there are sensible defaults. + # path_prefix: prometheus_alt + # dirs: + # files: files_alt + # default: default_alt + # source_files: + # prometheus-config-file-file-managed: + # - 'example_alt.tmpl' + # - 'example_alt.tmpl.jinja' + + # Pillar-based config + config: + # my global config + global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + + # Alertmanager configuration + alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + + # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. + rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + + # A scrape configuration containing exactly one endpoint to scrape: + # Here it's Prometheus itself. + scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'prometheus' + + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + + static_configs: + - targets: ['localhost:9090'] diff --git a/prometheus/clean.sls b/prometheus/clean.sls new file mode 100644 index 00000000..2cefe7dd --- /dev/null +++ b/prometheus/clean.sls @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .service.clean + - .config.clean + - .package.clean diff --git a/prometheus/config/clean.sls b/prometheus/config/clean.sls new file mode 100644 index 00000000..5dd4b809 --- /dev/null +++ b/prometheus/config/clean.sls @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_service_clean = tplroot ~ '.service.clean' %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +include: + - {{ sls_service_clean }} + +prometheus-config-clean-file-absent: + file.absent: + - name: {{ prometheus.config_file }} + - require: + - sls: {{ sls_service_clean }} diff --git a/prometheus/config/file.sls b/prometheus/config/file.sls new file mode 100644 index 00000000..20a4ff1d --- /dev/null +++ b/prometheus/config/file.sls @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_package_install = tplroot ~ '.package.install' %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} + +include: + - {{ sls_package_install }} + +prometheus-config-file-file-managed: + file.managed: + - name: {{ prometheus.config_file }} + - source: {{ files_switch(['prometheus.yml.jinja'], + lookup='prometheus-config-file-file-managed' + ) + }} + - mode: 644 + - user: root + - group: {{ prometheus.rootgroup }} + - template: jinja + - context: + config: {{ prometheus.config|json }} + - require: + - sls: {{ sls_package_install }} diff --git a/prometheus/config/init.sls b/prometheus/config/init.sls new file mode 100644 index 00000000..465ddfea --- /dev/null +++ b/prometheus/config/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .file diff --git a/prometheus/defaults.yaml b/prometheus/defaults.yaml new file mode 100644 index 00000000..17dc5f6f --- /dev/null +++ b/prometheus/defaults.yaml @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +prometheus: + pkg: prometheus + rootgroup: root + config_file: /etc/prometheus/prometheus.yml + config: {} + service: + name: prometheus + sysrc: False diff --git a/prometheus/files/default/prometheus.yml.jinja b/prometheus/files/default/prometheus.yml.jinja new file mode 100644 index 00000000..cd410da7 --- /dev/null +++ b/prometheus/files/default/prometheus.yml.jinja @@ -0,0 +1,6 @@ +######################################################################## +# File managed by Salt at <{{ source }}>. +# Your changes will be overwritten. +######################################################################## + +{{ config|yaml(False) }} diff --git a/prometheus/init.sls b/prometheus/init.sls new file mode 100644 index 00000000..858a8e6e --- /dev/null +++ b/prometheus/init.sls @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .package + - .config + - .service diff --git a/prometheus/libtofs.jinja b/prometheus/libtofs.jinja new file mode 100644 index 00000000..ab0d0f6c --- /dev/null +++ b/prometheus/libtofs.jinja @@ -0,0 +1,100 @@ +{%- macro files_switch(source_files, + lookup=None, + default_files_switch=['id', 'os_family'], + indent_width=6, + v1_path_prefix='') %} + {#- + Returns a valid value for the "source" parameter of a "file.managed" + state function. This makes easier the usage of the Template Override and + Files Switch (TOFS) pattern. + + Params: + * source_files: ordered list of files to look for + * lookup: key under ':tofs:source_files' to override + list of source files + * default_files_switch: if there's no config (e.g. pillar) + ':tofs:files_switch' this is the ordered list of grains to + use as selector switch of the directories under + "/files" + * indent_witdh: indentation of the result value to conform to YAML + * v1_path_prefix: (deprecated) only used for injecting a path prefix into + the source, to support older TOFS configs + + Example (based on a `tplroot` of `xxx`): + + If we have a state: + + Deploy configuration: + file.managed: + - name: /etc/yyy/zzz.conf + - source: {{ files_switch(['/etc/yyy/zzz.conf', '/etc/yyy/zzz.conf.jinja'], + lookup='Deploy configuration' + ) }} + - template: jinja + + In a minion with id=theminion and os_family=RedHat, it's going to be + rendered as: + + Deploy configuration: + file.managed: + - name: /etc/yyy/zzz.conf + - source: + - salt://xxx/files/theminion/etc/yyy/zzz.conf + - salt://xxx/files/theminion/etc/yyy/zzz.conf.jinja + - salt://xxx/files/RedHat/etc/yyy/zzz.conf + - salt://xxx/files/RedHat/etc/yyy/zzz.conf.jinja + - salt://xxx/files/default/etc/yyy/zzz.conf + - salt://xxx/files/default/etc/yyy/zzz.conf.jinja + - template: jinja + #} + {#- Get the `tplroot` from `tpldir` #} + {%- set tplroot = tpldir.split('/')[0] %} + {%- set path_prefix = salt['config.get'](tplroot ~ ':tofs:path_prefix', tplroot) %} + {%- set files_dir = salt['config.get'](tplroot ~ ':tofs:dirs:files', 'files') %} + {%- set files_switch_list = salt['config.get']( + tplroot ~ ':tofs:files_switch', + default_files_switch + ) %} + {#- Lookup source_files (v2), files (v1), or fallback to source_files parameter #} + {%- set src_files = salt['config.get']( + tplroot ~ ':tofs:source_files:' ~ lookup, + salt['config.get']( + tplroot ~ ':tofs:files:' ~ lookup, + source_files + ) + ) %} + {#- Only add to [''] when supporting older TOFS implementations #} + {%- set path_prefix_exts = [''] %} + {%- if v1_path_prefix != '' %} + {%- do path_prefix_exts.append(v1_path_prefix) %} + {%- endif %} + {%- for path_prefix_ext in path_prefix_exts %} + {%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %} + {#- For older TOFS implementation, use `files_switch` from the config #} + {#- Use the default, new method otherwise #} + {%- set fsl = salt['config.get']( + tplroot ~ path_prefix_ext|replace('/', ':') ~ ':files_switch', + files_switch_list + ) %} + {#- Append an empty value to evaluate as `default` in the loop below #} + {%- if '' not in fsl %} + {%- do fsl.append('') %} + {%- endif %} + {%- for fs in fsl %} + {%- for src_file in src_files %} + {%- if fs %} + {%- set fs_dir = salt['config.get'](fs, fs) %} + {%- else %} + {%- set fs_dir = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %} + {%- endif %} + {%- set url = '- salt://' ~ '/'.join([ + path_prefix_inc_ext, + files_dir, + fs_dir, + src_file.lstrip('/') + ]) %} +{{ url | indent(indent_width, true) }} + {%- endfor %} + {%- endfor %} + {%- endfor %} +{%- endmacro %} diff --git a/prometheus/map.jinja b/prometheus/map.jinja new file mode 100644 index 00000000..92af9310 --- /dev/null +++ b/prometheus/map.jinja @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# vim: ft=jinja + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{#- Start imports as #} +{%- import_yaml tplroot ~ "/defaults.yaml" as default_settings %} +{%- import_yaml tplroot ~ "/osfamilymap.yaml" as osfamilymap %} +{%- import_yaml tplroot ~ "/osmap.yaml" as osmap %} +{%- import_yaml tplroot ~ "/osfingermap.yaml" as osfingermap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='prometheus', + merge=salt['grains.filter_by'](osfamilymap, grain='os_family', + merge=salt['grains.filter_by'](osmap, grain='os', + merge=salt['grains.filter_by'](osfingermap, grain='osfinger', + merge=salt['pillar.get']('prometheus:lookup', default={}) + ) + ) + ) +) %} + +{#- Merge the prometheus pillar #} +{%- set prometheus = salt['pillar.get']('prometheus', default=defaults, merge=True) %} diff --git a/prometheus/osfamilymap.yaml b/prometheus/osfamilymap.yaml new file mode 100644 index 00000000..b460866c --- /dev/null +++ b/prometheus/osfamilymap.yaml @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +# +# Setup variables using grains['os_family'] based logic. +# You just need to add the key:values for an `os_family` that differ +# from `defaults.yaml`. +# Only add an `os_family` which is/will be supported by the formula +# +# If you do not need to provide defaults via the `os_family` grain, +# you will need to provide at least an empty dict in this file, e.g. +# osfamilymap: {} +--- +Debian: {} + +RedHat: {} + +Suse: {} + +Gentoo: {} + +Arch: {} + +Alpine: {} + +FreeBSD: + rootgroup: wheel + config_file: /usr/local/etc/prometheus.yml + service: + sysrc: True + +OpenBSD: + rootgroup: wheel + service: + sysrc: True + +Solaris: {} + +Windows: {} + +MacOS: {} diff --git a/prometheus/osfingermap.yaml b/prometheus/osfingermap.yaml new file mode 100644 index 00000000..0fac2c65 --- /dev/null +++ b/prometheus/osfingermap.yaml @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +# +# Setup variables using grains['osfinger'] based logic. +# You just need to add the key:values for an `osfinger` that differ +# from `defaults.yaml` + `os_family.yaml` + `osmap.yaml`. +# Only add an `osfinger` which is/will be supported by the formula +# +# If you do not need to provide defaults via the `os_finger` grain, +# you will need to provide at least an empty dict in this file, e.g. +# osfingermap: {} +--- +# os: Ubuntu +Ubuntu-18.04: {} diff --git a/prometheus/osmap.yaml b/prometheus/osmap.yaml new file mode 100644 index 00000000..20a12fd2 --- /dev/null +++ b/prometheus/osmap.yaml @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +# +# Setup variables using grains['os'] based logic. +# You just need to add the key:values for an `os` that differ +# from `defaults.yaml` + `os_family.yaml`. +# Only add an `os` which is/will be supported by the formula +# +# If you do not need to provide defaults via the `os` grain, +# you will need to provide at least an empty dict in this file, e.g. +# osmap: {} +--- +# os_family: Debian +Ubuntu: {} + +Raspbian: {} + +# os_family: Gentoo +Funtoo: {} + +# os_family: Arch +Manjaro: {} + +# os_family: Solaris +SmartOS: {} diff --git a/prometheus/package/clean.sls b/prometheus/package/clean.sls new file mode 100644 index 00000000..b4e5a80d --- /dev/null +++ b/prometheus/package/clean.sls @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_config_clean = tplroot ~ '.config.clean' %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +include: + - {{ sls_config_clean }} + +prometheus-package-clean-pkg-removed: + pkg.removed: + - name: {{ prometheus.pkg }} + - require: + - sls: {{ sls_config_clean }} diff --git a/prometheus/package/init.sls b/prometheus/package/init.sls new file mode 100644 index 00000000..d3e55181 --- /dev/null +++ b/prometheus/package/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .install diff --git a/prometheus/package/install.sls b/prometheus/package/install.sls new file mode 100644 index 00000000..873c4a7b --- /dev/null +++ b/prometheus/package/install.sls @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +prometheus-package-install-pkg-installed: + pkg.installed: + - name: {{ prometheus.pkg }} diff --git a/prometheus/service/clean.sls b/prometheus/service/clean.sls new file mode 100644 index 00000000..9bf34e57 --- /dev/null +++ b/prometheus/service/clean.sls @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +prometheus-service-clean-service-dead: + service.dead: + - name: {{ prometheus.service.name }} + - enable: False + +{%- if prometheus.service.use_sysrc %} +prometheus_flags: + sysrc.absent: + - require: + - service: prometheus-service-clean-service-dead +{%- endif %} diff --git a/prometheus/service/init.sls b/prometheus/service/init.sls new file mode 100644 index 00000000..6fe4d1a3 --- /dev/null +++ b/prometheus/service/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .running diff --git a/prometheus/service/running.sls b/prometheus/service/running.sls new file mode 100644 index 00000000..0f206e27 --- /dev/null +++ b/prometheus/service/running.sls @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_config_file = tplroot ~ '.config.file' %} +{%- from tplroot ~ "/map.jinja" import prometheus with context %} + +include: + - {{ sls_config_file }} + +{%- if prometheus.service.sysrc %} +prometheus_args: + sysrc.managed: + - value: {{ prometheus.service.flags }} +{%- endif %} + +{#- On FreeBSD restarting this service hangs. #} +{#- See https://github.com/saltstack/salt/issues/44848#issuecomment-486460601 #} +{%- if salt['grains.get']('os_family') == 'FreeBSD' %} +prometheus-service-running-service-enable: + service.enabled: + - name: {{ prometheus.service.name }} + +prometheus-service-running-service-running: + cmd.run: + - name: "service {{ prometheus.service.name }} onerestart >/dev/null 2>&1" + - hide_output: True + - timeout: 60 + - onchanges: +{%- else %}{# business as usual #} +prometheus-service-running-service-running: + service.running: + - name: {{ prometheus.service.name }} + - enable: True + - watch: +{%- endif %} + - file: prometheus-config-file-file-managed +{%- if prometheus.service.sysrc %} + - sysrc: prometheus_args +{%- endif %} + - require: + - sls: {{ sls_config_file }}