commit eaa6b99c5e9c3d03937ee950cd2976486290a553 Author: Paul Lecuq Date: Fri Jul 10 00:58:55 2020 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f14fbbe --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Pillars +/pillar + +# Python related +*.swp +*.pyc \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..dc40b7e --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +# paulbsd-salt + +## Summary + +paulbsd-salt are sets of SaltStack states for PaulBSD infrastructure + +## Howto + +### States + +```text +states +├── acme +├── androidstudio +├── apparmor +├── appimagekit +├── apt +├── arduino +├── bareos +├── burp +├── cds +├── clamav +├── collectd +├── cron +├── dovecot +├── flash +├── gitea +├── grafana +├── gufw +├── influxdb +├── ipfs +├── iptables +├── java +├── maildb +├── mariadb +├── misc +├── _modules +├── molotov +├── motd +├── netbox +├── nextcloud_desktop +├── nftables +├── nginx +├── npf +├── opendkim +├── openvpn_client +├── openvpn_server +├── packer +├── pkg +├── postfix +├── postgresql +├── pycharm +├── rclone +├── reactor +├── repos +├── rsync +├── rsyslog +├── _runners +├── salt_minion +├── samba +├── sensu +├── services +├── snmp +├── ssh +├── _states +├── sublimetext +├── sudo +├── syncthing +├── telegraf +├── telegram +├── tests +├── time +├── tmux +├── tor +├── transmission +├── users +├── vim +├── vsftpd +├── winpkg +├── wintse +└── zsh +``` + +### Scripts + +TBD + +## License + +```text +Copyright (c) 2019, 2020 PaulBSD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the paulbsd project. +``` diff --git a/cloud/cloud b/cloud/cloud new file mode 100644 index 0000000..b02a938 --- /dev/null +++ b/cloud/cloud @@ -0,0 +1,3 @@ +# vim:set ft=yaml: +wait_for_ip_timeout: 600 +sync_after_install: all diff --git a/cloud/cloud.profiles b/cloud/cloud.profiles new file mode 100644 index 0000000..4c7c759 --- /dev/null +++ b/cloud/cloud.profiles @@ -0,0 +1,20 @@ +# vim:set ft=yaml: +scaleway-xsmall-arm-ubuntu-16: + provider: scaleway-paris + image: eeb73cbf-78a9-4481-9e38-9aaadaf8e0c9 + commercial_type: C1 + +scaleway-xsmall-x86-ubuntu-16: + provider: scaleway-paris + image: 047f1372-3923-471f-82ca-5ff69dbaf0f7 + commercial_type: VC1S + +scaleway-lamp: + provider: scaleway-paris + image: 89457135-d446-41ba-a8df-d53e5bb54710 + commercial_type: VC1S + +scaleway-external: + provider: scaleway-amsterdam + image: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe + commercial_type: VC1S diff --git a/cloud/cloud.providers b/cloud/cloud.providers new file mode 100644 index 0000000..7dc4b15 --- /dev/null +++ b/cloud/cloud.providers @@ -0,0 +1,14 @@ +# vim:set ft=yaml: +scaleway-paris: + access_key: + token: + driver: scaleway + region: par1 + api_root: https://cp-par1.scaleway.com + +scaleway-amsterdam: + access_key: + token: + driver: scaleway + region: ams1 + api_root: https://cp-ams1.scaleway.com diff --git a/cloud/scaleway/scw01-ams.paulbsd.com b/cloud/scaleway/scw01-ams.paulbsd.com new file mode 100644 index 0000000..f55c1e0 --- /dev/null +++ b/cloud/scaleway/scw01-ams.paulbsd.com @@ -0,0 +1,6 @@ +scaleway-external: + - scw01-ams.paulbsd.com: + minion: + master: salt.paulbsd.com + ssh_username: root + key_filename: /root/.ssh/id_rsa diff --git a/cloud/scaleway/scw_lamp.map b/cloud/scaleway/scw_lamp.map new file mode 100644 index 0000000..8bc2182 --- /dev/null +++ b/cloud/scaleway/scw_lamp.map @@ -0,0 +1,7 @@ +scaleway-lamp: + - lamp1: + minion: + master: salt.paulbsd.com + ssh_username: root + key_filename: /root/.ssh/id_rsa + script_args: -P diff --git a/cloud/scaleway/scw_web.map b/cloud/scaleway/scw_web.map new file mode 100644 index 0000000..d375c2c --- /dev/null +++ b/cloud/scaleway/scw_web.map @@ -0,0 +1,16 @@ +scaleway-xsmall-x86-ubuntu-16: + - web1: + minion: + master: salt.paulbsd.com + ssh_username: root + key_filename: /root/.ssh/id_rsa + - web2: + minion: + master: salt.paulbsd.com + ssh_username: root + key_filename: /root/.ssh/id_rsa + - web3: + minion: + master: salt.paulbsd.com + ssh_username: root + key_filename: /root/.ssh/id_rsa diff --git a/config/master b/config/master new file mode 100644 index 0000000..fab423b --- /dev/null +++ b/config/master @@ -0,0 +1,80 @@ +# # vi:syntax=yaml + +interface: '0.0.0.0' + +log_level: debug +log_file: /var/log/salt/master + +file_recv: True + +#cache: mysql +#master_job_cache: redis +#ext_job_cache: redis +return: smtp +event_return: mysql + +external_auth: + pam: + paul: + - .* + salt: + - .* + - '@runner' + - '@wheel' + +rest_cherrypy: + port: 8033 + disable_ssl: True + +runner_dirs: + - /srv/salt/states/_runners + +reactor: + - 'salt/minion/*/start': + - salt://reactor/auth.sls + - 'salt/job/*/ret/*': + - salt://reactor/email-on-failure.sls + +state_output: changes +cython_enable: True + +file_roots: + base: + - /srv/salt/states + +pillar_roots: + base: + - /srv/salt/pillar + +pillar_includes_override_sls: True +pillar_merge_lists: False +pillar_source_merging_strategy: recurse + +ext_pillar: + - etcd: etcd_config root=/salt/common + - etcd: etcd_config root=/salt/hosts/%(minion_id)s + +etcd_config: + etcd.host: 127.0.0.1 + etcd.port: 2379 + +mysql.host: 'scw02-ams.paulbsd.com' +mysql.user: 'salt' +mysql.pass: '' +mysql.password: '' +mysql.db: 'salt' +mysql.port: 3306 +#mysql.table_name: 'salt_cache' + +#smtp.from: 'salt@paulbsd.com' +#smtp.to: 'postmaster@paulbsd.com' +#smtp.host: 'smtp.paulbsd.com' +#smtp.port: 465 +#smtp.username: 'sys@paulbsd.com' +#smtp.password: '' +#smtp.tls: True + +#mine_functions: +# provision: +# - mine_function: state.sls +# - provision diff --git a/config/master.sample b/config/master.sample new file mode 100644 index 0000000..8b30841 --- /dev/null +++ b/config/master.sample @@ -0,0 +1,867 @@ +##### Primary configuration settings ##### +########################################## +# This configuration file is used to manage the behavior of the Salt Master. +# Values that are commented out but have an empty line after the comment are +# defaults that do not need to be set in the config. If there is no blank line +# after the comment then the value is presented as an example and is not the +# default. + +# Per default, the master will automatically include all config files +# from master.d/*.conf (master.d is a directory in the same directory +# as the main master config file). +#default_include: master.d/*.conf + +# The address of the interface to bind to: +interface: '0.0.0.0' + +# Whether the master should listen for IPv6 connections. If this is set to True, +# the interface option must be adjusted, too. (For example: "interface: '::'") +#ipv6: True + +# The tcp port used by the publisher: +#publish_port: 4505 + +# The user under which the salt master will run. Salt will update all +# permissions to allow the specified user to run the master. The exception is +# the job cache, which must be deleted if this user is changed. If the +# modified files cause conflicts, set verify_env to False. +#user: root + +# The port used by the communication interface. The ret (return) port is the +# interface used for the file server, authentication, job returns, etc. +#ret_port: 4506 + +# Specify the location of the daemon process ID file: +#pidfile: /var/run/salt-master.pid + +# The root directory prepended to these options: pki_dir, cachedir, +# sock_dir, log_file, autosign_file, autoreject_file, extension_modules, +# key_logfile, pidfile: +#root_dir: / + +# Directory used to store public key data: +#pki_dir: /usr/pkg/etc/salt/pki/master + +# Directory to store job and cache data: +# This directory may contain sensitive data and should be protected accordingly. +# +#cachedir: /var/cache/salt/master + +# Directory for custom modules. This directory can contain subdirectories for +# each of Salt's module types such as "runners", "output", "wheel", "modules", +# "states", "returners", etc. +#extension_modules: + +# Directory for custom modules. This directory can contain subdirectories for +# each of Salt's module types such as "runners", "output", "wheel", "modules", +# "states", "returners", etc. +# Like 'extension_modules' but can take an array of paths +#module_dirs: +# - /var/cache/salt/minion/extmods + +# Verify and set permissions on configuration directories at startup: +#verify_env: True + +# Set the number of hours to keep old job information in the job cache: +#keep_jobs: 24 + +# Set the default timeout for the salt command and api. The default is 5 +# seconds. +#timeout: 5 + +# The loop_interval option controls the seconds for the master's maintenance +# process check cycle. This process updates file server backends, cleans the +# job cache and executes the scheduler. +#loop_interval: 60 + +# Set the default outputter used by the salt command. The default is "nested". +#output: nested + +# Return minions that timeout when running commands like test.ping +#show_timeout: True + +# By default, output is colored. To disable colored output, set the color value +# to False. +#color: True + +# Do not strip off the colored output from nested results and state outputs +# (true by default). +# strip_colors: False + +# Set the directory used to hold unix sockets: +#sock_dir: /var/run/salt/master + +# The master can take a while to start up when lspci and/or dmidecode is used +# to populate the grains for the master. Enable if you want to see GPU hardware +# data for your master. +# enable_gpu_grains: False + +# The master maintains a job cache. While this is a great addition, it can be +# a burden on the master for larger deployments (over 5000 minions). +# Disabling the job cache will make previously executed jobs unavailable to +# the jobs system and is not generally recommended. +#job_cache: True + +# Cache minion grains and pillar data in the cachedir. +#minion_data_cache: True + +# Store all returns in the given returner. +# Setting this option requires that any returner-specific configuration also +# be set. See various returners in salt/returners for details on required +# configuration values. (See also, event_return_queue below.) +# +event_return: mysql + +# On busy systems, enabling event_returns can cause a considerable load on +# the storage system for returners. Events can be queued on the master and +# stored in a batched fashion using a single transaction for multiple events. +# By default, events are not queued. +#event_return_queue: 0 + +# Only events returns matching tags in a whitelist +# event_return_whitelist: +# - salt/master/a_tag +# - salt/master/another_tag + +# Store all event returns _except_ the tags in a blacklist +# event_return_blacklist: +# - salt/master/not_this_tag +# - salt/master/or_this_one + +# Passing very large events can cause the minion to consume large amounts of +# memory. This value tunes the maximum size of a message allowed onto the +# master event bus. The value is expressed in bytes. +#max_event_size: 1048576 + +# By default, the master AES key rotates every 24 hours. The next command +# following a key rotation will trigger a key refresh from the minion which may +# result in minions which do not respond to the first command after a key refresh. +# +# To tell the master to ping all minions immediately after an AES key refresh, set +# ping_on_rotate to True. This should mitigate the issue where a minion does not +# appear to initially respond after a key is rotated. +# +# Note that ping_on_rotate may cause high load on the master immediately after +# the key rotation event as minions reconnect. Consider this carefully if this +# salt master is managing a large number of minions. +# +# If disabled, it is recommended to handle this event by listening for the +# 'aes_key_rotate' event with the 'key' tag and acting appropriately. +# ping_on_rotate: False + +# By default, the master deletes its cache of minion data when the key for that +# minion is removed. To preserve the cache after key deletion, set +# 'preserve_minion_cache' to True. +# +# WARNING: This may have security implications if compromised minions auth with +# a previous deleted minion ID. +#preserve_minion_cache: False + +# If max_minions is used in large installations, the master might experience +# high-load situations because of having to check the number of connected +# minions for every authentication. This cache provides the minion-ids of +# all connected minions to all MWorker-processes and greatly improves the +# performance of max_minions. +# con_cache: False + +# The master can include configuration from other files. To enable this, +# pass a list of paths to this option. The paths can be either relative or +# absolute; if relative, they are considered to be relative to the directory +# the main master configuration file lives in (this file). Paths can make use +# of shell-style globbing. If no files are matched by a path passed to this +# option, then the master will log a warning message. +# +# Include a config file from some other path: +# include: /usr/pkg/etc/salt/extra_config +# +# Include config from several files and directories: +# include: +# - /usr/pkg/etc/salt/extra_config + + +##### Large-scale tuning settings ##### +########################################## +# Max open files +# +# Each minion connecting to the master uses AT LEAST one file descriptor, the +# master subscription connection. If enough minions connect you might start +# seeing on the console (and then salt-master crashes): +# Too many open files (tcp_listener.cpp:335) +# Aborted (core dumped) +# +# By default this value will be the one of `ulimit -Hn`, ie, the hard limit for +# max open files. +# +# If you wish to set a different value than the default one, uncomment and +# configure this setting. Remember that this value CANNOT be higher than the +# hard limit. Raising the hard limit depends on your OS and/or distribution, +# a good way to find the limit is to search the internet. For example: +# raise max open files hard limit debian +# +#max_open_files: 100000 + +# The number of worker threads to start. These threads are used to manage +# return calls made from minions to the master. If the master seems to be +# running slowly, increase the number of threads. This setting can not be +# set lower than 3. +#worker_threads: 5 + +# Set the ZeroMQ high water marks +# http://api.zeromq.org/3-2:zmq-setsockopt + +# The publisher interface ZeroMQPubServerChannel +#pub_hwm: 1000 + +# These two ZMQ HWM settings, salt_event_pub_hwm and event_publisher_pub_hwm +# are significant for masters with thousands of minions. When these are +# insufficiently high it will manifest in random responses missing in the CLI +# and even missing from the job cache. Masters that have fast CPUs and many +# cores with appropriate worker_threads will not need these set as high. + +# On deployment with 8,000 minions, 2.4GHz CPUs, 24 cores, 32GiB memory has +# these settings: +# +# salt_event_pub_hwm: 128000 +# event_publisher_pub_hwm: 64000 + +# ZMQ high-water-mark for SaltEvent pub socket +#salt_event_pub_hwm: 20000 + +# ZMQ high-water-mark for EventPublisher pub socket +#event_publisher_pub_hwm: 10000 + + + +##### Security settings ##### +########################################## +# Enable "open mode", this mode still maintains encryption, but turns off +# authentication, this is only intended for highly secure environments or for +# the situation where your keys end up in a bad state. If you run in open mode +# you do so at your own risk! +#open_mode: False + +# Enable auto_accept, this setting will automatically accept all incoming +# public keys from the minions. Note that this is insecure. +#auto_accept: False + +# Time in minutes that a incoming public key with a matching name found in +# pki_dir/minion_autosign/keyid is automatically accepted. Expired autosign keys +# are removed when the master checks the minion_autosign directory. +# 0 equals no timeout +# autosign_timeout: 120 + +# If the autosign_file is specified, incoming keys specified in the +# autosign_file will be automatically accepted. This is insecure. Regular +# expressions as well as globing lines are supported. +#autosign_file: /usr/pkg/etc/salt/autosign.conf + +# Works like autosign_file, but instead allows you to specify minion IDs for +# which keys will automatically be rejected. Will override both membership in +# the autosign_file and the auto_accept setting. +#autoreject_file: /usr/pkg/etc/salt/autoreject.conf + +# Enable permissive access to the salt keys. This allows you to run the +# master or minion as root, but have a non-root group be given access to +# your pki_dir. To make the access explicit, root must belong to the group +# you've given access to. This is potentially quite insecure. If an autosign_file +# is specified, enabling permissive_pki_access will allow group access to that +# specific file. +#permissive_pki_access: False + +# Allow users on the master access to execute specific commands on minions. +# This setting should be treated with care since it opens up execution +# capabilities to non root users. By default this capability is completely +# disabled. +#client_acl: +# larry: +# - test.ping +# - network.* +# +# Blacklist any of the following users or modules +# +# This example would blacklist all non sudo users, including root from +# running any commands. It would also blacklist any use of the "cmd" +# module. This is completely disabled by default. +# +#client_acl_blacklist: +# users: +# - root +# - '^(?!sudo_).*$' # all non sudo users +# modules: +# - cmd + +# Enforce client_acl & client_acl_blacklist when users have sudo +# access to the salt command. +# +#sudo_acl: False + +# The external auth system uses the Salt auth modules to authenticate and +# validate users to access areas of the Salt system. +external_auth: + pam: + paul: + - .* + salt: + - .* + - '@runner' + - '@wheel' + +rest_cherrypy: +# host: 127.0.0.1 + port: 8000 + disable_ssl: True + +# +# Time (in seconds) for a newly generated token to live. Default: 12 hours +#token_expire: 43200 + +# Allow minions to push files to the master. This is disabled by default, for +# security purposes. +#file_recv: False + +# Set a hard-limit on the size of the files that can be pushed to the master. +# It will be interpreted as megabytes. Default: 100 +#file_recv_max_size: 100 + +# Signature verification on messages published from the master. +# This causes the master to cryptographically sign all messages published to its event +# bus, and minions then verify that signature before acting on the message. +# +# This is False by default. +# +# Note that to facilitate interoperability with masters and minions that are different +# versions, if sign_pub_messages is True but a message is received by a minion with +# no signature, it will still be accepted, and a warning message will be logged. +# Conversely, if sign_pub_messages is False, but a minion receives a signed +# message it will be accepted, the signature will not be checked, and a warning message +# will be logged. This behavior went away in Salt 2014.1.0 and these two situations +# will cause minion to throw an exception and drop the message. +# sign_pub_messages: False + +##### Salt-SSH Configuration ##### +########################################## + +# Pass in an alternative location for the salt-ssh roster file +#roster_file: /usr/pkg/etc/salt/roster + +# Pass in minion option overrides that will be inserted into the SHIM for +# salt-ssh calls. The local minion config is not used for salt-ssh. Can be +# overridden on a per-minion basis in the roster (`minion_opts`) +#ssh_minion_opts: +# gpg_keydir: /root/gpg + +##### Master Module Management ##### +########################################## +# Manage how master side modules are loaded. + +# Add any additional locations to look for master runners: +#runner_dirs: [] + +runner_dirs: + - /usr/pkg/etc/salt/_runners + +reactor: + - 'salt/minion/*/start': + - salt://reactor/auth.sls + - 'salt/job/*/ret/*': + - salt://reactor/email-on-failure.sls + +state_output: changes + +# Enable Cython for master side modules: +cython_enable: True + + +##### State System settings ##### +########################################## +# The state system uses a "top" file to tell the minions what environment to +# use and what modules to use. The state_top file is defined relative to the +# root of the base environment as defined in "File Server settings" below. +#state_top: top.sls + +# The master_tops option replaces the external_nodes option by creating +# a plugable system for the generation of external top data. The external_nodes +# option is deprecated by the master_tops option. +# +# To gain the capabilities of the classic external_nodes system, use the +# following configuration: +# master_tops: +# ext_nodes: +# +#master_tops: {} + +# The external_nodes option allows Salt to gather data that would normally be +# placed in a top file. The external_nodes option is the executable that will +# return the ENC data. Remember that Salt will look for external nodes AND top +# files and combine the results if both are enabled! +#external_nodes: None + +# The renderer to use on the minions to render the state data +#renderer: yaml_jinja + +# The Jinja renderer can strip extra carriage returns and whitespace +# See http://jinja.pocoo.org/docs/api/#high-level-api +# +# If this is set to True the first newline after a Jinja block is removed +# (block, not variable tag!). Defaults to False, corresponds to the Jinja +# environment init variable "trim_blocks". +#jinja_trim_blocks: True +# +# If this is set to True leading spaces and tabs are stripped from the start +# of a line to a block. Defaults to False, corresponds to the Jinja +# environment init variable "lstrip_blocks". +#jinja_lstrip_blocks: False + +# The failhard option tells the minions to stop immediately after the first +# failure detected in the state execution, defaults to False +#failhard: False + +# The state_verbose and state_output settings can be used to change the way +# state system data is printed to the display. By default all data is printed. +# The state_verbose setting can be set to True or False, when set to False +# all data that has a result of True and no changes will be suppressed. +#state_verbose: True + +# The state_output setting changes if the output is the full multi line +# output for each changed state if set to 'full', but if set to 'terse' +# the output will be shortened to a single line. If set to 'mixed', the output +# will be terse unless a state failed, in which case that output will be full. +# If set to 'changes', the output will be full unless the state didn't change. +#state_output: full + +# Automatically aggregate all states that have support for mod_aggregate by +# setting to 'True'. Or pass a list of state module names to automatically +# aggregate just those types. +# +# state_aggregate: +# - pkg +# +#state_aggregate: False + +# Send progress events as each function in a state run completes execution +# by setting to 'True'. Progress events are in the format +# 'salt/job//prog//'. +#state_events: False + +##### File Server settings ##### +########################################## +# Salt runs a lightweight file server written in zeromq to deliver files to +# minions. This file server is built into the master daemon and does not +# require a dedicated port. + +# The file server works on environments passed to the master, each environment +# can have multiple root directories, the subdirectories in the multiple file +# roots cannot match, otherwise the downloaded files will not be able to be +# reliably ensured. A base environment is required to house the top file. +# Example: +# file_roots: +# base: +# - /usr/pkg/etc/salt/states/ +# dev: +# - /usr/pkg/etc/salt/states/dev/services +# - /usr/pkg/etc/salt/states/dev/states +# prod: +# - /usr/pkg/etc/salt/states/prod/services +# - /usr/pkg/etc/salt/states/prod/states +# +file_roots: + base: + - /usr/pkg/etc/salt/states + - /home/shares/repo +# + +# When using multiple environments, each with their own top file, the +# default behaviour is an unordered merge. To prevent top files from +# being merged together and instead to only use the top file from the +# requested environment, set this value to 'same'. +#top_file_merging_strategy: merge + +# To specify the order in which environments are merged, set the ordering +# in the env_order option. Given a conflict, the last matching value will +# win. +#env_order: ['base', 'dev', 'prod'] + +# If top_file_merging_strategy is set to 'same' and an environment does not +# contain a top file, the top file in the environment specified by default_top +# will be used instead. +#default_top: base + +# The hash_type is the hash to use when discovering the hash of a file on +# the master server. The default is md5, but sha1, sha224, sha256, sha384 +# and sha512 are also supported. +# +# Prior to changing this value, the master should be stopped and all Salt +# caches should be cleared. +#hash_type: md5 + +# The buffer size in the file server can be adjusted here: +#file_buffer_size: 1048576 + +# A regular expression (or a list of expressions) that will be matched +# against the file path before syncing the modules and states to the minions. +# This includes files affected by the file.recurse state. +# For example, if you manage your custom modules and states in subversion +# and don't want all the '.svn' folders and content synced to your minions, +# you could set this to '/\.svn($|/)'. By default nothing is ignored. +#file_ignore_regex: +# - '/\.svn($|/)' +# - '/\.git($|/)' + +# A file glob (or list of file globs) that will be matched against the file +# path before syncing the modules and states to the minions. This is similar +# to file_ignore_regex above, but works on globs instead of regex. By default +# nothing is ignored. +# file_ignore_glob: +# - '*.pyc' +# - '*/somefolder/*.bak' +# - '*.swp' + +# File Server Backend +# +# Salt supports a modular fileserver backend system, this system allows +# the salt master to link directly to third party systems to gather and +# manage the files available to minions. Multiple backends can be +# configured and will be searched for the requested file in the order in which +# they are defined here. The default setting only enables the standard backend +# "roots" which uses the "file_roots" option. +#fileserver_backend: +# - roots +# +# To use multiple backends list them in the order they are searched: +#fileserver_backend: +# - git +# - roots +# +# Uncomment the line below if you do not want the file_server to follow +# symlinks when walking the filesystem tree. This is set to True +# by default. Currently this only applies to the default roots +# fileserver_backend. +#fileserver_followsymlinks: False +# +# Uncomment the line below if you do not want symlinks to be +# treated as the files they are pointing to. By default this is set to +# False. By uncommenting the line below, any detected symlink while listing +# files on the Master will not be returned to the Minion. +#fileserver_ignoresymlinks: True +# +# By default, the Salt fileserver recurses fully into all defined environments +# to attempt to find files. To limit this behavior so that the fileserver only +# traverses directories with SLS files and special Salt directories like _modules, +# enable the option below. This might be useful for installations where a file root +# has a very large number of files and performance is impacted. Default is False. +# fileserver_limit_traversal: False +# +# The fileserver can fire events off every time the fileserver is updated, +# these are disabled by default, but can be easily turned on by setting this +# flag to True +#fileserver_events: False + +# Git File Server Backend Configuration +# +# Gitfs can be provided by one of two python modules: GitPython or pygit2. If +# using pygit2, both libgit2 and git must also be installed. +#gitfs_provider: gitpython +# +# When using the git fileserver backend at least one git remote needs to be +# defined. The user running the salt master will need read access to the repo. +# +# The repos will be searched in order to find the file requested by a client +# and the first repo to have the file will return it. +# When using the git backend branches and tags are translated into salt +# environments. +# Note: file:// repos will be treated as a remote, so refs you want used must +# exist in that repo as *local* refs. +#gitfs_remotes: +# - git://github.com/saltstack/salt-states.git +# - file:///var/git/saltmaster +# +# The gitfs_ssl_verify option specifies whether to ignore ssl certificate +# errors when contacting the gitfs backend. You might want to set this to +# false if you're using a git backend that uses a self-signed certificate but +# keep in mind that setting this flag to anything other than the default of True +# is a security concern, you may want to try using the ssh transport. +#gitfs_ssl_verify: True +# +# The gitfs_root option gives the ability to serve files from a subdirectory +# within the repository. The path is defined relative to the root of the +# repository and defaults to the repository root. +#gitfs_root: somefolder/otherfolder +# +# +##### Pillar settings ##### +########################################## +# Salt Pillars allow for the building of global data that can be made selectively +# available to different minions based on minion grain filtering. The Salt +# Pillar is laid out in the same fashion as the file server, with environments, +# a top file and sls files. However, pillar data does not need to be in the +# highstate format, and is generally just key/value pairs. +pillar_roots: + base: + - /usr/pkg/etc/salt/pillar +# +#ext_pillar: +# - hiera: /etc/hiera.yaml +# - cmd_yaml: cat /usr/pkg/etc/salt/yaml + +#ext_pillar: +# - mysql: +# fromdb: +# query: 'SELECT +# FROM pillar +# WHERE minion_pattern LIKE %s' +# depth: 5 +# as_list: True +# with_lists: [1,3] + +#_pillar_first option allows for external pillar sources to populate +# before file system pillar. This allows for targeting file system pillar from +# ext_pillar. +#ext_pillar_first: False + +# The pillar_gitfs_ssl_verify option specifies whether to ignore ssl certificate +# errors when contacting the pillar gitfs backend. You might want to set this to +# false if you're using a git backend that uses a self-signed certificate but +# keep in mind that setting this flag to anything other than the default of True +# is a security concern, you may want to try using the ssh transport. +#pillar_gitfs_ssl_verify: True + +# The pillar_opts option adds the master configuration file data to a dict in +# the pillar called "master". This is used to set simple configurations in the +# master config file that can then be used on minions. +#pillar_opts: False + +# The pillar_safe_render_error option prevents the master from passing pillar +# render errors to the minion. This is set on by default because the error could +# contain templating data which would give that minion information it shouldn't +# have, like a password! When set true the error message will only show: +# Rendering SLS 'my.sls' failed. Please see master log for details. +#pillar_safe_render_error: True + +# The pillar_source_merging_strategy option allows you to configure merging strategy +# between different sources. It accepts four values: recurse, aggregate, overwrite, +# or smart. Recurse will merge recursively mapping of data. Aggregate instructs +# aggregation of elements between sources that use the #!yamlex renderer. Overwrite +# will verwrite elements according the order in which they are processed. This is +# behavior of the 2014.1 branch and earlier. Smart guesses the best strategy based +# on the "renderer" setting and is the default value. +#pillar_source_merging_strategy: smart + +# Recursively merge lists by aggregating them instead of replacing them. +#pillar_merge_lists: False + + +##### Syndic settings ##### +########################################## +# The Salt syndic is used to pass commands through a master from a higher +# master. Using the syndic is simple. If this is a master that will have +# syndic servers(s) below it, then set the "order_masters" setting to True. +# +# If this is a master that will be running a syndic daemon for passthrough, then +# the "syndic_master" setting needs to be set to the location of the master server +# to receive commands from. + +# Set the order_masters setting to True if this master will command lower +# masters' syndic interfaces. +#order_masters: False + +# If this master will be running a salt syndic daemon, syndic_master tells +# this master where to receive commands from. +#syndic_master: masterofmaster + +# This is the 'ret_port' of the MasterOfMaster: +#syndic_master_port: 4506 + +# PID file of the syndic daemon: +#syndic_pidfile: /var/run/salt-syndic.pid + +# LOG file of the syndic daemon: +#syndic_log_file: syndic.log + + +##### Peer Publish settings ##### +########################################## +# Salt minions can send commands to other minions, but only if the minion is +# allowed to. By default "Peer Publication" is disabled, and when enabled it +# is enabled for specific minions and specific commands. This allows secure +# compartmentalization of commands based on individual minions. + +# The configuration uses regular expressions to match minions and then a list +# of regular expressions to match functions. The following will allow the +# minion authenticated as foo.example.com to execute functions from the test +# and pkg modules. +#peer: +# foo.example.com: +# - test.* +# - pkg.* +# +# This will allow all minions to execute all commands: +#peer: +# .*: +# - .* +# +# This is not recommended, since it would allow anyone who gets root on any +# single minion to instantly have root on all of the minions! + +# Minions can also be allowed to execute runners from the salt master. +# Since executing a runner from the minion could be considered a security risk, +# it needs to be enabled. This setting functions just like the peer setting +# except that it opens up runners instead of module functions. +# +# All peer runner support is turned off by default and must be enabled before +# using. This will enable all peer runners for all minions: +#peer_run: +# .*: +# - .* +# +# To enable just the manage.up runner for the minion foo.example.com: +#peer_run: +# foo.example.com: +# - manage.up +# +# +##### Mine settings ##### +##################################### +# Restrict mine.get access from minions. By default any minion has a full access +# to get all mine data from master cache. In acl definion below, only pcre matches +# are allowed. +# mine_get: +# .*: +# - .* +# +# The example below enables minion foo.example.com to get 'network.interfaces' mine +# data only, minions web* to get all network.* and disk.* mine data and all other +# minions won't get any mine data. +# mine_get: +# foo.example.com: +# - network.interfaces +# web.*: +# - network.* +# - disk.* + + +##### Logging settings ##### +########################################## +# The location of the master log file +# The master log can be sent to a regular file, local path name, or network +# location. Remote logging works best when configured to use rsyslogd(8) (e.g.: +# ``file:///dev/log``), with rsyslogd(8) configured for network logging. The URI +# format is: ://:/ +log_file: /var/log/salt/master +#log_file: file:///dev/log +#log_file: udp://loghost:10514 + +#log_file: /var/log/salt/master +#key_logfile: /var/log/salt/key + +# The level of messages to send to the console. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# +# The following log levels are considered INSECURE and may log sensitive data: +# ['garbage', 'trace', 'debug'] +# +#log_level: warning +#log_level: debug + +# The level of messages to send to the log file. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# If using 'log_granular_levels' this must be set to the highest desired level. +#log_level_logfile: warning + +# The date and time format used in log messages. Allowed date/time formating +# can be seen here: http://docs.python.org/library/time.html#time.strftime +#log_datefmt: '%H:%M:%S' +#log_datefmt_logfile: '%Y-%m-%d %H:%M:%S' + +# The format of the console logging messages. Allowed formatting options can +# be seen here: http://docs.python.org/library/logging.html#logrecord-attributes +# +# Console log colors are specified by these additional formatters: +# +# %(colorlevel)s +# %(colorname)s +# %(colorprocess)s +# %(colormsg)s +# +# Since it is desirable to include the surrounding brackets, '[' and ']', in +# the coloring of the messages, these color formatters also include padding as +# well. Color LogRecord attributes are only available for console logging. +# +#log_fmt_console: '%(colorlevel)s %(colormsg)s' +#log_fmt_console: '[%(levelname)-8s] %(message)s' +# +#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s' + +# This can be used to control logging levels more specificically. This +# example sets the main salt library at the 'warning' level, but sets +# 'salt.modules' to log at the 'debug' level: +# log_granular_levels: +# 'salt': 'warning' +# 'salt.modules': 'debug' +# +#log_granular_levels: {} + + +##### Node Groups ###### +########################################## +# Node groups allow for logical groupings of minion nodes. A group consists of a group +# name and a compound target. +#nodegroups: +# group1: 'L@foo.domain.com,bar.domain.com,baz.domain.com and bl*.domain.com' +# group2: 'G@os:Debian and foo.domain.com' + + +##### Range Cluster settings ##### +########################################## +# The range server (and optional port) that serves your cluster information +# https://github.com/ytoolshed/range/wiki/%22yamlfile%22-module-file-spec +# +#range_server: range:80 + + +##### Windows Software Repo settings ##### +########################################### +# Location of the repo on the master: +#winrepo_dir_ng: '/usr/pkg/etc/salt/states/win/repo-ng' +# +# List of git repositories to include with the local repo: +#winrepo_remotes_ng: +# - 'https://github.com/saltstack/salt-winrepo-ng.git' + + +##### Windows Software Repo settings - Pre 2015.8 ##### +######################################################## +# Legacy repo settings for pre-2015.8 Windows minions. +# +# Location of the repo on the master: +#winrepo_dir: '/usr/pkg/etc/salt/states/win/repo' +# +# Location of the master's repo cache file: +#winrepo_mastercachefile: '/usr/pkg/etc/salt/states/win/repo/winrepo.p' +# +# List of git repositories to include with the local repo: +#winrepo_remotes: +# - 'https://github.com/saltstack/salt-winrepo.git' + + +##### Returner settings ###### +############################################ +# Which returner(s) will be used for minion's result: +#return: mysql +#return: smtp +return: mysql,smtp + +mysql.host: '127.0.0.1' +mysql.user: 'salt' +mysql.pass: 'pass' +mysql.db: 'salt' +mysql.port: 3306 + +###### Miscellaneous settings ###### +############################################ +# Default match type for filtering events tags: startswith, endswith, find, regex, fnmatch +#event_match_type: startswith + +smtp.from: salt@example.com +smtp.to: salt@example.com,bob@example.com +smtp.host: localhost +smtp.port: 25 diff --git a/config/minion b/config/minion new file mode 100755 index 0000000..9bc3f15 --- /dev/null +++ b/config/minion @@ -0,0 +1,10 @@ +## Managed by PaulBSD Salt +master: salt.paulbsd.com +hash_type: sha256 +state_verbose: True +tcp_keepalive: True +tcp_keepalive_idle: 300 +random_reauth_delay: 60 +recon_default: 1000 +recon_max: 10000 +recon_randomize: True diff --git a/config/minion.sample b/config/minion.sample new file mode 100644 index 0000000..f6e0dcb --- /dev/null +++ b/config/minion.sample @@ -0,0 +1,781 @@ +##### Primary configuration settings ##### +########################################## +# This configuration file is used to manage the behavior of the Salt Minion. +# With the exception of the location of the Salt Master Server, values that are +# commented out but have an empty line after the comment are defaults that need +# not be set in the config. If there is no blank line after the comment, the +# value is presented as an example and is not the default. + +# Per default the minion will automatically include all config files +# from minion.d/*.conf (minion.d is a directory in the same directory +# as the main minion config file). +#default_include: minion.d/*.conf + +# Set the location of the salt master server. If the master server cannot be +# resolved, then the minion will fail to start. +#master: salt + +# Set http proxy information for the minion when doing requests +#proxy_host: +#proxy_port: +#proxy_username: +#proxy_password: + +# If multiple masters are specified in the 'master' setting, the default behavior +# is to always try to connect to them in the order they are listed. If random_master is +# set to True, the order will be randomized instead. This can be helpful in distributing +# the load of many minions executing salt-call requests, for example, from a cron job. +# If only one master is listed, this setting is ignored and a warning will be logged. +# NOTE: If master_type is set to failover, use master_shuffle instead. +#random_master: False + +# Use if master_type is set to failover. +#master_shuffle: False + +# Minions can connect to multiple masters simultaneously (all masters +# are "hot"), or can be configured to failover if a master becomes +# unavailable. Multiple hot masters are configured by setting this +# value to "str". Failover masters can be requested by setting +# to "failover". MAKE SURE TO SET master_alive_interval if you are +# using failover. +# master_type: str + +# Poll interval in seconds for checking if the master is still there. Only +# respected if master_type above is "failover". To disable the interval entirely, +# set the value to -1. (This may be necessary on machines which have high numbers +# of TCP connections, such as load balancers.) +# master_alive_interval: 30 + +# If the minion is in multi-master mode and the master_type configuration option +# is set to "failover", this setting can be set to "True" to force the minion +# to fail back to the first master in the list if the first master is back online. +#master_failback: False + +# If the minion is in multi-master mode, the "master_type" configuration is set to +# "failover", and the "master_failback" option is enabled, the master failback +# interval can be set to ping the top master with this interval, in seconds. +#master_failback_interval: 0 + +# Set whether the minion should connect to the master via IPv6: +#ipv6: False + +# Set the number of seconds to wait before attempting to resolve +# the master hostname if name resolution fails. Defaults to 30 seconds. +# Set to zero if the minion should shutdown and not retry. +# retry_dns: 30 + +# Set the port used by the master reply and authentication server. +#master_port: 4506 + +# The user to run salt. +#user: root + +# The user to run salt remote execution commands as via sudo. If this option is +# enabled then sudo will be used to change the active user executing the remote +# command. If enabled the user will need to be allowed access via the sudoers +# file for the user that the salt minion is configured to run as. The most +# common option would be to use the root user. If this option is set the user +# option should also be set to a non-root user. If migrating from a root minion +# to a non root minion the minion cache should be cleared and the minion pki +# directory will need to be changed to the ownership of the new user. +#sudo_user: root + +# Specify the location of the daemon process ID file. +#pidfile: /var/run/salt-minion.pid + +# The root directory prepended to these options: pki_dir, cachedir, log_file, +# sock_dir, pidfile. +#root_dir: / + +# The path to the minion's configuration file. +#conf_file: /usr/pkg/etc/salt/minion + +# The directory to store the pki information in +#pki_dir: /usr/pkg/etc/salt/pki/minion + +# Explicitly declare the id for this minion to use, if left commented the id +# will be the hostname as returned by the python call: socket.getfqdn() +# Since salt uses detached ids it is possible to run multiple minions on the +# same machine but with different ids, this can be useful for salt compute +# clusters. +#id: + +# Cache the minion id to a file when the minion's id is not statically defined +# in the minion config. Defaults to "True". This setting prevents potential +# problems when automatic minion id resolution changes, which can cause the +# minion to lose connection with the master. To turn off minion id caching, +# set this config to ``False``. +#minion_id_caching: True + +# Append a domain to a hostname in the event that it does not exist. This is +# useful for systems where socket.getfqdn() does not actually result in a +# FQDN (for instance, Solaris). +#append_domain: + +# Custom static grains for this minion can be specified here and used in SLS +# files just like all other grains. This example sets 4 custom grains, with +# the 'roles' grain having two values that can be matched against. +#grains: +# roles: +# - webserver +# - memcache +# deployment: datacenter4 +# cabinet: 13 +# cab_u: 14-15 +# +# Where cache data goes. +# This data may contain sensitive data and should be protected accordingly. +#cachedir: /var/cache/salt/minion + +# Append minion_id to these directories. Helps with +# multiple proxies and minions running on the same machine. +# Allowed elements in the list: pki_dir, cachedir, extension_modules +# Normally not needed unless running several proxies and/or minions on the same machine +# Defaults to ['cachedir'] for proxies, [] (empty list) for regular minions +#append_minionid_config_dirs: + +# Verify and set permissions on configuration directories at startup. +#verify_env: True + +# The minion can locally cache the return data from jobs sent to it, this +# can be a good way to keep track of jobs the minion has executed +# (on the minion side). By default this feature is disabled, to enable, set +# cache_jobs to True. +#cache_jobs: False + +# Set the directory used to hold unix sockets. +#sock_dir: /var/run/salt/minion + +# Set the default outputter used by the salt-call command. The default is +# "nested". +#output: nested +# +# By default output is colored. To disable colored output, set the color value +# to False. +#color: True + +# Do not strip off the colored output from nested results and state outputs +# (true by default). +# strip_colors: False + +# Backup files that are replaced by file.managed and file.recurse under +# 'cachedir'/file_backups relative to their original location and appended +# with a timestamp. The only valid setting is "minion". Disabled by default. +# +# Alternatively this can be specified for each file in state files: +# /etc/ssh/sshd_config: +# file.managed: +# - source: salt://ssh/sshd_config +# - backup: minion +# +#backup_mode: minion + +# When waiting for a master to accept the minion's public key, salt will +# continuously attempt to reconnect until successful. This is the time, in +# seconds, between those reconnection attempts. +#acceptance_wait_time: 10 + +# If this is nonzero, the time between reconnection attempts will increase by +# acceptance_wait_time seconds per iteration, up to this maximum. If this is +# set to zero, the time between reconnection attempts will stay constant. +#acceptance_wait_time_max: 0 + +# If the master rejects the minion's public key, retry instead of exiting. +# Rejected keys will be handled the same as waiting on acceptance. +#rejected_retry: False + +# When the master key changes, the minion will try to re-auth itself to receive +# the new master key. In larger environments this can cause a SYN flood on the +# master because all minions try to re-auth immediately. To prevent this and +# have a minion wait for a random amount of time, use this optional parameter. +# The wait-time will be a random number of seconds between 0 and the defined value. +random_reauth_delay: 60 + +# When waiting for a master to accept the minion's public key, salt will +# continuously attempt to reconnect until successful. This is the timeout value, +# in seconds, for each individual attempt. After this timeout expires, the minion +# will wait for acceptance_wait_time seconds before trying again. Unless your master +# is under unusually heavy load, this should be left at the default. +#auth_timeout: 60 + +# Number of consecutive SaltReqTimeoutError that are acceptable when trying to +# authenticate. +#auth_tries: 7 + +# The number of attempts to connect to a master before giving up. +# Set this to -1 for unlimited attempts. This allows for a master to have +# downtime and the minion to reconnect to it later when it comes back up. +# In 'failover' mode, it is the number of attempts for each set of masters. +# In this mode, it will cycle through the list of masters for each attempt. +# +# This is different than auth_tries because auth_tries attempts to +# retry auth attempts with a single master. auth_tries is under the +# assumption that you can connect to the master but not gain +# authorization from it. master_tries will still cycle through all +# the masters in a given try, so it is appropriate if you expect +# occasional downtime from the master(s). +#master_tries: 1 + +# If authentication fails due to SaltReqTimeoutError during a ping_interval, +# cause sub minion process to restart. +#auth_safemode: False + +# Ping Master to ensure connection is alive (minutes). +#ping_interval: 0 + +# To auto recover minions if master changes IP address (DDNS) +# auth_tries: 10 +# auth_safemode: False +# ping_interval: 90 +# +# Minions won't know master is missing until a ping fails. After the ping fail, +# the minion will attempt authentication and likely fails out and cause a restart. +# When the minion restarts it will resolve the masters IP and attempt to reconnect. + +# If you don't have any problems with syn-floods, don't bother with the +# three recon_* settings described below, just leave the defaults! +# +# The ZeroMQ pull-socket that binds to the masters publishing interface tries +# to reconnect immediately, if the socket is disconnected (for example if +# the master processes are restarted). In large setups this will have all +# minions reconnect immediately which might flood the master (the ZeroMQ-default +# is usually a 100ms delay). To prevent this, these three recon_* settings +# can be used. +# recon_default: the interval in milliseconds that the socket should wait before +# trying to reconnect to the master (1000ms = 1 second) +# +# recon_max: the maximum time a socket should wait. each interval the time to wait +# is calculated by doubling the previous time. if recon_max is reached, +# it starts again at recon_default. Short example: +# +# reconnect 1: the socket will wait 'recon_default' milliseconds +# reconnect 2: 'recon_default' * 2 +# reconnect 3: ('recon_default' * 2) * 2 +# reconnect 4: value from previous interval * 2 +# reconnect 5: value from previous interval * 2 +# reconnect x: if value >= recon_max, it starts again with recon_default +# +# recon_randomize: generate a random wait time on minion start. The wait time will +# be a random value between recon_default and recon_default + +# recon_max. Having all minions reconnect with the same recon_default +# and recon_max value kind of defeats the purpose of being able to +# change these settings. If all minions have the same values and your +# setup is quite large (several thousand minions), they will still +# flood the master. The desired behavior is to have timeframe within +# all minions try to reconnect. +# +# Example on how to use these settings. The goal: have all minions reconnect within a +# 60 second timeframe on a disconnect. +recon_default: 1000 +recon_max: 59000 +recon_randomize: True +# +# Each minion will have a randomized reconnect value between 'recon_default' +# and 'recon_default + recon_max', which in this example means between 1000ms +# 60000ms (or between 1 and 60 seconds). The generated random-value will be +# doubled after each attempt to reconnect. Lets say the generated random +# value is 11 seconds (or 11000ms). +# reconnect 1: wait 11 seconds +# reconnect 2: wait 22 seconds +# reconnect 3: wait 33 seconds +# reconnect 4: wait 44 seconds +# reconnect 5: wait 55 seconds +# reconnect 6: wait time is bigger than 60 seconds (recon_default + recon_max) +# reconnect 7: wait 11 seconds +# reconnect 8: wait 22 seconds +# reconnect 9: wait 33 seconds +# reconnect x: etc. +# +# In a setup with ~6000 thousand hosts these settings would average the reconnects +# to about 100 per second and all hosts would be reconnected within 60 seconds. +# recon_default: 100 +# recon_max: 5000 +# recon_randomize: False +# +# +# The loop_interval sets how long in seconds the minion will wait between +# evaluating the scheduler and running cleanup tasks. This defaults to a +# sane 60 seconds, but if the minion scheduler needs to be evaluated more +# often lower this value +#loop_interval: 60 + +# The grains can be merged, instead of overridden, using this option. +# This allows custom grains to defined different subvalues of a dictionary +# grain. By default this feature is disabled, to enable set grains_deep_merge +# to ``True``. +#grains_deep_merge: False + +# The grains_refresh_every setting allows for a minion to periodically check +# its grains to see if they have changed and, if so, to inform the master +# of the new grains. This operation is moderately expensive, therefore +# care should be taken not to set this value too low. +# +# Note: This value is expressed in __minutes__! +# +# A value of 10 minutes is a reasonable default. +# +# If the value is set to zero, this check is disabled. +#grains_refresh_every: 1 + +# Cache grains on the minion. Default is False. +#grains_cache: False + +# Cache rendered pillar data on the minion. Default is False. +# This may cause 'cachedir'/pillar to contain sensitive data that should be +# protected accordingly. +#minion_pillar_cache: False + +# Grains cache expiration, in seconds. If the cache file is older than this +# number of seconds then the grains cache will be dumped and fully re-populated +# with fresh data. Defaults to 5 minutes. Will have no effect if 'grains_cache' +# is not enabled. +# grains_cache_expiration: 300 + +# Determines whether or not the salt minion should run scheduled mine updates. +# Defaults to "True". Set to "False" to disable the scheduled mine updates +# (this essentially just does not add the mine update function to the minion's +# scheduler). +#mine_enabled: True + +# Determines whether or not scheduled mine updates should be accompanied by a job +# return for the job cache. Defaults to "False". Set to "True" to include job +# returns in the job cache for mine updates. +#mine_return_job: False + +# Example functions that can be run via the mine facility +# NO mine functions are established by default. +# Note these can be defined in the minion's pillar as well. +#mine_functions: +# test.ping: [] +# network.ip_addrs: +# interface: eth0 +# cidr: '10.0.0.0/8' + +# Windows platforms lack posix IPC and must rely on slower TCP based inter- +# process communications. Set ipc_mode to 'tcp' on such systems +#ipc_mode: ipc + +# Overwrite the default tcp ports used by the minion when in tcp mode +#tcp_pub_port: 4510 +#tcp_pull_port: 4511 + +# Passing very large events can cause the minion to consume large amounts of +# memory. This value tunes the maximum size of a message allowed onto the +# minion event bus. The value is expressed in bytes. +#max_event_size: 1048576 + +# To detect failed master(s) and fire events on connect/disconnect, set +# master_alive_interval to the number of seconds to poll the masters for +# connection events. +# +#master_alive_interval: 30 + +# The minion can include configuration from other files. To enable this, +# pass a list of paths to this option. The paths can be either relative or +# absolute; if relative, they are considered to be relative to the directory +# the main minion configuration file lives in (this file). Paths can make use +# of shell-style globbing. If no files are matched by a path passed to this +# option then the minion will log a warning message. +# +# Include a config file from some other path: +# include: /usr/pkg/etc/salt/extra_config +# +# Include config from several files and directories: +#include: +# - /usr/pkg/etc/salt/extra_config +# - /etc/roles/webserver + +# The syndic minion can verify that it is talking to the correct master via the +# key fingerprint of the higher-level master with the "syndic_finger" config. +#syndic_finger: '' +# +# +# +##### Minion module management ##### +########################################## +# Disable specific modules. This allows the admin to limit the level of +# access the master has to the minion. +#disable_modules: [cmd,test] +#disable_returners: [] + +# This is the reverse of disable_modules. The default, like disable_modules, is the empty list, +# but if this option is set to *anything* then *only* those modules will load. +# Note that this is a very large hammer and it can be quite difficult to keep the minion working +# the way you think it should since Salt uses many modules internally itself. At a bare minimum +# you need the following enabled or else the minion won't start. +#whitelist_modules: +# - cmdmod +# - test +# - config + +# Modules can be loaded from arbitrary paths. This enables the easy deployment +# of third party modules. Modules for returners and minions can be loaded. +# Specify a list of extra directories to search for minion modules and +# returners. These paths must be fully qualified! +#module_dirs: [] +#returner_dirs: [] +#states_dirs: [] +#render_dirs: [] +#utils_dirs: [] +# +# A module provider can be statically overwritten or extended for the minion +# via the providers option, in this case the default module will be +# overwritten by the specified module. In this example the pkg module will +# be provided by the yumpkg5 module instead of the system default. +#providers: +# pkg: yumpkg5 +# +# Enable Cython modules searching and loading. (Default: False) +#cython_enable: False +# +# Specify a max size (in bytes) for modules on import. This feature is currently +# only supported on *nix operating systems and requires psutil. +# modules_max_memory: -1 + + +##### State Management Settings ##### +########################################### +# The state management system executes all of the state templates on the minion +# to enable more granular control of system state management. The type of +# template and serialization used for state management needs to be configured +# on the minion, the default renderer is yaml_jinja. This is a yaml file +# rendered from a jinja template, the available options are: +# yaml_jinja +# yaml_mako +# yaml_wempy +# json_jinja +# json_mako +# json_wempy +# +#renderer: yaml_jinja +# +# The failhard option tells the minions to stop immediately after the first +# failure detected in the state execution. Defaults to False. +#failhard: False +# +# Reload the modules prior to a highstate run. +#autoload_dynamic_modules: True +# +# clean_dynamic_modules keeps the dynamic modules on the minion in sync with +# the dynamic modules on the master, this means that if a dynamic module is +# not on the master it will be deleted from the minion. By default, this is +# enabled and can be disabled by changing this value to False. +#clean_dynamic_modules: True +# +# Normally, the minion is not isolated to any single environment on the master +# when running states, but the environment can be isolated on the minion side +# by statically setting it. Remember that the recommended way to manage +# environments is to isolate via the top file. +#environment: None +# +# Isolates the pillar environment on the minion side. This functions the same +# as the environment setting, but for pillar instead of states. +#pillarenv: None +# +# If using the local file directory, then the state top file name needs to be +# defined, by default this is top.sls. +#state_top: top.sls +# +# Run states when the minion daemon starts. To enable, set startup_states to: +# 'highstate' -- Execute state.highstate +# 'sls' -- Read in the sls_list option and execute the named sls files +# 'top' -- Read top_file option and execute based on that file on the Master +#startup_states: '' +# +# List of states to run when the minion starts up if startup_states is 'sls': +#sls_list: +# - edit.vim +# - hyper +# +# Top file to execute if startup_states is 'top': +#top_file: '' + +# Automatically aggregate all states that have support for mod_aggregate by +# setting to True. Or pass a list of state module names to automatically +# aggregate just those types. +# +# state_aggregate: +# - pkg +# +#state_aggregate: False + +##### File Directory Settings ##### +########################################## +# The Salt Minion can redirect all file server operations to a local directory, +# this allows for the same state tree that is on the master to be used if +# copied completely onto the minion. This is a literal copy of the settings on +# the master but used to reference a local directory on the minion. + +# Set the file client. The client defaults to looking on the master server for +# files, but can be directed to look at the local file directory setting +# defined below by setting it to "local". Setting a local file_client runs the +# minion in masterless mode. +#file_client: remote + +# The file directory works on environments passed to the minion, each environment +# can have multiple root directories, the subdirectories in the multiple file +# roots cannot match, otherwise the downloaded files will not be able to be +# reliably ensured. A base environment is required to house the top file. +# Example: +# file_roots: +# base: +# - /usr/pkg/etc/salt/states/ +# dev: +# - /usr/pkg/etc/salt/states/dev/services +# - /usr/pkg/etc/salt/states/dev/states +# prod: +# - /usr/pkg/etc/salt/states/prod/services +# - /usr/pkg/etc/salt/states/prod/states +# +#file_roots: +# base: +# - /usr/pkg/etc/salt/states + +# Uncomment the line below if you do not want the file_server to follow +# symlinks when walking the filesystem tree. This is set to True +# by default. Currently this only applies to the default roots +# fileserver_backend. +#fileserver_followsymlinks: False +# +# Uncomment the line below if you do not want symlinks to be +# treated as the files they are pointing to. By default this is set to +# False. By uncommenting the line below, any detected symlink while listing +# files on the Master will not be returned to the Minion. +#fileserver_ignoresymlinks: True +# +# By default, the Salt fileserver recurses fully into all defined environments +# to attempt to find files. To limit this behavior so that the fileserver only +# traverses directories with SLS files and special Salt directories like _modules, +# enable the option below. This might be useful for installations where a file root +# has a very large number of files and performance is negatively impacted. Default +# is False. +#fileserver_limit_traversal: False + +# The hash_type is the hash to use when discovering the hash of a file in +# the local fileserver. The default is sha256, sha224, sha384 and sha512 are also supported. +# +# WARNING: While md5 and sha1 are also supported, do not use it due to the high chance +# of possible collisions and thus security breach. +# +# Warning: Prior to changing this value, the minion should be stopped and all +# Salt caches should be cleared. +#hash_type: sha256 + +# The Salt pillar is searched for locally if file_client is set to local. If +# this is the case, and pillar data is defined, then the pillar_roots need to +# also be configured on the minion: +#pillar_roots: +# base: +# - /usr/pkg/etc/salt/pillar + +# Set a hard-limit on the size of the files that can be pushed to the master. +# It will be interpreted as megabytes. Default: 100 +#file_recv_max_size: 100 +# +# +###### Security settings ##### +########################################### +# Enable "open mode", this mode still maintains encryption, but turns off +# authentication, this is only intended for highly secure environments or for +# the situation where your keys end up in a bad state. If you run in open mode +# you do so at your own risk! +#open_mode: False + +# Enable permissive access to the salt keys. This allows you to run the +# master or minion as root, but have a non-root group be given access to +# your pki_dir. To make the access explicit, root must belong to the group +# you've given access to. This is potentially quite insecure. +#permissive_pki_access: False + +# The state_verbose and state_output settings can be used to change the way +# state system data is printed to the display. By default all data is printed. +# The state_verbose setting can be set to True or False, when set to False +# all data that has a result of True and no changes will be suppressed. +#state_verbose: True + +# The state_output setting changes if the output is the full multi line +# output for each changed state if set to 'full', but if set to 'terse' +# the output will be shortened to a single line. +#state_output: full + +# The state_output_diff setting changes whether or not the output from +# successful states is returned. Useful when even the terse output of these +# states is cluttering the logs. Set it to True to ignore them. +#state_output_diff: False + +# The state_output_profile setting changes whether profile information +# will be shown for each state run. +#state_output_profile: True + +# Fingerprint of the master public key to validate the identity of your Salt master +# before the initial key exchange. The master fingerprint can be found by running +# "salt-key -F master" on the Salt master. +#master_finger: '' + + +###### Thread settings ##### +########################################### +# Disable multiprocessing support, by default when a minion receives a +# publication a new process is spawned and the command is executed therein. +#multiprocessing: True + + +##### Logging settings ##### +########################################## +# The location of the minion log file +# The minion log can be sent to a regular file, local path name, or network +# location. Remote logging works best when configured to use rsyslogd(8) (e.g.: +# ``file:///dev/log``), with rsyslogd(8) configured for network logging. The URI +# format is: ://:/ +#log_file: /var/log/salt/minion +#log_file: file:///dev/log +#log_file: udp://loghost:10514 +# +#log_file: /var/log/salt/minion +#key_logfile: /var/log/salt/key + +# The level of messages to send to the console. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# +# The following log levels are considered INSECURE and may log sensitive data: +# ['garbage', 'trace', 'debug'] +# +# Default: 'warning' +log_level: debug + +# The level of messages to send to the log file. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# If using 'log_granular_levels' this must be set to the highest desired level. +# Default: 'warning' +#log_level_logfile: + +# The date and time format used in log messages. Allowed date/time formatting +# can be seen here: http://docs.python.org/library/time.html#time.strftime +#log_datefmt: '%H:%M:%S' +#log_datefmt_logfile: '%Y-%m-%d %H:%M:%S' + +# The format of the console logging messages. Allowed formatting options can +# be seen here: http://docs.python.org/library/logging.html#logrecord-attributes +# +# Console log colors are specified by these additional formatters: +# +# %(colorlevel)s +# %(colorname)s +# %(colorprocess)s +# %(colormsg)s +# +# Since it is desirable to include the surrounding brackets, '[' and ']', in +# the coloring of the messages, these color formatters also include padding as +# well. Color LogRecord attributes are only available for console logging. +# +#log_fmt_console: '%(colorlevel)s %(colormsg)s' +#log_fmt_console: '[%(levelname)-8s] %(message)s' +# +#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s' + +# This can be used to control logging levels more specificically. This +# example sets the main salt library at the 'warning' level, but sets +# 'salt.modules' to log at the 'debug' level: +# log_granular_levels: +# 'salt': 'warning' +# 'salt.modules': 'debug' +# +#log_granular_levels: {} + +# To diagnose issues with minions disconnecting or missing returns, ZeroMQ +# supports the use of monitor sockets to log connection events. This +# feature requires ZeroMQ 4.0 or higher. +# +# To enable ZeroMQ monitor sockets, set 'zmq_monitor' to 'True' and log at a +# debug level or higher. +# +# A sample log event is as follows: +# +# [DEBUG ] ZeroMQ event: {'endpoint': 'tcp://127.0.0.1:4505', 'event': 512, +# 'value': 27, 'description': 'EVENT_DISCONNECTED'} +# +# All events logged will include the string 'ZeroMQ event'. A connection event +# should be logged as the minion starts up and initially connects to the +# master. If not, check for debug log level and that the necessary version of +# ZeroMQ is installed. +# +#zmq_monitor: False + +###### Module configuration ##### +########################################### +# Salt allows for modules to be passed arbitrary configuration data, any data +# passed here in valid yaml format will be passed on to the salt minion modules +# for use. It is STRONGLY recommended that a naming convention be used in which +# the module name is followed by a . and then the value. Also, all top level +# data must be applied via the yaml dict construct, some examples: +# +# You can specify that all modules should run in test mode: +#test: True +# +# A simple value for the test module: +#test.foo: foo +# +# A list for the test module: +#test.bar: [baz,quo] +# +# A dict for the test module: +#test.baz: {spam: sausage, cheese: bread} +# +# +###### Update settings ###### +########################################### +# Using the features in Esky, a salt minion can both run as a frozen app and +# be updated on the fly. These options control how the update process +# (saltutil.update()) behaves. +# +# The url for finding and downloading updates. Disabled by default. +#update_url: False +# +# The list of services to restart after a successful update. Empty by default. +#update_restart_services: [] + + +###### Keepalive settings ###### +############################################ +# ZeroMQ now includes support for configuring SO_KEEPALIVE if supported by +# the OS. If connections between the minion and the master pass through +# a state tracking device such as a firewall or VPN gateway, there is +# the risk that it could tear down the connection the master and minion +# without informing either party that their connection has been taken away. +# Enabling TCP Keepalives prevents this from happening. + +# Overall state of TCP Keepalives, enable (1 or True), disable (0 or False) +# or leave to the OS defaults (-1), on Linux, typically disabled. Default True, enabled. +#tcp_keepalive: True + +# How long before the first keepalive should be sent in seconds. Default 300 +# to send the first keepalive after 5 minutes, OS default (-1) is typically 7200 seconds +# on Linux see /proc/sys/net/ipv4/tcp_keepalive_time. +#tcp_keepalive_idle: 300 + +# How many lost probes are needed to consider the connection lost. Default -1 +# to use OS defaults, typically 9 on Linux, see /proc/sys/net/ipv4/tcp_keepalive_probes. +#tcp_keepalive_cnt: -1 + +# How often, in seconds, to send keepalives after the first one. Default -1 to +# use OS defaults, typically 75 seconds on Linux, see +# /proc/sys/net/ipv4/tcp_keepalive_intvl. +#tcp_keepalive_intvl: -1 + + +###### Windows Software settings ###### +############################################ +# Location of the repository cache file on the master: +#win_repo_cachefile: 'salt://win/repo/winrepo.p' + + +###### Returner settings ###### +############################################ +# Which returner(s) will be used for minion's result: +#return: mysql + + +###### Miscellaneous settings ###### +############################################ +# Default match type for filtering events tags: startswith, endswith, find, regex, fnmatch +#event_match_type: startswith diff --git a/config/roster b/config/roster new file mode 100644 index 0000000..b422c39 --- /dev/null +++ b/config/roster @@ -0,0 +1,17 @@ +scw01-ams: + host: scw01-ams.paulbsd.com + user: paul + sudo: True + +scw02-ams: + host: scw02-ams.paulbsd.com + user: paul + +lxc01: + host: lxc01.paulbsd.com + user: paul + sudo: True + +nuc: + host: nuc.paulbsd.com + user: paul diff --git a/config/roster.sample b/config/roster.sample new file mode 100644 index 0000000..acdf276 --- /dev/null +++ b/config/roster.sample @@ -0,0 +1,11 @@ +scw01-ams.paulbsd.com: + host: scw01-ams.paulbsd.com + user: paul + sudo: True + priv: /home/paul/.ssh/id_rsa + +aws01-par.paulbsd.com: + host: aws01-par.paulbsd.com + user: ubuntu + sudo: True + priv: /home/paul/.ssh/id_rsa diff --git a/scripts/encrypt_password b/scripts/encrypt_password new file mode 100755 index 0000000..0a8cb8b --- /dev/null +++ b/scripts/encrypt_password @@ -0,0 +1,10 @@ +#!/bin/bash + +key_id=salt + +if [[ $1 != "" ]] +then + echo -n $1 | gpg --armor --batch --homedir="/etc/salt/gpgkeys" --trust-model always --encrypt -r "${key_id}" +else + echo "Please specify a password" +fi diff --git a/scripts/salt-test.sh b/scripts/salt-test.sh new file mode 100755 index 0000000..01b525e --- /dev/null +++ b/scripts/salt-test.sh @@ -0,0 +1,2 @@ +#!/bin/bash +salt-call -l debug --local --file-root=./states state.sls $1 diff --git a/states/_modules/custom.py b/states/_modules/custom.py new file mode 100755 index 0000000..db9af76 --- /dev/null +++ b/states/_modules/custom.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 + +import salt.exceptions + +def current_state(name): + ret = dict() + + ret['name'] = name + ret['foo'] = 'foo' + + return ret + +def change_state(name, foo): + ret = dict() + + ret['name'] = name + ret['foo'] = foo + + return ret \ No newline at end of file diff --git a/states/_modules/dkron.py b/states/_modules/dkron.py new file mode 100644 index 0000000..4999a78 --- /dev/null +++ b/states/_modules/dkron.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 + +import requests +import json + +def get_jobs(url="http://localhost:8080", verify=False): + fullurl = f"{url}/v1/jobs" + ret = dict() + try: + req = requests.request("get", fullurl, verify=verify) + except (requests.exceptions.RequestException) as exc: + raise f"Exception {exc} occured" + ret = req.json() + if req.status_code == 200: + return ret + return None + +def set_jobs(url="http://localhost:8080", verify=False, job={}): + fullurl = f"{url}/v1/jobs" + ret = dict() + try: + req = requests.request("post", fullurl, verify=verify, json=job) + except (requests.exceptions.RequestException) as exc: + raise f"Exception {exc} occured" + ret = req.json() + if req.status_code == 201: + return ret + return None \ No newline at end of file diff --git a/states/_modules/ovhapi.py b/states/_modules/ovhapi.py new file mode 100644 index 0000000..a929e94 --- /dev/null +++ b/states/_modules/ovhapi.py @@ -0,0 +1,153 @@ +#!/usr/bin/python3 + +from __future__ import absolute_import, unicode_literals, print_function + +import re +import salt +import requests +import ovh + +from salt.exceptions import CommandExecutionError, ArgumentValueError +from ovh.exceptions import ResourceNotFoundError, APIError + + +def __virtual__(): + return True + +def _config(): + config = __salt__['config.get']('ovh') + if not config: + raise CommandExecutionError( + 'OVH execution module configuration could not be found' + ) + return config + + +def _auth(): + cfg = _config() + client = ovh.Client( + endpoint=cfg['endpoint'], + application_key=cfg['application_key'], + application_secret=cfg['application_secret'], + consumer_key=cfg['consumer_key'], + ) + return client + + +def domain_get_zone(zone=""): + ''' + Get DNS zone extraction + + zone + Zone name to fetch + ''' + + if zone == "": + raise ArgumentValueError("Zone is not defined") + client = _auth() + results = client.get(f'/domain/zone/{zone}/export') + return results + + +def domain_get_record(zone="", fieldType="", subDomain=""): + ''' + Records of the zone + + zone + Zone name to fetch + fieldType + Filter the value of fieldType property (like) + subDomain + Filter the value of subDomain property (like) + ''' + + if zone == "": + raise ArgumentValueError("Zone is not defined") + results = [] + client = _auth() + try: + records = client.get(f'/domain/zone/{zone}/record', + fieldType=fieldType, + subDomain=subDomain) + except APIError: + return "Query failed in OVH API" + for record in records: + try: + req = client.get(f'/domain/zone/{zone}/record/{record}') + results.append(req) + except APIError: + return "Query failed in OVH API" + return results + + +def domain_post_record(zone="", fieldType="", subDomain="", target="", ttl=0): + ''' + Create a new DNS record + + zone + The internal name of your zone + fieldType + Filter the value of fieldType property (like) + subDomain + Filter the value of subDomain property (like) + target + Resource record target + ttl + Resource record ttl + ''' + + if zone == "": + raise ArgumentValueError("Zone is not defined") + client = _auth() + req = client.post(f'/domain/zone/{zone}/record', + fieldType=fieldType, + subDomain=subDomain, + target=target, + ttl=ttl) + return req + + +def domain_delete_record(zone="", fieldType="", subDomain=""): + ''' + Delete a DNS record (Don't forget to refresh the zone) + + zone + The internal name of your zone + fieldType + Filter the value of fieldType property (like) + subDomain + Filter the value of subDomain property (like) + ''' + + if zone == "": + raise ArgumentValueError("Zone is not defined") + results = [] + client = _auth() + try: + records = client.get(f'/domain/zone/{zone}/record', + fieldType=fieldType, + subDomain=subDomain) + except APIError: + return "Query failed in OVH API" + for record in records: + try: + req = client.delete(f'/domain/zone/{zone}/record/{record}') + results.append(req) + except ResourceNotFoundError: + return "Resource not found in OVH API" + return results + + +def domain_refresh_zone(zone=""): + ''' + Apply zone modification on DNS servers + + zone + The internal name of your zone + ''' + + if zone == "": + raise ArgumentValueError("Zone is not defined") + client = _auth() + req = client.post(f'/domain/zone/{zone}/refresh') + return req \ No newline at end of file diff --git a/states/_modules/syncthing.py b/states/_modules/syncthing.py new file mode 100644 index 0000000..cae0b23 --- /dev/null +++ b/states/_modules/syncthing.py @@ -0,0 +1,59 @@ +#!/usr/bin/python3 + +import requests +import json +import salt.exceptions +import xml.etree.ElementTree as ET + +def get_apikey(configfile="/root/.config/syncthing/config.xml"): + try: + tree = ET.parse(configfile) + root = tree.getroot() + apikey = root.find("./gui/apikey").text + return apikey + except (FileNotFoundError,ET.ParseError,AttributeError) as e: + raise "Exception {0} occured".format(e) + return "" + +def get_config(url, verify, apikey): + fullurl = "{0}/rest/system/config".format(url) + ret = dict() + try: + req = requests.request("get", fullurl, verify=verify, headers={"X-API-Key": apikey}) + except (requests.exceptions.RequestException) as exc: + raise "Exception {0} occured".format(exc) + ret = req.json() + if req.status_code == 200: + return ret + return None + +def set_config(url, verify, apikey, config): + fullurl = "{0}/rest/system/config".format(url) + try: + req = requests.request("post", fullurl, verify=verify, headers={"X-API-Key": apikey}, json=config) + except (requests.exceptions.RequestException) as exc: + raise "Exception {0} occured".format(exc) + if req.status_code == 200: + return True + return None + +def insync(url, verify, apikey): + fullurl = "{0}/rest/system/config/insync".format(url) + try: + req = requests.request("get", fullurl, verify=verify, headers={"X-API-Key": apikey}) + except (requests.exceptions.RequestException) as exc: + raise "Exception {0} occured".format(exc) + ret = req.json() + if req.status_code == 200: + return ret + return None + +def restart(url, verify, apikey): + fullurl = "{0}/rest/system/restart".format(url) + try: + req = requests.post(fullurl, verify=verify, headers={"X-API-Key": apikey}) + except (requests.exceptions.RequestException) as exc: + raise "Exception {0} occured".format(exc) + if req.status_code == 200: + return {} + return None \ No newline at end of file diff --git a/states/_runners/process_minion_data.py b/states/_runners/process_minion_data.py new file mode 100755 index 0000000..8503982 --- /dev/null +++ b/states/_runners/process_minion_data.py @@ -0,0 +1,51 @@ +#!/usr/pkg/bin/python2 +#-*- coding: utf-8 -*- + +import os +import subprocess +import salt.modules.smtp +import json + +''' +For use with salt reactor +''' + +def email_errors(fromaddr, toaddrs, subject, data_str, smtp_server): + data = eval(data_str) + error = False + changes = False + + try: + if type(data['return']) is dict: + for state, result in data['return'].iteritems(): + if not result['result']: + error = True + break + if result['changes']: + changes = True + break + else: + if not data['success']: + error = True + except KeyError as e: + exit() + + #if error or changes: + if error: + js = subprocess.check_output(["salt-run", "--out=json", "jobs.lookup_jid", data['jid']]) + body = "JobId is %s\n" % (data['jid']) + outdata = json.loads(js) + nodename = outdata.keys()[0] + for i in outdata[nodename]: + if not outdata[nodename][i]["result"]: + name = outdata[nodename][i]["name"] + comment = outdata[nodename][i]["comment"].rstrip('\n') + data = "%s- %s / %s\n" % (body, name, comment) + salt.modules.smtp.send_msg(recipient=toaddrs, message=data, subject=subject, sender=fromaddr, server=smtp_server, use_ssl=False) + return True + +def email_auth(fromaddr, toaddrs, subject, data_str, smtp_server): + data = eval(data_str) + salt.modules.smtp.send_msg(recipient=toaddrs, message=data, subject=subject, sender=fromaddr, server=smtp_server, use_ssl=False) + + return True \ No newline at end of file diff --git a/states/_states/custom.py b/states/_states/custom.py new file mode 100755 index 0000000..caa0e1a --- /dev/null +++ b/states/_states/custom.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 + +import salt.exceptions + +def current_state(name): + ret = dict() + + ret['name'] = 'blabla' + + return ret + +def enforce_custom_thing(name, foo, bar=True): + ''' + Enforce the state of a custom thing + + This state module does a custom thing. It calls out to the execution module + ``y_custom_module`` in order to check the current system and perform any + needed changes. + + name + The thing to do something to + foo + A required argument + bar : True + An argument with a default value + ''' + ret = { + 'name': name, + 'changes': {}, + 'result': False, + 'comment': '', + } + + # Start with basic error-checking. Do all the passed parameters make sense + # and agree with each-other? + if bar == True and foo.startswith('Foo'): + raise salt.exceptions.SaltInvocationError( + 'Argument "foo" cannot start with "Foo" if argument "bar" is True.') + + # Check the current state of the system. Does anything need to change? + current_state = __salt__['custom.current_state'](name) + + if current_state == foo: + ret['result'] = True + ret['comment'] = 'System already in the correct state %s' % name + return ret + + # The state of the system does need to be changed. Check if we're running + # in ``test=true`` mode. + if __opts__['test'] == True: + ret['comment'] = 'The state of "{0}" will be changed.'.format(name) + ret['changes'] = { + 'old': current_state, + 'new': 'Description, diff, whatever of the new state', + } + + # Return ``None`` when running with ``test=true``. + ret['result'] = None + + return ret + + # Finally, make the actual change and return the result. + new_state = __salt__['custom.change_state'](name, foo) + + ret['comment'] = 'The state of "{0}" was changed!'.format(name) + + ret['changes'] = { + 'old': current_state, + 'new': new_state, + } + + ret['result'] = True + + return ret \ No newline at end of file diff --git a/states/_states/dkron.py b/states/_states/dkron.py new file mode 100644 index 0000000..6cdaf91 --- /dev/null +++ b/states/_states/dkron.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +from __future__ import absolute_import, print_function, unicode_literals +import salt.utils.dictupdate +import salt.utils.dictdiffer + +def jobs(name, url="http://localhost:8080", verify=False, jobs=[]): + ret = {'name': name, + 'changes': {}, + 'result': True, + 'comment': 'Config is up to date'} + + #dk_jobs = [] + #dk_jobs = __salt__['dkron.get_jobs'](url, verify) + + for job in jobs: + res = __salt__['dkron.set_jobs'](url, verify, job) + if res is not None: + ret['changes'][job['name']] = res + else: + ret['result'] = False + ret['comment'] = "Error occured" + + return ret diff --git a/states/_states/ovhapi.py b/states/_states/ovhapi.py new file mode 100644 index 0000000..faf2698 --- /dev/null +++ b/states/_states/ovhapi.py @@ -0,0 +1,65 @@ +#!/usr/bin/python3 + +from __future__ import absolute_import, print_function, unicode_literals + +import salt.utils.dictupdate +import salt.utils.dictdiffer + +def _error(ret, err_msg): + ret['result'] = False + ret['comment'] = err_msg + return ret + +def _str_split(string): + delim = "\n" + return [e + delim for e in string.split(delim) if e] + +def domain_record_present(name, + zone=None, + recordname=None, + recordtype=None, + target=None, + ttl=0): + ret = { + 'name': name, + 'changes': {}, + 'result': True, + 'comment': 'Config is up to date' + } + + + if name is None: + return _error(ret, 'Must provide name to ovhapi.domain_record_present') + if zone is None: + return _error(ret, 'Must provide dns zone to ovhapi.domain_record_present') + if recordname is None: + return _error(ret, 'Must provide record name to ovhapi.domain_record_present') + if recordtype is None: + return _error(ret, 'Must provide record type to ovhapi.domain_record_present') + if target is None: + return _error(ret, 'Must provide target to ovhapi.domain_record_present') + + # check if record exists + if len(__salt__['ovhapi.domain_get_record'](zone=zone, + fieldType=recordtype, + subDomain=recordname)): + ret['comment'] = f"Record on {zone} named {recordname} with type {recordtype} already exists" + return ret + + cur_zone_state = __salt__['ovhapi.domain_get_zone'](zone=zone) + + res = __salt__['ovhapi.domain_post_record']( + zone=zone, + subDomain=recordname, + fieldType=recordtype, + target=target, + ttl=ttl) + + new_zone_state = __salt__['ovhapi.domain_get_zone'](zone=zone) + + ret['changes'] = { + "diff": salt.utils.stringutils.get_diff(_str_split(cur_zone_state), _str_split(new_zone_state)) + } + ret['comment'] = f'Result is {res}' + + return ret \ No newline at end of file diff --git a/states/_states/syncthing.py b/states/_states/syncthing.py new file mode 100644 index 0000000..197510a --- /dev/null +++ b/states/_states/syncthing.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 + +from __future__ import absolute_import, print_function, unicode_literals +import salt.utils.dictupdate +import salt.utils.dictdiffer + +def config(name, verify, url, cfg): + ret = {'name': name, + 'changes': {}, + 'result': True, + 'comment': 'config is up to date'} + + cfg = dict(cfg) + + apikey = __salt__['syncthing.get_apikey']() + st_cfg = __salt__['syncthing.get_config'](url, verify, apikey) + + cfg['gui']['apiKey'] = apikey + + res_cfg = salt.utils.dictupdate.update(st_cfg, cfg, recursive_update=True, merge_lists=False) + + ## Return to managed to set result + __salt__['syncthing.set_config'](url, verify, apikey, res_cfg) + + ret['changes'] = salt.utils.dictdiffer.deep_diff(st_cfg, res_cfg) + + return ret \ No newline at end of file diff --git a/states/acme/defaults.yaml b/states/acme/defaults.yaml new file mode 100644 index 0000000..f66d5ee --- /dev/null +++ b/states/acme/defaults.yaml @@ -0,0 +1,20 @@ +--- +acme: + enabled: true + directories: + - "/etc/acme/dh/" + - "/etc/acme/keys/" + - "/etc/acme/certs/" + dh: + path: "/etc/acme/dh/dh.pem" + keysize: 1024 + keysize: 4096 + domain: "*.example.com" + dns: "dns_provider" + keyfile: "/etc/acme/keys/private.key" + fullchainfile: "/etc/acme/certs/certificate.crt" + provider: + api: + application_key: "test" + application_secret: "test" + consumer_key: "test" \ No newline at end of file diff --git a/states/acme/init.sls b/states/acme/init.sls new file mode 100644 index 0000000..72d1d77 --- /dev/null +++ b/states/acme/init.sls @@ -0,0 +1,50 @@ +# vim:syntax=yaml +--- +{%- from "acme/map.jinja" import acme with context %} +acme-install: + cmd.run: + - name: "curl https://get.acme.sh | sh" + - runas: root + - cwd: /root + - env: + - HOME: /root + - unless: /bin/bash -c "[[ -f /root/.acme.sh/acme.sh ]]" + +acme-upgrade: + cmd.run: + - name: /root/.acme.sh/acme.sh --upgrade + - runas: root + - cwd: /root + - env: + - HOME: /root + - require: + - cmd: acme-install + +{%- for dir in acme.directories %} +acme-directories-{{ dir }}: + file.directory: + - name: {{ dir }} + - makedirs: True +{%- endfor %} + +acme-dh-params: + cmd.run: + - name: openssl dhparam -out {{ acme.dh.path }} {{ acme.dh.keysize }} + - creates: {{ acme.dh.path }} + +acme-certs: + cmd.run: + - name: /root/.acme.sh/acme.sh --issue {%- for dom in acme.domains %} -d '{{ dom }}' {% endfor -%} --dns dns_ovh --cert-file '' --key-file '{{ acme.keyfile }}' --fullchain-file '{{ acme.fullchainfile }}' -k {{ acme.keysize }} + - env: + - OVH_AK: '{{ acme.provider.api.application_key }}' + - OVH_AS: '{{ acme.provider.api.application_secret }}' + - OVH_CK: '{{ acme.provider.api.consumer_key }}' + - HOME: '/root' + - success_retcodes: + - 0 + - 1 + - 2 + - runas: root + - cwd: /root + - require: + - cmd: acme-install \ No newline at end of file diff --git a/states/acme/map.jinja b/states/acme/map.jinja new file mode 100644 index 0000000..e63dc4b --- /dev/null +++ b/states/acme/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "acme/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='acme') -%} + +{%- set acme = salt['pillar.get']('acme', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/androidstudio/defaults.yaml b/states/androidstudio/defaults.yaml new file mode 100644 index 0000000..9f678cd --- /dev/null +++ b/states/androidstudio/defaults.yaml @@ -0,0 +1,5 @@ +--- +androidstudio: + enabled: true + install_dir: /usr/local/apps + config: \ No newline at end of file diff --git a/states/androidstudio/init.sls b/states/androidstudio/init.sls new file mode 100644 index 0000000..cf8e776 --- /dev/null +++ b/states/androidstudio/init.sls @@ -0,0 +1,24 @@ +--- +# https://developer.android.com/studio/archive.html +{%- from "androidstudio/map.jinja" import androidstudio with context %} + +{%- if salt['file.grep'](androidstudio.install_dir + '/android-studio/build.txt', androidstudio.version_regex)['retcode'] == 1 or not salt['file.file_exists'](androidstudio.install_dir + '/android-studio/build.txt') %} +androidstudio-archive-extract: + archive.extracted: + - name: {{ androidstudio.install_dir }} + - source: {{ androidstudio.mirror }}/{{ androidstudio.version }}/android-studio-ide-{{ androidstudio.tag }}-linux.tar.gz + - skip_verify: True + - archive_format: tar + - overwrite: True + +androidstudio-shortcut: + file.managed: + - name: /usr/share/applications/jetbrains-studio.desktop + - source: salt://androidstudio/jetbrains-studio.desktop.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - onchanges: + - androidstudio-archive-extract +{%- endif %} \ No newline at end of file diff --git a/states/androidstudio/jetbrains-studio.desktop.j2 b/states/androidstudio/jetbrains-studio.desktop.j2 new file mode 100644 index 0000000..94f0193 --- /dev/null +++ b/states/androidstudio/jetbrains-studio.desktop.j2 @@ -0,0 +1,12 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "androidstudio/map.jinja" import androidstudio with context %} +[Desktop Entry] +Version=1.0 +Type=Application +Name=Android Studio +Icon={{ androidstudio.install_dir }}/android-studio/bin/studio.png +Exec="{{ androidstudio.install_dir }}/android-studio/bin/studio.sh" %f +Comment=Develop with pleasure on Android! +Categories=Development;IDE; +Terminal=false +StartupWMClass=jetbrains-studio \ No newline at end of file diff --git a/states/androidstudio/map.jinja b/states/androidstudio/map.jinja new file mode 100644 index 0000000..eb4d55f --- /dev/null +++ b/states/androidstudio/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "androidstudio/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='androidstudio') -%} + +{%- set androidstudio = salt['pillar.get']('androidstudio', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/apparmor/defaults.yaml b/states/apparmor/defaults.yaml new file mode 100644 index 0000000..b45cafb --- /dev/null +++ b/states/apparmor/defaults.yaml @@ -0,0 +1,4 @@ +--- +apparmor: + enabled: true + config: \ No newline at end of file diff --git a/states/apparmor/init.sls b/states/apparmor/init.sls new file mode 100644 index 0000000..11d7d66 --- /dev/null +++ b/states/apparmor/init.sls @@ -0,0 +1,21 @@ +--- +{%- from "apparmor/map.jinja" import apparmor with context %} +{%- if apparmor.enabled is defined and apparmor.enabled %} +{%- for apparmor_config in ['usr.bin.skype','opt.kingsoft','usr.bin.spotify','opt.sublime_text_3.sublime_text'] %} +apparmor-{{ apparmor_config }}: + file.managed: + - name: "/etc/apparmor.d/{{ apparmor_config }}" + - source: "salt://apparmor/{{ apparmor_config }}.j2" + - user: root + - group: root + - mode: 0644 + - template: jinja + - watch_in: + - service: apparmor-reload +{%- endfor %} + +apparmor-reload: + service.running: + - name: apparmor + - enable: true +{%- endif %} \ No newline at end of file diff --git a/states/apparmor/map.jinja b/states/apparmor/map.jinja new file mode 100644 index 0000000..9776a15 --- /dev/null +++ b/states/apparmor/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "apparmor/defaults.yaml" as default_settings %} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='apparmor') %} + +{%- set apparmor = salt['pillar.get']('apparmor', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/apparmor/opt.kingsoft.j2 b/states/apparmor/opt.kingsoft.j2 new file mode 100644 index 0000000..fd28818 --- /dev/null +++ b/states/apparmor/opt.kingsoft.j2 @@ -0,0 +1,27 @@ +#include +/opt/kingsoft/** { + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /opt/kingsoft/** rwmkl, + owner @{HOME}/.kingsoft/** rw, + owner @{HOME}/.config/Kingsoft/ rwmkl, + owner @{HOME}/.config/Kingsoft/** rwmkl, + owner @{HOME}/ r, + owner @{HOME}/Documents/ rw, + owner @{HOME}/Documents/** rw, + + deny network inet, +} \ No newline at end of file diff --git a/states/apparmor/opt.sublime_text_3.sublime_text.j2 b/states/apparmor/opt.sublime_text_3.sublime_text.j2 new file mode 100644 index 0000000..2cccf00 --- /dev/null +++ b/states/apparmor/opt.sublime_text_3.sublime_text.j2 @@ -0,0 +1,37 @@ +#include + +/opt/sublime_text_3/sublime_text { + #include + #include + #include + #include + #include + #include + #include + #include + + /usr/share/mate/applications/** r, + /usr/bin/caja rwix, + /usr/share/glib-*/schemas/** r, + /dev/null r, + + /{dev,run}/{,shm/}** rwmkl, + /opt/sublime_text_3/ rwixmkl, + /opt/sublime_text_3/** rwixmkl, + + owner @{HOME}/.config/sublime-text-3/ rwmkl, + owner @{HOME}/.config/sublime-text-3/** rwmkl, + owner @{HOME}/ rwmkl, + owner @{HOME}/** rwmkl, + + deny network inet, + deny network inet6, + deny network raw, +} + +/opt/sublime_text_3/plugin_host { + #include + deny network inet, + deny network inet6, + deny network raw, +} \ No newline at end of file diff --git a/states/apparmor/usr.bin.skype.j2 b/states/apparmor/usr.bin.skype.j2 new file mode 100644 index 0000000..0fb3c34 --- /dev/null +++ b/states/apparmor/usr.bin.skype.j2 @@ -0,0 +1,77 @@ +#include +/usr/bin/skype { + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + @{PROC}/sys/kernel/{ostype,osrelease} r, + @{PROC}/@{pid}/net/arp r, + owner @{PROC}/@{pid}/auxv r, + owner @{PROC}/@{pid}/cmdline r, + owner @{PROC}/@{pid}/fd/ r, + owner @{PROC}/@{pid}/task/ r, + owner @{PROC}/@{pid}/task/[0-9]*/stat r, + + /sys/devices/**/power_supply/**/online r, + /sys/devices/system/cpu/ r, + /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_{cur_freq,max_freq} r, + + /dev/ r, + owner /{dev,run}/shm/pulse-shm* m, + /dev/snd/* m, + /dev/video* mrw, + + /var/cache/libx11/compose/* r, + + # should this be in a separate KDE abstraction? + owner @{HOME}/.kde{,4}/share/config/kioslaverc r, + + /usr/bin/skype mr, + /etc/xdg/sni-qt.conf rk, + /etc/xdg/Trolltech.conf rk, + /usr/share/skype/** kr, + /usr/share/skype/**/*.qm mr, + /usr/share/skype/sounds/*.wav kr, + /usr/lib{,32}/pango/** mr, + /usr/lib{,32}/libv4l/* mr, + + # For opening links in the browser (still requires explicit access to execute + # the browser) + /usr/bin/xdg-open ixr, + + owner @{HOME}/.Skype/ rw, + owner @{HOME}/.Skype/** krw, + owner @{HOME}/.config/ r, + owner @{HOME}/.config/*/ r, + owner @{HOME}/.config/Skype/Skype.conf rw, + owner @{HOME}/.config/Trolltech.conf kr, + + # Skype traverses the .mozilla directory and needs access to prefs.js + deny owner @{HOME}/.mozilla/ r, + deny owner @{HOME}/.mozilla/**/ r, + deny owner @{HOME}/.mozilla/*/*/prefs.js r, + + # Skype also looks around in these directories + /{,usr/,usr/local/}lib{,32}/ r, + + # Recent skype builds have an executable stack, so it tries to mmap certain + # files. Let's deny them for now. + deny /etc/passwd m, + deny /etc/group m, + deny /usr/share/fonts/** m, + + # Silence a few non-needed writes + deny /var/cache/fontconfig/ w, + deny owner @{HOME}/.fontconfig/ w, + deny owner @{HOME}/.fontconfig/*.cache-*.TMP* w, +} \ No newline at end of file diff --git a/states/apparmor/usr.bin.spotify.j2 b/states/apparmor/usr.bin.spotify.j2 new file mode 100644 index 0000000..0893217 --- /dev/null +++ b/states/apparmor/usr.bin.spotify.j2 @@ -0,0 +1,24 @@ +#include + +/usr/bin/spotify { + #include + #include + #include + #include + + /etc/xdg/Trolltech.conf rk, + /etc/xdg/sni-qt.conf r, + + /usr/share/icons/*.theme k, + /usr/share/spotify/theme/**.{png,ico} r, + /usr/share/spotify/theme/**.{splang,xml} r, + + owner @{PROC}/[0-9]*/task/ r, + + owner @{HOME}/.cache/spotify/ rw, + owner @{HOME}/.cache/spotify/** rw, + owner @{HOME}/.config/Trolltech.conf rw, + owner @{HOME}/.config/spotify/ w, + + owner @{HOME}/Music/** r, +} \ No newline at end of file diff --git a/states/appimagekit/init.sls b/states/appimagekit/init.sls new file mode 100644 index 0000000..6f2f912 --- /dev/null +++ b/states/appimagekit/init.sls @@ -0,0 +1,8 @@ +--- +appimage-config-dir: + file.directory: + - name: /usr/share/appimagekit/ + +appimage-config-file: + file.absent: + - name: /usr/share/appimagekit/no_desktopintegration \ No newline at end of file diff --git a/states/apt/10proxy.j2 b/states/apt/10proxy.j2 new file mode 100644 index 0000000..00f6880 --- /dev/null +++ b/states/apt/10proxy.j2 @@ -0,0 +1,3 @@ +{%- if salt['pillar.get']('apt-proxy:name') != "None" %} +Acquire::http { proxy "http://{{salt['pillar.get']('apt-proxy:name')}}:{{ salt['pillar.get']('apt-proxy:port')}}" } +{%- endif %} \ No newline at end of file diff --git a/states/apt/init.sls b/states/apt/init.sls new file mode 100644 index 0000000..0eefb0e --- /dev/null +++ b/states/apt/init.sls @@ -0,0 +1,28 @@ +--- +apt-unauth: + file.append: + - name: /etc/apt/apt.conf.d/99-unauth + - text: 'APT::Get::AllowUnauthenticated "true";' + +apt-aptitude-install: + pkg.latest: + - pkgs: + - aptitude + - apt-transport-https +# +# apt-upgrade: +# pkg.uptodate: +# - refresh: True +# +#apt-cacher-ng-proxy: +# file.managed: +# - name: /etc/apt/apt.conf.d/10proxy +# - source: salt://apt/10proxy.j2 +# - user: root +# - group: root +# - mode: 0644 +# - template: jinja +# +# apt-cacher-ng-proxy-delete: +# file.absent: +# - name: /etc/apt/apt.conf.d/10proxy \ No newline at end of file diff --git a/states/arduino/arduino-arduinoide.desktop.j2 b/states/arduino/arduino-arduinoide.desktop.j2 new file mode 100644 index 0000000..ccc64ea --- /dev/null +++ b/states/arduino/arduino-arduinoide.desktop.j2 @@ -0,0 +1,14 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "arduino/map.jinja" import arduino with context %} +[Desktop Entry] +Type=Application +Name=Arduino IDE +GenericName=Arduino IDE +Comment=Open-source electronics prototyping platform +Exec={{ arduino.install_dir }}/arduino +Icon=arduino-arduinoide +Terminal=false +Categories=Development;IDE;Electronics; +MimeType=text/x-arduino +Keywords=embedded electronics;electronics;avr;microcontroller; +StartupWMClass=processing-app-Base \ No newline at end of file diff --git a/states/arduino/defaults.yaml b/states/arduino/defaults.yaml new file mode 100644 index 0000000..de9672d --- /dev/null +++ b/states/arduino/defaults.yaml @@ -0,0 +1,4 @@ +--- +arduino: + mirror: "https://downloads.arduino.cc" + install_dir: "/usr/local/apps" \ No newline at end of file diff --git a/states/arduino/init.sls b/states/arduino/init.sls new file mode 100644 index 0000000..d55d903 --- /dev/null +++ b/states/arduino/init.sls @@ -0,0 +1,40 @@ +--- +{%- from "arduino/map.jinja" import arduino with context %} +{%- if not salt['file.directory_exists']( arduino.install_dir + '/arduino-' + arduino.version ) %} +arduino-archive-extract: + archive.extracted: + - name: {{ arduino.install_dir }} + - source: {{ arduino.mirror }}/arduino-{{ arduino.version }}-{{ arduino.arch }}.tar.xz + - skip_verify: True + - archive_format: tar + - keep: True + - if_missing: {{ arduino.install_dir }}/arduino-{{ arduino.version }} + +arduino-symlink: + file.symlink: + - name: {{ arduino.install_dir }}/arduino + - target: {{ arduino.install_dir }}/arduino-{{ arduino.version }} + - force: True + - onchanges: + - arduino-archive-extract + +arduino-bin-symlink: + file.symlink: + - name: /usr/bin/arduino + - target: {{ arduino.install_dir }}/arduino-{{ arduino.version }}/arduino + - force: True + - onchanges: + - arduino-archive-extract + +arduino-shortcut: + file.managed: + - name: /usr/share/applications/arduino-arduinoide.desktop + - source: salt://arduino/arduino-arduinoide.desktop.j2 + - template: jinja + - user: root + - group: root + - mode: 644 + - onchanges: + - arduino-archive-extract + - arduino-symlink +{%- endif %} \ No newline at end of file diff --git a/states/arduino/map.jinja b/states/arduino/map.jinja new file mode 100644 index 0000000..a3f6437 --- /dev/null +++ b/states/arduino/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "arduino/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='arduino') -%} + +{%- set arduino = salt['pillar.get']('arduino', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/bareos/bareos-fd.conf.j2 b/states/bareos/bareos-fd.conf.j2 new file mode 100644 index 0000000..8bbd8ef --- /dev/null +++ b/states/bareos/bareos-fd.conf.j2 @@ -0,0 +1,20 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +FileDaemon { + Name = {{ grains.get('host') }} + Maximum Concurrent Jobs = {{ salt['pillar.get']('bareos:director:max_concurrent_jobs', default=10) }} + Compatible = {{ salt['pillar.get']('bareos:director:compatible', default='No') }} + Working Directory = {{ salt['pillar.get']('bareos:director:working_dir', default='/var/run') }} +} + +Director { + Name = {{ salt['pillar.get']('bareos:director:name', default='bareos-dir') }} + Address = {{ salt['pillar.get']('bareos:director:addr', default='localhost') }} + Password = "{{ salt['pillar.get']('bareos:director:password', default='password') }}" + Connection From Client To Director = {{ salt['pillar.get']('bareos:director:initiated', default='No') }} +} + +Messages { + Name = standard + director = {{ salt['pillar.get']('bareos:director:name',default='bareos-dir') }} = all, !skipped, !restored +} \ No newline at end of file diff --git a/states/bareos/bareos-fd.service.j2 b/states/bareos/bareos-fd.service.j2 new file mode 100644 index 0000000..d315640 --- /dev/null +++ b/states/bareos/bareos-fd.service.j2 @@ -0,0 +1,21 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +[Unit] +Description=Bareos File Daemon +Before=multi-user.target +Before=graphical.target +Before=shutdown.target +After=network-online.target +After=remote-fs.target +After=time-sync.target +After=systemd-journald-dev-log.socket +Wants=network-online.target +Conflicts=shutdown.target + +[Service] +Type=forking +KillMode=process +ExecStart=/usr/sbin/bareos-fd -c /etc/bareos/bareos-fd.conf +SuccessExitStatus=0 15 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/bareos/bareos-fd.sls b/states/bareos/bareos-fd.sls new file mode 100644 index 0000000..5ff04f1 --- /dev/null +++ b/states/bareos/bareos-fd.sls @@ -0,0 +1,59 @@ +--- +{%- if salt['grains.get']('kernel') == 'Linux' %} +#bareos-pkg: +# pkg.purged: +# - pkgs: +# - bareos-common +# - bareos-filedaemon +# - bareos-bconsole + +bareos-fd-bin: + file.managed: + - name: /usr/sbin/bareos-fd + - source: https://paulbsd-pub.s3.fr-par.scw.cloud/bareos/static-bareos-fd-{{ salt['grains.get']('osarch')|lower }} + - skip_verify: True + - user: root + - group: root + - mode: 0755 + +bareos-fd-service-file: + file.managed: + - name: /etc/systemd/system/bareos-fd.service + - source: salt://bareos/bareos-fd.service.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - watch_in: + - service: bareos-fd-service + - require: + - file: bareos-fd-bin + +bareos-fd-config-dir: + file.directory: + - name: /etc/bareos + - user: root + - group: root + - mode: 0755 + +bareos-fd-config: + file.managed: + - name: /etc/bareos/bareos-fd.conf + - source: salt://bareos/bareos-fd.conf.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - watch_in: + - service: bareos-fd-service + - require: + - file: bareos-fd-bin + - file: bareos-fd-config-dir + +bareos-fd-service: + service.running: + - name: bareos-fd + - enable: True + - require: + - file: bareos-fd-service-file +{%- endif %} \ No newline at end of file diff --git a/states/bareos/config.sls b/states/bareos/config.sls new file mode 100644 index 0000000..16f08db --- /dev/null +++ b/states/bareos/config.sls @@ -0,0 +1,21 @@ +--- +bareos-fd-config-dir: + file.directory: + - name: {{ bareos.config_dir }} + - user: root + - group: root + - mode: 0755 + +bareos-fd-config: + file.managed: + - name: {{ bareos.config_dir }}/bareos-fd.conf + - source: salt://bareos/bareos-fd.conf.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - watch_in: + - service: bareos-fd-service + - require: + - file: bareos-fd-bin + - file: bareos-fd-config-dir \ No newline at end of file diff --git a/states/bareos/defaults.yaml b/states/bareos/defaults.yaml new file mode 100644 index 0000000..8366fae --- /dev/null +++ b/states/bareos/defaults.yaml @@ -0,0 +1,8 @@ +--- +bareos: + enabled: true + config_dir: /etc/bareos + install_dir: /usr/local/bin + mirror: https://paulbsd-pub.s3.fr-par.scw.cloud/bareos + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/bareos/init.sls b/states/bareos/init.sls new file mode 100644 index 0000000..93e8737 --- /dev/null +++ b/states/bareos/init.sls @@ -0,0 +1,5 @@ +--- +{%- if salt['grains.get']('kernel') == 'Linux' %} +include: + - .install +{%- endif %} \ No newline at end of file diff --git a/states/bareos/install.sls b/states/bareos/install.sls new file mode 100644 index 0000000..4afb8a9 --- /dev/null +++ b/states/bareos/install.sls @@ -0,0 +1,17 @@ +--- +{%- from "bareos/map.jinja" import bareos with context %} +#bareos-pkg: +# pkg.purged: +# - pkgs: +# - bareos-common +# - bareos-filedaemon +# - bareos-bconsole + +bareos-fd-bin: + file.managed: + - name: /usr/sbin/bareos-fd + - source: {{ bareos.mirror }}/static-bareos-fd-{{ bareos.arch }} + - skip_verify: True + - user: root + - group: root + - mode: 0755 \ No newline at end of file diff --git a/states/bareos/kernelmap.yaml b/states/bareos/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/bareos/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/bareos/map.jinja b/states/bareos/map.jinja new file mode 100644 index 0000000..2203636 --- /dev/null +++ b/states/bareos/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "bareos/defaults.yaml" as default_settings -%} + +{%- import_yaml "bareos/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "bareos/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='bareos', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set bareos = salt['pillar.get']('bareos', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/bareos/osarchmap.yaml b/states/bareos/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/bareos/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/bareos/service.sls b/states/bareos/service.sls new file mode 100644 index 0000000..4ac5266 --- /dev/null +++ b/states/bareos/service.sls @@ -0,0 +1,20 @@ +--- +bareos-fd-service-file: + file.managed: + - name: /etc/systemd/system/bareos-fd.service + - source: salt://bareos/bareos-fd.service.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - watch_in: + - service: bareos-fd-service + - require: + - file: bareos-fd-bin + +bareos-fd-service: + service.running: + - name: bareos-fd + - enable: True + - require: + - file: bareos-fd-service-file \ No newline at end of file diff --git a/states/burp/burp.conf.j2 b/states/burp/burp.conf.j2 new file mode 100644 index 0000000..1b7c49d --- /dev/null +++ b/states/burp/burp.conf.j2 @@ -0,0 +1,4 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- for key, value in burp.config.items() %} +{{ key }} = {{ value }} +{%- endfor %} \ No newline at end of file diff --git a/states/burp/burp.conf.j2.sample b/states/burp/burp.conf.j2.sample new file mode 100644 index 0000000..76dba65 --- /dev/null +++ b/states/burp/burp.conf.j2.sample @@ -0,0 +1,131 @@ +# This is an example config file for the burp client. + +mode = client +port = 4971 +# A different port to use for restores - see the man page for more options. +#port_restore = 5971 +status_port = 4972 +server = {{ salt["pillar.get"]("burp:name") }} +password = {{ salt["pillar.get"]("burp:password") }} +cname = {{ grains.get('fqdn') }} + +# Choose the protocol to use. +# 0 to decide automatically, 1 to force protocol1 mode (file level granularity +# with a pseudo mirrored storage on the server and optional rsync). 2 forces +# protocol2 mode (inline deduplication with variable length blocks). +# protocol = 0 +pidfile = /var/run/burp.client.pid +syslog = 0 +stdout = 1 +progress_counter = 1 + +# Ratelimit throttles the send speed. Specified in Megabits per second (Mb/s). +# ratelimit = 1.5 +# Network timeout defaults to 7200 seconds (2 hours). +# network_timeout = 7200 +# The directory to which autoupgrade files will be downloaded. +# To never autoupgrade, leave it commented out. +# autoupgrade_dir=/etc/burp/autoupgrade/client +# OS path component for the autoupgrade directory on the server. +# autoupgrade_os=test_os +# Wait a random number of seconds between 0 and the given number before +# contacting the server on a timed backup. +# randomise = 1200 + +# Set server_can_restore to 0 if you do not want the server to be able to +# initiate a restore. +server_can_restore = 1 + +# Set server_can_override_includes to 0 if you do not want the server to be +# able to override the local include/exclude list. The default is 1. +# server_can_override_includes = 1 + +# Set an encryption password if you do not trust the server with your data. +# Note that this will mean that network deltas will not be possible. Each time +# a file changes, the whole file will be transferred on the next backup. +# encryption_password = My^$pAsswIrD%@ + +# More configuration files can be read, using syntax like the following +# (without the leading '# '). +# . path/to/more/conf + +# Run as different user/group. +# user=graham +# group=nogroup + +cross_filesystem=/home +cross_all_filesystems=0 + +# Uncomment the following lines to automatically generate a certificate signing +# request and send it to the server. +ca_burp_ca = /usr/sbin/burp_ca +ca_csr_dir = /etc/burp/CA-client + +# SSL certificate authority - same file on both server and client +ssl_cert_ca = /etc/burp/ssl_cert_ca.pem + +# Client SSL certificate +ssl_cert = /etc/burp/ssl_cert-client.pem + +# Client SSL key +ssl_key = /etc/burp/ssl_cert-client.key + +# Client SSL ciphers +#ssl_ciphers = + +# Client SSL compression. Default is zlib5. Set to zlib0 to turn it off. +#ssl_compression = zlib5 + +# SSL key password, for loading a certificate with encryption. +#ssl_key_password = password + +# Common name in the certificate that the server gives us +ssl_peer_cn = burpserver + +# Example syntax for pre/post scripts +#backup_script_pre=/path/to/a/script +#backup_script_post=/path/to/a/script +#restore_script_pre=/path/to/a/script +#restore_script_post=/path/to/a/script + +# The following options specify exactly what to backup. +# The server will override them if there is at least one 'include=' line on +# the server side and 'server_can_override_includes=1'. +#include = /home +#exclude = /home/graham/testdir/librsync-0.9.7/testsuite +#include = /home/graham/testdir/librsync-0.9.7/testsuite/deep +#include = /home/graham/xdir +#exclude = /home/graham/testdir/libr +# Exclude file names ending in '.vdi' or '.vmdk' (case insensitive) +#exclude_ext = vdi +#exclude_ext = vmd +# Exlude file path matching a regular expression +# (note that 'include_regex' is not yet implemented) +#exclude_regex = \.cache +# Exclude various temporary file systems. You may want to add devfs, devpts, +# proc, ramfs, etc. +exclude_fs = sysfs +exclude_fs = tmpfs +# Exclude files based on size. Defaults are 0, which means no limit. +#min_file_size = 0 Mb +#max_file_size = 0 Mb +# The content of directories containing a filesystem entry named like this +# will not be backed up. +nobackup = .nobackup +# By default, burp backups up the fifos themselves, rather than reading from +# them. These two options let you choose a particular fifo to read, or read +# from all fifos. +#read_fifo=/path/to/a/fifo +#read_all_fifos=0 +# The same for block device nodes. +#read_blockdev=/path/to/a/blockdev +#read_all_blockdevs=0 +# Exclude files from compression by extension. +exclude_comp=bz2 +exclude_comp=gz +# When backing up, whether to enable O_NOATIME when opening files and +# directories. The default is atime=0, which enables O_NOATIME. +#atime=1 +# When enabled, this causes problems in the phase1 scan (such as an 'include' +# being missing) to be treated as fatal errors. The default is 0. +#scan_problem_raises_error=1 \ No newline at end of file diff --git a/states/burp/client/burp-backup.service.j2 b/states/burp/client/burp-backup.service.j2 new file mode 100644 index 0000000..c5ae19a --- /dev/null +++ b/states/burp/client/burp-backup.service.j2 @@ -0,0 +1,12 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +[Unit] +Description=Burp backup task +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/usr/sbin/burp -ab + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/burp/client/burp-backup.timer.j2 b/states/burp/client/burp-backup.timer.j2 new file mode 100644 index 0000000..653ad46 --- /dev/null +++ b/states/burp/client/burp-backup.timer.j2 @@ -0,0 +1,12 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +[Unit] +Description=Burp backup timer +After=network-online.target +Wants=network-online.target + +[Timer] +OnCalendar=Mon-Sun 23:30 +Persistent=true + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/states/burp/client/config.sls b/states/burp/client/config.sls new file mode 100644 index 0000000..d3a270e --- /dev/null +++ b/states/burp/client/config.sls @@ -0,0 +1,11 @@ +--- +{%- from "burp/map.jinja" import burp with context %} +burp-client-config: + file.managed: + - name: /etc/burp/burp.conf + - source: salt://burp/burp.conf.j2 + - user: root + - mode: 0644 + - template: jinja + - require: + - pkg: burp-pkg \ No newline at end of file diff --git a/states/burp/client/service.sls b/states/burp/client/service.sls new file mode 100644 index 0000000..d7e6869 --- /dev/null +++ b/states/burp/client/service.sls @@ -0,0 +1,19 @@ +--- +{%- from "burp/map.jinja" import burp with context %} +{%- if salt['grains.get']('init') == 'systemd' %} +burp-task: + file.managed: + - name: /etc/systemd/system/burp-backup.service + - source: salt://burp/burp-backup.service.j2 + - user: root + - mode: 0644 + - template: jinja + +burp-timer: + file.managed: + - name: /etc/systemd/system/burp-backup.timer + - source: salt://burp/burp-backup.timer.j2 + - user: root + - mode: 0644 + - template: jinja +{%- endif %} \ No newline at end of file diff --git a/states/burp/defaults.yaml b/states/burp/defaults.yaml new file mode 100644 index 0000000..5729862 --- /dev/null +++ b/states/burp/defaults.yaml @@ -0,0 +1,66 @@ +--- +burp: + enabled: true + server: + name: nuc.paulbsd.com + config: + mode: server + port: 4971 + port_restore: 5971 + status_port: 4972 + password: password + cname: hostname + pidfile: /var/run/burp.client.pid + syslog: 0 + stdout: 1 + progress_counter: 1 + server_can_restore: 1 + cross_filesystem: /home + cross_all_filesystems: 0 + ca_burp_ca: /usr/sbin/burp_ca + ca_csr_dir: /etc/burp/CA-client + ssl_cert_ca: /etc/burp/ssl_cert_ca.pem + ssl_cert: /etc/burp/ssl_cert-client.pem + ssl_key: /etc/burp/ssl_cert-client.key + ssl_peer_cn: burpserver + exclude_fs: sysfs + exclude_fs: tmpfs + exclude_comp: bz2 + exclude_comp: gz + nobackup: .nobackup + clients: + - name: thinkpad.paulbsd.com + schedule: + type: "after" + value: "600" + - name: scw01-ams.paulbsd.com + schedule: + type: "at" + value: "22h" + client: + config: + mode: client + port: 4971 + port_restore: 5971 + status_port: 4972 + server: nuc.paulbsd.com + password: password + cname: hostname + pidfile: /var/run/burp.client.pid + syslog: 0 + stdout: 1 + progress_counter: 1 + server_can_restore: 1 + cross_filesystem: /home + cross_all_filesystems: 0 + ca_burp_ca: /usr/sbin/burp_ca + ca_csr_dir: /etc/burp/CA-client + ssl_cert_ca: /etc/burp/ssl_cert_ca.pem + ssl_cert: /etc/burp/ssl_cert-client.pem + ssl_key: /etc/burp/ssl_cert-client.key + ssl_peer_cn: burpserver + exclude_fs: sysfs + exclude_fs: tmpfs + exclude_comp: bz2 + exclude_comp: gz + nobackup: .nobackup \ No newline at end of file diff --git a/states/burp/init.sls b/states/burp/init.sls new file mode 100644 index 0000000..5fa3b56 --- /dev/null +++ b/states/burp/init.sls @@ -0,0 +1,12 @@ +--- +{%- from "burp/map.jinja" import burp with context %} +include: + - .install + - .pkg +{%- if salt['grains.get']('fqdn') == burp.server.name %} + - .server.config + - .server.service +{%- elif salt['grains.get']('fqdn') in burp.hosts.name %} + - .client.config + - .client.service +{%- endif %} \ No newline at end of file diff --git a/states/burp/install.sls b/states/burp/install.sls new file mode 100644 index 0000000..0ceeea6 --- /dev/null +++ b/states/burp/install.sls @@ -0,0 +1,7 @@ +--- +{%- from "burp/map.jinja" import burp with context %} +burp-config-dir: + file.directory: + - name: /etc/burp + - user: root + - mode: 0755 \ No newline at end of file diff --git a/states/burp/map.jinja b/states/burp/map.jinja new file mode 100644 index 0000000..2b73e3a --- /dev/null +++ b/states/burp/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "burp/defaults.yaml" as defaults -%} + +{%- set burp = salt['pillar.get']( + 'burp', + default=defaults.burp, + merge=True + ) +-%} \ No newline at end of file diff --git a/states/burp/pkg.sls b/states/burp/pkg.sls new file mode 100644 index 0000000..c69df6a --- /dev/null +++ b/states/burp/pkg.sls @@ -0,0 +1,4 @@ +--- +burp-pkg: + pkg.installed: + - name: burp \ No newline at end of file diff --git a/states/burp/server/burp.service.j2 b/states/burp/server/burp.service.j2 new file mode 100644 index 0000000..f165edb --- /dev/null +++ b/states/burp/server/burp.service.j2 @@ -0,0 +1,10 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +[Unit] +Description=Burp backup timer + +[Timer] +OnStartupSec=600 +#OnCalendar=Mon-Sun 22:00 + +[Install] +WantedBy=timers.target \ No newline at end of file diff --git a/states/burp/server/config.sls b/states/burp/server/config.sls new file mode 100644 index 0000000..0851869 --- /dev/null +++ b/states/burp/server/config.sls @@ -0,0 +1,11 @@ +--- +{% from "burp/map.jinja" import burp with context %} +burp-config: + file.managed: + - name: /etc/burp/burp-server.conf + - source: salt://burp/burp.conf.j2 + - user: root + - mode: 0644 + - template: jinja + - require: + - pkg: burp-pkg diff --git a/states/burp/server/service.sls b/states/burp/server/service.sls new file mode 100644 index 0000000..f8d3f7e --- /dev/null +++ b/states/burp/server/service.sls @@ -0,0 +1,11 @@ +--- +{% from "burp/map.jinja" import burp with context %} +{% if salt['grains.get']('init') == 'systemd' %} +burp-task: + file.managed: + - name: /etc/systemd/system/burp.service + - source: salt://burp/burp.service.j2 + - user: root + - mode: 0644 + - template: jinja +{% endif %} diff --git a/states/cds/config.sls b/states/cds/config.sls new file mode 100644 index 0000000..1b056bd --- /dev/null +++ b/states/cds/config.sls @@ -0,0 +1,17 @@ +--- +{%- from "cds/map.jinja" import cds with context %} +cds-config-dir: + file.directory: + - name: /etc/cds + - watch_in: + - service: cds-service + +cds-config-file: + file.managed: + - name: /etc/cds/cds.conf + - source: salt://cds/cds.conf.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: cds-service \ No newline at end of file diff --git a/states/cds/defaults.yaml b/states/cds/defaults.yaml new file mode 100644 index 0000000..7742735 --- /dev/null +++ b/states/cds/defaults.yaml @@ -0,0 +1,7 @@ +--- +cds: + engine: + enabled: true + config: + mirror: https://github.com/ovh/cds/releases/download/ + version: 0.43.1 \ No newline at end of file diff --git a/states/cds/init.sls b/states/cds/init.sls new file mode 100644 index 0000000..d3c2f35 --- /dev/null +++ b/states/cds/init.sls @@ -0,0 +1,6 @@ +--- +{%- from "cds/map.jinja" import cds with context %} +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/cds/install.sls b/states/cds/install.sls new file mode 100644 index 0000000..fef6edc --- /dev/null +++ b/states/cds/install.sls @@ -0,0 +1,12 @@ +--- +{%- from "cds/map.jinja" import cds with context %} +cds-engine-install: + file.managed: + - name: /usr/bin/cds-engine-{{ salt['pillar.get']('cds:engine:version') }} + - source: {{ cds.mirror }}/{{ cds.version }}/cds-engine-{{ salt['grains.get']('kernel')|lower }}-{{ salt['grains.get']('osarch') }} + - skip_verify: True + +cds-bin-symlink: + file.symlink: + - name: /usr/bin/cds-engine + - target: /usr/bin/cds-engine-{{ salt['pillar.get']('cds:version') }} \ No newline at end of file diff --git a/states/cds/map.jinja b/states/cds/map.jinja new file mode 100644 index 0000000..7b48c42 --- /dev/null +++ b/states/cds/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "cds/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='cds') -%} + +{%- set cds = salt['pillar.get']('cds', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/cds/service.sls b/states/cds/service.sls new file mode 100644 index 0000000..5ecf308 --- /dev/null +++ b/states/cds/service.sls @@ -0,0 +1,15 @@ +--- +{%- from "cds/map.jinja" import cds with context %} +cds-service-file: + file.managed: + - name: /etc/systemd/system/cds.service + - source: salt://cds/cds.service.j2 + - user: root + - group: root + - watch_in: + - service: cds-service + +cds-service: + service.running: + - name: cds + - enable: True \ No newline at end of file diff --git a/states/cds/telegraf.service.j2 b/states/cds/telegraf.service.j2 new file mode 100644 index 0000000..4d95d40 --- /dev/null +++ b/states/cds/telegraf.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=The plugin-driven server agent for reporting metrics into InfluxDB +Documentation=https://github.com/influxdata/telegraf +After=network.target + +[Service] +EnvironmentFile=-/etc/default/telegraf +#User=telegraf +ExecStart=/usr/bin/telegraf --config $INFLUX_CONFIG +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-failure +RestartForceExitStatus=SIGPIPE +KillMode=control-group + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/config/defaults.yaml b/states/config/defaults.yaml new file mode 100644 index 0000000..8df4e56 --- /dev/null +++ b/states/config/defaults.yaml @@ -0,0 +1,6 @@ +--- +config: + enabled: true + install_dir: "/usr/local/apps/config" + filename: "common.ini" + config: {} diff --git a/states/config/init.sls b/states/config/init.sls new file mode 100644 index 0000000..24ca5a8 --- /dev/null +++ b/states/config/init.sls @@ -0,0 +1,19 @@ +--- +{%- from "config/map.jinja" import config with context %} +config-dir: + file.directory: + - name: {{ config.install_dir }} + - user: root + - mode: "0755" + +config-file: + file.managed: + - name: {{ config.install_dir }}/{{ config.filename }} + - user: root + - mode: "0755" + +config-file-config: + ini.options_present: + - name: {{ config.install_dir }}/{{ config.filename }} + - separator: '=' + - sections: {{ config.config }} diff --git a/states/config/map.jinja b/states/config/map.jinja new file mode 100644 index 0000000..19fbdc9 --- /dev/null +++ b/states/config/map.jinja @@ -0,0 +1,3 @@ +{%- import_yaml "config/defaults.yaml" as defaults %} + +{%- set config = salt['pillar.get']('config', default=defaults.config, merge=True) -%} diff --git a/states/coronafana/defaults.yaml b/states/coronafana/defaults.yaml new file mode 100644 index 0000000..d3d12ad --- /dev/null +++ b/states/coronafana/defaults.yaml @@ -0,0 +1,9 @@ +--- +coronafana: + enabled: true + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + mirror: https://git.paulbsd.com/paulbsd/coronafana/releases/download + version: 1.0.3 + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/coronafana/init.sls b/states/coronafana/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/coronafana/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/coronafana/install.sls b/states/coronafana/install.sls new file mode 100644 index 0000000..227ae2a --- /dev/null +++ b/states/coronafana/install.sls @@ -0,0 +1,16 @@ +--- +{% from "coronafana/map.jinja" import coronafana with context %} +coronafana-archive-extract: + archive.extracted: + - name: {{ coronafana.release_dir }}/coronafana-{{ coronafana.version }} + - source: {{ coronafana.mirror }}/{{ coronafana.version }}/coronafana-{{ coronafana.version }}-{{ coronafana.os }}-{{ coronafana.arch }}.tar.gz + - skip_verify: True + - enforce_toplevel: False + - if_missing: {{ coronafana.release_dir }}/coronafana-{{ coronafana.version }} + +coronafana-binary-symlink: + file.symlink: + - name: {{ coronafana.install_dir }}/coronafana + - target: {{ coronafana.release_dir }}/coronafana-{{ coronafana.version }} + - require: + - archive: coronafana-archive-extract \ No newline at end of file diff --git a/states/coronafana/kernelmap.yaml b/states/coronafana/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/coronafana/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/coronafana/map.jinja b/states/coronafana/map.jinja new file mode 100644 index 0000000..b2ef6f1 --- /dev/null +++ b/states/coronafana/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "coronafana/defaults.yaml" as default_settings -%} + +{%- import_yaml "coronafana/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "coronafana/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='coronafana', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set coronafana = salt['pillar.get']('coronafana', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/coronafana/osarchmap.yaml b/states/coronafana/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/coronafana/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/cron/defaults.yaml b/states/cron/defaults.yaml new file mode 100644 index 0000000..e22a0a1 --- /dev/null +++ b/states/cron/defaults.yaml @@ -0,0 +1,10 @@ +--- +cron: + env: + SHELL: + name: SHELL + command: /bin/bash + MAILTO: + name: MAILTO + command: {{ salt['pillar.get']('syscontact') }} + tasks: \ No newline at end of file diff --git a/states/cron/init.sls b/states/cron/init.sls new file mode 100644 index 0000000..ec980ca --- /dev/null +++ b/states/cron/init.sls @@ -0,0 +1,8 @@ +--- +{%- from "cron/map.jinja" import cron with context %} +{%- for key, value in cron.env.items() %} +cron-env-{{ key.lower }}: + cron.env_present: + - name: {{ value.name }} + - value: {{ value.command }} +{%- endfor %} \ No newline at end of file diff --git a/states/cron/map.jinja b/states/cron/map.jinja new file mode 100644 index 0000000..e37acb7 --- /dev/null +++ b/states/cron/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "cron/defaults.yaml" as defaults %} + +{%- set cron = salt['pillar.get']( + 'cron', + default=defaults.cron, + merge=True + ) +-%} \ No newline at end of file diff --git a/states/custom.sls b/states/custom.sls new file mode 100644 index 0000000..c7e2fce --- /dev/null +++ b/states/custom.sls @@ -0,0 +1,6 @@ +--- +human_friendly_state_id: + custom.enforce_custom_thing: + - name: Nom + - foo: Valeur + - bar: False \ No newline at end of file diff --git a/states/dkron/config.sls b/states/dkron/config.sls new file mode 100644 index 0000000..b02c973 --- /dev/null +++ b/states/dkron/config.sls @@ -0,0 +1,15 @@ +--- +{%- from "dkron/map.jinja" import dkron with context -%} +dkron-config-dir: + file.directory: + - name: /etc/dkron + - user: {{ dkron.runuser }} + +dkron-config: + file.managed: + - name: /etc/dkron/dkron.yml + - source: salt://dkron/dkron.yml.j2 + - user: {{ dkron.runuser }} + - template: jinja + - watch_in: + - service: dkron-service \ No newline at end of file diff --git a/states/dkron/defaults.yaml b/states/dkron/defaults.yaml new file mode 100644 index 0000000..2a39264 --- /dev/null +++ b/states/dkron/defaults.yaml @@ -0,0 +1,20 @@ +--- +dkron: + enabled: true + install_dir: "/usr/local/apps" + release_dir: "/usr/local/apps/releases" + mirror: "https://github.com/distribworks/dkron/releases/download" + version: "2.1.1" + os: "linux" + arch: "amd64" + runuser: "dkron" + user: "user" + password: "password" + url: "http://localhost:8898" + verify: false + config: + bootstrap-expect: 1 + server: true + http-addr: "127.0.0.1:8898" + data-dir: "/var/lib/dkron" + jobs: [] diff --git a/states/dkron/dkron.service.j2 b/states/dkron/dkron.service.j2 new file mode 100644 index 0000000..2e4b62b --- /dev/null +++ b/states/dkron/dkron.service.j2 @@ -0,0 +1,15 @@ +{%- from "dkron/map.jinja" import dkron with context -%} +[Unit] +Description=dkron - Open Source task scheduler +Documentation=https://dkron.io/ +After=network.target + +[Service] +User=%i +ExecStart={{ dkron.install_dir }}/dkron/dkron agent +Restart=on-failure +SuccessExitStatus=3 4 +RestartForceExitStatus=3 4 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/dkron/dkron.yml.j2 b/states/dkron/dkron.yml.j2 new file mode 100644 index 0000000..68b912d --- /dev/null +++ b/states/dkron/dkron.yml.j2 @@ -0,0 +1,4 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +--- +{%- from "dkron/map.jinja" import dkron with context %} +{{ dkron.config|yaml(False) }} \ No newline at end of file diff --git a/states/dkron/init.sls b/states/dkron/init.sls new file mode 100644 index 0000000..ef5fec3 --- /dev/null +++ b/states/dkron/init.sls @@ -0,0 +1,6 @@ +--- +include: + - .install + - .config + - .service + - .jobs \ No newline at end of file diff --git a/states/dkron/install.sls b/states/dkron/install.sls new file mode 100644 index 0000000..99828ba --- /dev/null +++ b/states/dkron/install.sls @@ -0,0 +1,30 @@ +--- +{%- from "dkron/map.jinja" import dkron with context %} +dkron-user: + user.present: + - name: {{ dkron.runuser }} + +dkron-archive-extract: + archive.extracted: + - name: {{ dkron.release_dir }}/dkron_{{ dkron.version }} + - source: {{ dkron.mirror }}/v{{ dkron.version }}/dkron_{{ dkron.version }}_{{ dkron.os }}_{{ dkron.arch }}.tar.gz + - user: {{ dkron.runuser }} + - enforce_toplevel: False + - skip_verify: True + - archive_format: tar + - if_missing: {{ dkron.release_dir }}/dkron_{{ dkron.version }} + +dkron-bin-symlink: + file.symlink: + - name: {{ dkron.install_dir }}/dkron + - target: {{ dkron.release_dir }}/dkron_{{ dkron.version }} + - user: {{ dkron.runuser }} + - watch_in: + - service: dkron-service + +dkron-data-dir: + file.directory: + - name: {{ dkron.config.get('data-dir') }} + - user: {{ dkron.runuser }} + - watch_in: + - service: dkron-service \ No newline at end of file diff --git a/states/dkron/jobs.sls b/states/dkron/jobs.sls new file mode 100644 index 0000000..7441ff4 --- /dev/null +++ b/states/dkron/jobs.sls @@ -0,0 +1,8 @@ +--- +{%- from "dkron/map.jinja" import dkron with context %} +dkron-jobs: + dkron.jobs: + - name: dkron-jobs + - url: {{ dkron.url }} + - verify: {{ dkron.verify }} + - jobs: {{ dkron.jobs }} \ No newline at end of file diff --git a/states/dkron/kernelmap.yaml b/states/dkron/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/dkron/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/dkron/map.jinja b/states/dkron/map.jinja new file mode 100644 index 0000000..c29f8a3 --- /dev/null +++ b/states/dkron/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "dkron/defaults.yaml" as default_settings -%} + +{%- import_yaml "dkron/kernelmap.yaml" as kernelmap %} +{%- import_yaml "dkron/osarchmap.yaml" as osarchmap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='dkron', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set dkron = salt['pillar.get']('dkron', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/dkron/osarchmap.yaml b/states/dkron/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/dkron/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/dkron/service.sls b/states/dkron/service.sls new file mode 100644 index 0000000..ec0657c --- /dev/null +++ b/states/dkron/service.sls @@ -0,0 +1,16 @@ +--- +{%- from "dkron/map.jinja" import dkron with context %} +dkron-service-file: + file.managed: + - name: /etc/systemd/system/dkron@.service + - source: salt://dkron/dkron.service.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: dkron-service + +dkron-service: + service.running: + - name: dkron@{{ dkron.runuser }} + - enable: True \ No newline at end of file diff --git a/states/docker/config.sls b/states/docker/config.sls new file mode 100644 index 0000000..2ab846e --- /dev/null +++ b/states/docker/config.sls @@ -0,0 +1,16 @@ +--- +{%- from "docker/map.jinja" import docker with context %} +docker-config-dir: + file.directory: + - name: /etc/docker + +docker-config-file: + file.managed: + - name: {{ docker.config_dir }}/{{ docker.config_file }} + - source: salt://docker/daemon.json.j2 + - mode: 644 + - template: jinja + - require: + - file: docker-config-dir + - watch_in: + - service: docker-service \ No newline at end of file diff --git a/states/docker/daemon.json.j2 b/states/docker/daemon.json.j2 new file mode 100644 index 0000000..fcb3f3b --- /dev/null +++ b/states/docker/daemon.json.j2 @@ -0,0 +1,2 @@ +{%- from "docker/map.jinja" import docker with context -%} +{{ docker.daemon.config | tojson }} \ No newline at end of file diff --git a/states/docker/defaults.yaml b/states/docker/defaults.yaml new file mode 100644 index 0000000..604f112 --- /dev/null +++ b/states/docker/defaults.yaml @@ -0,0 +1,13 @@ +--- +docker: + enabled: true + config_dir: "/etc/docker" + config_file: "daemon.json" + pkgs: + - docker-ce + - docker-ce-cli + pip_pkgs: + - docker-compose + daemon: + config: + storage-driver: overlay2 \ No newline at end of file diff --git a/states/docker/init.sls b/states/docker/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/docker/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/docker/install.sls b/states/docker/install.sls new file mode 100644 index 0000000..72261d0 --- /dev/null +++ b/states/docker/install.sls @@ -0,0 +1,11 @@ +--- +{%- from "docker/map.jinja" import docker with context %} +docker-pkgs: + pkg.latest: + - pkgs: {{ docker.pkgs }} + +docker-pip-pkgs: + pip.installed: +{%- for pip in docker.pip_pkgs %} + - name: {{ pip }} +{%- endfor %} \ No newline at end of file diff --git a/states/docker/map.jinja b/states/docker/map.jinja new file mode 100644 index 0000000..5b076cc --- /dev/null +++ b/states/docker/map.jinja @@ -0,0 +1,6 @@ +{%- import_yaml "docker/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='docker') +-%} + +{%- set docker = salt['pillar.get']('docker', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/docker/service.sls b/states/docker/service.sls new file mode 100644 index 0000000..8c2ffed --- /dev/null +++ b/states/docker/service.sls @@ -0,0 +1,5 @@ +--- +docker-service: + service.running: + - name: docker + - enable: True \ No newline at end of file diff --git a/states/dokuwiki/config.sls b/states/dokuwiki/config.sls new file mode 100644 index 0000000..b6c6e04 --- /dev/null +++ b/states/dokuwiki/config.sls @@ -0,0 +1,9 @@ +--- +{%- from "dokuwiki/map.jinja" import dokuwiki with context %} +dokuwiki-config: + file.managed: + - name: {{ dokuwiki.install_dir }}/dokuwiki/conf/local.php + - source: salt://dokuwiki/templates/local.php.j2 + - user: {{ dokuwiki.user }} + - group: {{ dokuwiki.group }} + - template: jinja \ No newline at end of file diff --git a/states/dokuwiki/defaults.yaml b/states/dokuwiki/defaults.yaml new file mode 100644 index 0000000..f9fdd82 --- /dev/null +++ b/states/dokuwiki/defaults.yaml @@ -0,0 +1,15 @@ +--- +dokuwiki: + version: release_stable_2018-04-22b + mirror: https://github.com/splitbrain/dokuwiki/archive + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + user: www-data + group: www-data + config: + title: "Dokuwiki" + license: '0' + useacl: 1 + superuser: '@admin' + disableactions: 'register' + savedir: '/home/dokuwiki' diff --git a/states/dokuwiki/init.sls b/states/dokuwiki/init.sls new file mode 100644 index 0000000..6bc76b0 --- /dev/null +++ b/states/dokuwiki/init.sls @@ -0,0 +1,5 @@ +--- +include: + - php + - .install + - .config \ No newline at end of file diff --git a/states/dokuwiki/install.sls b/states/dokuwiki/install.sls new file mode 100644 index 0000000..d027aac --- /dev/null +++ b/states/dokuwiki/install.sls @@ -0,0 +1,23 @@ +--- +{%- from "dokuwiki/map.jinja" import dokuwiki with context %} +dokuwiki-archive: + archive.extracted: + - name: {{ dokuwiki.release_dir }} + - source: {{ dokuwiki.mirror }}/{{ dokuwiki.version }}.tar.gz + - skip_verify: True + - archive_format: tar + - user: {{ dokuwiki.user }} + - group: {{ dokuwiki.group }} + - if_missing: {{ dokuwiki.release_dir }}/dokuwiki-{{ dokuwiki.version }} + +dokuwiki-install-link: + file.symlink: + - name: {{ dokuwiki.install_dir }}/dokuwiki + - target: {{ dokuwiki.release_dir }}/dokuwiki-{{ dokuwiki.version }} + - force: True + +dokuwiki-savedir: + file.directory: + - name: {{ dokuwiki.config.savedir }} + - user: {{ dokuwiki.user }} + - group: {{ dokuwiki.group }} diff --git a/states/dokuwiki/map.jinja b/states/dokuwiki/map.jinja new file mode 100644 index 0000000..0c30141 --- /dev/null +++ b/states/dokuwiki/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "dokuwiki/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='dokuwiki') -%} + +{%- set dokuwiki = salt['pillar.get']('dokuwiki', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/dokuwiki/templates/local.php.j2 b/states/dokuwiki/templates/local.php.j2 new file mode 100644 index 0000000..0a22bb2 --- /dev/null +++ b/states/dokuwiki/templates/local.php.j2 @@ -0,0 +1,9 @@ + 0 %} + +include: + - {{ sls_archive_clean if grafana.pkg.use_upstream_archive else sls_package_clean }} + +grafana-package-archive-remove-home-alternative-remove: + alternatives.remove: + - name: grafana-home + - path: {{ grafana.pkg.archive.name }} + - onlyif: update-alternatives --get-selections |grep ^grafana-home + - require: + - sls: {{ sls_archive_clean if grafana.pkg.use_upstream_archive else sls_package_clean }} + + {% for i in ['grafana-cli', 'grafana-server'] %} + +grafana-package-archive-remove-{{ i }}-alternative-remove: + alternatives.remove: + - name: link-{{ i }} + - path: {{ grafana.pkg.archive.name }}/bin/{{ i }} + - onlyif: update-alternatives --get-selections |grep ^link-{{ i }} + - require: + - sls: {{ sls_archive_clean if grafana.pkg.use_upstream_archive else sls_package_clean }} + + {% endfor %} + {%- endif %} diff --git a/states/grafana/config/alternatives/init.sls b/states/grafana/config/alternatives/init.sls new file mode 100644 index 0000000..d3e5518 --- /dev/null +++ b/states/grafana/config/alternatives/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .install diff --git a/states/grafana/config/alternatives/install.sls b/states/grafana/config/alternatives/install.sls new file mode 100644 index 0000000..0104710 --- /dev/null +++ b/states/grafana/config/alternatives/install.sls @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} +{%- set sls_archive_install = tplroot ~ '.archive.install' %} + + {%- if grafana.pkg.use_upstream_archive %} + {%- if grains.kernel|lower == 'linux' and grafana.linux.altpriority|int > 0 %} + +include: + - {{ sls_archive_install }} + +grafana-package-archive-install-home-alternative-install: + cmd.run: + - name: update-alternatives --install {{ grafana.dir }} grafana-home {{ grafana.pkg.archive.name }} {{grafana.linux.altpriority}} + - watch: + - archive: grafana-package-archive-install-archive-extracted + - require: + - sls: {{ sls_archive_install }} + - onlyif: {{ grains.os_family in ('Suse',) }} + alternatives.install: + - name: grafana-home + - link: {{ grafana.dir }} + - path: {{ grafana.pkg.archive.name }} + - priority: {{ grafana.linux.altpriority }} + - order: 10 + - watch: + - archive: grafana-package-archive-install-archive-extracted + - unless: {{ grains.os_family in ('Suse',) }} + - require: + - sls: {{ sls_archive_install }} + +grafana-package-archive-install-home-alternative-set: + alternatives.set: + - name: grafana-home + - path: {{ grafana.pkg.archive.name }} + - require: + - alternatives: grafana-package-archive-install-home-alternative-install + - unless: {{ grains.os_family in ('Suse',) }} + + {% for i in ['grafana-cli', 'grafana-server'] %} + +grafana-package-archive-install-{{ i }}-alternative-install: + cmd.run: + - name: update-alternatives --install /usr/bin/{{i}} link-{{i}} {{ grafana.pkg.archive.name }}/bin/{{i}} {{grafana.linux.altpriority}} + - require: + - cmd: grafana-package-archive-install-home-alternative-install + - onlyif: {{ grains.os_family in ('Suse',) }} + alternatives.install: + - name: link-{{ i }} + - link: /usr/bin/{{ i }} + - path: {{ grafana.pkg.archive.name }}/bin/{{ i }} + - priority: {{ grafana.linux.altpriority }} + - order: 10 + - require: + - alternatives: grafana-package-archive-install-home-alternative-install + - unless: {{ grains.os_family in ('Suse',) }} + +grafana-package-archive-install-{{ i }}-alternative-set: + alternatives.set: + - name: link-{{ i }} + - path: {{ grafana.pkg.archive.name }}/bin/{{ i }} + - require: + - alternatives: grafana-package-archive-install-{{ i }}-alternative-install + - unless: {{ grains.os_family in ('Suse',) }} + + {% endfor %} + {%- endif %} + {%- endif %} diff --git a/states/grafana/config/clean.sls b/states/grafana/config/clean.sls new file mode 100644 index 0000000..8e66263 --- /dev/null +++ b/states/grafana/config/clean.sls @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} +{%- set sls_archive_clean = tplroot ~ '.archive.clean' %} +{%- set sls_package_clean = tplroot ~ '.package.clean' %} +{%- set sls_service_clean = tplroot ~ '.service.clean' %} +{%- set sls_alternatives_clean = tplroot ~ '.config.alternatives.clean' %} + + {%- if grains.kernel|lower == 'linux' and grafana.linux.altpriority|int > 0 %} + +include: + - {{ sls_service_clean }} + - {{ sls_archive_clean if grafana.pkg.use_upstream_archive else sls_package_clean }} + - {{ sls_alternatives_clean }} + +grafana-config-clean-file-absent: + file.absent: + - names: + - {{ grafana.config_file }} + - {{ grafana.environ_file }} + - require: + - sls: {{ sls_archive_clean if grafana.pkg.use_upstream_archive else sls_package_clean }} + - sls: {{ sls_alternatives_clean }} + + {%- endif %} diff --git a/states/grafana/config/environ.sls b/states/grafana/config/environ.sls new file mode 100644 index 0000000..3805aee --- /dev/null +++ b/states/grafana/config/environ.sls @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- set sls_archive_install = tplroot ~ '.archive.install' %} +{%- set sls_package_install = tplroot ~ '.package.install' %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} + +include: + - {{ sls_archive_install if grafana.pkg.use_upstream_archive else sls_package_install }} + +grafana-config-file-file-managed-environ_file: + file.managed: + - name: {{ grafana.environ_file }} + - source: {{ files_switch(['grafana.sh.jinja'], + lookup='grafana-config-file-file-managed-environ_file' + ) + }} + - mode: 640 + - user: root + - group: {{ grafana.rootgroup if grafana.pkg.use_upstream_archive else grafana.group }} + - makedirs: True + - template: jinja + - context: + config: {{ grafana.environ|json }} + - require: + - sls: {{ sls_archive_install if grafana.pkg.use_upstream_archive else sls_package_install }} diff --git a/states/grafana/config/file.sls b/states/grafana/config/file.sls new file mode 100644 index 0000000..75256ad --- /dev/null +++ b/states/grafana/config/file.sls @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} + +{%- if 'config' in grafana and grafana.config %} + {%- if grafana.pkg.use_upstream_archive %} + {%- set sls_package_install = tplroot ~ '.archive.install' %} + {%- else %} + {%- set sls_package_install = tplroot ~ '.package.install' %} + {%- endif %} + +include: + - {{ sls_package_install }} + +grafana-config-file-file-managed-config_file: + file.managed: + - name: {{ grafana.config_file }} + - source: {{ files_switch(['grafana.ini.jinja'], + lookup='grafana-config-file-file-managed-config_file' + ) + }} + - mode: 640 + - user: {{ grafana.grafana_user }} + - group: {{ grafana.rootgroup if grafana.pkg.use_upstream_archive else grafana.group }} + - makedirs: True + - template: jinja + - context: + config: {{ grafana.config|json }} + - require: + - sls: {{ sls_package_install }} + +{%- endif %} diff --git a/states/grafana/config/init.sls b/states/grafana/config/init.sls new file mode 100644 index 0000000..008eaa5 --- /dev/null +++ b/states/grafana/config/init.sls @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .file + - .environ + - .alternatives diff --git a/states/grafana/defaults.yaml b/states/grafana/defaults.yaml new file mode 100644 index 0000000..433e082 --- /dev/null +++ b/states/grafana/defaults.yaml @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +--- +grafana: + dir: /opt/grafana + version: '6.2.2' + grafana_url: 'https://grafana.exemple.com' + grafana_user: grafana + grafana_password: grafana + grafana_timeout: 3 + + pkg: + name: grafana + binary: grafana + use_upstream_archive: False + use_upstream_repo: False + repo: + humanname: grafana + name: grafana + comments: + - installed by salt + enabled: 1 + gpgcheck: 1 + archive: + name: /opt + uri: https://dl.grafana.com/oss/release + source: None + source_hash: None + trim_output: True {# works in 2018.3.2. onwards #} + archive_suffix: tar.gz + archive_format: tar + enforce_toplevel: False # needed for grafana + options: '--strip-components=1' # needed for grafana + + kernel: {{grains.kernel|lower}} + rootgroup: root + group: grafana + config_file: /etc/grafana/grafana.ini + config: {} + environ_file: /etc/default/grafana.sh + environ: [] + service: + name: grafana-server + user: grafana + group: grafana + + linux: + altpriority: 0 {# 'Alternatives system' priority: zero disables (default) #} diff --git a/states/grafana/files/default/grafana.ini.jinja b/states/grafana/files/default/grafana.ini.jinja new file mode 100644 index 0000000..ab79337 --- /dev/null +++ b/states/grafana/files/default/grafana.ini.jinja @@ -0,0 +1,17 @@ +######################################################################## +# File managed by Salt at <{{ source }}>. +# Your changes will be overwritten. +######################################################################## + +{%- macro render_key_value_pairs(cfg) %} +{%- for k,v in cfg.items() -%} +{{ k }} = {{ v }} +{% endfor %} +{%- endmacro %} + +{{ render_key_value_pairs(config.get("default", {})) }} +{% for section, cfg in config.items() %} +{%- if section == "default" %}{% continue %}{% endif %} +[{{section}}] +{{ render_key_value_pairs(cfg) }} +{% endfor %} diff --git a/states/grafana/files/default/grafana.sh.jinja b/states/grafana/files/default/grafana.sh.jinja new file mode 100644 index 0000000..c4e6352 --- /dev/null +++ b/states/grafana/files/default/grafana.sh.jinja @@ -0,0 +1,8 @@ +######################################################################## +# File managed by Salt at <{{ source }}>. +# Your changes will be overwritten. +######################################################################## + +{%- for item in config %} +{{ item }} +{%- endfor %} diff --git a/states/grafana/init.sls b/states/grafana/init.sls new file mode 100644 index 0000000..eb20f80 --- /dev/null +++ b/states/grafana/init.sls @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} + +include: + - {{ '.archive' if grafana.pkg.use_upstream_archive else '.package' }} + - .config + - .service diff --git a/states/grafana/jinja/macros.jinja b/states/grafana/jinja/macros.jinja new file mode 100644 index 0000000..05ce5fc --- /dev/null +++ b/states/grafana/jinja/macros.jinja @@ -0,0 +1,10 @@ +# +# Collection of common macros + +{%- macro format_kwargs(kwarg) -%} + {%- filter indent(4) %} + {%- for k, v in kwarg|dictsort() %} +- {{ k }}: {{ v }} + {%- endfor %} + {%- endfilter %} +{%- endmacro %} diff --git a/states/grafana/libtofs.jinja b/states/grafana/libtofs.jinja new file mode 100644 index 0000000..ab0d0f6 --- /dev/null +++ b/states/grafana/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/states/grafana/map.jinja b/states/grafana/map.jinja new file mode 100644 index 0000000..a914239 --- /dev/null +++ b/states/grafana/map.jinja @@ -0,0 +1,49 @@ +{#- 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 ~ "/osarchmap.yaml" as osarchmap %} +{%- import_yaml tplroot ~ "/osmap.yaml" as osmap %} +{%- import_yaml tplroot ~ "/osfingermap.yaml" as osfingermap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='grafana', + merge=salt['grains.filter_by'](osfamilymap, grain='os_family', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](osmap, grain='os', + merge=salt['grains.filter_by'](osfingermap, grain='osfinger', + merge=salt['pillar.get']('grafana:lookup', default={}) + ) + ) + ) + ) +) %} + +{#- Merge the grafana pillar #} +{%- set grafana = salt['pillar.get']('grafana', default=defaults, merge=True) %} + +{#- archive jinja #} +{%- if grafana.pkg.use_upstream_archive %} + {%- set name = 'grafana-%s.%s-%s'|format(grafana.version, grafana.kernel, grafana.arch) %} + {%- set uri = grafana.pkg.archive.uri + '/' + name %} + {%- do grafana.pkg.archive.update({ + 'name': grafana.pkg.archive.name + '/' + name, + 'source': uri + '.' + grafana.pkg.archive.archive_suffix, + 'source_hash': uri + '.' + grafana.pkg.archive.archive_suffix + '.sha256', + 'archive_format': grafana.pkg.archive.archive_format + }) %} + {%- do grafana.environ.append('export PATH=${PATH}:' + grafana.pkg.archive.name + '/bin') %} +{%- endif %} + +{#- Contactenate arguments #} +{%- macro concat_args(args) %} +{%- set args = args|dictsort %} +{%- if args|length > 0 %} +{%- for k,v in args -%} +{%- if not k or not v %}{% continue %}{% endif -%} + --{{ k }}={{ v }} +{%- if not loop.last %} {% endif -%} +{%- endfor -%} +{%- endif -%} +{%- endmacro %} diff --git a/states/grafana/osarchmap.yaml b/states/grafana/osarchmap.yaml new file mode 100644 index 0000000..aca537a --- /dev/null +++ b/states/grafana/osarchmap.yaml @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# vim: ft=yaml +# +# Setup variables using grains['osarch'] based logic. +# You just need to add the key:values for an `osarch` that differ +# from `defaults.yaml` + `os_family.yaml`. +# Only add an `osarch` which is/will be supported by the formula +# +# If you do not need to provide defaults via the `osarch` grain, +# you will need to provide at least an empty dict in this file, e.g. +# osarch: {} +--- +amd64: + arch: amd64 + +x86_64: + arch: amd64 + +386: + arch: 386 + +arm64: + arch: arm64 + +armv6l: + arch: armv6l + +armv7l: + arch: armv6l + +ppc64le: + arch: ppc64le + +s390x: + arch: s390x diff --git a/states/grafana/osfamilymap.yaml b/states/grafana/osfamilymap.yaml new file mode 100644 index 0000000..3c40a18 --- /dev/null +++ b/states/grafana/osfamilymap.yaml @@ -0,0 +1,91 @@ +# -*- 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: {} +--- +{%- if grains.os == 'MacOS' %} + {% set macos_user = salt['cmd.run']("stat -f '%Su' /dev/console") %} + {% set macos_group = salt['cmd.run']("stat -f '%Sg' /dev/console") %} +{%- endif %} + +Debian: + pkg: + use_upstream_repo: True + repo: + humanname: grafana_official + name: deb https://packages.grafana.com/oss/deb stable main + file: /etc/apt/sources.list.d/grafana.list + key_url: https://packages.grafana.com/gpg.key + +RedHat: + pkg: + use_upstream_repo: True + repo: + baseurl: https://packages.grafana.com/oss/rpm-beta + repo_gpgcheck: 1 + gpgkey: https://packages.grafana.com/gpg.key + sslverify: 1 + sslcacert: /etc/pki/tls/certs/ca-bundle.crt + comments: + - instructions from https://grafana.com/docs/installation/rpm/ + +Suse: + pkg: + use_upstream_repo: True + repo: + baseurl: https://packages.grafana.com/oss/rpm-beta + repo_gpgcheck: 1 + gpgkey: https://packages.grafana.com/gpg.key + sslverify: 1 + sslcacert: /etc/pki/tls/certs/ca-bundle.crt + comments: + - instructions from https://grafana.com/docs/installation/rpm/ + +Gentoo: {} + +Arch: {} + +Alpine: {} + +FreeBSD: + pkg: + name: grafana5 + config_file: /usr/local/etc/grafana.conf + config: + paths: + data: /var/db/grafana/ + logs: /var/log/grafana/ + plugins: /var/db/grafana/plugins + provisioning: /var/db/grafana/provisioning + database: + log_queries: '' + service: + name: grafana + +OpenBSD: {} + +Solaris: {} + +Windows: + dir: C:\\Program Files + pkg: + archive: + name: C:\\Program Files + archive_suffix: zip + archive_format: zip + +MacOS: + rootuser: {{ macos_user | d('') }} + rootgroup: {{ macos_group | d('') }} + group: {{ macos_group | d('') }} + service: + name: grafana + rootgroup: {{ macos_group | d('') }} + group: {{ macos_group | d('') }} diff --git a/states/grafana/osfingermap.yaml b/states/grafana/osfingermap.yaml new file mode 100644 index 0000000..0fac2c6 --- /dev/null +++ b/states/grafana/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/states/grafana/osmap.yaml b/states/grafana/osmap.yaml new file mode 100644 index 0000000..20a12fd --- /dev/null +++ b/states/grafana/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/states/grafana/package/clean.sls b/states/grafana/package/clean.sls new file mode 100644 index 0000000..8570ed6 --- /dev/null +++ b/states/grafana/package/clean.sls @@ -0,0 +1,21 @@ +# -*- 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 grafana with context %} + +include: + - {{ sls_config_clean }} + + {%- if grafana.pkg.use_upstream_repo %} +include: + - .repo.clean + {%- endif %} + +grafana-package-clean-pkg-removed: + pkg.removed: + - name: {{ grafana.pkg.name }} + # require: + # sls: {{ sls_config_clean }} diff --git a/states/grafana/package/init.sls b/states/grafana/package/init.sls new file mode 100644 index 0000000..d3e5518 --- /dev/null +++ b/states/grafana/package/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .install diff --git a/states/grafana/package/install.sls b/states/grafana/package/install.sls new file mode 100644 index 0000000..d3496c3 --- /dev/null +++ b/states/grafana/package/install.sls @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} + + {%- if grafana.pkg.use_upstream_repo %} +include: + - .repo + {%- endif %} + +grafana-package-install-pkg-installed: + pkg.installed: + - name: {{ grafana.pkg.name }} + - version: {{ grafana.version }} \ No newline at end of file diff --git a/states/grafana/package/repo/clean.sls b/states/grafana/package/repo/clean.sls new file mode 100644 index 0000000..d84ac4e --- /dev/null +++ b/states/grafana/package/repo/clean.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 grafana with context %} + +grafana-package-repo-clean-pkgrepo-absent: + pkgrepo.absent: + - name: {{ grafana.pkg.repo.name }} diff --git a/states/grafana/package/repo/init.sls b/states/grafana/package/repo/init.sls new file mode 100644 index 0000000..d3e5518 --- /dev/null +++ b/states/grafana/package/repo/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .install diff --git a/states/grafana/package/repo/install.sls b/states/grafana/package/repo/install.sls new file mode 100644 index 0000000..d53fdbb --- /dev/null +++ b/states/grafana/package/repo/install.sls @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} + + {%- if grafana.pkg.use_upstream_repo %} + {%- from tplroot ~ "/jinja/macros.jinja" import format_kwargs with context %} + +grafana-package-repo-install-pkgrepo-managed: + pkgrepo.managed: + {{- format_kwargs(grafana.pkg.repo) }} + + {%- endif %} diff --git a/states/grafana/service/clean.sls b/states/grafana/service/clean.sls new file mode 100644 index 0000000..1eed0e6 --- /dev/null +++ b/states/grafana/service/clean.sls @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import grafana with context %} + +grafana-service-clean-service-dead: + service.dead: + - name: {{ grafana.service.name }} + - enable: False diff --git a/states/grafana/service/init.sls b/states/grafana/service/init.sls new file mode 100644 index 0000000..6fe4d1a --- /dev/null +++ b/states/grafana/service/init.sls @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# vim: ft=sls + +include: + - .running diff --git a/states/grafana/service/running.sls b/states/grafana/service/running.sls new file mode 100644 index 0000000..06dd27b --- /dev/null +++ b/states/grafana/service/running.sls @@ -0,0 +1,27 @@ +# -*- 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 grafana with context %} + +include: + - {{ sls_config_file }} + +grafana-service-running-service-unmasked: + service.unmasked: + - name: {{ grafana.service.name }} + - onlyif: systemctl list-unit-files | grep {{ grafana.service.name }} >/dev/null 2>&1 + +grafana-service-running-service-running: + service.running: + - name: {{ grafana.service.name }} + - enable: True + {%- if 'config' in grafana and grafana.config %} + - watch: + - file: grafana-config-file-file-managed-config_file + - require: + - sls: {{ sls_config_file }} + {%- endif %} + - onlyif: systemctl list-unit-files | grep {{ grafana.service.name }} >/dev/null 2>&1 diff --git a/states/gufw/Desktop.profile b/states/gufw/Desktop.profile new file mode 100644 index 0000000..238eaa9 --- /dev/null +++ b/states/gufw/Desktop.profile @@ -0,0 +1,95 @@ +[fwBasic] +status = enabled +incoming = deny +outgoing = allow +routed = disabled + +[Rule0] +ufw_rule = Anywhere ALLOW IN 82.246.174.207 +description = IPv4 Granville +command = /usr/sbin/ufw allow in from 82.246.174.207 to any +policy = allow +direction = in +protocol = +from_ip = 82.246.174.207 +from_port = +to_ip = +to_port = +iface = +routed = +logging = + +[Rule1] +ufw_rule = Anywhere ALLOW IN 192.168.60.0/24 +description = IPv4 St-Pierre +command = /usr/sbin/ufw allow in from 192.168.60.0/24 to any +policy = allow +direction = in +protocol = +from_ip = 192.168.60.0/24 +from_port = +to_ip = +to_port = +iface = +routed = +logging = + +[Rule2] +ufw_rule = Anywhere ALLOW IN 192.168.50.0/24 +description = IPv4 Granville +command = /usr/sbin/ufw allow in from 192.168.50.0/24 to any +policy = allow +direction = in +protocol = +from_ip = 192.168.50.0/24 +from_port = +to_ip = +to_port = +iface = +routed = +logging = + +[Rule3] +ufw_rule = Anywhere ALLOW IN 10.0.0.0/8 +description = IPv4 Local 10.0.0.0/8 +command = /usr/sbin/ufw allow in from 10.0.0.0/8 to any +policy = allow +direction = in +protocol = +from_ip = 10.0.0.0/8 +from_port = +to_ip = +to_port = +iface = +routed = +logging = + +[Rule4] +ufw_rule = Anywhere (v6) ALLOW IN 2a01:e34:ec85:f190::/64 +description = IPv6 St-Pierre +command = /usr/sbin/ufw allow in from 2a01:e34:ec85:f190::/64 to any +policy = allow +direction = in +protocol = +from_ip = 2a01:e34:ec85:f190::/64 +from_port = +to_ip = +to_port = +iface = +routed = +logging = + +[Rule5] +ufw_rule = Anywhere (v6) ALLOW IN 2a01:e35:2f6a:ecf0::/64 +description = IPv6 Granville +command = /usr/sbin/ufw allow in from 2a01:e35:2f6a:ecf0::/64 to any +policy = allow +direction = in +protocol = +from_ip = 2a01:e35:2f6a:ecf0::/64 +from_port = +to_ip = +to_port = +iface = +routed = +logging = \ No newline at end of file diff --git a/states/gufw/gufw.cfg b/states/gufw/gufw.cfg new file mode 100644 index 0000000..f0b027d --- /dev/null +++ b/states/gufw/gufw.cfg @@ -0,0 +1,5 @@ +[GufwConfiguration] +profile = Desktop +showdonationbtn = no +windowwidth = 800 +windowheight = 530 \ No newline at end of file diff --git a/states/gufw/init.sls b/states/gufw/init.sls new file mode 100644 index 0000000..22a2b27 --- /dev/null +++ b/states/gufw/init.sls @@ -0,0 +1,16 @@ +--- +gufw-cfg: + file.managed: + - source: salt://gufw/gufw.cfg + - name: /etc/gufw/gufw.cfg + - user: root + - group: root + - mode: 600 + +gufw-desktop-cfg: + file.managed: + - source: salt://gufw/Desktop.profile + - name: /etc/gufw/Desktop.profile + - user: root + - group: root + - mode: 600 \ No newline at end of file diff --git a/states/influxdb/config.sls b/states/influxdb/config.sls new file mode 100644 index 0000000..06a1195 --- /dev/null +++ b/states/influxdb/config.sls @@ -0,0 +1,20 @@ +--- +{%- from "influxdb/map.jinja" import influxdb with context %} +influxdb-config-dir: + file.directory: + - name: {{ influxdb.config_dir }} + - user: {{ influxdb.user.name }} + - group: {{ influxdb.group.name }} + - watch_in: + - service: influxdb-service + +influxdb-config-file: + file.managed: + - name: {{ influxdb.config_dir }}/{{ influxdb.config_file }} + - source: salt://influxdb/influxdb.conf.j2 + - user: {{ influxdb.user.name }} + - group: {{ influxdb.group.name }} + - mode: 644 + - template: jinja + - watch_in: + - service: influxdb-service \ No newline at end of file diff --git a/states/influxdb/defaults.yaml b/states/influxdb/defaults.yaml new file mode 100644 index 0000000..7e99f44 --- /dev/null +++ b/states/influxdb/defaults.yaml @@ -0,0 +1,20 @@ +--- +influxdb: + enabled: true + mirror: "https://dl.influxdata.com/influxdb/releases" + dependencies: + - collectd + install_dir: "/usr/local/apps" + release_dir: "/usr/local/apps/releases" + config_dir: "/etc/influxdb" + config_file: "influxdb.conf" + data_dir: "/var/lib/influxdb" + version: "1.8.0" + os: linux + arch: amd64 + user: + name: influxdb + uid: 901 + group: + name: influxdb + gid: 901 diff --git a/states/influxdb/influxdb.conf.j2 b/states/influxdb/influxdb.conf.j2 new file mode 100644 index 0000000..7f91dc6 --- /dev/null +++ b/states/influxdb/influxdb.conf.j2 @@ -0,0 +1,39 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "influxdb/map.jinja" import influxdb with context %} +[meta] + dir = "{{ influxdb.data_dir }}/meta" + +[data] + dir = "{{ influxdb.data_dir }}/data" + wal-dir = "{{ influxdb.data_dir }}/wal" + +[coordinator] + +[retention] + +[shard-precreation] + +[monitor] + +[http] + enabled = true + bind-address = "127.0.0.1:8086" + auth-enabled = true + log-enabled = true + +[admin] + enabled = true + bind-address = ":8083" + https-enabled = false + +[ifql] + +[logging] + +[subscriber] + +[[collectd]] + enabled = true + port = 25826 + database = "collectd" + typesdb = "/usr/share/collectd/types.db" \ No newline at end of file diff --git a/states/influxdb/influxdb.service.j2 b/states/influxdb/influxdb.service.j2 new file mode 100644 index 0000000..f022a21 --- /dev/null +++ b/states/influxdb/influxdb.service.j2 @@ -0,0 +1,17 @@ +{%- from "influxdb/map.jinja" import influxdb with context -%} +[Unit] +Description=InfluxDB is an open-source, distributed, time series database +Documentation=https://docs.influxdata.com/influxdb/ +After=network-online.target + +[Service] +User={{ influxdb.user.name }} +Group={{ influxdb.group.name }} +LimitNOFILE=65536 +ExecStart={{ influxdb.install_dir }}/influxdb/influxd -config /etc/influxdb/influxdb.conf +KillMode=control-group +Restart=on-failure + +[Install] +WantedBy=multi-user.target +Alias=influxd.service \ No newline at end of file diff --git a/states/influxdb/init.sls b/states/influxdb/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/influxdb/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/influxdb/install.sls b/states/influxdb/install.sls new file mode 100644 index 0000000..e854fbe --- /dev/null +++ b/states/influxdb/install.sls @@ -0,0 +1,55 @@ +--- +{%- from "influxdb/map.jinja" import influxdb with context %} +influxdb-group: + group.present: + - name: influxdb + - gid: {{ influxdb.group.gid }} + - watch_in: + - service: influxdb-service + +influxdb-user: + user.present: + - name: influxdb + - uid: {{ influxdb.user.uid }} + - gid: {{ influxdb.group.gid }} + - allow_uid_change: True + - allow_gid_change: True + - home: /var/lib/influxdb + - watch_in: + - service: influxdb-service + +influxdb-dependencies: + pkg.installed: + - pkgs: {{ influxdb.dependencies }} + +influxdb-archive-extract: + archive.extracted: + - name: {{ influxdb.release_dir }}/influxdb-{{ influxdb.version }} + - source: {{ influxdb.mirror }}/influxdb-{{ influxdb.version }}_{{ influxdb.os }}_{{ influxdb.arch }}.tar.gz + - skip_verify: True + - archive_format: tar + - options: --strip 4 + - enforce_toplevel: False + - if_missing: {{ influxdb.release_dir }}/influxdb-{{ influxdb.version }}/influxd + - watch_in: + - service: influxdb-service + +influxdb-bin-symlink: + file.symlink: + - name: {{ influxdb.install_dir }}/influxdb + - target: {{ influxdb.release_dir }}/influxdb-{{ influxdb.version }} + +influxdb-data-dir: + file.directory: + - name: {{ influxdb.data_dir }} + - user: {{ influxdb.user.uid }} + - group: {{ influxdb.group.gid }} + - watch_in: + - service: influxdb-service + +{%- for bin in ['influx', 'influxd'] %} +influxdb-{{ bin }}-symlink: + file.symlink: + - name: /usr/local/sbin/{{ bin }} + - target: {{ influxdb.release_dir }}/{{ bin }} +{%- endfor %} diff --git a/states/influxdb/kernelmap.yaml b/states/influxdb/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/influxdb/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/influxdb/map.jinja b/states/influxdb/map.jinja new file mode 100644 index 0000000..8b8b0ca --- /dev/null +++ b/states/influxdb/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "influxdb/defaults.yaml" as default_settings -%} + +{%- import_yaml "influxdb/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "influxdb/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='influxdb', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set influxdb = salt['pillar.get']('influxdb', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/influxdb/osarchmap.yaml b/states/influxdb/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/influxdb/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/influxdb/service.sls b/states/influxdb/service.sls new file mode 100644 index 0000000..c44fa5e --- /dev/null +++ b/states/influxdb/service.sls @@ -0,0 +1,15 @@ +--- +{%- from "influxdb/map.jinja" import influxdb with context %} +influxdb-service-file: + file.managed: + - name: /etc/systemd/system/influxdb.service + - source: salt://influxdb/influxdb.service.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + +influxdb-service: + service.running: + - name: influxdb + - enable: True \ No newline at end of file diff --git a/states/influxdb/v2/influxdb.service_v2.j2 b/states/influxdb/v2/influxdb.service_v2.j2 new file mode 100644 index 0000000..b45e998 --- /dev/null +++ b/states/influxdb/v2/influxdb.service_v2.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=InfluxDB is an open-source, distributed, time series database +Documentation=https://docs.influxdata.com/influxdb/ +After=network-online.target + +[Service] +User=influxdb +Group=influxdb +LimitNOFILE=65536 +ExecStart=/usr/local/influxdb/influxd +KillMode=control-group +Restart=on-failure + +[Install] +WantedBy=multi-user.target +Alias=influxd.service diff --git a/states/influxdb/v2/init_v2.sls b/states/influxdb/v2/init_v2.sls new file mode 100644 index 0000000..6b9bb64 --- /dev/null +++ b/states/influxdb/v2/init_v2.sls @@ -0,0 +1,58 @@ +--- +influxdb-group: + group.present: + - name: influxdb + - gid: {{ salt['pillar.get']('influxdb:gid') }} + +influxdb-user: + user.present: + - name: influxdb + - uid: {{ salt['pillar.get']('influxdb:uid') }} + - gid: {{ salt['pillar.get']('influxdb:gid') }} + - allow_uid_change: True + - allow_gid_change: True + - home: /var/lib/influxdb + +influxdb-archive-extract: + archive.extracted: + - source: {{ salt['pillar.get']('influxdb:mirror') }}/influxdb-{{ salt['pillar.get']('influxdb:version') }}_{{ salt['grains.get']('kernel')|lower }}_{{ salt['grains.get']('osarch') }}.tar.gz + - skip_verify: True + - archive_format: tar + - user: influxdb + - group: influxdb + - name: /usr/local + - if_missing: /usr/local/influxdb-{{ salt['pillar.get']('influxdb:version') }}_{{ salt['grains.get']('kernel')|lower }}_{{ salt['grains.get']('osarch') }} + +influxdb_directory: + file.directory: + - name: /var/lib/influxdb + - user: influxdb + - group: influxdb + - recurse: + - user + - group + +influxdb-link: + file.symlink: + - name: /usr/local/influxdb + - user: influxdb + - group: influxdb + - target: /usr/local/influxdb_{{ salt['pillar.get']('influxdb:version') }}_{{ salt['grains.get']('kernel')|lower }}_{{ salt['grains.get']('osarch') }} + - force: True + +influxdb-influx-link: + file.symlink: + - name: /usr/sbin/influx + - target: /usr/local/influxdb/influx + +influxdb-service-file: + file.managed: + - name: /lib/systemd/system/influxdb.service + - source: salt://influxdb/influxdb.service.j2 + - user: root + - group: root + +influxdb-service: + service.running: + - name: influxdb + - enable: True diff --git a/states/ipfs/init.sls b/states/ipfs/init.sls new file mode 100644 index 0000000..5344d13 --- /dev/null +++ b/states/ipfs/init.sls @@ -0,0 +1,89 @@ +--- +ipfs-group: + group.present: + - name: ipfs + - gid: 899 + +ipfs-user: + user.present: + - name: ipfs + - uid: 899 + - gid: 899 + - home: /var/lib/ipfs + - allow_uid_change: True + - allow_gid_change: True + +ipfs-dir: + file.directory: + - name: /var/lib/ipfs + - user: ipfs + - group: ipfs + - mode: 0750 + - recurse: + - user + +ipfs-init: + cmd.run: + - name: /usr/local/sbin/ipfs init + - runas: ipfs + - cwd: /var/lib/ipfs + - success_retcodes: + - 0 + - 1 + - watch-in: + - service: ipfs-service + +ipfs-set-storagemax: + cmd.run: + - name: /usr/local/sbin/ipfs config Datastore.StorageMax "20GB" + - runas: ipfs + - cwd: /var/lib/ipfs + - watch-in: + - service: ipfs-service + +ipfs-set-headers-1: + cmd.run: + - name: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]' + - runas: ipfs + - cwd: /var/lib/ipfs + - watch-in: + - service: ipfs-service + +ipfs-set-headers-2: + cmd.run: + #- name: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://localhost:8888", "http://127.0.0.1:5001", "https://webui.ipfs.io"]' + - name: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]' + - runas: ipfs + - cwd: /var/lib/ipfs + - watch-in: + - service: ipfs-service + +ipfs-set-api: + cmd.run: + - name: /usr/local/sbin/ipfs config Addresses.API "/ip4/0.0.0.0/tcp/5001" + - runas: ipfs + - cwd: /var/lib/ipfs + - watch-in: + - service: ipfs-service + +ipfs-set-gateway: + cmd.run: + - name: /usr/local/sbin/ipfs config Addresses.Gateway "/ip4/0.0.0.0/tcp/8888" + - runas: ipfs + - cwd: /var/lib/ipfs + - watch-in: + - service: ipfs-service + +ipfs-service-file: + file.managed: + - name: /etc/systemd/system/ipfs.service + - source: salt://ipfs/ipfs.service + - watch-in: + - service: ipfs-service + +ipfs-service: + service.running: + - name: ipfs + - enable: True + - require: + - file: ipfs-dir \ No newline at end of file diff --git a/states/ipfs/ipfs.service b/states/ipfs/ipfs.service new file mode 100644 index 0000000..afa5ba3 --- /dev/null +++ b/states/ipfs/ipfs.service @@ -0,0 +1,20 @@ +[Unit] +Description=ipfs p2p daemon +After=network.target +Requires=network.target + +[Service] +Type=simple +User=ipfs +RestartSec=1 +Restart=always +PermissionsStartOnly=true +Nice=18 +LimitNOFILE=8192 +Environment=IPFS_FD_MAX=8192 +EnvironmentFile=-/etc/sysconfig/ipfs +StandardOutput=journal +ExecStart=/usr/local/sbin/ipfs daemon + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/iptables/init.sls b/states/iptables/init.sls new file mode 100644 index 0000000..f20b099 --- /dev/null +++ b/states/iptables/init.sls @@ -0,0 +1,96 @@ +--- +iptables-pkg: + pkg.latest: + - name: iptables + +iptables-service-config-1: + file.managed: + - name: /etc/systemd/system/iptables.service + - source: salt://iptables/iptables.service.j2 + - template: jinja + - watch_in: + cmd: iptables-reload-systemd + - require: + - pkg: iptables-pkg + +iptables-service-config-2: + file.managed: + - name: /lib/systemd/system/iptables.service + - source: salt://iptables/iptables.service.j2 + - template: jinja + - watch_in: + cmd: iptables-reload-systemd + - require: + - pkg: iptables-pkg + +iptables-reload-systemd: + cmd.run: + - name: systemctl daemon-reload + - require: + - pkg: iptables-pkg + +iptables-service-script: + file.managed: + - name: /sbin/iptables-service + - source: salt://iptables/iptables-service.j2 + - template: jinja + - user: root + - group: root + - mode: 0755 + - require: + - pkg: iptables-pkg + +iptables-config-dir: + file.directory: + - name: /etc/iptables + +iptables-main-config: + file.managed: + - name: /etc/iptables/iptables.conf + - source: salt://iptables/iptables.conf.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +iptables-reset-config: + file.managed: + - name: /etc/iptables/iptables.reset.conf + - source: salt://iptables/iptables.conf.reset.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +ip6tables-main-config: + file.managed: + - name: /etc/iptables/ip6tables.conf + - source: salt://iptables/ip6tables.conf.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +ip6tables-reset-config: + file.managed: + - name: /etc/iptables/ip6tables.reset.conf + - source: salt://iptables/ip6tables.conf.reset.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +iptables-service: + service.running: + - name: iptables + - enable: True + - require: + - pkg: iptables-pkg \ No newline at end of file diff --git a/states/iptables/ip6tables.conf.j2 b/states/iptables/ip6tables.conf.j2 new file mode 100644 index 0000000..b092b64 --- /dev/null +++ b/states/iptables/ip6tables.conf.j2 @@ -0,0 +1,18 @@ +*nat +:PREROUTING ACCEPT [10:1400] +:INPUT ACCEPT [10:1400] +:OUTPUT ACCEPT [30:15184] +:POSTROUTING ACCEPT [30:15184] +COMMIT +*filter +:INPUT DROP [7132:3757309] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [133292:28518143] +-A INPUT -i lo -j ACCEPT +-A INPUT -i tun+ -j ACCEPT +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p ipv6-icmp -j ACCEPT +{% for pub_port in salt['pillar.get']('public_ports') %}-A INPUT -p {{ pub_port.proto }} -m {{ pub_port.proto }} --dport {{ pub_port.port }} -j ACCEPT +{% endfor %}{% for net in salt['pillar.get']('ipv6_networks') %}-A INPUT -s {{ net.ip }}/{{ net.mask }} -j ACCEPT +{% endfor %}-A INPUT -j LOG +COMMIT \ No newline at end of file diff --git a/states/iptables/ip6tables.conf.reset.j2 b/states/iptables/ip6tables.conf.reset.j2 new file mode 100644 index 0000000..3f4c684 --- /dev/null +++ b/states/iptables/ip6tables.conf.reset.j2 @@ -0,0 +1,18 @@ +*mangle +:PREROUTING ACCEPT [5346:7156816] +:INPUT ACCEPT [5346:7156816] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [5178:4339396] +:POSTROUTING ACCEPT [5200:4342124] +COMMIT +*nat +:PREROUTING ACCEPT [2159:266785] +:INPUT ACCEPT [2093:262909] +:OUTPUT ACCEPT [72:6182] +:POSTROUTING ACCEPT [72:6182] +COMMIT +*filter +:INPUT ACCEPT [80:9692] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [70:34623] +COMMIT \ No newline at end of file diff --git a/states/iptables/iptables-service.j2 b/states/iptables/iptables-service.j2 new file mode 100644 index 0000000..00b8c53 --- /dev/null +++ b/states/iptables/iptables-service.j2 @@ -0,0 +1,35 @@ +#!/bin/bash + +flush() +{ + for chain in INPUT OUTPUT FORWARD + do + iptables -P $chain ACCEPT + iptables -F $chain + ip6tables -P $chain ACCEPT + ip6tables -F $chain + done + #for chain in INPUT OUTPUT PREROUTING POSTROUTING + for chain in POSTROUTING + do + iptables -t nat -F $chain + ip6tables -t nat -F $chain + done +} + +load() +{ + iptables-restore -n /etc/iptables/iptables.conf + ip6tables-restore -n /etc/iptables/ip6tables.conf +} + +if [[ $1 == 'start' || $1 == 'restart' ]] +then + flush + load +elif [[ $1 == 'stop' ]] +then + flush +else + echo "Please provide start or stop" +fi \ No newline at end of file diff --git a/states/iptables/iptables.conf.j2 b/states/iptables/iptables.conf.j2 new file mode 100644 index 0000000..e3f1ff0 --- /dev/null +++ b/states/iptables/iptables.conf.j2 @@ -0,0 +1,25 @@ +*filter +:INPUT DROP [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -i lo -j ACCEPT +-A INPUT -i tun+ -j ACCEPT +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +{%- for pub_port in salt['pillar.get']('public_ports') %} +-A INPUT -p {{ pub_port.proto }} -m {{ pub_port.proto }} --dport {{ pub_port.port }} -j ACCEPT +{%- endfor %} +{%- for net in salt['pillar.get']('ipv4_networks') %} +-A INPUT -s {{ net.ip }}/{{ net.mask }} -j ACCEPT +{%- endfor %} +-A INPUT -j LOG +COMMIT +*nat +:PREROUTING ACCEPT [0:0] +:INPUT ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +{%- for net in salt['pillar.get']('nats') %} +-A POSTROUTING -s {{ net.ip }}/{{ net.mask }} -j MASQUERADE +{%- endfor %} +COMMIT \ No newline at end of file diff --git a/states/iptables/iptables.conf.reset.j2 b/states/iptables/iptables.conf.reset.j2 new file mode 100644 index 0000000..3f4c684 --- /dev/null +++ b/states/iptables/iptables.conf.reset.j2 @@ -0,0 +1,18 @@ +*mangle +:PREROUTING ACCEPT [5346:7156816] +:INPUT ACCEPT [5346:7156816] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [5178:4339396] +:POSTROUTING ACCEPT [5200:4342124] +COMMIT +*nat +:PREROUTING ACCEPT [2159:266785] +:INPUT ACCEPT [2093:262909] +:OUTPUT ACCEPT [72:6182] +:POSTROUTING ACCEPT [72:6182] +COMMIT +*filter +:INPUT ACCEPT [80:9692] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [70:34623] +COMMIT \ No newline at end of file diff --git a/states/iptables/iptables.service.j2 b/states/iptables/iptables.service.j2 new file mode 100644 index 0000000..9a123cd --- /dev/null +++ b/states/iptables/iptables.service.j2 @@ -0,0 +1,14 @@ +[Unit] +Description=Iptables firewall rules +Documentation=man:iptables(8) + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/bash -c "/sbin/iptables-service start" +ExecReload=/bin/bash -c "/sbin/iptables-service restart" +ExecStop=/bin/bash -c "/sbin/iptables-service stop" +StandardOutput=syslog + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/iptables/iptables.sls b/states/iptables/iptables.sls new file mode 100644 index 0000000..38dd307 --- /dev/null +++ b/states/iptables/iptables.sls @@ -0,0 +1,92 @@ +--- +iptables-service-config-1: + file.managed: + - name: /etc/systemd/system/iptables.service + - source: salt://firewall/iptables.service.j2 + - template: jinja + - watch_in: + cmd: iptables-reload-systemd + - require: + - pkg: iptables-pkg + +iptables-service-config-2: + file.managed: + - name: /lib/systemd/system/iptables.service + - source: salt://firewall/iptables.service.j2 + - template: jinja + - watch_in: + cmd: iptables-reload-systemd + - require: + - pkg: iptables-pkg + +iptables-reload-systemd: + cmd.run: + - name: systemctl daemon-reload + - require: + - pkg: iptables-pkg + +iptables-service-script: + file.managed: + - name: /sbin/iptables-service + - source: salt://firewall/iptables-service.j2 + - template: jinja + - user: root + - group: root + - mode: 0755 + - require: + - pkg: iptables-pkg + +iptables-config-dir: + file.directory: + - name: /etc/iptables + +iptables-main-config: + file.managed: + - name: /etc/iptables/iptables.conf + - source: salt://firewall/iptables.conf.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +iptables-reset-config: + file.managed: + - name: /etc/iptables/iptables.reset.conf + - source: salt://firewall/iptables.conf.reset.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +ip6tables-main-config: + file.managed: + - name: /etc/iptables/ip6tables.conf + - source: salt://firewall/ip6tables.conf.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +ip6tables-reset-config: + file.managed: + - name: /etc/iptables/ip6tables.reset.conf + - source: salt://firewall/ip6tables.conf.reset.j2 + - template: jinja + - watch_in: + - service: iptables-service + - require: + - pkg: iptables-pkg + - file: iptables-config-dir + +iptables-service: + service.running: + - name: iptables + - enable: True + - require: + - pkg: iptables-pkg \ No newline at end of file diff --git a/states/java/defaults.yaml b/states/java/defaults.yaml new file mode 100644 index 0000000..239c4c0 --- /dev/null +++ b/states/java/defaults.yaml @@ -0,0 +1,8 @@ +--- +java: + enabled: true + fetch_url: https://paulbsd-pub.s3.fr-par.scw.cloud/java + version: "11.0.5" + install_dir: /usr/java + os: linux + arch: x64 \ No newline at end of file diff --git a/states/java/init.sls b/states/java/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/java/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/java/install.sls b/states/java/install.sls new file mode 100644 index 0000000..2e3310f --- /dev/null +++ b/states/java/install.sls @@ -0,0 +1,39 @@ +--- +{%- from "java/map.jinja" import java with context %} +java_directory: + file.directory: + - name: {{ java.install_dir }} + - user: root + - group: root + - dir_mode: 755 + - file_mode: 644 + +java_extract: + archive.extracted: + - name: {{ java.install_dir }} + - source: {{ java.fetch_url }}/jdk-{{ java.version }}_{{ java.os }}-{{ java.arch }}_bin.tar.gz + - user: root + - group: root + - skip_verify: True + - if_missing: {{ java.install_dir }}/jdk-{{ java.version }} + +java_link: + file.symlink: + - name: {{ java.install_dir }}/default + - target: {{ java.install_dir }}/jdk-{{ java.version }} + - force: True + - user: root + - group: root + +java_updatealternatives_script: + file.managed: + - name: {{ java.install_dir }}/default/update-alternatives-java.sh + - source: salt://java/update-alternatives-java.sh.j2 + - template: jinja + - user: root + - group: root + - mode: 755 + +java_default: + cmd.run: + - name: {{ java.install_dir }}/default/update-alternatives-java.sh \ No newline at end of file diff --git a/states/java/kernelmap.yaml b/states/java/kernelmap.yaml new file mode 100644 index 0000000..b01f41d --- /dev/null +++ b/states/java/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: linux \ No newline at end of file diff --git a/states/java/map.jinja b/states/java/map.jinja new file mode 100644 index 0000000..a215f2d --- /dev/null +++ b/states/java/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "java/defaults.yaml" as default_settings %} + +{%- import_yaml "java/kernelmap.yaml" as kernelmap %} +{%- import_yaml "java/osarchmap.yaml" as osarchmap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='java', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +%} + +{%- set java = salt['pillar.get']('java', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/java/osarchmap.yaml b/states/java/osarchmap.yaml new file mode 100644 index 0000000..9c56fe7 --- /dev/null +++ b/states/java/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: x64 + +x86_64: + arch: x64 + +# 386: +# arch: 386 + +# arm64: +# arch: arm64 + +# armv6l: +# arch: arm + +# armv7l: +# arch: arm + +# armhf: +# arch: arm \ No newline at end of file diff --git a/states/java/update-alternatives-java.sh.j2 b/states/java/update-alternatives-java.sh.j2 new file mode 100644 index 0000000..1f22940 --- /dev/null +++ b/states/java/update-alternatives-java.sh.j2 @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +{%- from "java/map.jinja" import java with context %} +for item in $(ls {{ java.install_dir }}/default/bin) +do + update-alternatives --install /usr/bin/${item} ${item} {{ java.install_dir }}/default/bin/${item} 1 + update-alternatives --set ${item} {{ java.install_dir }}/default/bin/${item} +done \ No newline at end of file diff --git a/states/maildb/defaults.yaml b/states/maildb/defaults.yaml new file mode 100644 index 0000000..5bfa2af --- /dev/null +++ b/states/maildb/defaults.yaml @@ -0,0 +1,13 @@ +--- +maildb: + enabled: true + appdir: /usr/local/apps/maildb + datadir: /usr/local/data/maildb + configfile: /usr/local/apps/maildb/maildb.cfg + config: + file: /usr/local/apps/maildb/maildb.ini + db: + hostname: localhost + username: username + password: password + database: maildb \ No newline at end of file diff --git a/states/maildb/init.sls b/states/maildb/init.sls new file mode 100644 index 0000000..2c44435 --- /dev/null +++ b/states/maildb/init.sls @@ -0,0 +1,53 @@ +--- +{%- from "maildb/map.jinja" import maildb with context %} +maildb-pkg: + pkg.latest: + - pkgs: + - python + - python-mysqldb + - python3 + - python3-mysqldb + +maildb-user-vmail: + user.present: + - name: vmail + - home: /home/vmail + +maildb-apps-dir: + file.directory: + - name: {{ maildb.appdir }} + - user: vmail + - group: vmail + - mode: 0755 + - makedirs: true + +maildb-data-dir: + file.directory: + - name: {{ maildb.datadir }} + - user: vmail + - group: vmail + - mode: 0755 + - makedirs: true + +maildb-script: + file.managed: + - name: {{ maildb.appdir }}/maildb.py + - source: salt://maildb/maildb.py + - user: vmail + - group: vmail + - mode: 0755 + - require: + - file: maildb-apps-dir + - file: maildb-data-dir + +maildb-config: + file.managed: + - name: {{ maildb.appdir }}/maildb.ini + - source: salt://maildb/maildb.ini.j2 + - user: vmail + - group: vmail + - mode: 0755 + - template: jinja + - require: + - file: maildb-apps-dir + - file: maildb-data-dir \ No newline at end of file diff --git a/states/maildb/maildb.ini.j2 b/states/maildb/maildb.ini.j2 new file mode 100644 index 0000000..46f6eaf --- /dev/null +++ b/states/maildb/maildb.ini.j2 @@ -0,0 +1,6 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "maildb/map.jinja" import maildb with context %} +[maildb] +{%- for param, value in maildb.db.items() %} +{{ param }}={{ value }} +{%- endfor %} \ No newline at end of file diff --git a/states/maildb/maildb.py b/states/maildb/maildb.py new file mode 100644 index 0000000..da29254 --- /dev/null +++ b/states/maildb/maildb.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +#-*- coding: utf-8 -*- + +import argparse +import sys +import MySQLdb +import configparser +import email +from email.utils import parseaddr + + +def DBConfig(configfile): + config = configparser.ConfigParser() + config.read(configfile) + + d_dbconfig = { + 'host' : config.get("maildb", "hostname"), + 'user' : config.get("maildb", "username"), + 'passwd' : config.get("maildb", "password"), + 'db' : config.get("maildb", "database") + } + + return d_dbconfig + + +def ConnectMysqlDB(dbconfig): + conn = MySQLdb.connect(**dbconfig) + + return conn, conn.cursor() + + +def CloseDB(conn): + conn.close() + + +def CreateDB(conn, cursor): + try: + cursor.execute('''CREATE TABLE IF NOT EXISTS mail (id int(10) PRIMARY KEY AUTO_INCREMENT, sender varchar(50), recipient varchar(50), date datetime NOT NULL DEFAULT current_timestamp(), content mediumtext);''') + conn.commit() + except Exception as e: + print(e) + + +def InsertMail(conn, cursor, sender, recipient, content): + try: + cursor.execute("INSERT INTO mail (sender, recipient, content) values ('%s','%s','%s')" % (sender, recipient, content)) + conn.commit() + except Exception as e: + print(e) + + +def ParseMail(input_data): + content = "" + for line in input_data: + if line != "": + content += line + + msgobj = email.message_from_string(content) + sender = email.utils.parseaddr(msgobj['From'])[1] + recipient = email.utils.parseaddr(msgobj['To'])[1] + + return sender, recipient, content + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-c", "--config", help="config file path", default="maildb.cfg") + parser.add_argument("sender", help="sender") + parser.add_argument("recipient", help="recipient") + args = parser.parse_args() + + d_dbconfig = DBConfig(args.config) + + maildata = ParseMail(sys.stdin) + sender = maildata[0] + recipient = maildata[1] + mailcontent = maildata[2] + + conn, cursor = ConnectMysqlDB(d_dbconfig) + CreateDB(conn, cursor) + + InsertMail(conn, cursor, sender, recipient, mailcontent) + + CloseDB(conn) + + +if __name__ == '__main__': + main() diff --git a/states/maildb/map.jinja b/states/maildb/map.jinja new file mode 100644 index 0000000..d8393b7 --- /dev/null +++ b/states/maildb/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "maildb/defaults.yaml" as default_settings %} + +{%- set defaults = salt['grains.filter_by'](default_settings,default='maildb') %} + +{%- set maildb = salt['pillar.get']('maildb', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/mariadb/config.sls b/states/mariadb/config.sls new file mode 100644 index 0000000..97b2dc6 --- /dev/null +++ b/states/mariadb/config.sls @@ -0,0 +1,15 @@ +--- +{%- from "mariadb/map.jinja" import mariadb with context %} +mariadb-config: + file.managed: + - name: /etc/mysql/mariadb.conf.d/server.cnf + - source: salt://mariadb/server.cnf.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - require: + - pkg: mariadb-install-pkgs + - pip: mariadb-install-pip-pkgs + - watch_in: + - service: mariadb-service \ No newline at end of file diff --git a/states/mariadb/databases.sls b/states/mariadb/databases.sls new file mode 100644 index 0000000..8e0fd81 --- /dev/null +++ b/states/mariadb/databases.sls @@ -0,0 +1,9 @@ +--- +{%- from "mariadb/map.jinja" import mariadb with context %} +{%- for key, value in mariadb.databases.items() %} +mariadb-database-{{ value.name }}: + mysql_database.present: + - name: {{ value.name }} + - connection_user: {{ mariadb.connection_user }} + - connection_pass: {{ mariadb.connection_pass }} +{%- endfor %} \ No newline at end of file diff --git a/states/mariadb/defaults.yaml b/states/mariadb/defaults.yaml new file mode 100644 index 0000000..a8c0a3f --- /dev/null +++ b/states/mariadb/defaults.yaml @@ -0,0 +1,42 @@ +--- +mariadb: + enabled: true + connection_user: root + connection_pass: password + connection_conv: None + databases: {} + users: {} + config: + mysqld: + name: mysqld + options: + binlog_format: ROW + bulk_insert_buffer_size: 16M + expire_logs_days: 10 + event_scheduler: 'ON' + innodb_buffer_pool_size: 256M + innodb_file_per_table: 1 + innodb_flush_method: O_DIRECT + innodb_io_capacity: 400 + innodb_log_buffer_size: 8M + innodb_open_files: 400 + key_buffer_size: 128M + log_slow_verbosity: query_plan + log_warnings: 2 + log-bin: localhost + long_query_time: 10 + max_allowed_packet: 16M + max_binlog_size: 100M + max_connections: 20 + max_heap_table_size: 32M + query_cache_limit: 128K + query_cache_size: 64M + read_buffer_size: 2M + read_rnd_buffer_size: 1M + server-id: 9999 + slow_query_log_file: /var/log/mysql/mariadb-slow.log + sort_buffer_size: 8M + table_open_cache: 400 + thread_cache_size: 128 + tmp_table_size: 32M + wait_timeout: 600 \ No newline at end of file diff --git a/states/mariadb/init.sls b/states/mariadb/init.sls new file mode 100644 index 0000000..43f5f7c --- /dev/null +++ b/states/mariadb/init.sls @@ -0,0 +1,7 @@ +--- +include: + - .install + - .config + - .service + - .databases + - .users \ No newline at end of file diff --git a/states/mariadb/install.sls b/states/mariadb/install.sls new file mode 100644 index 0000000..0419de3 --- /dev/null +++ b/states/mariadb/install.sls @@ -0,0 +1,15 @@ +--- +mariadb-install-pkgs: + pkg.installed: + - pkgs: + - libmariadb-dev + - libmariadbclient18 + - mariadb-client + - mariadb-backup + - mariadb-server + +{%- for pkg in ['mysqlclient'] %} +mariadb-install-pip-pkgs: + pip.installed: + - name: {{ pkg }} +{%- endfor %} \ No newline at end of file diff --git a/states/mariadb/map.jinja b/states/mariadb/map.jinja new file mode 100644 index 0000000..731ff93 --- /dev/null +++ b/states/mariadb/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "mariadb/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='mariadb') -%} + +{%- set mariadb = salt['pillar.get']('mariadb', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/mariadb/server.cnf.j2 b/states/mariadb/server.cnf.j2 new file mode 100644 index 0000000..c36b5ee --- /dev/null +++ b/states/mariadb/server.cnf.j2 @@ -0,0 +1,9 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "mariadb/map.jinja" import mariadb with context -%} +{%- for section, elems in mariadb.config.items() %} +[{{ elems.name }}] +{%- for key, value in elems.options.items() %} +{{ key }}={{ value }} +{%- endfor %} +{%- endfor %} \ No newline at end of file diff --git a/states/mariadb/service.sls b/states/mariadb/service.sls new file mode 100644 index 0000000..1c7f3d6 --- /dev/null +++ b/states/mariadb/service.sls @@ -0,0 +1,5 @@ +--- +mariadb-service: + service.running: + - name: mariadb + - enable: True \ No newline at end of file diff --git a/states/mariadb/users.sls b/states/mariadb/users.sls new file mode 100644 index 0000000..db335a8 --- /dev/null +++ b/states/mariadb/users.sls @@ -0,0 +1,23 @@ +--- +{%- from "mariadb/map.jinja" import mariadb with context %} +{%- for key, user in mariadb.users.items() %} +mariadb-user-{{ user.name }}: + mysql_user.present: + - name: {{ user.name }} + - password: {{ user.password }} + - host: '{{ user.host }}' + - connection_user: {{ mariadb.connection_user }} + - connection_pass: {{ mariadb.connection_pass }} + +{%- for grant in user.grants %} +mariadb-grants-{{ grant.name }}: + mysql_grants.present: + - name: {{ grant.name }} + - grant: '{{ grant.grant }}' + - database: '{{ grant.database }}' + - user: '{{ user.name }}' + - host: '{{ user.host }}' + - connection_user: {{ mariadb.connection_user }} + - connection_pass: {{ mariadb.connection_pass }} +{%- endfor %} +{%- endfor %} diff --git a/states/misc/init.sls b/states/misc/init.sls new file mode 100644 index 0000000..7b87592 --- /dev/null +++ b/states/misc/init.sls @@ -0,0 +1,35 @@ +--- +us_locale: + locale.present: + - name: en_US.UTF-8 + +default_locale: + locale.system: + - name: en_US.UTF-8 + - require: + - locale: us_locale + +misc-public-dir: + file.directory: + - name: /home/public + - user: root + - group: root + - mode: 0755 + +{%- for file in salt['pillar.get']('misc_files') %} +{{ file.name }}: + file.managed: + - name: {{ file.dest }} + - source: {{ file.src }} + - source_hash: sha256={{ file.checksum }} + - user: root + - group: root + - mode: 644 +{%- endfor %} + +misc-files-delete: + file.absent: + - names: +{%- for file in salt['pillar.get']('misc_files_delete') %} + - {{ file }} +{%- endfor %} diff --git a/states/molotov/init.sls b/states/molotov/init.sls new file mode 100644 index 0000000..c6d1b93 --- /dev/null +++ b/states/molotov/init.sls @@ -0,0 +1,28 @@ +--- +{%- if not salt['file.file_exists']( salt['pillar.get']('molotov:dest_path') ) or not salt['file.check_hash']( salt['pillar.get']('molotov:dest_path'), salt['pillar.get']('molotov:file_sha256sum') ) %} +molotov-install: + file.managed: + - name: {{ salt['pillar.get']('molotov:dest_path') }} + - source: {{ salt['pillar.get']('molotov:url') }}/{{ salt['pillar.get']('molotov:file') }} + - source_hash: sha256={{ salt['pillar.get']('molotov:file_sha256sum') }} + - user: root + - group: root + - mode: 755 +{%- endif %} + +molotov-icon: + file.managed: + - name: /usr/share/icons/molotov.png + - source: salt://molotov/molotov.png + - user: root + - group: root + - mode: 644 + +molotov-desktop-entry: + file.managed: + - name: /usr/share/applications/molotov.desktop + - source: salt://molotov/molotov.desktop.j2 + - template: jinja + - user: root + - group: root + - mode: 644 diff --git a/states/molotov/molotov.desktop.j2 b/states/molotov/molotov.desktop.j2 new file mode 100644 index 0000000..fdbc7a4 --- /dev/null +++ b/states/molotov/molotov.desktop.j2 @@ -0,0 +1,12 @@ +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=Molotov +Comment=L'app pour regarder la TV, gratuitement +Exec={{ salt['pillar.get']('molotov:dest_path') }} +Icon=/usr/share/icons/molotov.png +Terminal=false +StartupWMClass=Molotov +Type=Application +Categories=AudioVideo;Player; +X-Desktop-File-Install-Version=0.22 \ No newline at end of file diff --git a/states/molotov/molotov.png b/states/molotov/molotov.png new file mode 100644 index 0000000..99ac819 Binary files /dev/null and b/states/molotov/molotov.png differ diff --git a/states/motd/init.sls b/states/motd/init.sls new file mode 100644 index 0000000..6404c8f --- /dev/null +++ b/states/motd/init.sls @@ -0,0 +1,6 @@ +--- +motd-file: + file.managed: + - name: /etc/motd + - source: salt://motd/motd.j2 + - template: jinja \ No newline at end of file diff --git a/states/motd/motd.j2 b/states/motd/motd.j2 new file mode 100644 index 0000000..cd59606 --- /dev/null +++ b/states/motd/motd.j2 @@ -0,0 +1,2 @@ +{{ salt['cmd.run']('figlet -w 120 '+salt['grains.get']('host')) }} + diff --git a/states/netbox/defaults.yaml b/states/netbox/defaults.yaml new file mode 100644 index 0000000..3fb05ac --- /dev/null +++ b/states/netbox/defaults.yaml @@ -0,0 +1,97 @@ +--- +netbox: + enabled: true + install_dir: '/usr/local/apps' + release_dir: '/usr/local/apps/releases' + archive_url: 'https://github.com/netbox-community/netbox/archive' + version: '2.6.0' + gunicorn: + bind_addr: '127.0.0.1' + bind_port: '8888' + run_user: 'www-data' + pkgs: + - "build-essential" + - "graphviz" + - "libffi-dev" + - "libjpeg-dev" + - "libpq-dev" + - "libssl-dev" + - "libxml2-dev" + - "libxslt1-dev" + - "python3" + - "python3-dev" + - "python3-pip" + - "python3-virtualenv" + - "virtualenv" + - "zlib1g-dev" + config: + allowed_hosts: "[ '127.0.0.1' ]" + database: + name: "netbox" + user: + password: + host: "localhost" + port: + conn_max_age: 300 + secret_key: "azerty" + redis: + tasks: + host: "localhost" + port: 6379 + password: + database: 0 + cache_database: 1 + default_timeout: 300 + ssl: False + caching: + host: "localhost" + port: 6379 + password: + database: 0 + cache_database: 1 + default_timeout: 300 + ssl: False + admins: + - ['John Doe', 'jdoe@example.com'] + - ['Bob Reptincel', 'breptincel@example.com'] + banner_top: "" + banner_bottom: "" + banner_login: "NetBox" + base_path: "" + cache_timeout: 900 + changelog_retention: 90 + cors_origin_allow_all: False + cors_origin_whitelist: [] + cors_origin_regex_whitelist: [] + debug: False + email: + server: "localhost" + port: 25 + username: username + password: password + timeout: 10 + from_email: user@domain.com + enforce_global_unique: False + exempt_view_permissions: [] + logging: {} + login_required: False + login_timeout: 3600 + maintenance_mode: False + max_page_size: 1000 + metrics_enabled: False + napalm_username: '' + napalm_password: '' + napalm_timeout: 30 + napalm_args: {} + paginate_count: 50 + prefer_ipv4: False + session_file_path: "/tmp" + session_cookie_age: 3600 + time_zone: "UTC" + webhooks_enabled: False + 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" \ No newline at end of file diff --git a/states/netbox/init.sls b/states/netbox/init.sls new file mode 100644 index 0000000..131d140 --- /dev/null +++ b/states/netbox/init.sls @@ -0,0 +1,6 @@ +--- +include: + - redis + - .pkgs + - .install + - .service \ No newline at end of file diff --git a/states/netbox/install.sls b/states/netbox/install.sls new file mode 100644 index 0000000..54f9177 --- /dev/null +++ b/states/netbox/install.sls @@ -0,0 +1,72 @@ +--- +{%- from "netbox/map.jinja" import netbox with context %} +netbox-virtualenv-pkg: + pip.installed: + - name: virtualenv + - bin_env: /usr/bin/pip3 + +netbox-archive-extract: + archive.extracted: + - name: {{ netbox.release_dir }} + - source: {{ netbox.archive_url }}/v{{ netbox.version }}.tar.gz + - skip_verify: True + +netbox-install-link: + file.symlink: + - name: {{ netbox.install_dir }}/netbox + - target: {{ netbox.release_dir }}/netbox-{{ netbox.version }} + - watch_in: + - service: netbox-service + - require: + - archive: netbox-archive-extract + +netbox-virtualenv: + virtualenv.managed: + - name: {{ netbox.install_dir }}/netbox + - requirements: {{ netbox.install_dir }}/netbox/requirements.txt + - python: /usr/bin/python3 + - require: + - pip: netbox-virtualenv-pkg + +netbox-gunicorn-pkg: + pip.installed: + - name: gunicorn + - bin_env: {{ netbox.install_dir }}/netbox/bin/pip3 + - require: + - virtualenv: netbox-virtualenv + +netbox-gunicorn-execfile: + file.managed: + - name: {{ netbox.install_dir }}/netbox/gunicorn.py + - source: salt://netbox/templates/gunicorn.py.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + +netbox-config-file: + file.managed: + - name: {{ netbox.install_dir }}/netbox/netbox/netbox/configuration.py + - source: salt://netbox/templates/configuration.py.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + +netbox-migration: + module.run: + - name: django.migrate + - settings_module: netbox.settings + - pythonpath: {{ netbox.install_dir }}/netbox/netbox + - bin_env: {{ netbox.install_dir }}/netbox + - require: + - virtualenv: netbox-virtualenv + +netbox-install-static-files: + module.run: + - name: django.collectstatic + - settings_module: netbox.settings + - pythonpath: {{ netbox.install_dir }}/netbox/netbox + - bin_env: {{ netbox.install_dir }}/netbox + - require: + - virtualenv: netbox-virtualenv \ No newline at end of file diff --git a/states/netbox/map.jinja b/states/netbox/map.jinja new file mode 100644 index 0000000..93cb445 --- /dev/null +++ b/states/netbox/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "netbox/defaults.yaml" as defaults -%} + +{%- set netbox = salt['pillar.get']( + 'netbox', + default=defaults.netbox, + merge=True + ) +-%} \ No newline at end of file diff --git a/states/netbox/pkgs.sls b/states/netbox/pkgs.sls new file mode 100644 index 0000000..8e1e14f --- /dev/null +++ b/states/netbox/pkgs.sls @@ -0,0 +1,8 @@ +--- +{%- from "netbox/map.jinja" import netbox with context %} +netbox_pkg_reqs: + pkg.latest: + - pkgs: +{%- for pkg in netbox.pkgs %} + - {{ pkg }} +{%- endfor %} \ No newline at end of file diff --git a/states/netbox/service.sls b/states/netbox/service.sls new file mode 100644 index 0000000..4d684dd --- /dev/null +++ b/states/netbox/service.sls @@ -0,0 +1,14 @@ +--- +netbox-service-file: + file.managed: + - name: /etc/systemd/system/netbox.service + - source: salt://netbox/templates/netbox.service.j2 + - template: jinja + - user: root + - group: root + - mode: 0755 + +netbox-service: + service.running: + - name: netbox + - enable: True \ No newline at end of file diff --git a/states/netbox/templates/configuration.py.j2 b/states/netbox/templates/configuration.py.j2 new file mode 100644 index 0000000..f8f2c71 --- /dev/null +++ b/states/netbox/templates/configuration.py.j2 @@ -0,0 +1,47 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "netbox/map.jinja" import netbox with context -%} + +{%- macro subdict(data) %} +{%- for item, value in data.items() %} +{%- if value is string or value == "" %} + "{{ item|upper }}": "{{ value }}", +{%- else %} + "{{ item|upper }}": {{ value }}, +{%- endif %} +{%- endfor %} +{%- endmacro %} + +{%- for item, value in netbox.config.items() %} +{%- if value is mapping %} +{{ item|upper }} = { +{%- for item2, value2 in value.items() %} +{%- if value2 is mapping %} +"{{ item2 }}": { + {{ subdict(value2) }} +}{%- if not loop.last -%},{%- endif -%} +{%- elif value2 is string or value2 == "" %} + "{{ item2|upper }}": "{{ value2 }}", +{%- else %} + "{{ item2|upper }}": {{ value2 }}, +{%- endif %} +{%- endfor %} +} +{% elif value is iterable and value is not string %} +{{ item|upper }} = [ + {%- for v in value %} + {%- if v is string %} + "{{ v }}", + {%- else %} + {{ v }}, + {%- endif %} + {%- endfor %} +] +{% else %} +{%- if value is string or value == "" %} +{{ item|upper }} = "{{ value }}" +{%- else %} +{{ item|upper }} = {{ value }} +{%- endif %} +{%- endif %} +{%- endfor %} \ No newline at end of file diff --git a/states/netbox/templates/gunicorn.py.j2 b/states/netbox/templates/gunicorn.py.j2 new file mode 100644 index 0000000..b93cd7f --- /dev/null +++ b/states/netbox/templates/gunicorn.py.j2 @@ -0,0 +1,10 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "netbox/map.jinja" import netbox with context -%} +command = '{{ netbox.install_dir }}/netbox/bin/gunicorn' +pythonpath = '{{ netbox.install_dir }}/netbox/netbox' +bind = '{{ netbox.gunicorn.bind_addr }}:{{ netbox.gunicorn.bind_port }}' +workers = 3 +user = '{{ netbox.gunicorn.run_user }}' +max_requests = 5000 +max_requests_jitter = 500 \ No newline at end of file diff --git a/states/netbox/templates/netbox.service.j2 b/states/netbox/templates/netbox.service.j2 new file mode 100644 index 0000000..aa44253 --- /dev/null +++ b/states/netbox/templates/netbox.service.j2 @@ -0,0 +1,18 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "netbox/map.jinja" import netbox with context -%} +[Unit] +Description=Netbox +After=network.target postgresql.service redis.service + +[Service] +Type=notify +NotifyAccess=all +LimitNOFILE=8192 +ExecStart={{ netbox.install_dir }}/netbox/bin/gunicorn -c {{ netbox.install_dir }}/netbox/gunicorn.py netbox.wsgi +KillMode=process +Restart=on-failure +RestartSec=15 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/netboxinventory/defaults.yaml b/states/netboxinventory/defaults.yaml new file mode 100644 index 0000000..3d4a207 --- /dev/null +++ b/states/netboxinventory/defaults.yaml @@ -0,0 +1,6 @@ +--- +netbox: + sites: + - Caen + - Saint-Lo + - Amsterdam \ No newline at end of file diff --git a/states/netboxinventory/init.sls b/states/netboxinventory/init.sls new file mode 100644 index 0000000..718b1b7 --- /dev/null +++ b/states/netboxinventory/init.sls @@ -0,0 +1,31 @@ +--- +{%- from "netboxinventory/map.jinja" import netbox with context %} +netboxinventory_dependencies: + pip.installed: + - name: pynetbox + +{%- if salt['netbox.get'](app='dcim', endpoint='sites', name=salt['grains.get']('location')) == {} %} +netbox.create_site_{{ salt['grains.get']('location') }}: + module.run: + - name: netbox.create_site + - site: {{ salt['grains.get']('location') }} +{%- endif %} + +{%- if salt['netbox.get'](app='dcim', endpoint='device-roles', name=salt['grains.get']('type')) == {} %} +netbox.create_device_role_{{ salt['grains.get']('type') }}: + module.run: + - name: netbox.create_device_role + - role: {{ salt['grains.get']('type') }} + - color: "2196f3" +{%- endif %} + +{%- if salt['netbox.get'](app='dcim', endpoint='devices', name=salt['grains.get']('nodename')) == {} %} +netbox.create_device_{{ salt['grains.get']('nodename')|to_camelcase }}: + module.run: + - name: netbox.create_device + - m_name: {{ salt['grains.get']('nodename') }} + - site: {{ salt['grains.get']('location') }} + - role: {{ salt['grains.get']('type') }} + - manufacturer: default + - model: default +{%- endif %} diff --git a/states/netboxinventory/map.jinja b/states/netboxinventory/map.jinja new file mode 100644 index 0000000..f8e99d7 --- /dev/null +++ b/states/netboxinventory/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "netboxinventory/defaults.yaml" as defaults %} + +{%- set netbox = salt['pillar.get']( + 'netbox', + default=defaults.netbox, + merge=True + ) +-%} \ No newline at end of file diff --git a/states/nextcloud/config.sls b/states/nextcloud/config.sls new file mode 100644 index 0000000..1eb8b90 --- /dev/null +++ b/states/nextcloud/config.sls @@ -0,0 +1,9 @@ +--- +{%- from "nextcloud/map.jinja" import nextcloud with context %} +nextcloud-config: + file.managed: + - name: {{ nextcloud.install_dir }}/nextcloud/config/config.php + - source: salt://nextcloud/templates/config.php.j2 + - user: {{ nextcloud.user }} + - group: {{ nextcloud.group }} + - template: jinja diff --git a/states/nextcloud/defaults.yaml b/states/nextcloud/defaults.yaml new file mode 100644 index 0000000..d1a47dc --- /dev/null +++ b/states/nextcloud/defaults.yaml @@ -0,0 +1,148 @@ +--- +nextcloud: + version: 18.0.4 + mirror: https://download.nextcloud.com/server/releases + #https://download.nextcloud.com/server/releases/nextcloud-18.0.4.tar.bz2 + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + user: www-data + group: www-data + config: + instanceid: '' + passwordsalt: '' + trusted_domains: + - demo.example.org + - otherdomain.example.org + datadirectory: '/var/www/nextcloud/data' + version: '' + dbtype: 'sqlite3' + dbhost: '' + dbname: 'nextcloud' + dbuser: '' + dbpassword: '' + dbtableprefix: '' + installed: false + default_language: 'en' + force_language: 'en' + default_locale: 'en_US' + force_locale: 'en_US' + defaultapp: 'files' + knowledgebaseenabled: true + allow_user_to_change_display_name: true + session_keepalive: true + token_auth_enforced: false + auth.bruteforce.protection.enabled: true + skeletondirectory: '/path/to/nextcloud/core/skeleton' + mail_domain: 'example.com' + mail_from_address: 'nextcloud' + mail_smtpdebug: false + mail_smtpmode: 'smtp' + mail_smtphost: '127.0.0.1' + mail_smtpport: 25 + mail_smtptimeout: 10 + mail_smtpsecure: '' + mail_smtpauth: false + mail_smtpauthtype: 'LOGIN' + mail_smtpname: '' + mail_smtppassword: '' + mail_template_class: '\OC\Mail\EMailTemplate' + mail_send_plaintext_only: false + mail_sendmailmode: 'smtp' + overwritehost: '' + overwriteprotocol: '' + overwritewebroot: '' + overwritecondaddr: '' + overwrite.cli.url: '' + htaccess.RewriteBase: '/' + htaccess.IgnoreFrontController: false + proxy: '' + proxyuserpwd: '' + trashbin_retention_obligation: 'auto' + versions_retention_obligation: 'auto' + appcodechecker: true + updatechecker: true + updater.release.channel: 'stable' + has_internet_connection: true + connectivity_check_domains: + - www.nextcloud.com + - www.startpage.com + - www.eff.org + - www.edri.org + check_for_working_wellknown_setup: true + check_for_working_htaccess: true + check_data_directory_permissions: true + config_is_read_only: false + log_type: 'file' + logfile: '/var/log/nextcloud.log' + logfilemode: 0640 + loglevel: 2 + syslog_tag: 'Nextcloud' + logdateformat: 'F d Y H:i:s' + logtimezone: 'Europe/Paris' + log_query: false + customclient_desktop: 'https://nextcloud.com/install/#install-clients' + customclient_android: 'https://play.google.com/store/apps/details?id=com.nextcloud.client' + customclient_ios: 'https://itunes.apple.com/us/app/nextcloud/id1125420102?mt=8' + customclient_ios_appid: 1125420102 + appstoreenabled: true + apps_paths: + - + - path: '/var/www/nextcloud/apps' + url: '/apps' + writable: true + enable_previews: true + ldapUserCleanupInterval: 51 + sort_groups_by_name: false + comments.managerFactory: '\OC\Comments\ManagerFactory' + systemtags.managerFactory: '\OC\SystemTag\ManagerFactory' + maintenance: false + openssl: + - config: '/absolute/location/of/openssl.cnf' + memcache.local: '\OC\Memcache\APCu' + memcache.distributed: '\OC\Memcache\Memcached' + memcached_servers: + - + - "'localhost' 11211" + cache_path: '' + sharing.managerFactory: '\OC\Share20\ProviderFactory' + sharing.maxAutocompleteResults: 0 + sharing.minSearchStringLength: 0 + sharing.enable_share_accept: false + sharing.force_share_accept: false + sqlite.journal_mode: 'DELETE' + mysql.utf8mb4: false + tempdirectory: '/tmp/nextcloudtemp' + hashing_default_password: false + hashingCost: 10 + blacklisted_files: + - .htaccess + share_folder: '/' + theme: '' + cipher: 'AES-256-CFB' + minimum.supported.desktop.version: '2.0.0' + quota_include_external_storage: false + external_storage.auth_availability_delay: 1800 + filesystem_check_changes: 0 + part_file_in_storage: true + mount_file: '/var/www/nextcloud/data/mount.json' + filesystem_cache_readonly: false + secret: '' + trusted_proxies: + - '203.0.113.45' + - '198.51.100.128' + - '192.168.2.0/24' + forwarded_for_headers: + - HTTP_X_FORWARDED + - HTTP_FORWARDED_FOR + max_filesize_animated_gifs_public_sharing: 10 + filelocking.enabled: true + memcache.locking: '\\OC\\Memcache\\Redis' + filelocking.debug: false + upgrade.disable-web: false + debug: false + data-fingerprint: '' + copied_sample_config: true + gs.enabled: false + gs.federation: 'internal' + simpleSignUpLink.shown: true + login_form_autocomplete: true diff --git a/states/nextcloud/init.sls b/states/nextcloud/init.sls new file mode 100644 index 0000000..4c9899e --- /dev/null +++ b/states/nextcloud/init.sls @@ -0,0 +1,6 @@ +--- +include: + - php + - redis + - .install + - .config \ No newline at end of file diff --git a/states/nextcloud/install.sls b/states/nextcloud/install.sls new file mode 100644 index 0000000..03cfc2f --- /dev/null +++ b/states/nextcloud/install.sls @@ -0,0 +1,25 @@ +--- +{%- from "nextcloud/map.jinja" import nextcloud with context %} +nextcloud-archive: + archive.extracted: + - name: {{ nextcloud.release_dir }}/nextcloud-{{ nextcloud.version }} + - source: {{ nextcloud.mirror }}/nextcloud-{{ nextcloud.version }}.tar.bz2 + - skip_verify: True + - archive_format: tar + - enforce_toplevel: False + - options: --strip 1 + - user: {{ nextcloud.user }} + - group: {{ nextcloud.group }} + - if_missing: {{ nextcloud.release_dir }}/nextcloud-{{ nextcloud.version }} + +nextcloud-install-link: + file.symlink: + - name: {{ nextcloud.install_dir }}/nextcloud + - target: {{ nextcloud.release_dir }}/nextcloud-{{ nextcloud.version }} + - force: True + +nextcloud-datadirectory: + file.directory: + - name: {{ nextcloud.config.datadirectory}} + - user: {{ nextcloud.user }} + - group: {{ nextcloud.group }} diff --git a/states/nextcloud/map.jinja b/states/nextcloud/map.jinja new file mode 100644 index 0000000..26adf42 --- /dev/null +++ b/states/nextcloud/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "nextcloud/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='nextcloud') -%} + +{%- set nextcloud = salt['pillar.get']('nextcloud', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/nextcloud/templates/config.php.j2 b/states/nextcloud/templates/config.php.j2 new file mode 100644 index 0000000..21f837d --- /dev/null +++ b/states/nextcloud/templates/config.php.j2 @@ -0,0 +1,26 @@ + "{{ v }}"{% if last %},{% else %}{% endif %} +{%- endfor %} +{%- elif value is sequence and value is not string -%} +array( + {%- for value2 in value %} + {{ mac(value2,loop.last) }} + {%- endfor -%} + ), +{%- elif value is true or value is false -%} +{{ value|lower }}, +{%- elif value is number -%} +{{ value }}, +{%- else -%} +"{{ value }}", +{%- endif %} +{%- endmacro %} +$CONFIG = array( +{%- for key, value in nextcloud.config.items() %} + "{{ key }}" => {{ mac(value,loop.last) }} +{%- endfor %} +); \ No newline at end of file diff --git a/states/nextcloud_desktop/init.sls b/states/nextcloud_desktop/init.sls new file mode 100644 index 0000000..b2040a2 --- /dev/null +++ b/states/nextcloud_desktop/init.sls @@ -0,0 +1,27 @@ +--- +{%- if not salt['file.file_exists']( salt['pillar.get']('nextcloud_desktop:dest_path') ) or not salt['file.check_hash']( salt['pillar.get']('nextcloud_desktop:dest_path'), salt['pillar.get']('nextcloud_desktop:file_sha256sum') ) %} +nextcloud-install: + file.managed: + - name: {{ salt['pillar.get']('nextcloud_desktop:dest_path') }} + - source: {{ salt['pillar.get']('nextcloud_desktop:url') }}/Nextcloud-{{ salt['pillar.get']('nextcloud_desktop:version') }}-x86_64.AppImage + - source_hash: sha256={{ salt['pillar.get']('nextcloud_desktop:file_sha256sum') }} + - user: root + - group: root + - mode: 755 +{%- endif %} + +nextcloud-icon: + file.managed: + - name: /usr/share/icons/nextcloud.png + - source: salt://nextcloud_desktop/nextcloud.png + - user: root + - group: root + - mode: 644 + +nextcloud-desktop-entry: + file.managed: + - name: /usr/share/applications/nextcloud.desktop + - source: salt://nextcloud_desktop/nextcloud.desktop + - user: root + - group: root + - mode: 644 \ No newline at end of file diff --git a/states/nextcloud_desktop/nextcloud.desktop b/states/nextcloud_desktop/nextcloud.desktop new file mode 100644 index 0000000..3911044 --- /dev/null +++ b/states/nextcloud_desktop/nextcloud.desktop @@ -0,0 +1,188 @@ +[Desktop Entry] +Categories=Utility; +Type=Application +Exec=nextcloud +Name=Nextcloud +Comment=PaulBSD Cloud desktop synchronization client +GenericName=Folder Sync +Icon=Nextcloud +Keywords=Nextcloud;syncing;file;sharing; +X-GNOME-Autostart-Delay=3 + +Comment[oc]=Nextcloud sincronizacion del client +GenericName[oc]=Dorsièr de Sincronizacion +Name[oc]=Nextcloud sincronizacion del client +Icon[oc]=Nextcloud +Comment[ar]=Nextcloud زبون مزامنة مكتبي +GenericName[ar]=مزامنة المجلد +Name[ar]=Nextcloud زبون مزامنة مكتبي +Icon[ar]=Nextcloud +Comment[bg_BG]=Nextcloud клиент за десктоп синхронизация +GenericName[bg_BG]=Синхронизиране на папката +Name[bg_BG]=Nextcloud клиент десктоп синхронизация +Icon[bg_BG]=Nextcloud +Comment[ca]=Client de sincronització d'escriptori Nextcloud +GenericName[ca]=Sincronització de carpetes +Name[ca]=Client de sincronització d'escriptori Nextcloud +Icon[ca]=Nextcloud +Comment[da]=Nextcloud skrivebordsklient til synkronisering +GenericName[da]=Mappesynkronisering +Name[da]=Nextcloud skrivebordsklient til synk +Icon[da]=Nextcloud +Comment[de]=Nextcloud Desktop-Synchronisationsclient +GenericName[de]=Ordner-Synchronisation +Name[de]=Nextcloud Desktop-Synchronisationsclient +Icon[de]=Nextcloud +Comment[ja_JP]=Nextcloud デスクトップ同期クライアント +GenericName[ja_JP]=フォルダー同期 +Name[ja_JP]=Nextcloud デスクトップ同期クライアント +Icon[ja_JP]=Nextcloud +Comment[el]=@ΟΝΟΜΑ_ΕΦΑΡΜΟΓΗΣ@ συγχρονισμός επιφάνειας εργασίας πελάτη +GenericName[el]=Συγχρονισμός φακέλου +Name[el]=@ΟΝΟΜΑ_ΕΦΑΡΜΟΓΗΣ@ συγχρονισμός επιφάνειας εργασίας πελάτη +Icon[el]=Nextcloud +Comment[en_GB]=Nextcloud desktop synchronisation client +GenericName[en_GB]=Folder Sync +Name[en_GB]=Nextcloud desktop sync client +Icon[en_GB]=Nextcloud +Comment[es]=Nextcloud cliente de sincronización de escritorio +GenericName[es]=Sincronización de carpeta +Name[es]=Nextcloud cliente de sincronización de escritorio +Icon[es]=Nextcloud +Comment[de_DE]=Nextcloud Desktop-Synchronisationsclient +GenericName[de_DE]=Ordner-Synchronisation +Name[de_DE]=Nextcloud Desktop-Synchronisationsclient +Icon[de_DE]=Nextcloud +Comment[eu]=Nextcloud mahaigaineko sinkronizazio bezeroa +GenericName[eu]=Karpetaren sinkronizazioa +Name[eu]=Nextcloud mahaigaineko sinkronizazio bezeroa +Icon[eu]=Nextcloud +GenericName[fa]=همسان سازی پوشه‌ها +Name[fa]=nextcloud نسخه‌ی همسان سازی مشتری +Icon[fa]=Nextcloud +Comment[fr]=Synchronisez vos dossiers avec un serveur Nextcloud +GenericName[fr]=Synchronisation de dossier +Name[fr]=Client de synchronisation Nextcloud +Icon[fr]=Nextcloud +Comment[gl]=Nextcloud cliente de sincronización para escritorio +GenericName[gl]=Sincronizar Cartafol +Name[gl]=Nextcloud cliente de sincronización para escritorio +Icon[gl]=Nextcloud +Comment[he]=Nextcloud לקוח סנכון שולחן עבודה +GenericName[he]=סנכון תיקייה +Name[he]=Nextcloud לקוח סנכרון שולחן עבודה +Icon[he]=Nextcloud +Comment[ia]=Nextcloud cliente de synchronisation pro scriptorio +GenericName[ia]=Synchronisar Dossier +Name[ia]=Nextcloud cliente de synchronisation pro scriptorio +Icon[ia]=Nextcloud +Comment[id]=Klien sinkronisasi desktop Nextcloud +GenericName[id]=Folder Sync +Name[id]=Klien sync desktop Nextcloud +Icon[id]=Nextcloud +Comment[is]=Nextcloud skjáborðsforrit samstillingar +GenericName[is]=Samstilling möppu +Name[is]=Nextcloud skjáborðsforrit samstillingar +Icon[is]=Nextcloud +Comment[it]=Client di sincronizzazione del desktop di Nextcloud +GenericName[it]=Sincronizzazione cartella +Name[it]=Client di sincronizzazione del desktop di Nextcloud +Icon[it]=Nextcloud +Comment[ko]=Nextcloud 데스크톱 동기화 클라이언트 +GenericName[ko]=폴더 동기화 +Name[ko]=Nextcloud 데스크톱 동기화 클라이언트 +Comment[hu_HU]=Nextcloud asztali szinkronizációs kliens +GenericName[hu_HU]=Könyvtár szinkronizálás +Name[hu_HU]=Nextcloud asztali szinkr. kliens +Icon[hu_HU]=Nextcloud +Comment[nl]=Nextcloud desktop synchronisatie client +GenericName[nl]=Mappen sync +Name[nl]=Nextcloud desktop sync client +Icon[nl]=Nextcloud +Comment[et_EE]=Nextcloud sünkroonimise klient töölauale +GenericName[et_EE]=Kaustade sünkroonimine +Name[et_EE]=Nextcloud sünkroonimise klient töölauale +Icon[et_EE]=Nextcloud +Comment[pl]=Nextcloud klient synchronizacji dla komputerów stacjonarnych +GenericName[pl]=Folder Synchronizacji +Name[pl]=Nextcloud klient synchronizacji dla komputerów stacjonarnych +Icon[pl]=Nextcloud +Comment[pt_BR]=Nextcloud cliente de sincronização do computador +GenericName[pt_BR]=Sincronização de Pasta +Name[pt_BR]=Nextcloud cliente de sincronização de desktop +Icon[pt_BR]=Nextcloud +Comment[cs_CZ]=Nextcloud počítačový synchronizační klient +GenericName[cs_CZ]=Synchronizace adresáře +Name[cs_CZ]=Nextcloud počítačový synchronizační klient +Icon[cs_CZ]=Nextcloud +Comment[ru]=Настольный клиент синхронизации Nextcloud +GenericName[ru]=Синхронизация каталогов +Name[ru]=Настольный клиент синхронизации Nextcloud +Icon[ru]=Nextcloud +Comment[sl]=Nextcloud ‒ Program za usklajevanje datotek z namizjem +GenericName[sl]=Usklajevanje map +Name[sl]=Nextcloud ‒ Program za usklajevanje datotek z namizjem +Icon[sl]=Nextcloud +Comment[sq]=Klient njëkohësimesh Nextcloud për desktop +GenericName[sq]=Njëkohësim Dosjesh +Name[sq]=Klient njëkohësimesh Nextcloud për desktop +Icon[sq]=Nextcloud +Comment[fi_FI]=Nextcloud työpöytäsynkronointisovellus +GenericName[fi_FI]=Kansion synkronointi +Name[fi_FI]=Nextcloud työpöytäsynkronointisovellus +Icon[fi_FI]=Nextcloud +Comment[sv]=Nextcloud desktop synkroniseringsklient +GenericName[sv]=Mappsynk +Name[sv]=Nextcloud desktop synk-klient +Icon[sv]=Nextcloud +Comment[tr]=Nextcloud masaüstü eşitleme istemcisi +GenericName[tr]=Dosya Eşitleme +Name[tr]=Nextcloud masaüstü eşitleme istemcisi +Icon[tr]=Nextcloud +Comment[uk]=Настільний клієнт синхронізації Nextcloud +GenericName[uk]=Синхронізація теки +Name[uk]=Настільний клієнт синхронізації Nextcloud +Icon[uk]=Nextcloud +Comment[ro]=Nextcloud client de sincronizare pe desktop +GenericName[ro]=Sincronizare director +Name[ro]=Nextcloud client de sincronizare pe desktop +Icon[ro]=Nextcloud +Comment[zh_CN]=Nextcloud 桌面同步客户端 +GenericName[zh_CN]=文件夹同步 +Name[zh_CN]=Nextcloud 桌面同步客户端 +Icon[zh_CN]=Nextcloud +Comment[zh_HK]=桌面版同步客户端 +GenericName[zh_TW]=資料夾同步 +Comment[es_AR]=Cliente de sincronización para escritorio Nextcloud +GenericName[es_AR]=Sincronización de directorio +Name[es_AR]=Cliente de sincronización para escritorio Nextcloud +Icon[es_AR]=Nextcloud +Comment[lt_LT]=Nextcloud darbalaukio sinchronizavimo programa +GenericName[lt_LT]=Katalogo sinchnorizacija +Name[lt_LT]=Nextcloud darbalaukio programa +Icon[lt_LT]=Nextcloud +Comment[th_TH]=Nextcloud ไคลเอนต์ประสานข้อมูลเดสก์ท็อป +GenericName[th_TH]=ประสานข้อมูลโฟลเดอร์ +Name[th_TH]= Nextcloud ไคลเอนต์ประสานข้อมูลเดสก์ท็อป +Icon[th_TH]=Nextcloud +Comment[es_MX]=Cliente de escritorio para sincronziación de Nextcloud +GenericName[es_MX]=Sincronización de Carpetas +Name[es_MX]=Cliente de escritorio para sincronziación de Nextcloud +Icon[es_MX]=Nextcloud +Comment[nb_NO]=Nextcloud skrivebordssynkroniseringsklient +GenericName[nb_NO]=Mappesynkronisering +Name[nb_NO]=Nextcloud skrivebordssynkroniseringsklient +Icon[nb_NO]=Nextcloud +Comment[nn_NO]=Nextcloud klient for å synkronisera frå skrivebord +GenericName[nn_NO]=Mappe synkronisering +Name[nn_NO]=Nextcloud klient for å synkronisera frå skrivebord +Icon[nn_NO]=Nextcloud +Comment[pt_PT]=Nextcloud - Cliente de Sincronização para PC +GenericName[pt_PT]=Sincronizar Pasta +Name[pt_PT]=Nextcloud - Cliente de Sincronização para PC +Icon[pt_PT]=Nextcloud +Icon[km]=Nextcloud +Comment[lb]=Nextcloud Desktop Synchronisatioun Client +GenericName[lb]=Dossier Dync +Name[lb]=Nextcloud Desktop Sync Client +Icon[lb]=Nextcloud \ No newline at end of file diff --git a/states/nextcloud_desktop/nextcloud.png b/states/nextcloud_desktop/nextcloud.png new file mode 100644 index 0000000..c97f368 Binary files /dev/null and b/states/nextcloud_desktop/nextcloud.png differ diff --git a/states/nftables/defaults.yaml b/states/nftables/defaults.yaml new file mode 100644 index 0000000..d969a98 --- /dev/null +++ b/states/nftables/defaults.yaml @@ -0,0 +1,4 @@ +--- +nftables: + enabled: true + networks: {{ salt['pillar.get']('networks') }} \ No newline at end of file diff --git a/states/nftables/init.sls b/states/nftables/init.sls new file mode 100644 index 0000000..030c26c --- /dev/null +++ b/states/nftables/init.sls @@ -0,0 +1,22 @@ +--- +{%- from "nftables/map.jinja" import nftables with context %} +nftables-pkg: + pkg.latest: + - name: nftables + +nftables-main-config: + file.managed: + - name: /etc/nftables.conf + - source: salt://nftables/nftables.conf.j2 + - template: jinja + - watch_in: + - service: nftables-service + - require: + - pkg: nftables-pkg + +nftables-service: + service.running: + - name: nftables + - enable: True + - require: + - pkg: nftables-pkg \ No newline at end of file diff --git a/states/nftables/map.jinja b/states/nftables/map.jinja new file mode 100644 index 0000000..72a2446 --- /dev/null +++ b/states/nftables/map.jinja @@ -0,0 +1,7 @@ +{%- import_yaml "nftables/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='nftables') -%} + +{%- set nftables = salt['pillar.get']('nftables', default=defaults, merge=True) -%} + +{%- set net = salt['pillar.get']('net', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/nftables/nftables.conf.j2 b/states/nftables/nftables.conf.j2 new file mode 100644 index 0000000..5bacc4c --- /dev/null +++ b/states/nftables/nftables.conf.j2 @@ -0,0 +1,48 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "nftables/map.jinja" import nftables with context %} +{%- from "nftables/map.jinja" import net with context %} + +## IPv4 filtering +add table ip filter +add chain ip filter input { type filter hook input priority 0; policy drop; } +add chain ip filter forward { type filter hook forward priority 0; policy accept; } +add chain ip filter output { type filter hook output priority 0; policy accept; } +add rule ip filter input iifname lo counter accept +add rule ip filter input iifname tun* counter accept +add rule ip filter input ct state related,established counter accept +add rule ip filter input ip protocol icmp counter accept +{%- for key, value in net.ipv4_networks.items() %} +add rule ip filter input ip saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept +{%- endfor %} +{%- for key, value in net.public_ports.items() %} +add rule ip filter input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept +{%- endfor %} +add rule ip filter input counter log + +## IPv4 NAT +add table ip nat +add chain ip nat prerouting { type nat hook prerouting priority 0; policy accept; } +add chain ip nat input { type nat hook input priority 0; policy accept; } +add chain ip nat output { type nat hook output priority 0; policy accept; } +add chain ip nat postrouting { type nat hook postrouting priority 0; policy accept; } +{%- for key, value in net.nats.items() %} +add rule ip nat postrouting ip saddr {{ value.ip }}/{{ value.mask }} counter masquerade +{%- endfor %} + +## IPv6 filtering +add table ip6 filter6 +add chain ip6 filter6 input { type filter hook input priority 0; policy drop; } +add chain ip6 filter6 forward { type filter hook forward priority 0; policy accept; } +add chain ip6 filter6 output { type filter hook output priority 0; policy accept; } +add rule ip6 filter6 input iifname lo counter accept +add rule ip6 filter6 input iifname tun* counter accept +add rule ip6 filter6 input ct state related,established counter accept +add rule ip6 filter6 input icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept +{%- for key, value in net.ipv6_networks.items() %} +add rule ip6 filter6 input ip6 saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept +{%- endfor %} +{%- for key, value in net.public_ports.items() %} +add rule ip6 filter6 input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept +{%- endfor %} +add rule ip6 filter6 input counter log \ No newline at end of file diff --git a/states/nginx/auth.sls b/states/nginx/auth.sls new file mode 100644 index 0000000..271ee16 --- /dev/null +++ b/states/nginx/auth.sls @@ -0,0 +1,25 @@ +--- +{%- from "nginx/map.jinja" import nginx with context %} + +{%- for user in salt['pillar.get']('htpasswds') %} +{%- if user.state == 'present' %} + +nginx-auth-present-{{ user.name }}: + webutil.user_exists: + - name: {{ user.name }} +{%- if user.password is defined %} + - password: {{ user.password }} +{%- endif %} + - htpasswd_file: {{ nginx.config.dir }}/auth/htpasswd + - require: + - file: nginx-config-dir-auth + +{%- else %} +nginx-auth-absent-{{ user.name }}: + webutil.user_absent: + - name: {{ user.name }} + - htpasswd_file: {{ nginx.config.dir }}/auth/htpasswd + - require: + - file: nginx-config-dir-auth +{%- endif %} +{%- endfor %} \ No newline at end of file diff --git a/states/nginx/config.sls b/states/nginx/config.sls new file mode 100644 index 0000000..5f52694 --- /dev/null +++ b/states/nginx/config.sls @@ -0,0 +1,73 @@ +--- +{%- from "nginx/map.jinja" import nginx with context -%} + +{%- for configfile in nginx.config.files %} +nginx-config-{{ configfile }}: + file.managed: + - name: {{ nginx.config.dir }}/{{ configfile }} + - source: salt://nginx/templates/{{ configfile }}.j2 + - template: jinja + - user: {{ nginx.config.user }} + - group: {{ nginx.config.group }} + - watch_in: + - service: nginx-service + - watch: + - cmd: acme-certs + - require: + - sls: acme +{%- endfor %} + +nginx-config-wipe-default: + file.absent: + - name: /etc/nginx/sites-enabled/default + +{%- for subdir in nginx.config.subdirs %} +nginx-config-dir-{{ subdir }}: + file.directory: + - name: {{ nginx.config.dir }}/{{ subdir }} + - user: {{ nginx.config.user }} + - group: {{ nginx.config.group }} + - watch_in: + - service: nginx-service +{%- endfor %} + +{#% for vhost in salt['file.find']( nginx.config.dir+'/sites-enabled/',type='f') %#} +{#% do salt['file.remove'](vhost) %#} +{#% endfor %#} + +{%- for key, vhost in nginx.vhosts.items() %} +nginx-sites-available-{{ key }}: + file.managed: + - name: {{ nginx.config.dir }}/sites-available/{{ key }} + - source: salt://nginx/vhost.j2 + - template: jinja + - user: {{ nginx.config.user }} + - group: {{ nginx.config.group }} + - require: + - file: nginx-config-dir-sites-available + - file: nginx-config-dir-sites-enabled + - context: + vhost_name: {{ vhost.name }} + https: {{ vhost.https|default(true) }} + proxy: {{ vhost.proxy|default(false) }} + proxy_pass: {{ vhost.proxy_pass|default("") }} + cache: {{ vhost.cache|default(true) }} + autoindex: {{ vhost.autoindex|default(false) }} + root_dir: {{ vhost.root_dir|default(None) }} + internal_access: {{ vhost.internal_access|default(false) }} + dirs: {{ vhost.dirs|default([]) }} + +nginx-site-enabled-{{ key }}: + file.symlink: + - name: {{ nginx.config.dir }}/sites-enabled/{{ key }} + - target: {{ nginx.config.dir }}/sites-available/{{ key }} + - template: jinja + - user: {{ nginx.config.user }} + - group: {{ nginx.config.group }} + - require: + - file: nginx-config-dir-sites-available + - file: nginx-config-dir-sites-enabled + - nginx-sites-available-{{ key }} + - watch_in: + - service: nginx-service +{%- endfor %} \ No newline at end of file diff --git a/states/nginx/defaults.yaml b/states/nginx/defaults.yaml new file mode 100644 index 0000000..38421e9 --- /dev/null +++ b/states/nginx/defaults.yaml @@ -0,0 +1,29 @@ +--- +nginx: + enabled: true + packages: + - apache2-utils + - nginx-extras + config: + dir: "/etc/nginx" + user: www-data + group: www-data + subdirs: + - auth + - modules-available + - modules-enabled + - sites-available + - sites-enabled + - ssl + files: + - access + - fastcgi_params + - http + - https + - mime.types + - nginx.conf + - proxy_params + - scgi_params + - ssl_params + - uwsgi_params + vhosts: {} \ No newline at end of file diff --git a/states/nginx/init.sls b/states/nginx/init.sls new file mode 100644 index 0000000..23536b9 --- /dev/null +++ b/states/nginx/init.sls @@ -0,0 +1,7 @@ +--- +include: + - acme + - .install + - .config + - .auth + - .service \ No newline at end of file diff --git a/states/nginx/install.sls b/states/nginx/install.sls new file mode 100644 index 0000000..01d9939 --- /dev/null +++ b/states/nginx/install.sls @@ -0,0 +1,5 @@ +--- +{%- from "nginx/map.jinja" import nginx with context %} +nginx-pkg: + pkg.installed: + - pkgs: {{ nginx.packages }} \ No newline at end of file diff --git a/states/nginx/map.jinja b/states/nginx/map.jinja new file mode 100644 index 0000000..d5a9bb4 --- /dev/null +++ b/states/nginx/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "nginx/defaults.yaml" as defaults %} + +{%- set nginx = salt['pillar.get']('nginx', default=defaults.nginx, merge=True) %} + +{%- set net = salt['pillar.get']('net', merge=True) %} \ No newline at end of file diff --git a/states/nginx/service.sls b/states/nginx/service.sls new file mode 100644 index 0000000..a338524 --- /dev/null +++ b/states/nginx/service.sls @@ -0,0 +1,6 @@ +--- +nginx-service: + service.running: + - name: nginx + - enable: True + - reload: True \ No newline at end of file diff --git a/states/nginx/templates/access.j2 b/states/nginx/templates/access.j2 new file mode 100644 index 0000000..c5d5aac --- /dev/null +++ b/states/nginx/templates/access.j2 @@ -0,0 +1,8 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- for key, value in salt['pillar.get']('net:ipv4_networks').items() %} +allow {{ value.ip }}/{{ value.mask }}; +{%- endfor %} +{%- for key, value in salt['pillar.get']('net:ipv6_networks').items() %} +allow {{ value.ip }}/{{ value.mask }}; +{%- endfor %} +deny all; \ No newline at end of file diff --git a/states/nginx/templates/fastcgi_params.j2 b/states/nginx/templates/fastcgi_params.j2 new file mode 100644 index 0000000..3dcd9d2 --- /dev/null +++ b/states/nginx/templates/fastcgi_params.j2 @@ -0,0 +1,27 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +fastcgi_param QUERY_STRING $query_string; +fastcgi_param REQUEST_METHOD $request_method; +fastcgi_param CONTENT_TYPE $content_type; +fastcgi_param CONTENT_LENGTH $content_length; + +fastcgi_param SCRIPT_NAME $fastcgi_script_name; +fastcgi_param REQUEST_URI $request_uri; +fastcgi_param DOCUMENT_URI $document_uri; +fastcgi_param DOCUMENT_ROOT $document_root; +fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param HTTPS $https if_not_empty; + +fastcgi_param GATEWAY_INTERFACE CGI/1.1; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + +fastcgi_param REMOTE_ADDR $remote_addr; +fastcgi_param REMOTE_PORT $remote_port; +fastcgi_param SERVER_ADDR $server_addr; +fastcgi_param SERVER_PORT $server_port; +fastcgi_param SERVER_NAME $server_name; + +fastcgi_param REDIRECT_STATUS 200; + +fastcgi_pass_header Cookie; +fastcgi_ignore_headers Expires Cache-Control Set-Cookie; \ No newline at end of file diff --git a/states/nginx/templates/http.j2 b/states/nginx/templates/http.j2 new file mode 100644 index 0000000..bf8b0a3 --- /dev/null +++ b/states/nginx/templates/http.j2 @@ -0,0 +1,4 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +listen 80; +listen [::]:80; \ No newline at end of file diff --git a/states/nginx/templates/https.j2 b/states/nginx/templates/https.j2 new file mode 100644 index 0000000..1545f49 --- /dev/null +++ b/states/nginx/templates/https.j2 @@ -0,0 +1,4 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +listen 443 ssl http2; +listen [::]:443 ssl http2; \ No newline at end of file diff --git a/states/nginx/templates/mime.types.j2 b/states/nginx/templates/mime.types.j2 new file mode 100644 index 0000000..3ba20d4 --- /dev/null +++ b/states/nginx/templates/mime.types.j2 @@ -0,0 +1,87 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/png png; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + image/svg+xml svg svgz; + image/webp webp; + + application/font-woff woff; + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.wap.wmlc wmlc; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} \ No newline at end of file diff --git a/states/nginx/templates/nginx.conf.j2 b/states/nginx/templates/nginx.conf.j2 new file mode 100644 index 0000000..dedb35b --- /dev/null +++ b/states/nginx/templates/nginx.conf.j2 @@ -0,0 +1,57 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +user www-data; + +worker_processes 4; + +error_log /var/log/nginx/error.log; +error_log syslog:server=localhost:514 info; + +events { + worker_connections 1024; +} + +http { + include fastcgi_params; + include proxy_params; + include mime.types; + include ssl_params; + charset utf-8; + + include sites-enabled/*; + + access_log /var/log/nginx/$host.access.log; + access_log syslog:server=localhost:514 combined; + + default_type application/octet-stream; + sendfile on; + keepalive_timeout 60; + server_tokens off; + #more_set_headers 'Server: PaulBSD Fast Webserver'; + + proxy_intercept_errors on; + fastcgi_intercept_errors on; + fastcgi_read_timeout 300; + + error_page 403 =403 /403.html; + error_page 404 =404 /fuck.html; + + server { + listen 80 default_server; + listen 443 default_server ssl; + + listen [::]:80 default_server; + listen [::]:443 default_server ssl; + + root /var/www/html; + index index.html; + + location /status { + stub_status on; + access_log off; + allow 127.0.0.1; + allow ::1; + deny all; + } + } +} \ No newline at end of file diff --git a/states/nginx/templates/proxy_params.j2 b/states/nginx/templates/proxy_params.j2 new file mode 100644 index 0000000..f6b540d --- /dev/null +++ b/states/nginx/templates/proxy_params.j2 @@ -0,0 +1,17 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +proxy_redirect off; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +client_max_body_size 1024m; +client_body_buffer_size 8192k; +proxy_connect_timeout 600; +proxy_send_timeout 600; +proxy_read_timeout 600; +proxy_buffers 32 4k; + +proxy_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=cache:10m inactive=24h max_size=1g; +proxy_cache cache; +proxy_cache_valid 200 302 1h; +proxy_cache_valid 404 1d; \ No newline at end of file diff --git a/states/nginx/templates/scgi_params.j2 b/states/nginx/templates/scgi_params.j2 new file mode 100644 index 0000000..fe44b29 --- /dev/null +++ b/states/nginx/templates/scgi_params.j2 @@ -0,0 +1,18 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +scgi_param REQUEST_METHOD $request_method; +scgi_param REQUEST_URI $request_uri; +scgi_param QUERY_STRING $query_string; +scgi_param CONTENT_TYPE $content_type; + +scgi_param DOCUMENT_URI $document_uri; +scgi_param DOCUMENT_ROOT $document_root; +scgi_param SCGI 1; +scgi_param SERVER_PROTOCOL $server_protocol; +scgi_param REQUEST_SCHEME $scheme; +scgi_param HTTPS $https if_not_empty; + +scgi_param REMOTE_ADDR $remote_addr; +scgi_param REMOTE_PORT $remote_port; +scgi_param SERVER_PORT $server_port; +scgi_param SERVER_NAME $server_name; \ No newline at end of file diff --git a/states/nginx/templates/ssl_params.j2 b/states/nginx/templates/ssl_params.j2 new file mode 100644 index 0000000..8e999a6 --- /dev/null +++ b/states/nginx/templates/ssl_params.j2 @@ -0,0 +1,23 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +ssl_certificate /etc/acme/certs/paulbsd.com.cert; +ssl_certificate_key /etc/acme/keys/paulbsd.com.key; +ssl_session_timeout 5m; +#ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2; +ssl_protocols TLSv1.2; +#ssl_ciphers HIGH:!aNULL:!MD5; +#ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; +ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20; +ssl_prefer_server_ciphers on; +ssl_ecdh_curve secp384r1; +ssl_session_cache shared:SSL:10m; +ssl_session_tickets off; +ssl_stapling on; +ssl_stapling_verify on; +ssl_dhparam /etc/acme/dh/dh.pem; +#resolver $DNS-IP-1 $DNS-IP-2 valid=300s; +resolver_timeout 5s; +add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; +add_header X-Frame-Options DENY; +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block"; \ No newline at end of file diff --git a/states/nginx/templates/uwsgi_params.j2 b/states/nginx/templates/uwsgi_params.j2 new file mode 100644 index 0000000..d992536 --- /dev/null +++ b/states/nginx/templates/uwsgi_params.j2 @@ -0,0 +1,18 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; + +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REQUEST_SCHEME $scheme; +uwsgi_param HTTPS $https if_not_empty; + +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; \ No newline at end of file diff --git a/states/nginx/vhost.j2 b/states/nginx/vhost.j2 new file mode 100644 index 0000000..c004d37 --- /dev/null +++ b/states/nginx/vhost.j2 @@ -0,0 +1,34 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +server { + include http; + server_name {{ vhost_name }}; + return 301 https://$server_name$request_uri; +} + +server { + include https; + server_name {{ vhost_name }}; + {%- if not proxy %} + root {{ root_dir }}; + {%- endif %} + location / { + {%- if proxy %} + proxy_pass {{ proxy_pass }}; + {%- if not cache %} + proxy_no_cache 1; + proxy_cache_bypass 1; + {%- endif %} + {%- endif %} + {%- if autoindex %} + autoindex on; + autoindex_localtime on; + {%- endif %} + } + + {%- for dir in dirs %} + location {{ dir.name }} { + alias {{ dir.alias }}; + } + {%- endfor %} +} \ No newline at end of file diff --git a/states/npf/defaults.yaml b/states/npf/defaults.yaml new file mode 100644 index 0000000..676c40d --- /dev/null +++ b/states/npf/defaults.yaml @@ -0,0 +1,3 @@ +--- +npf: + enabled: true \ No newline at end of file diff --git a/states/npf/init.sls b/states/npf/init.sls new file mode 100644 index 0000000..76738fd --- /dev/null +++ b/states/npf/init.sls @@ -0,0 +1,14 @@ +--- +npf-main-config: + file.managed: + - name: /etc/npf.conf + - source: salt://npf/npf.conf.j2 + - template: jinja + - watch_in: + - service: npf-service + +npf-service: + service.running: + - name: npf + - enable: True + - reload: True \ No newline at end of file diff --git a/states/npf/map.jinja b/states/npf/map.jinja new file mode 100644 index 0000000..8040d2c --- /dev/null +++ b/states/npf/map.jinja @@ -0,0 +1,6 @@ +{%- import_yaml "npf/defaults.yaml" as default_settings -%} + +{%- set defaults_npf = salt['grains.filter_by'](default_settings, default='npf') -%} +{%- set defaults_net = salt['grains.filter_by'](default_settings, default='net') -%} +{%- set npf = salt['pillar.get']('npf', default=defaults_npf, merge=True) -%} +{%- set net = salt['pillar.get']('net', default=defaults_net, merge=True) -%} \ No newline at end of file diff --git a/states/npf/npf.conf.j2 b/states/npf/npf.conf.j2 new file mode 100644 index 0000000..099e9db --- /dev/null +++ b/states/npf/npf.conf.j2 @@ -0,0 +1,104 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "npf/map.jinja" import net with context %} + +{%- macro set_log() %} apply "log"{%- endmacro %} + +## Macros ## +{%- for key, value in net.interfaces.items() %} +${{ key }} = "{{ value.id }}" +{%- endfor %} + +{% set my_net4=[] -%} +{%- for key, value in net.ipv4_networks.items() -%} +{%- do my_net4.append( value.ip + "/" + value.mask ) -%} +{%- endfor -%} + +{%- set my_net6=[] -%} +{%- for key, value in net.ipv6_networks.items() -%} +{%- do my_net6.append( value.ip + "/" + value.mask ) -%} +{%- endfor -%} + +{%- set work_net4=[] -%} +{%- for key, value in net.work_ipv4_networks.items() -%} +{%- do work_net4.append( value.ip + "/" + value.mask ) -%} +{%- endfor -%} + +{%- set public_ports_tcp=[] -%} +{%- set public_ports_udp=[] -%} +{%- for key, value in net.public_ports.items() -%} +{%- if value.proto == 'tcp' -%} +{%- do public_ports_tcp.append(value.port) -%} +{%- elif value.proto == 'udp' -%} +{%- do public_ports_udp.append(value.port) -%} +{%- endif -%} +{%- endfor -%} + +$mynet4 = { {{ my_net4|join(', ') }} } +$mynet6 = { {{ my_net6|join(', ') }} } + +$public_ports_tcp = { {{ public_ports_tcp|join(', ') }} } +$public_ports_udp = { {{ public_ports_udp|join(', ') }} } + + +## Tables ## +{%- if net.tables is defined %} +{%- for key, value in net.tables.items() %} +table <{{ key }}> type ipset file "{{ value.filename }}" +#table <{{ key }}> type cdb file "{{ value.filename }}" +{%- endfor %} +{%- endif %} + + +## Translations ## +{%- for key, value in net.nats.items() %} +#map $ext dynamic {{ value.ip }}/{{ value.mask }} -> inet4({{ net.interfaces.ext.id }}) +{%- endfor %} +map $ext dynamic 10.99.99.0/24 -> inet4({{ net.interfaces.ext.id }}) +map $ext dynamic 192.168.50.0/26 -> inet4({{ net.interfaces.ext.id }}) + +alg "icmp" + +{%- if net.log is defined and net.log.enabled %} +## Procedures ## +procedure "log" { + log: {{ net.log.interface }} + normalize: {{ net.log.normalize }} +} +{%- endif %} + + +## Rules ## +{%- for key, value in net.interfaces.items() %} +{%- if value.type == 'lan' %} +group "{{ key }}" on ${{ key }} { +{%- for family, net in [('inet4','mynet4'), ('inet6','mynet6')] %} + pass stateful out final family {{ family }} all +{%- endfor %} +{%- for family, net in [('inet4','mynet4'), ('inet6','mynet6')] %} + pass stateful in final family {{ family }} from ${{ net }} to any +{%- endfor %} + + block in all apply "log" + block in final from apply "log" + + pass stateful in final family inet4 proto icmp all + pass stateful in final family inet6 proto ipv6-icmp all + + pass stateful in family inet4 proto tcp from any to any port $public_ports_tcp + pass stateful in family inet6 proto tcp from any to any port $public_ports_tcp + + pass stateful in family inet4 proto udp from any to any port $public_ports_udp + pass stateful in family inet6 proto udp from any to any port $public_ports_udp +} +{%- endif %} +{%- endfor %} + +group default { + block all {%- if net.log is defined and net.log.enabled %}{{ set_log() }}{%- endif %} +{%- for key, value in net.interfaces.items() %} +{%- if value.skip is defined and value.skip %} + pass on ${{ key }} all +{%- endif %} +{%- endfor %} +} \ No newline at end of file diff --git a/states/oldstates/clamav/clamd.conf.j2 b/states/oldstates/clamav/clamd.conf.j2 new file mode 100644 index 0000000..6c91da2 --- /dev/null +++ b/states/oldstates/clamav/clamd.conf.j2 @@ -0,0 +1,4 @@ +{%- from "maildb/map.jinja" import maildb with context -%} +{%- for option, param in clamav.config.clamd.options.items() %} +{{ option }}={{ param }} +{%- endfor %} \ No newline at end of file diff --git a/states/oldstates/clamav/config.sls b/states/oldstates/clamav/config.sls new file mode 100644 index 0000000..3362c77 --- /dev/null +++ b/states/oldstates/clamav/config.sls @@ -0,0 +1,11 @@ +--- +clamav-clamd-config: + file.managed: + - name: {{ clamav.config.clamd.file }} + - source: salt://clamav/clamd.conf.j2 + - user: root + - group: root + - mode: 0755 + - template: jinja + - watch_in: + - service: clamav-clamd-service \ No newline at end of file diff --git a/states/oldstates/clamav/defaults.yaml b/states/oldstates/clamav/defaults.yaml new file mode 100644 index 0000000..229fed2 --- /dev/null +++ b/states/oldstates/clamav/defaults.yaml @@ -0,0 +1,91 @@ +--- +clamav: + enabled: true + config: + clamd: + file: /etc/clamav/clamd.conf + options: + AlgorithmicDetection: true + AllowAllMatchScan: true + ArchiveBlockEncrypted: false + Bytecode: true + BytecodeSecurity: TrustSigned + BytecodeTimeout: 60000 + CommandReadTimeout: 5 + CrossFilesystems: true + DatabaseDirectory: /var/lib/clamav + Debug: false + DetectBrokenExecutables: false + DetectPUA: false + DisableCache: false + DisableCertCheck: false + ExitOnOOM: false + ExtendedDetectionInfo: true + FixStaleSocket: true + FollowDirectorySymlinks: false + FollowFileSymlinks: false + ForceToDisk: false + Foreground: false + HeuristicScanPrecedence: false + IdleTimeout: 30 + LeaveTemporaryFiles: false + LocalSocket: /var/run/clamav/clamd.ctl + LocalSocketGroup: root + LocalSocketMode: 666 + LogClean: false + LogFacility: LOG_LOCAL6 + LogFile: /var/log/clamav/clamav.log + LogFileMaxSize: 0 + LogFileUnlock: false + LogRotate: true + LogSyslog: true + LogTime: true + LogVerbose: false + MaxConnectionQueueLength: 15 + MaxDirectoryRecursion: 15 + MaxEmbeddedPE: 10M + MaxFileSize: 25M + MaxFiles: 10000 + MaxHTMLNoTags: 2M + MaxHTMLNormalize: 10M + MaxIconsPE: 100 + MaxPartitions: 50 + MaxQueue: 100 + MaxRecHWP3: 16 + MaxRecursion: 16 + MaxScanSize: 100M + MaxScriptNormalize: 5M + MaxThreads: 12 + MaxZipTypeRcg: 1M + OLE2BlockMacros: false + OfficialDatabaseOnly: false + OnAccessIncludePath: /home + OnAccessPrevention: yes + PCREMatchLimit: 10000 + PCREMaxFileSize: 25M + PCRERecMatchLimit: 5000 + PartitionIntersection: false + PhishingAlwaysBlockCloak: false + PhishingAlwaysBlockSSLMismatch: false + PhishingScanURLs: true + PhishingSignatures: true + PreludeAnalyzerName: ClamAV + PreludeEnable: no + ReadTimeout: 180 + ScanArchive: true + ScanELF: true + ScanHTML: true + ScanHWP3: true + ScanMail: true + ScanOLE2: true + ScanOnAccess: true + ScanPDF: true + ScanPE: true + ScanPartialMessages: false + ScanSWF: true + ScanXMLDOCS: true + SelfCheck: 3600 + SendBufTimeout: 200 + StreamMaxLength: 25M + StructuredDataDetection: false + User: root \ No newline at end of file diff --git a/states/oldstates/clamav/init.sls b/states/oldstates/clamav/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/oldstates/clamav/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/oldstates/clamav/install.sls b/states/oldstates/clamav/install.sls new file mode 100644 index 0000000..189b062 --- /dev/null +++ b/states/oldstates/clamav/install.sls @@ -0,0 +1,6 @@ +--- +clamav-install: + pkg.latest: + - pkgs: + - clamav + - clamav-daemon \ No newline at end of file diff --git a/states/oldstates/clamav/map.jinja b/states/oldstates/clamav/map.jinja new file mode 100644 index 0000000..8135e2f --- /dev/null +++ b/states/oldstates/clamav/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "clamav/defaults.yaml" as default_settings %} + +{%- set defaults = salt['grains.filter_by'](default_settings,default='clamav') %} + +{%- set clamav = salt['pillar.get']('clamav', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/oldstates/clamav/service.sls b/states/oldstates/clamav/service.sls new file mode 100644 index 0000000..0a06f3a --- /dev/null +++ b/states/oldstates/clamav/service.sls @@ -0,0 +1,7 @@ +--- +clamav-clamd-service: + service.dead: + - name: clamav-daemon + - enable: False + - require: + - file: clamav-clamd-config \ No newline at end of file diff --git a/states/oldstates/collectd/collectd.conf.j2 b/states/oldstates/collectd/collectd.conf.j2 new file mode 100644 index 0000000..24069c6 --- /dev/null +++ b/states/oldstates/collectd/collectd.conf.j2 @@ -0,0 +1,83 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +Hostname "{{ grains.get('fqdn') }}" +FQDNLookup true +Interval 60.0 + +TypesDB "/usr/share/collectd/types.db" + +LoadPlugin battery +LoadPlugin contextswitch +LoadPlugin cpu +LoadPlugin df +LoadPlugin disk +LoadPlugin entropy +LoadPlugin interface +LoadPlugin irq +LoadPlugin load +LoadPlugin memory +LoadPlugin network +#LoadPlugin ping +LoadPlugin processes +#LoadPlugin rrdtool +LoadPlugin sensors +LoadPlugin swap +LoadPlugin syslog +LoadPlugin tcpconns +LoadPlugin uptime +LoadPlugin users + + + ReportByCpu true + ReportByState true + ValuesPercentage false + ReportNumCpu false + ReportGuestState false + SubtractGuestState true + + + + FSType rootfs + FSType sysfs + FSType proc + FSType devtmpfs + FSType devpts + FSType tmpfs + FSType fusectl + FSType cgroup + IgnoreSelected true + + + + Server "{{ salt['pillar.get']('collectd:hostname') }}" "{{ salt['pillar.get']('collectd:port')}}" + Username "{{ salt['pillar.get']('collectd:username') }}" + Password "{{ salt['pillar.get']('collectd:password') }}" + + +# +# DataDir "/var/lib/collectd/rrd" +# + + + LogLevel info + + + + + Instance "auth" + + Regex "\\" + DSType "CounterInc" + Type "counter" + Instance "sshd-invalid_user" + + + + + + ListeningPorts true + + + + Filter "*.conf" + \ No newline at end of file diff --git a/states/oldstates/collectd/config.sls b/states/oldstates/collectd/config.sls new file mode 100644 index 0000000..bcdbaa8 --- /dev/null +++ b/states/oldstates/collectd/config.sls @@ -0,0 +1,13 @@ +--- +collectd-config: + file.managed: + - name: /etc/collectd/collectd.conf + - source: salt://collectd/collectd.conf.j2 + - user: root + - group: root + - mode: 0664 + - template: jinja + - watch_in: + - service: collectd-service + - require: + - pkg: collectd-pkg \ No newline at end of file diff --git a/states/oldstates/collectd/init.sls b/states/oldstates/collectd/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/oldstates/collectd/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/oldstates/collectd/install.sls b/states/oldstates/collectd/install.sls new file mode 100644 index 0000000..4b8051e --- /dev/null +++ b/states/oldstates/collectd/install.sls @@ -0,0 +1,6 @@ +--- +collectd-pkg: + pkg.latest: + - pkgs: + - collectd + - collectd-utils \ No newline at end of file diff --git a/states/oldstates/collectd/service.sls b/states/oldstates/collectd/service.sls new file mode 100644 index 0000000..8e204d0 --- /dev/null +++ b/states/oldstates/collectd/service.sls @@ -0,0 +1,5 @@ +--- +collectd-service: + service.dead: + - name: collectd + - enable: False \ No newline at end of file diff --git a/states/oldstates/snmp/init.sls b/states/oldstates/snmp/init.sls new file mode 100644 index 0000000..91e40b2 --- /dev/null +++ b/states/oldstates/snmp/init.sls @@ -0,0 +1,16 @@ +--- +snmp-snmpd-config: + file.managed: + - name: /etc/snmp/snmpd.conf + - source: salt://snmp/snmpd.conf.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: snmp-snmpd-service + +snmp-snmpd-service: + service.running: + - name: snmpd + - enable: True \ No newline at end of file diff --git a/states/oldstates/snmp/snmpd.conf.j2 b/states/oldstates/snmp/snmpd.conf.j2 new file mode 100644 index 0000000..8b6a70b --- /dev/null +++ b/states/oldstates/snmp/snmpd.conf.j2 @@ -0,0 +1,29 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +agentAddress udp:161,udp6:161 +dontLogTCPWrappersConnects yes + +syscontact {{ salt['pillar.get']('snmp_syscontact') }} +{% if salt['grains.get']('location') is defined %}syslocation {{ salt['grains.get']('location') }}{% endif %} + +rocommunity {{ salt['pillar.get']('snmp_community') }} default +rocommunity6 {{ salt['pillar.get']('snmp_community') }} default + +# IPv4 settings +{% for net in salt['pillar.get']('ipv4_networks') %}com2sec {{ salt['pillar.get']('snmp_community') }}-ro {{ net.ip }}/{{ net.mask }} {{ salt['pillar.get']('snmp_community') }} +{% endfor %} +# IPv6 settings +{% for net in salt['pillar.get']('ipv6_networks') %}com2sec {{ salt['pillar.get']('snmp_community') }}-ro {{ net.ip }}/{{ net.mask }} {{ salt['pillar.get']('snmp_community') }} +{% endfor %} +group {{ salt['pillar.get']('snmp_community')}}-gro v2c {{ salt['pillar.get']('snmp_community') }}-ro + +view all included .1 + +access paulbsd-gro "" any noauth exact all none none + +# Disks to monitor +{%- for partition in salt['mount.fstab']() %} +{%- if partition != "none" -%} +disk {{ partition }} +{%- endif -%} +{%- endfor %} \ No newline at end of file diff --git a/states/opendkim/TrustedHosts.j2 b/states/opendkim/TrustedHosts.j2 new file mode 100644 index 0000000..3c2f449 --- /dev/null +++ b/states/opendkim/TrustedHosts.j2 @@ -0,0 +1,9 @@ +{%- for key, value in salt['pillar.get']('net:ipv4_networks').items() %} +{{ value.ip }}/{{ value.mask }} +{%- endfor %} +{%- for key, value in salt['pillar.get']('net:ipv6_networks').items() %} +{{ value.ip }}/{{ value.mask }} +{%- endfor %} +{%- for hostname in salt['pillar.get']('mail:hostnames') %} +{{ hostname }} +{%- endfor %} \ No newline at end of file diff --git a/states/opendkim/config.sls b/states/opendkim/config.sls new file mode 100644 index 0000000..8175da5 --- /dev/null +++ b/states/opendkim/config.sls @@ -0,0 +1,52 @@ +--- +{%- from "opendkim/map.jinja" import opendkim with context %} +opendkim-config-dir: + file.directory: + - name: {{ opendkim.config.dir }} + - user: {{ opendkim.config.user }} + - group: {{ opendkim.config.group }} + - mode: 755 + +opendkim-configuration-key: + file.managed: + - name: {{ opendkim.config.dir }}/{{ opendkim.config.key.name }} + - source: salt://opendkim/key.j2 + - user: {{ opendkim.config.user }} + - group: {{ opendkim.config.group }} + - mode: 600 + - template: jinja + - watch_in: + - service: opendkim-service + +opendkim-trusted-hosts: + file.managed: + - name: {{ opendkim.config.dir }}/TrustedHosts + - source: salt://opendkim/TrustedHosts.j2 + - user: {{ opendkim.config.user }} + - group: {{ opendkim.config.group }} + - mode: 644 + - template: jinja + - watch_in: + - service: opendkim-service + +opendkim-service-defaults: + file.managed: + - name: {{ opendkim.config.default_file }} + - source: salt://opendkim/service_defaults.j2 + - user: {{ opendkim.config.user }} + - group: {{ opendkim.config.group }} + - mode: 644 + - template: jinja + - watch_in: + - service: opendkim-service + +opendkim-config-file: + file.managed: + - name: {{ opendkim.config.file }} + - source: salt://opendkim/opendkim.conf.j2 + - user: {{ opendkim.config.user }} + - group: {{ opendkim.config.group }} + - mode: 644 + - template: jinja + - watch_in: + - service: opendkim-service \ No newline at end of file diff --git a/states/opendkim/defaults.yaml b/states/opendkim/defaults.yaml new file mode 100644 index 0000000..add16ef --- /dev/null +++ b/states/opendkim/defaults.yaml @@ -0,0 +1,49 @@ +--- +opendkim: + enabled: true + config: + dir: '/etc/opendkim' + file: '/etc/opendkim.conf' + pid_file: '/var/run/opendkim/opendkim.pid' + default_file: '/etc/default/opendkim' + user: opendkim + group: opendkim + notify_addr: postmaster@example.com + notify_report: yes + host: 'localhost' + port: 8891 + log_why: yes + canonicalization: 'relaxed/simple' + require_safe_keys: false + syslog: yes + syslog_success: yes + key: + name: mx + content: > + '-----BEGIN RSA PRIVATE KEY----- + MIIEpAIBAAKCAQEA2vdXKLA+uWs87E82sHNYCe/LH5uf8nMfuuaCAv3sZSM1VR/N + YeifdBRPujMPgCi/vXjXFLjl4mSZb/xhX9pmqSvpDTnRr6HF/0JhtSIakBjr+BE/ + ESGx3DVuJCxEnm9q2DjZwwCBEOrVwXnSRXrzJvn5CGz8Gb4buty5t79KaXd0qxmG + bV5aSEaRU9fqB5pMfRnRdBX2W5NGGfamv6lXo9MqTJglwm4z+cU/gQTL4BDT6itH + TH0WDjaXdal8w0q99Ov20XWQGzGTeveZXS24AIQMZuSgmMrBoQbcT2XCgIoF9xOQ + eMQFv4uxAdnBihnnkpKVTcmtJ9QBtKY+/wYsXQIDAQABAoIBAHFGCOm8mwYyqraY + l/MaCE5DpXG5gTncQmreeh1wHI2JdDqQFCB1RZ+4LjJl3bvv2Jj83U8UA6BlaFbd + WcZLZlZXp902rvnLl3Dgd0lL1i/7JH8U9Oo44xjG7y55VBoeC0jFyCkvppUI1wGa + sqNM4mKkaCbqslPi29eD/fNHWwhJVYc3EsmC+HpW0EfwU0vNYetmE0tpWpvkjvVs + 8sLqAf4PmEUZwx6YPAmBgb0h2cNDqzv2e57aK05mwZ7CkCk9Nj3Ex5s/2J7HqvtR + lpSwgEREDYCnYem3Ow6LL3jFTf/ENDcaS4Y9lsVQFOZ9A/XyHjIvrAfH+LFg5ZNn + vFRJv0ECgYEA9e4W9Mh/QNlOxywFC0TdseCuT45Wql0iXUAfoEBjsdiQFpodesSq + 3mulxnZAL83PommEse2mubksBhU5LrQ04tKA6xpksQeQsEwZ+/aQTeE3yXpbD1DZ + k/LUG/PQjPJxbqZlHMCaFQbZMWQKK+ygVHbrqlXnSQ5ahnFn7EkQqRECgYEA4+6b + kups1qC5/OwotxZGfnhjB658BnZ+DpFtT4QTgo+LbXzluUR1vk3QncmowzUAOo8V + LYrUruPYLiFwj+9YjMkwOJM5xLJLY8iRj/kgHUU5U0vxzdyRAt5F+dvMu6yw5NqF + MFpwxpaABryJTedtqH1yB4Hqb87zILG6Blr4Lo0CgYAJWuY6p4nXsKyDfRQwCo2Y + X6Ch3BtF3ccZ3v+U+/4O3NsWUQSAEA0j6tpig0sLxnt4hSUME6s882NOU+5Z7Xb5 + jeJjjxx3c384hZyTbhytKb0Sh/oAyiWMsDcLXSn4wpw4BlJgVp9F333RmCme5CBx + Nhje4OesasRcyuGWJm1g0QKBgQC+CIHMy4ZSq05lgL+xZfEAIH7wOJlPChuvKbBp + S0S45dTpQ+iDvoAsWdREuYzqs5WtPP37KnSIG45xZ4/hcTvypQp/IMBZLg2M8/vo + fVw5Cy3wNLE1YV/FdGwDFS5sil4xb777wWulJnU3KJmRShIzF+OqPram4XPzHjpq + cg3ZQQKBgQCYN5mgdzjjQ2DQ6lT9V8C60/Etp1L2+UuQvFs29Wq6rSwuoTEiMOzZ + HbOcr9HGn7W/ocEZwSaMNB5jbtXuSJ4IInT3+PE1Qu1mbMavyv9yl/Y3saIJ8i1T + 3+EflCWWLXEVPTazoBscnjrbDfdJly3DVOn2g0IaerdZFb0w4o1+YA== + -----END RSA PRIVATE KEY-----' \ No newline at end of file diff --git a/states/opendkim/init.sls b/states/opendkim/init.sls new file mode 100644 index 0000000..1c23bd4 --- /dev/null +++ b/states/opendkim/init.sls @@ -0,0 +1,6 @@ +--- +{%- from "opendkim/map.jinja" import opendkim with context %} +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/opendkim/install.sls b/states/opendkim/install.sls new file mode 100644 index 0000000..f1754da --- /dev/null +++ b/states/opendkim/install.sls @@ -0,0 +1,7 @@ +--- +{%- from "opendkim/map.jinja" import opendkim with context %} +opendkim-pkg: + pkg.latest: + - pkgs: + - opendkim + - opendkim-tools \ No newline at end of file diff --git a/states/opendkim/key.j2 b/states/opendkim/key.j2 new file mode 100644 index 0000000..4aabaa5 --- /dev/null +++ b/states/opendkim/key.j2 @@ -0,0 +1,2 @@ +{%- from "opendkim/map.jinja" import opendkim with context -%} +{{ opendkim.config.key.content }} \ No newline at end of file diff --git a/states/opendkim/map.jinja b/states/opendkim/map.jinja new file mode 100644 index 0000000..24009c3 --- /dev/null +++ b/states/opendkim/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "opendkim/defaults.yaml" as defaults %} + +{%- set opendkim = salt['pillar.get']( + 'opendkim', + default=defaults.opendkim, + merge=True + ) +-%} \ No newline at end of file diff --git a/states/opendkim/opendkim.conf.j2 b/states/opendkim/opendkim.conf.j2 new file mode 100644 index 0000000..f713606 --- /dev/null +++ b/states/opendkim/opendkim.conf.j2 @@ -0,0 +1,23 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "opendkim/map.jinja" import opendkim with context %} +LogWhy {{ opendkim.config.log_why }} +Syslog {{ opendkim.config.syslog }} +SyslogSuccess {{ opendkim.config.syslog_success }} +RequireSafeKeys {{ opendkim.config.require_safe_keys }} + +Canonicalization {{ opendkim.config.canonicalization }} + +InternalHosts refile:{{ opendkim.config.dir }}/TrustedHosts + +Domain paulbsd.com +Selector mx +KeyFile {{ opendkim.config.dir }}/mx + +UserID {{ opendkim.config.user }} +PidFile {{ opendkim.config.pid_file }} + +Socket inet:{{ opendkim.config.port }}@{{ opendkim.config.host }} + +ReportAddress {{ opendkim.config.notify_addr }} +SendReports {{ opendkim.config.notify_report }} \ No newline at end of file diff --git a/states/opendkim/service.sls b/states/opendkim/service.sls new file mode 100644 index 0000000..aafe7e5 --- /dev/null +++ b/states/opendkim/service.sls @@ -0,0 +1,6 @@ +--- +{%- from "opendkim/map.jinja" import opendkim with context %} +opendkim-service: + service.running: + - name: opendkim + - enable: True \ No newline at end of file diff --git a/states/opendkim/service_defaults.j2 b/states/opendkim/service_defaults.j2 new file mode 100644 index 0000000..3af85d3 --- /dev/null +++ b/states/opendkim/service_defaults.j2 @@ -0,0 +1,2 @@ +{%- from "opendkim/map.jinja" import opendkim with context %} +SOCKET="inet:{{ opendkim.config.port }}@{{ opendkim.config.host }}" \ No newline at end of file diff --git a/states/openvpn_client/config.sls b/states/openvpn_client/config.sls new file mode 100644 index 0000000..bcdd608 --- /dev/null +++ b/states/openvpn_client/config.sls @@ -0,0 +1,32 @@ +--- +{%- from "openvpn_client/map.jinja" import openvpn with context %} +openvpn-client-main-config: + file.managed: + - name: {{ openvpn.config_dir }}/vpn.conf + - source: salt://openvpn_client/vpn.conf.j2 + - user: root + - group: root + - mode: 0600 + - template: jinja + - watch_in: + - service: openvpn-client-service + +openvpn-client-private-dir: + file.directory: + - name: {{ openvpn.config_dir }}/vpn + - user: root + - group: root + - mode: 0700 + - watch_in: + - service: openvpn-client-service + +openvpn-client-private-access: + file.managed: + - name: {{ openvpn.config_dir }}/vpn/pass + - source: salt://openvpn_client/pass.j2 + - template: jinja + - user: root + - group: root + - mode: 0600 + - watch_in: + - service: openvpn-client-service \ No newline at end of file diff --git a/states/openvpn_client/defaults.yaml b/states/openvpn_client/defaults.yaml new file mode 100644 index 0000000..ea016a4 --- /dev/null +++ b/states/openvpn_client/defaults.yaml @@ -0,0 +1,3 @@ +--- +openvpn: + config_dir: /etc/openvpn diff --git a/states/openvpn_client/init.sls b/states/openvpn_client/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/openvpn_client/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/openvpn_client/install.sls b/states/openvpn_client/install.sls new file mode 100644 index 0000000..18e459c --- /dev/null +++ b/states/openvpn_client/install.sls @@ -0,0 +1,6 @@ +--- +openvpn-client-install: + pkg.installed: + - name: openvpn + - watch_in: + - service: openvpn-client-service \ No newline at end of file diff --git a/states/openvpn_client/map.jinja b/states/openvpn_client/map.jinja new file mode 100644 index 0000000..d9f068b --- /dev/null +++ b/states/openvpn_client/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "openvpn_client/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='openvpn') -%} + +{%- set openvpn = salt['pillar.get']('openvpn', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/openvpn_client/pass.j2 b/states/openvpn_client/pass.j2 new file mode 100644 index 0000000..a586a3e --- /dev/null +++ b/states/openvpn_client/pass.j2 @@ -0,0 +1,7 @@ +{%- from "openvpn_client/map.jinja" import openvpn with context -%} +{%- for client in openvpn.config.vpn.remote_hosts -%} +{%- if client.name == salt['grains.get']('host') -%} +{{ client.name }} +{{ client.password }} +{%- endif -%} +{%- endfor -%} \ No newline at end of file diff --git a/states/openvpn_client/service.sls b/states/openvpn_client/service.sls new file mode 100644 index 0000000..af7fdaf --- /dev/null +++ b/states/openvpn_client/service.sls @@ -0,0 +1,5 @@ +--- +openvpn-client-service: + service.running: + - name: openvpn@vpn + - enable: True \ No newline at end of file diff --git a/states/openvpn_client/vpn.conf.j2 b/states/openvpn_client/vpn.conf.j2 new file mode 100644 index 0000000..aea637b --- /dev/null +++ b/states/openvpn_client/vpn.conf.j2 @@ -0,0 +1,29 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "openvpn_client/map.jinja" import openvpn with context %} + +{{ openvpn.config.vpn.ca }} + + +{{ openvpn.config.vpn.cert }} + + +{{ openvpn.config.vpn.key }} + +client +remote {{ openvpn.config.vpn.global_endpoint_host }} {{ openvpn.config.vpn.global_endpoint_port }} +proto {{ openvpn.config.vpn.global_endpoint_proto }} +dev tun + +topology subnet + +keepalive 10 120 + +nobind + +persist-key +persist-tun + +compress lzo +fast-io + +auth-user-pass vpn/pass \ No newline at end of file diff --git a/states/ovh/defaults.yaml b/states/ovh/defaults.yaml new file mode 100644 index 0000000..342be5f --- /dev/null +++ b/states/ovh/defaults.yaml @@ -0,0 +1,6 @@ +--- +ovh: + enabled: true + version: '0.5.0' + domain: + zones: {} \ No newline at end of file diff --git a/states/ovh/domain.sls b/states/ovh/domain.sls new file mode 100644 index 0000000..61fa5f1 --- /dev/null +++ b/states/ovh/domain.sls @@ -0,0 +1,14 @@ +--- +{%- from "ovh/map.jinja" import ovh with context %} +{%- for domain, values in ovh.domain.zones.items() %} +{%- for record in values.records %} +ovh-domain-{{ domain }}-{{ "{}-{}-{}".format(record.name, record.type, record.target)|md5 }}: + ovhapi.domain_record_present: + - name: ovh-domain-{{ domain }}-{{ "{}-{}-{}".format(record.name, record.type, record.target)|md5 }} + - zone: {{ domain }} + - recordname: {{ record.name }} + - recordtype: {{ record.type }} + - target: {{ record.target }} + - ttl: {{ record.ttl|default(0) }} +{%- endfor %} +{%- endfor %} \ No newline at end of file diff --git a/states/ovh/init.sls b/states/ovh/init.sls new file mode 100644 index 0000000..6e46cda --- /dev/null +++ b/states/ovh/init.sls @@ -0,0 +1,5 @@ +--- +{%- from "ovh/map.jinja" import ovh with context %} +include: + - .pkg + - .domain \ No newline at end of file diff --git a/states/ovh/map.jinja b/states/ovh/map.jinja new file mode 100644 index 0000000..9e9cf8d --- /dev/null +++ b/states/ovh/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "ovh/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='ovh') -%} + +{%- set ovh = salt['pillar.get']('ovh', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/ovh/pkg.sls b/states/ovh/pkg.sls new file mode 100644 index 0000000..07e9c73 --- /dev/null +++ b/states/ovh/pkg.sls @@ -0,0 +1,5 @@ +--- +{%- from "ovh/map.jinja" import ovh with context %} +ovh-install-pkg: + pip.installed: + - name: ovh=={{ ovh.version|default('0.5.0') }} \ No newline at end of file diff --git a/states/packer/defaults.yaml b/states/packer/defaults.yaml new file mode 100644 index 0000000..3dfb22b --- /dev/null +++ b/states/packer/defaults.yaml @@ -0,0 +1,8 @@ +--- +packer: + enabled: true + install_dir: /usr/local/sbin + mirror: https://releases.hashicorp.com/packer + version: "1.5.5" + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/packer/init.sls b/states/packer/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/packer/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/packer/install.sls b/states/packer/install.sls new file mode 100644 index 0000000..0507b78 --- /dev/null +++ b/states/packer/install.sls @@ -0,0 +1,8 @@ +--- +{%- from "packer/map.jinja" import packer with context %} +packer-archive-extract: + archive.extracted: + - name: {{ packer.install_dir }} + - source: {{ packer.mirror }}/{{ packer.version }}/packer_{{ packer.version }}_{{ packer.kernel }}_{{ packer.osarch }}.zip + - skip_verify: True + - enforce_toplevel: False \ No newline at end of file diff --git a/states/packer/kernelmap.yaml b/states/packer/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/packer/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/packer/map.jinja b/states/packer/map.jinja new file mode 100644 index 0000000..bbf256a --- /dev/null +++ b/states/packer/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "packer/defaults.yaml" as default_settings -%} + +{%- import_yaml "packer/kernelmap.yaml" as kernelmap %} +{%- import_yaml "packer/osarchmap.yaml" as osarchmap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='packer', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set packer = salt['pillar.get']('packer', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/packer/osarchmap.yaml b/states/packer/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/packer/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/php/config.sls b/states/php/config.sls new file mode 100644 index 0000000..55643cb --- /dev/null +++ b/states/php/config.sls @@ -0,0 +1,29 @@ +--- +{%- from "php/map.jinja" import php with context %} +{%- if php.fpm.config != None %} +php-config: + ini.options_present: + - name: {{ php.config_file }} + - separator: '=' + - sections: {{ php.config }} + - watch_in: + - service: php-fpm-service +{%- endif %} + +{%- if php.fpm.config != None %} +php-fpm-config: + ini.options_present: + - name: {{ php.fpm.config_file }} + - separator: '=' + - sections: {{ php.fpm.config }} + - watch_in: + - service: php-fpm-service +{%- endif %} + +{%- for extension in php.extensions %} +php-extension-enable-{{ extension }}: + cmd.run: + - name: phpenmod {{ extension }} + - watch_in: + - service: php-fpm-service +{%- endfor %} \ No newline at end of file diff --git a/states/php/defaults.yaml b/states/php/defaults.yaml new file mode 100644 index 0000000..5952e94 --- /dev/null +++ b/states/php/defaults.yaml @@ -0,0 +1,148 @@ +--- +php: + version: '7.3' + pkgs: + - php7.3 + - php7.3-curl + - php7.3-fpm + - php7.3-gd + - php7.3-mbstring + - php7.3-pgsql + - php7.3-xml + - php7.3-zip + extensions: + - readline + config_file: /etc/php/7.3/fpm/php.ini + config: + PHP: + engine: 'On' + short_open_tag: 'Off' + precision: 14 + output_buffering: 4096 + zlib.output_compression: 'Off' + implicit_flush: 'Off' + serialize_precision: -1 + disable_functions: 'pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,' + zend.enable_gc: 'On' + expose_php: 'Off' + max_execution_time: 30 + max_input_time: 60 + memory_limit: 256M + error_reporting: E_ALL & ~E_DEPRECATED & ~E_STRICT + display_errors: 'Off' + display_startup_errors: 'Off' + log_errors: 'On' + log_errors_max_len: 1024 + ignore_repeated_errors: 'Off' + ignore_repeated_source: 'Off' + report_memleaks: 'On' + html_errors: 'On' + variables_order: "GPCS" + request_order: "GP" + register_argc_argv: 'Off' + auto_globals_jit: 'On' + post_max_size: 8M + default_mimetype: "text/html" + default_charset: "UTF-8" + enable_dl: 'Off' + file_uploads: 'On' + upload_max_filesize: 2M + max_file_uploads: 20 + allow_url_fopen: 'On' + allow_url_include: 'Off' + default_socket_timeout: 60 + CLI Server: + cli_server.color: 'On' + Date: + filter: + iconv: + imap: + intl: + sqlite3: + Pcre: + Pdo: + Pdo_mysql: + Phar: + mail function: + SMTP: localhost + smtp_port: 25 + mail.add_x_header: 'Off' + ODBC: + odbc.allow_persistent: 'On' + odbc.check_persistent: 'On' + odbc.max_persistent: -1 + odbc.max_links: -1 + odbc.defaultlrl: 4096 + odbc.defaultbinmode: 1 + Interbase: + ibase.allow_persistent: 1 + ibase.max_persistent: -1 + ibase.max_links: -1 + ibase.timestampformat: "%Y-%m-%d %H:%M:%S" + ibase.dateformat: "%Y-%m-%d" + ibase.timeformat: "%H:%M:%S" + MySQLi: + mysqli.max_persistent: -1 + mysqli.allow_persistent: 'On' + mysqli.max_links: -1 + mysqli.default_port: 3306 + mysqli.reconnect: 'Off' + mysqlnd: + mysqlnd.collect_statistics: 'On' + mysqlnd.collect_memory_statistics: 'Off' + OCI8: + PostgreSQL: + pgsql.allow_persistent: 'On' + pgsql.auto_reset_persistent: 'Off' + pgsql.max_persistent: -1 + pgsql.max_links: -1 + pgsql.ignore_notice: 0 + pgsql.log_notice: 0 + bcmath: + bcmath.scale: 0 + browscap: + Session: + session.save_handler: files + session.use_strict_mode: 0 + session.use_cookies: 1 + session.use_only_cookies: 1 + session.name: PHPSESSID + session.auto_start: 0 + session.cookie_lifetime: 0 + session.cookie_path: / + session.serialize_handler: php + session.gc_probability: 0 + session.gc_divisor: 1000 + session.gc_maxlifetime: 1440 + session.cache_limiter: nocache + session.cache_expire: 180 + session.use_trans_sid: 0 + session.sid_length: 26 + session.trans_sid_tags: "'a=href,area=href,frame=src,form='" + session.sid_bits_per_character: 5 + Assertion: + zend.assertions: -1 + COM: + mbstring: + gd: + exif: + Tidy: + tidy.clean_output: 'Off' + + soap: + soap.wsdl_cache_enabled: 1 + soap.wsdl_cache_dir: "/tmp" + soap.wsdl_cache_ttl: 86400 + soap.wsdl_cache_limit: 5 + sysvshm: + ldap: + ldap.max_links: -1 + dba: + opcache: + curl: + openssl: + + fpm: + config_file: /etc/php/7.3/fpm/php-fpm.conf + config: + socket: /var/run/php/php7.3-fpm.sock \ No newline at end of file diff --git a/states/php/init.sls b/states/php/init.sls new file mode 100644 index 0000000..83c8ed9 --- /dev/null +++ b/states/php/init.sls @@ -0,0 +1,6 @@ +--- +{%- from "php/map.jinja" import php with context %} +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/php/install.sls b/states/php/install.sls new file mode 100644 index 0000000..2c64b5a --- /dev/null +++ b/states/php/install.sls @@ -0,0 +1,7 @@ +--- +{%- from "php/map.jinja" import php with context %} +php-pkgs: + pkg.latest: + - pkgs: {{ php.pkgs }} + - watch_in: + - service: php-fpm-service \ No newline at end of file diff --git a/states/php/map.jinja b/states/php/map.jinja new file mode 100644 index 0000000..6dce858 --- /dev/null +++ b/states/php/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "php/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='php') -%} + +{%- set php = salt['pillar.get']('php', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/php/service.sls b/states/php/service.sls new file mode 100644 index 0000000..6073d34 --- /dev/null +++ b/states/php/service.sls @@ -0,0 +1,6 @@ +--- +php-fpm-service: + service.running: + - name: php7.3-fpm + - enable: True + - reload: True \ No newline at end of file diff --git a/states/pkg/bootstrap.sls b/states/pkg/bootstrap.sls new file mode 100644 index 0000000..21d4140 --- /dev/null +++ b/states/pkg/bootstrap.sls @@ -0,0 +1,9 @@ +--- +pkg-full-upgrade: + pkg.uptodate: + - name: pkg-full-upgrade + - refresh: True + +pkg-install-apt-transport-https: + pkg.latest: + - name: apt-transport-https \ No newline at end of file diff --git a/states/pkg/defaults.yaml b/states/pkg/defaults.yaml new file mode 100644 index 0000000..7287ffd --- /dev/null +++ b/states/pkg/defaults.yaml @@ -0,0 +1,5 @@ +--- +pkg: + aptpkgs: [] + manual: [] + remove: [] diff --git a/states/pkg/init.sls b/states/pkg/init.sls new file mode 100644 index 0000000..7c0e2ac --- /dev/null +++ b/states/pkg/init.sls @@ -0,0 +1,8 @@ +--- +include: + - repos + - .tasks + - .bootstrap + - .install + - .manual + - .remove diff --git a/states/pkg/install.sls b/states/pkg/install.sls new file mode 100644 index 0000000..9da8980 --- /dev/null +++ b/states/pkg/install.sls @@ -0,0 +1,13 @@ +--- +{%- from "pkg/map.jinja" import pkg with context %} +{%- if pkg.aptpkgs|length > 0 %} +pkg-install: + pkg.latest: + - pkgs: + {%- for pkg in pkg.aptpkgs %} + - {{ pkg }} + {%- endfor %} + - refresh: False + - require: + - sls: repos +{%- endif %} diff --git a/states/pkg/manual.sls b/states/pkg/manual.sls new file mode 100644 index 0000000..a0f3493 --- /dev/null +++ b/states/pkg/manual.sls @@ -0,0 +1,12 @@ +--- +{%- from "pkg/map.jinja" import pkg with context %} +{%- if pkg.manual|length > 0 %} +{%- for pkg in pkg.manual %} +{%- if salt['pkg.version'](pkg.name) != pkg.version or salt['pkg.version'](pkg.name) == None %} +pkg-install-manual-{{ pkg.name }}: + pkg.installed: + - sources: + - {{ pkg.name }}: {{ pkg.src }} +{%- endif %} +{%- endfor %} +{%- endif %} diff --git a/states/pkg/map.jinja b/states/pkg/map.jinja new file mode 100644 index 0000000..7861d59 --- /dev/null +++ b/states/pkg/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "pkg/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='pkg') -%} + +{%- set pkg = salt['pillar.get']('pkg', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/pkg/remove.sls b/states/pkg/remove.sls new file mode 100644 index 0000000..8db55b3 --- /dev/null +++ b/states/pkg/remove.sls @@ -0,0 +1,10 @@ +--- +{%- from "pkg/map.jinja" import pkg with context %} +{%- if pkg.remove|length > 0 %} +pkg-remove: + pkg.purged: + - pkgs: +{%- for pkg in pkg.remove %} + - {{ pkg }} +{%- endfor %} +{%- endif %} \ No newline at end of file diff --git a/states/pkg/tasks.sls b/states/pkg/tasks.sls new file mode 100644 index 0000000..1108529 --- /dev/null +++ b/states/pkg/tasks.sls @@ -0,0 +1,8 @@ +--- +pkg-clean-task: + cron.present: + - name: apt-get clean + - user: root + - minute: {{ range(1, 59) | random }} + - hour: {{ range(1, 23) | random }} + - identifier: pkg-clean-task \ No newline at end of file diff --git a/states/postfix/defaults.yaml b/states/postfix/defaults.yaml new file mode 100644 index 0000000..d7f8ea7 --- /dev/null +++ b/states/postfix/defaults.yaml @@ -0,0 +1,46 @@ +--- +postfix: + enabled: true + base_dir: '/etc/postfix' + config: + main: + alias_database: 'hash:/etc/aliases' + alias_maps: 'hash:/etc/aliases' + append_dot_mydomain: 'no' + biff: 'no' + enable_original_recipient: 'yes' + inet_interfaces: 'all' + inet_protocols: 'all' + mailbox_size_limit: '0' + message_size_limit: '30480000' + mydestination: + - '$myhostname' + - 'localhost.$mydomain' + - 'localhost' + mydomain: 'example.com' + myhostname: 'mx.example.com' + mynetworks: '127.0.0.1' + myorigin: '$mydomain' + non_smtpd_milters: '$smtpd_milters' + readme_directory: 'no' + recipient_delimiter: '+' + relay_domains: 'example.com' + smtp_connect_timeout: '2m' + smtpd_banner: 'Example SMTP Server' + smtpd_helo_required: 'yes' + smtpd_relay_restrictions: + - 'permit_mynetworks' + - 'defer_unauth_destination' + - 'permit' + smtpd_sender_restrictions: + - 'permit_mynetworks' + - 'check_sender_access hash:/etc/postfix/sender_access' + - 'permit' + smtputf8_enable: 'yes' + soft_bounce: 'yes' + transport_maps: 'hash:/etc/postfix/transport' + unknown_local_recipient_reject_code: 550 + compatibility_level: 2 + master: {} + sender_access: {} + transport: {} \ No newline at end of file diff --git a/states/postfix/init.sls b/states/postfix/init.sls new file mode 100644 index 0000000..c0c4af4 --- /dev/null +++ b/states/postfix/init.sls @@ -0,0 +1,73 @@ +--- +{%- from "postfix/map.jinja" import postfix with context %} +postfix-pkg: + pkg.latest: + - name: postfix + +postfix-pgsql-dir: + file.directory: + - name: {{ postfix.base_dir }}/pgsql + - user: root + - group: root + +postfix-main-cf: + file.managed: + - name: {{ postfix.base_dir }}/main.cf + - source: salt://postfix/main.cf.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: postfix-service + +postfix-master-cf: + file.managed: + - name: {{ postfix.base_dir }}/master.cf + - source: salt://postfix/master.cf.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: postfix-service + +postfix-transport-maps: + file.managed: + - name: {{ postfix.base_dir }}/transport + - source: salt://postfix/transport.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: postfix-service + - cmd: postfix-transport + +postfix-sender-access-maps: + file.managed: + - name: {{ postfix.base_dir }}/sender_access + - source: salt://postfix/sender_access.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: postfix-service + - cmd: postfix-sender-access + +postfix-transport: + cmd.run: + - name: postmap transport + - cwd: {{ postfix.base_dir }} + +postfix-sender-access: + cmd.run: + - name: postmap sender_access + - cwd: {{ postfix.base_dir }} + +postfix-service: + service.running: + - name: postfix + - enable: True + - reload: True \ No newline at end of file diff --git a/states/postfix/main.cf.j2 b/states/postfix/main.cf.j2 new file mode 100644 index 0000000..f207dd2 --- /dev/null +++ b/states/postfix/main.cf.j2 @@ -0,0 +1,6 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "postfix/map.jinja" import postfix with context %} +{%- for key, value in postfix.config.main.items() %} +{{ key }} = {% if value is iterable and value is not string -%}{{ value|join(',') }}{%- else -%}{{ value }}{%- endif -%} +{%- endfor %} \ No newline at end of file diff --git a/states/postfix/map.jinja b/states/postfix/map.jinja new file mode 100644 index 0000000..3c6175a --- /dev/null +++ b/states/postfix/map.jinja @@ -0,0 +1,8 @@ +{%- import_yaml "postfix/defaults.yaml" as defaults %} + +{%- set postfix = salt['pillar.get']( + 'postfix', + default=defaults.postfix, + merge=True + ) +-%} diff --git a/states/postfix/master.cf.j2 b/states/postfix/master.cf.j2 new file mode 100644 index 0000000..eb8a9d5 --- /dev/null +++ b/states/postfix/master.cf.j2 @@ -0,0 +1,40 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +smtp inet n - - - - smtpd +pickup unix n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr unix n - n 300 1 qmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +relay unix - - - - - smtp +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 1 scache + +maildrop unix - n n - - pipe + flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} + +uucp unix - n n - - pipe + flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) + +maildb unix - n n - - pipe + flags=DROhu user=vmail:vmail argv=/usr/local/apps/maildb/maildb.py --config /usr/local/apps/maildb/maildb.ini ${sender} ${original_recipient} + +127.0.0.1:10025 inet n - n - - smtpd + -o content_filter= + -o mynetworks=127.0.0.0/8 + -o smtpd_recipient_restrictions=permit_mynetworks,reject \ No newline at end of file diff --git a/states/postfix/sender_access.j2 b/states/postfix/sender_access.j2 new file mode 100644 index 0000000..b44b756 --- /dev/null +++ b/states/postfix/sender_access.j2 @@ -0,0 +1,6 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "postfix/map.jinja" import postfix with context %} +{%- for key, value in postfix.config.sender_access.items() %} +{{ value.domain }} {{ value.action }} +{%- endfor %} \ No newline at end of file diff --git a/states/postfix/transport.j2 b/states/postfix/transport.j2 new file mode 100644 index 0000000..fadc567 --- /dev/null +++ b/states/postfix/transport.j2 @@ -0,0 +1,6 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "postfix/map.jinja" import postfix with context %} +{%- for key, value in postfix.config.transport.items() %} +{{ value.destination }} {{ value.endpoint }} +{%- endfor %} \ No newline at end of file diff --git a/states/postgresql/databases.sls b/states/postgresql/databases.sls new file mode 100644 index 0000000..e5c8ec7 --- /dev/null +++ b/states/postgresql/databases.sls @@ -0,0 +1,15 @@ +--- +{%- from "postgresql/map.jinja" import postgresql with context %} +{%- for database in postgresql.databases %} +postgresql_database_{{ database.name }}: + postgres_database.present: + - name: {{ database.name }} + - owner: {{ database.user }} + - db_user: postgres + - template: template0 + - encoding: {{ database.encoding }} + - lc_collate: {{ database.collate|default("en_US.UTF-8") }} + - lc_ctype: {{ database.ctype|default("en_US.UTF-8") }} + - require: + - postgres_user: postgresql_user_{{ database.user }} +{% endfor %} diff --git a/states/postgresql/defaults.yaml b/states/postgresql/defaults.yaml new file mode 100644 index 0000000..8e04d3d --- /dev/null +++ b/states/postgresql/defaults.yaml @@ -0,0 +1,6 @@ +--- +postgresql: + databases: + - name: postgres + user: postgres + users: [] \ No newline at end of file diff --git a/states/postgresql/init.sls b/states/postgresql/init.sls new file mode 100644 index 0000000..05606af --- /dev/null +++ b/states/postgresql/init.sls @@ -0,0 +1,6 @@ +--- +include: + - .install + - .service + - .users + - .databases \ No newline at end of file diff --git a/states/postgresql/install.sls b/states/postgresql/install.sls new file mode 100644 index 0000000..9632ac1 --- /dev/null +++ b/states/postgresql/install.sls @@ -0,0 +1,4 @@ +--- +postgresql-install: + pkg.latest: + - name: postgresql \ No newline at end of file diff --git a/states/postgresql/map.jinja b/states/postgresql/map.jinja new file mode 100644 index 0000000..cc6d1c5 --- /dev/null +++ b/states/postgresql/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "postgresql/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='postgresql') -%} + +{%- set postgresql = salt['pillar.get']('postgresql', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/postgresql/service.sls b/states/postgresql/service.sls new file mode 100644 index 0000000..664c435 --- /dev/null +++ b/states/postgresql/service.sls @@ -0,0 +1,5 @@ +--- +postgresql-service: + service.running: + - name: postgresql + - enable: True \ No newline at end of file diff --git a/states/postgresql/users.sls b/states/postgresql/users.sls new file mode 100644 index 0000000..489e39a --- /dev/null +++ b/states/postgresql/users.sls @@ -0,0 +1,13 @@ +--- +{%- from "postgresql/map.jinja" import postgresql with context %} +{%- for user in postgresql.users %} +postgresql_user_{{ user.name }}: + postgres_user.present: + - name: {{ user.name }} + {%- if user.password is defined %} + - password: {{ user.password }} + {%- endif %} + - login: {{ user.login|default(true) }} + - superuser: {{ user.superuser|default(false) }} + - db_user: postgres +{% endfor %} diff --git a/states/provision/defaults.yaml b/states/provision/defaults.yaml new file mode 100644 index 0000000..e78460b --- /dev/null +++ b/states/provision/defaults.yaml @@ -0,0 +1,12 @@ +--- +specs: + default: + enabled: true + type: none + country: none + location: none + cloud: false + container: false + sensu: false + sudo: true + websdr: false \ No newline at end of file diff --git a/states/provision/init.sls b/states/provision/init.sls new file mode 100644 index 0000000..8bc90a2 --- /dev/null +++ b/states/provision/init.sls @@ -0,0 +1,31 @@ +--- +{%- from "provision/map.jinja" import specs with context %} +schedule_highstate: + schedule.present: + - name: schedule_highstate + - function: state.highstate + - minutes: 30 + - run_on_start: False + +schedule_saltutil_clear_cache: + schedule.present: + - name: schedule_saltutil_clear_cache + - function: saltutil.clear_cache + - hours: 2 + - run_on_start: False + +schedule_pkg_refresh: + schedule.absent: + - name: schedule_pkg_refresh + +schedule_pkg_upgrade: + schedule.absent: + - name: schedule_pkg_upgrade + +{%- for key, value in specs.default.items() %} +{{ key }}: + grains.present: + - name: {{ key }} + - value: {% if specs[salt['grains.get']('id')][key] is defined %}{{ specs[salt['grains.get']('id')][key] }}{% else %}{{ value }}{% endif %} + - force: True +{% endfor %} diff --git a/states/provision/map.jinja b/states/provision/map.jinja new file mode 100644 index 0000000..e1b5fc6 --- /dev/null +++ b/states/provision/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "provision/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='specs') -%} + +{%- set specs = salt['pillar.get']('specs', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/pycharm/defaults.yaml b/states/pycharm/defaults.yaml new file mode 100644 index 0000000..8518c27 --- /dev/null +++ b/states/pycharm/defaults.yaml @@ -0,0 +1,6 @@ +--- +pycharm: + enabled: true + install_dir: /usr/local/apps + mirror: https://download.jetbrains.com/python + config: \ No newline at end of file diff --git a/states/pycharm/init.sls b/states/pycharm/init.sls new file mode 100644 index 0000000..0762b2a --- /dev/null +++ b/states/pycharm/init.sls @@ -0,0 +1,29 @@ +--- +{%- from "pycharm/map.jinja" import pycharm with context %} +{%- if not salt['file.directory_exists'](pycharm.install_dir + '/pycharm-community-' + pycharm.version) %} +pycharm-archive-extract: + archive.extracted: + - source: {{ pycharm.mirror }}/pycharm-community-{{ pycharm.version }}.tar.gz + - source_hash: {{ pycharm.mirror }}/pycharm-community-{{ pycharm.version }}.tar.gz.sha256 + - archive_format: tar + - name: {{ pycharm.install_dir }} + - if_missing: {{ pycharm.install_dir }}/pycharm-community-{{ pycharm.version }} + - watch: + - file: pycharm-link + - file: pycharm-shortcut +{%- endif %} + +pycharm-link: + file.symlink: + - name: {{ pycharm.install_dir }}/pycharm + - target: {{ pycharm.install_dir }}/pycharm-community-{{ pycharm.version }} + - force: True + +pycharm-shortcut: + file.managed: + - name: /usr/share/applications/jetbrains-pycharm-ce.desktop + - source: salt://pycharm/jetbrains-pycharm-ce.desktop.j2 + - template: jinja + - user: root + - group: root + - mode: 644 \ No newline at end of file diff --git a/states/pycharm/jetbrains-pycharm-ce.desktop.j2 b/states/pycharm/jetbrains-pycharm-ce.desktop.j2 new file mode 100644 index 0000000..9b84771 --- /dev/null +++ b/states/pycharm/jetbrains-pycharm-ce.desktop.j2 @@ -0,0 +1,12 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "pycharm/map.jinja" import pycharm with context %} +[Desktop Entry] +Version=1.0 +Type=Application +Name=PyCharm +Icon={{ pycharm.install_dir }}/pycharm/bin/pycharm.png +Exec="{{ pycharm.install_dir }}/pycharm/bin/pycharm.sh" %f +Comment=Develop with pleasure! +Categories=Development;IDE; +Terminal=false +StartupWMClass=jetbrains-pycharm-ce \ No newline at end of file diff --git a/states/pycharm/map.jinja b/states/pycharm/map.jinja new file mode 100644 index 0000000..4c5652d --- /dev/null +++ b/states/pycharm/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "pycharm/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='pycharm') -%} + +{%- set pycharm = salt['pillar.get']('pycharm', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/qrz/defaults.yaml b/states/qrz/defaults.yaml new file mode 100644 index 0000000..614c931 --- /dev/null +++ b/states/qrz/defaults.yaml @@ -0,0 +1,10 @@ +--- +qrz: + enabled: true + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + port: 8087 + mirror: https://git.paulbsd.com/paulbsd/qrz/releases/download + version: 1.0.2 + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/qrz/init.sls b/states/qrz/init.sls new file mode 100644 index 0000000..b07358d --- /dev/null +++ b/states/qrz/init.sls @@ -0,0 +1,4 @@ +--- +include: + - .install + - .service \ No newline at end of file diff --git a/states/qrz/install.sls b/states/qrz/install.sls new file mode 100644 index 0000000..18ed5a6 --- /dev/null +++ b/states/qrz/install.sls @@ -0,0 +1,20 @@ +--- +{%- from "qrz/map.jinja" import qrz with context %} +qrz-archive-extract: + archive.extracted: + - name: {{ qrz.release_dir }}/qrz-{{ qrz.version }} + - source: {{ qrz.mirror }}/{{ qrz.version }}/qrz-{{ qrz.version }}-{{ qrz.os }}-{{ qrz.arch }}.tar.gz + - skip_verify: True + - enforce_toplevel: False + - if_missing: {{ qrz.release_dir }}/qrz-{{ qrz.version }} + - watch_in: + - service: qrz-service + +qrz-binary-symlink: + file.symlink: + - name: {{ qrz.install_dir }}/qrz + - target: {{ qrz.release_dir }}/qrz-{{ qrz.version }} + - require: + - archive: qrz-archive-extract + - watch_in: + - service: qrz-service \ No newline at end of file diff --git a/states/qrz/kernelmap.yaml b/states/qrz/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/qrz/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/qrz/map.jinja b/states/qrz/map.jinja new file mode 100644 index 0000000..f10ff44 --- /dev/null +++ b/states/qrz/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "qrz/defaults.yaml" as default_settings -%} + +{%- import_yaml "qrz/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "qrz/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='qrz', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set qrz = salt['pillar.get']('qrz', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/qrz/osarchmap.yaml b/states/qrz/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/qrz/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/qrz/qrz.service.j2 b/states/qrz/qrz.service.j2 new file mode 100644 index 0000000..a6b3128 --- /dev/null +++ b/states/qrz/qrz.service.j2 @@ -0,0 +1,11 @@ +{%- from "qrz/map.jinja" import qrz with context %} +[Unit] +Description=QRZ +After=network.target + +[Service] +Type=simple +ExecStart={{ qrz.install_dir }}/qrz/qrz -configfile {{ qrz.install_dir }}/config/common.ini -port {{ qrz.port }} + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/qrz/service.sls b/states/qrz/service.sls new file mode 100644 index 0000000..8c93740 --- /dev/null +++ b/states/qrz/service.sls @@ -0,0 +1,14 @@ +--- +{%- from "qrz/map.jinja" import qrz with context %} +qrz-service-file: + file.managed: + - name: /etc/systemd/system/qrz.service + - source: salt://qrz/qrz.service.j2 + - user: root + - group: root + - template: jinja + +qrz-service: + service.running: + - name: qrz + - enable: True \ No newline at end of file diff --git a/states/rclone/defaults.yaml b/states/rclone/defaults.yaml new file mode 100644 index 0000000..5058dae --- /dev/null +++ b/states/rclone/defaults.yaml @@ -0,0 +1,9 @@ +--- +rclone: + enabled: true + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + mirror: https://downloads.rclone.org + version: v1.50.2 + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/rclone/init.sls b/states/rclone/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/rclone/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/rclone/install.sls b/states/rclone/install.sls new file mode 100644 index 0000000..c5750ed --- /dev/null +++ b/states/rclone/install.sls @@ -0,0 +1,19 @@ +--- +{%- from "rclone/map.jinja" import rclone with context %} +{%- if not salt['file.file_exists']( rclone.install_dir +"/rclone-" + rclone.version) %} +rclone-archive-extract: + archive.extracted: + - name: {{ rclone.release_dir }} + - source: {{ rclone.mirror }}/{{ rclone.version }}/rclone-{{ rclone.version }}-{{ rclone.os }}-{{ rclone.arch }}.zip + - skip_verify: True + - enforce_toplevel: False + - if_missing: {{ rclone.release_dir }}/rclone + +rclone-binary-symlink: + file.symlink: + - name: /usr/local/bin/rclone + - target: {{ rclone.release_dir }}/rclone-{{ rclone.version }}-{{ rclone.os }}-{{ rclone.arch }}/rclone + - force: True + - require: + - archive: rclone-archive-extract +{%- endif %} \ No newline at end of file diff --git a/states/rclone/kernelmap.yaml b/states/rclone/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/rclone/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/rclone/map.jinja b/states/rclone/map.jinja new file mode 100644 index 0000000..5bd605b --- /dev/null +++ b/states/rclone/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "rclone/defaults.yaml" as default_settings -%} + +{%- import_yaml "rclone/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "rclone/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='rclone', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set rclone = salt['pillar.get']('rclone', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/rclone/osarchmap.yaml b/states/rclone/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/rclone/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/reactor/auth.sls b/states/reactor/auth.sls new file mode 100644 index 0000000..1305600 --- /dev/null +++ b/states/reactor/auth.sls @@ -0,0 +1,15 @@ +--- +email-auth: + runner.process_minion_data.email_auth: + - smtp_server: 127.0.0.1 + - fromaddr: salt@paulbsd.com + - toaddrs: paul@paulbsd.com + - subject: "Salt master: minion auth: id: {{ data['id'] }}" + - data_str: {{ data|yaml_dquote }} + +#provision-run: +# local.state.sls: +# - tgt: {{ data['id'] }} +# - args: +# - mods: provision +# - ret: smtp \ No newline at end of file diff --git a/states/reactor/email-on-failure.sls b/states/reactor/email-on-failure.sls new file mode 100644 index 0000000..5e04317 --- /dev/null +++ b/states/reactor/email-on-failure.sls @@ -0,0 +1,8 @@ +--- +email-on-failure: + runner.process_minion_data.email_errors: + - smtp_server: 127.0.0.1 + - fromaddr: salt@paulbsd.com + - toaddrs: paul@paulbsd.com + - subject: "Salt failure or changes on {{ data['id'] }}" + - data_str: {{ data|yaml_dquote }} \ No newline at end of file diff --git a/states/redis/defaults.yaml b/states/redis/defaults.yaml new file mode 100644 index 0000000..18e5e68 --- /dev/null +++ b/states/redis/defaults.yaml @@ -0,0 +1,2 @@ +--- +redis: \ No newline at end of file diff --git a/states/redis/init.sls b/states/redis/init.sls new file mode 100644 index 0000000..b07358d --- /dev/null +++ b/states/redis/init.sls @@ -0,0 +1,4 @@ +--- +include: + - .install + - .service \ No newline at end of file diff --git a/states/redis/install.sls b/states/redis/install.sls new file mode 100644 index 0000000..f724236 --- /dev/null +++ b/states/redis/install.sls @@ -0,0 +1,4 @@ +--- +redis-install: + pkg.latest: + - name: redis-server \ No newline at end of file diff --git a/states/redis/map.jinja b/states/redis/map.jinja new file mode 100644 index 0000000..350f773 --- /dev/null +++ b/states/redis/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "redis/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='redis') -%} + +{%- set redis = salt['pillar.get']('redis', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/redis/service.sls b/states/redis/service.sls new file mode 100644 index 0000000..2f7c534 --- /dev/null +++ b/states/redis/service.sls @@ -0,0 +1,5 @@ +--- +redis-service: + service.running: + - name: redis + - enable: True \ No newline at end of file diff --git a/states/repos/init.sls b/states/repos/init.sls new file mode 100644 index 0000000..05ee7da --- /dev/null +++ b/states/repos/init.sls @@ -0,0 +1,33 @@ +--- +{%- for repo in pillar.get('repos') %} + +{%- if repo['enabled'] %} +pkg-repo-{{ repo['name'] }}: + pkgrepo.managed: + - humanname: {{ repo['humanname'] }} + {%- if repo['ppa'] %} + - ppa: {{ repo['ppasrc'] }} + - dist: {{ repo['dist'] }} + {%- elif not repo['ppa'] %} + - name: {{ repo['src'] }} + - gpgcheck: {{ repo['gpgcheck'] }} + - file: {{ repo['file'] }} + - clean_file: True + {%- if repo['key_method'] == 'file' %} + - key_url: {{ repo['key_url'] }} + {%- elif repo['key_method'] == 'server' %} + - keyid: {{ repo['keyid'] }} + - keyserver: {{ repo['keyserver'] }} + {%- endif %} + {%- endif %} + - refresh: True +{%- else %} + +pkg-repo-{{ repo['name'] }}: + file.absent: +{%- if not repo['ppa'] %} + - name: {{ repo['file'] }} +{%- endif %} +{%- endif %} + +{%- endfor %} \ No newline at end of file diff --git a/states/rspamd/config.sls b/states/rspamd/config.sls new file mode 100644 index 0000000..9454ff3 --- /dev/null +++ b/states/rspamd/config.sls @@ -0,0 +1,14 @@ +--- +{%- from "rspamd/map.jinja" import rspamd with context %} + +{%- for configfile in rspamd.config.files.items() %} +rspamd-config-{{ configfile }}: + file.managed: + - name: {{ rspamd.config.dir }}/{{ configfile }} + - source: salt://rspamd/templates/config.j2 + - template: jinja + - user: root + - group: root + - watch_in: + - service: rspamd-service +{%- endfor %} \ No newline at end of file diff --git a/states/rspamd/defaults.yaml b/states/rspamd/defaults.yaml new file mode 100644 index 0000000..5c38334 --- /dev/null +++ b/states/rspamd/defaults.yaml @@ -0,0 +1,5 @@ +--- +rspamd: + config: + dir: /etc/rspamd + files: {} \ No newline at end of file diff --git a/states/rspamd/init.sls b/states/rspamd/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/rspamd/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/rspamd/install.sls b/states/rspamd/install.sls new file mode 100644 index 0000000..c044be9 --- /dev/null +++ b/states/rspamd/install.sls @@ -0,0 +1,6 @@ +--- +{%- from "rspamd/map.jinja" import rspamd with context %} + +rspamd-pkgs: + pkg.installed: + - name: rspamd \ No newline at end of file diff --git a/states/rspamd/map.jinja b/states/rspamd/map.jinja new file mode 100644 index 0000000..c8d6ce8 --- /dev/null +++ b/states/rspamd/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "rspamd/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='rspamd') -%} + +{%- set rspamd = salt['pillar.get']('rspamd', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/rspamd/service.sls b/states/rspamd/service.sls new file mode 100644 index 0000000..765da76 --- /dev/null +++ b/states/rspamd/service.sls @@ -0,0 +1,5 @@ +--- +rspamd-service: + service.running: + - name: rspamd + - enable: True \ No newline at end of file diff --git a/states/rsync/config.sls b/states/rsync/config.sls new file mode 100644 index 0000000..a7c7253 --- /dev/null +++ b/states/rsync/config.sls @@ -0,0 +1,13 @@ +--- +rsync-config: + file.managed: + - name: /etc/rsyncd.conf + - source: salt://rsync/rsyncd.conf.j2 + - user: root + - group: root + - mode: 0755 + - template: jinja + - watch_in: + - service: rsync-service + - require: + - pkg: rsync-install \ No newline at end of file diff --git a/states/rsync/defaults.yaml b/states/rsync/defaults.yaml new file mode 100644 index 0000000..78fdfdb --- /dev/null +++ b/states/rsync/defaults.yaml @@ -0,0 +1,16 @@ +--- +rsync: + enabled: true + config: + global: + uid: 'root' + gid: 'root' + use chroot: 'no' + max connections: 4 + syslog facility: 4 + pid file: '/var/run/rsyncd.pid' + sections: + - name: 'tmp' + settings: + path: '/tmp' + read only: 'yes' \ No newline at end of file diff --git a/states/rsync/init.sls b/states/rsync/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/rsync/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/rsync/install.sls b/states/rsync/install.sls new file mode 100644 index 0000000..752ef61 --- /dev/null +++ b/states/rsync/install.sls @@ -0,0 +1,4 @@ +--- +rsync-install: + pkg.latest: + - name: rsync \ No newline at end of file diff --git a/states/rsync/map.jinja b/states/rsync/map.jinja new file mode 100644 index 0000000..cfc7425 --- /dev/null +++ b/states/rsync/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "rsync/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='rsync') -%} + +{%- set rsync = salt['pillar.get']('rsync', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/rsync/rsyncd.conf.j2 b/states/rsync/rsyncd.conf.j2 new file mode 100644 index 0000000..3edd11f --- /dev/null +++ b/states/rsync/rsyncd.conf.j2 @@ -0,0 +1,12 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "rsync/map.jinja" import rsync with context %} +{% for key, value in rsync.config.global.items() %} +{{ key }} = {{ value }} +{%- endfor %} + +{% for section in rsync.config.sections -%} +[{{ section.name }}] +{%- for key, value in section.settings.items() %} + {{ key }} = {{ value }} +{%- endfor %} +{%- endfor %} \ No newline at end of file diff --git a/states/rsync/service.sls b/states/rsync/service.sls new file mode 100644 index 0000000..65722f6 --- /dev/null +++ b/states/rsync/service.sls @@ -0,0 +1,7 @@ +--- +rsync-service: + service.running: + - name: rsync + - enable: True + - require: + - file: rsync-config \ No newline at end of file diff --git a/states/rsyslog/config.sls b/states/rsyslog/config.sls new file mode 100644 index 0000000..8c42880 --- /dev/null +++ b/states/rsyslog/config.sls @@ -0,0 +1,10 @@ +--- +rsyslog-main-config: + file.managed: + - name: /etc/rsyslog.conf + - source: salt://rsyslog/rsyslog.conf.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: rsyslog-service \ No newline at end of file diff --git a/states/rsyslog/init.sls b/states/rsyslog/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/rsyslog/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/rsyslog/install.sls b/states/rsyslog/install.sls new file mode 100644 index 0000000..a7fb5e9 --- /dev/null +++ b/states/rsyslog/install.sls @@ -0,0 +1,4 @@ +--- +rsyslog-pkg: + pkg.installed: + - name: rsyslog \ No newline at end of file diff --git a/states/rsyslog/rsyslog.conf.j2 b/states/rsyslog/rsyslog.conf.j2 new file mode 100644 index 0000000..fa686a6 --- /dev/null +++ b/states/rsyslog/rsyslog.conf.j2 @@ -0,0 +1,46 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +module(load="imuxsock") +module(load="imklog" permitnonkernelfacility="on") + +$ModLoad imudp.so + +$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format +$RepeatedMsgReduction on +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$PrivDropToUser syslog +$PrivDropToGroup syslog +$UDPServerRun 514 +$Umask 0022 + +$WorkDirectory /var/spool/rsyslog + +$IncludeConfig /etc/rsyslog.d/*.conf + +auth,authpriv.* /var/log/auth.log +*.*;auth,authpriv.none -/var/log/syslog +cron.* /var/log/cron.log +daemon.* -/var/log/daemon.log +kern.* -/var/log/kern.log +lpr.* -/var/log/lpr.log +mail.* -/var/log/mail.log +user.* -/var/log/user.log + +mail.info -/var/log/mail.info +mail.warn -/var/log/mail.warn +mail.err /var/log/mail.err + +*.=debug;\ + auth,authpriv.none;\ + news.none;mail.none -/var/log/debug +*.=info;*.=notice;*.=warn;\ + auth,authpriv.none;\ + cron,daemon.none;\ + mail,news.none -/var/log/messages + +*.emerg :omusrmsg:* + +*.* @localhost:6514;RSYSLOG_SyslogProtocol23Format diff --git a/states/rsyslog/rsyslog.conf.j2.orig b/states/rsyslog/rsyslog.conf.j2.orig new file mode 100644 index 0000000..7bd37a2 --- /dev/null +++ b/states/rsyslog/rsyslog.conf.j2.orig @@ -0,0 +1,60 @@ +# /etc/rsyslog.conf Configuration file for rsyslog. +# +# For more information see +# /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html +# +# Default logging rules can be found in /etc/rsyslog.d/50-default.conf + + +################# +#### MODULES #### +################# + +module(load="imuxsock") # provides support for local system logging +#module(load="immark") # provides --MARK-- message capability + +# provides UDP syslog reception +#module(load="imudp") +#input(type="imudp" port="514") + +# provides TCP syslog reception +#module(load="imtcp") +#input(type="imtcp" port="514") + +# provides kernel logging support and enable non-kernel klog messages +module(load="imklog" permitnonkernelfacility="on") + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +$ActionFileDefaultTemplate RSYSLOG_SyslogProtocol23Format + +# Filter duplicated messages +$RepeatedMsgReduction on + +# +# Set the default permissions for all log files. +# +$FileOwner syslog +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 +$PrivDropToUser syslog +$PrivDropToGroup syslog + +# +# Where to place spool and state files +# +$WorkDirectory /var/spool/rsyslog + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf \ No newline at end of file diff --git a/states/rsyslog/service.sls b/states/rsyslog/service.sls new file mode 100644 index 0000000..88be17b --- /dev/null +++ b/states/rsyslog/service.sls @@ -0,0 +1,5 @@ +--- +rsyslog-service: + service.running: + - name: rsyslog + - enable: True \ No newline at end of file diff --git a/states/salt_minion/defaults.yaml b/states/salt_minion/defaults.yaml new file mode 100644 index 0000000..e1d9802 --- /dev/null +++ b/states/salt_minion/defaults.yaml @@ -0,0 +1,14 @@ +--- +salt_minion: + enabled: true + version: 3000 + config: + master: salt.paulbsd.com + #hash_type: sha256 + #state_verbose: True + #tcp_keepalive: True + #tcp_keepalive_idle: 300 + #random_reauth_delay: 60 + #recon_default: 1000 + #recon_max: 10000 + #recon_randomize: True diff --git a/states/salt_minion/init.sls b/states/salt_minion/init.sls new file mode 100644 index 0000000..e41737d --- /dev/null +++ b/states/salt_minion/init.sls @@ -0,0 +1,19 @@ +--- +{%- from "salt_minion/map.jinja" import salt_minion with context -%} +salt-minion-config: + file.managed: + - name: /etc/salt/minion + - source: salt://salt_minion/minion.j2 + - template: jinja + - user: root + - group: root + - mode: 755 + +salt-minion-service: + file.managed: + - name: /etc/systemd/system/salt-minion.service + - source: salt://salt_minion/salt-minion.service.j2 + - template: jinja + - user: root + - group: root + - mode: 755 \ No newline at end of file diff --git a/states/salt_minion/map.jinja b/states/salt_minion/map.jinja new file mode 100644 index 0000000..fe97e56 --- /dev/null +++ b/states/salt_minion/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "salt_minion/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='salt_minion') -%} + +{%- set salt_minion = salt['pillar.get']('salt_minion', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/salt_minion/minion.j2 b/states/salt_minion/minion.j2 new file mode 100644 index 0000000..27a5d5c --- /dev/null +++ b/states/salt_minion/minion.j2 @@ -0,0 +1,5 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "salt_minion/map.jinja" import salt_minion with context %} +{%- for key, value in salt_minion.config.items() %} +{{ key }}: {{ value }} +{%- endfor -%} \ No newline at end of file diff --git a/states/salt_minion/minion.sample b/states/salt_minion/minion.sample new file mode 100644 index 0000000..3885e7c --- /dev/null +++ b/states/salt_minion/minion.sample @@ -0,0 +1,781 @@ +##### Primary configuration settings ##### +########################################## +# This configuration file is used to manage the behavior of the Salt Minion. +# With the exception of the location of the Salt Master Server, values that are +# commented out but have an empty line after the comment are defaults that need +# not be set in the config. If there is no blank line after the comment, the +# value is presented as an example and is not the default. + +# Per default the minion will automatically include all config files +# from minion.d/*.conf (minion.d is a directory in the same directory +# as the main minion config file). +#default_include: minion.d/*.conf + +# Set the location of the salt master server. If the master server cannot be +# resolved, then the minion will fail to start. +#master: salt + +# Set http proxy information for the minion when doing requests +#proxy_host: +#proxy_port: +#proxy_username: +#proxy_password: + +# If multiple masters are specified in the 'master' setting, the default behavior +# is to always try to connect to them in the order they are listed. If random_master is +# set to True, the order will be randomized instead. This can be helpful in distributing +# the load of many minions executing salt-call requests, for example, from a cron job. +# If only one master is listed, this setting is ignored and a warning will be logged. +# NOTE: If master_type is set to failover, use master_shuffle instead. +#random_master: False + +# Use if master_type is set to failover. +#master_shuffle: False + +# Minions can connect to multiple masters simultaneously (all masters +# are "hot"), or can be configured to failover if a master becomes +# unavailable. Multiple hot masters are configured by setting this +# value to "str". Failover masters can be requested by setting +# to "failover". MAKE SURE TO SET master_alive_interval if you are +# using failover. +# master_type: str + +# Poll interval in seconds for checking if the master is still there. Only +# respected if master_type above is "failover". To disable the interval entirely, +# set the value to -1. (This may be necessary on machines which have high numbers +# of TCP connections, such as load balancers.) +# master_alive_interval: 30 + +# If the minion is in multi-master mode and the master_type configuration option +# is set to "failover", this setting can be set to "True" to force the minion +# to fail back to the first master in the list if the first master is back online. +#master_failback: False + +# If the minion is in multi-master mode, the "master_type" configuration is set to +# "failover", and the "master_failback" option is enabled, the master failback +# interval can be set to ping the top master with this interval, in seconds. +#master_failback_interval: 0 + +# Set whether the minion should connect to the master via IPv6: +#ipv6: False + +# Set the number of seconds to wait before attempting to resolve +# the master hostname if name resolution fails. Defaults to 30 seconds. +# Set to zero if the minion should shutdown and not retry. +# retry_dns: 30 + +# Set the port used by the master reply and authentication server. +#master_port: 4506 + +# The user to run salt. +#user: root + +# The user to run salt remote execution commands as via sudo. If this option is +# enabled then sudo will be used to change the active user executing the remote +# command. If enabled the user will need to be allowed access via the sudoers +# file for the user that the salt minion is configured to run as. The most +# common option would be to use the root user. If this option is set the user +# option should also be set to a non-root user. If migrating from a root minion +# to a non root minion the minion cache should be cleared and the minion pki +# directory will need to be changed to the ownership of the new user. +#sudo_user: root + +# Specify the location of the daemon process ID file. +#pidfile: /var/run/salt-minion.pid + +# The root directory prepended to these options: pki_dir, cachedir, log_file, +# sock_dir, pidfile. +#root_dir: / + +# The path to the minion's configuration file. +#conf_file: /usr/pkg/etc/salt/minion + +# The directory to store the pki information in +#pki_dir: /usr/pkg/etc/salt/pki/minion + +# Explicitly declare the id for this minion to use, if left commented the id +# will be the hostname as returned by the python call: socket.getfqdn() +# Since salt uses detached ids it is possible to run multiple minions on the +# same machine but with different ids, this can be useful for salt compute +# clusters. +#id: + +# Cache the minion id to a file when the minion's id is not statically defined +# in the minion config. Defaults to "True". This setting prevents potential +# problems when automatic minion id resolution changes, which can cause the +# minion to lose connection with the master. To turn off minion id caching, +# set this config to ``False``. +#minion_id_caching: True + +# Append a domain to a hostname in the event that it does not exist. This is +# useful for systems where socket.getfqdn() does not actually result in a +# FQDN (for instance, Solaris). +#append_domain: + +# Custom static grains for this minion can be specified here and used in SLS +# files just like all other grains. This example sets 4 custom grains, with +# the 'roles' grain having two values that can be matched against. +#grains: +# roles: +# - webserver +# - memcache +# deployment: datacenter4 +# cabinet: 13 +# cab_u: 14-15 +# +# Where cache data goes. +# This data may contain sensitive data and should be protected accordingly. +#cachedir: /var/cache/salt/minion + +# Append minion_id to these directories. Helps with +# multiple proxies and minions running on the same machine. +# Allowed elements in the list: pki_dir, cachedir, extension_modules +# Normally not needed unless running several proxies and/or minions on the same machine +# Defaults to ['cachedir'] for proxies, [] (empty list) for regular minions +#append_minionid_config_dirs: + +# Verify and set permissions on configuration directories at startup. +#verify_env: True + +# The minion can locally cache the return data from jobs sent to it, this +# can be a good way to keep track of jobs the minion has executed +# (on the minion side). By default this feature is disabled, to enable, set +# cache_jobs to True. +#cache_jobs: False + +# Set the directory used to hold unix sockets. +#sock_dir: /var/run/salt/minion + +# Set the default outputter used by the salt-call command. The default is +# "nested". +#output: nested +# +# By default output is colored. To disable colored output, set the color value +# to False. +#color: True + +# Do not strip off the colored output from nested results and state outputs +# (true by default). +# strip_colors: False + +# Backup files that are replaced by file.managed and file.recurse under +# 'cachedir'/file_backups relative to their original location and appended +# with a timestamp. The only valid setting is "minion". Disabled by default. +# +# Alternatively this can be specified for each file in state files: +# /etc/ssh/sshd_config: +# file.managed: +# - source: salt://ssh/sshd_config +# - backup: minion +# +#backup_mode: minion + +# When waiting for a master to accept the minion's public key, salt will +# continuously attempt to reconnect until successful. This is the time, in +# seconds, between those reconnection attempts. +#acceptance_wait_time: 10 + +# If this is nonzero, the time between reconnection attempts will increase by +# acceptance_wait_time seconds per iteration, up to this maximum. If this is +# set to zero, the time between reconnection attempts will stay constant. +#acceptance_wait_time_max: 0 + +# If the master rejects the minion's public key, retry instead of exiting. +# Rejected keys will be handled the same as waiting on acceptance. +#rejected_retry: False + +# When the master key changes, the minion will try to re-auth itself to receive +# the new master key. In larger environments this can cause a SYN flood on the +# master because all minions try to re-auth immediately. To prevent this and +# have a minion wait for a random amount of time, use this optional parameter. +# The wait-time will be a random number of seconds between 0 and the defined value. +#random_reauth_delay: 60 + +# When waiting for a master to accept the minion's public key, salt will +# continuously attempt to reconnect until successful. This is the timeout value, +# in seconds, for each individual attempt. After this timeout expires, the minion +# will wait for acceptance_wait_time seconds before trying again. Unless your master +# is under unusually heavy load, this should be left at the default. +#auth_timeout: 60 + +# Number of consecutive SaltReqTimeoutError that are acceptable when trying to +# authenticate. +#auth_tries: 7 + +# The number of attempts to connect to a master before giving up. +# Set this to -1 for unlimited attempts. This allows for a master to have +# downtime and the minion to reconnect to it later when it comes back up. +# In 'failover' mode, it is the number of attempts for each set of masters. +# In this mode, it will cycle through the list of masters for each attempt. +# +# This is different than auth_tries because auth_tries attempts to +# retry auth attempts with a single master. auth_tries is under the +# assumption that you can connect to the master but not gain +# authorization from it. master_tries will still cycle through all +# the masters in a given try, so it is appropriate if you expect +# occasional downtime from the master(s). +#master_tries: 1 + +# If authentication fails due to SaltReqTimeoutError during a ping_interval, +# cause sub minion process to restart. +#auth_safemode: False + +# Ping Master to ensure connection is alive (minutes). +#ping_interval: 0 + +# To auto recover minions if master changes IP address (DDNS) +# auth_tries: 10 +# auth_safemode: False +# ping_interval: 90 +# +# Minions won't know master is missing until a ping fails. After the ping fail, +# the minion will attempt authentication and likely fails out and cause a restart. +# When the minion restarts it will resolve the masters IP and attempt to reconnect. + +# If you don't have any problems with syn-floods, don't bother with the +# three recon_* settings described below, just leave the defaults! +# +# The ZeroMQ pull-socket that binds to the masters publishing interface tries +# to reconnect immediately, if the socket is disconnected (for example if +# the master processes are restarted). In large setups this will have all +# minions reconnect immediately which might flood the master (the ZeroMQ-default +# is usually a 100ms delay). To prevent this, these three recon_* settings +# can be used. +# recon_default: the interval in milliseconds that the socket should wait before +# trying to reconnect to the master (1000ms = 1 second) +# +# recon_max: the maximum time a socket should wait. each interval the time to wait +# is calculated by doubling the previous time. if recon_max is reached, +# it starts again at recon_default. Short example: +# +# reconnect 1: the socket will wait 'recon_default' milliseconds +# reconnect 2: 'recon_default' * 2 +# reconnect 3: ('recon_default' * 2) * 2 +# reconnect 4: value from previous interval * 2 +# reconnect 5: value from previous interval * 2 +# reconnect x: if value >= recon_max, it starts again with recon_default +# +# recon_randomize: generate a random wait time on minion start. The wait time will +# be a random value between recon_default and recon_default + +# recon_max. Having all minions reconnect with the same recon_default +# and recon_max value kind of defeats the purpose of being able to +# change these settings. If all minions have the same values and your +# setup is quite large (several thousand minions), they will still +# flood the master. The desired behavior is to have timeframe within +# all minions try to reconnect. +# +# Example on how to use these settings. The goal: have all minions reconnect within a +# 60 second timeframe on a disconnect. +# recon_default: 1000 +# recon_max: 59000 +# recon_randomize: True +# +# Each minion will have a randomized reconnect value between 'recon_default' +# and 'recon_default + recon_max', which in this example means between 1000ms +# 60000ms (or between 1 and 60 seconds). The generated random-value will be +# doubled after each attempt to reconnect. Lets say the generated random +# value is 11 seconds (or 11000ms). +# reconnect 1: wait 11 seconds +# reconnect 2: wait 22 seconds +# reconnect 3: wait 33 seconds +# reconnect 4: wait 44 seconds +# reconnect 5: wait 55 seconds +# reconnect 6: wait time is bigger than 60 seconds (recon_default + recon_max) +# reconnect 7: wait 11 seconds +# reconnect 8: wait 22 seconds +# reconnect 9: wait 33 seconds +# reconnect x: etc. +# +# In a setup with ~6000 thousand hosts these settings would average the reconnects +# to about 100 per second and all hosts would be reconnected within 60 seconds. +# recon_default: 100 +# recon_max: 5000 +# recon_randomize: False +# +# +# The loop_interval sets how long in seconds the minion will wait between +# evaluating the scheduler and running cleanup tasks. This defaults to a +# sane 60 seconds, but if the minion scheduler needs to be evaluated more +# often lower this value +#loop_interval: 60 + +# The grains can be merged, instead of overridden, using this option. +# This allows custom grains to defined different subvalues of a dictionary +# grain. By default this feature is disabled, to enable set grains_deep_merge +# to ``True``. +#grains_deep_merge: False + +# The grains_refresh_every setting allows for a minion to periodically check +# its grains to see if they have changed and, if so, to inform the master +# of the new grains. This operation is moderately expensive, therefore +# care should be taken not to set this value too low. +# +# Note: This value is expressed in __minutes__! +# +# A value of 10 minutes is a reasonable default. +# +# If the value is set to zero, this check is disabled. +#grains_refresh_every: 1 + +# Cache grains on the minion. Default is False. +#grains_cache: False + +# Cache rendered pillar data on the minion. Default is False. +# This may cause 'cachedir'/pillar to contain sensitive data that should be +# protected accordingly. +#minion_pillar_cache: False + +# Grains cache expiration, in seconds. If the cache file is older than this +# number of seconds then the grains cache will be dumped and fully re-populated +# with fresh data. Defaults to 5 minutes. Will have no effect if 'grains_cache' +# is not enabled. +# grains_cache_expiration: 300 + +# Determines whether or not the salt minion should run scheduled mine updates. +# Defaults to "True". Set to "False" to disable the scheduled mine updates +# (this essentially just does not add the mine update function to the minion's +# scheduler). +#mine_enabled: True + +# Determines whether or not scheduled mine updates should be accompanied by a job +# return for the job cache. Defaults to "False". Set to "True" to include job +# returns in the job cache for mine updates. +#mine_return_job: False + +# Example functions that can be run via the mine facility +# NO mine functions are established by default. +# Note these can be defined in the minion's pillar as well. +#mine_functions: +# test.ping: [] +# network.ip_addrs: +# interface: eth0 +# cidr: '10.0.0.0/8' + +# Windows platforms lack posix IPC and must rely on slower TCP based inter- +# process communications. Set ipc_mode to 'tcp' on such systems +#ipc_mode: ipc + +# Overwrite the default tcp ports used by the minion when in tcp mode +#tcp_pub_port: 4510 +#tcp_pull_port: 4511 + +# Passing very large events can cause the minion to consume large amounts of +# memory. This value tunes the maximum size of a message allowed onto the +# minion event bus. The value is expressed in bytes. +#max_event_size: 1048576 + +# To detect failed master(s) and fire events on connect/disconnect, set +# master_alive_interval to the number of seconds to poll the masters for +# connection events. +# +#master_alive_interval: 30 + +# The minion can include configuration from other files. To enable this, +# pass a list of paths to this option. The paths can be either relative or +# absolute; if relative, they are considered to be relative to the directory +# the main minion configuration file lives in (this file). Paths can make use +# of shell-style globbing. If no files are matched by a path passed to this +# option then the minion will log a warning message. +# +# Include a config file from some other path: +# include: /usr/pkg/etc/salt/extra_config +# +# Include config from several files and directories: +#include: +# - /usr/pkg/etc/salt/extra_config +# - /etc/roles/webserver + +# The syndic minion can verify that it is talking to the correct master via the +# key fingerprint of the higher-level master with the "syndic_finger" config. +#syndic_finger: '' +# +# +# +##### Minion module management ##### +########################################## +# Disable specific modules. This allows the admin to limit the level of +# access the master has to the minion. +#disable_modules: [cmd,test] +#disable_returners: [] + +# This is the reverse of disable_modules. The default, like disable_modules, is the empty list, +# but if this option is set to *anything* then *only* those modules will load. +# Note that this is a very large hammer and it can be quite difficult to keep the minion working +# the way you think it should since Salt uses many modules internally itself. At a bare minimum +# you need the following enabled or else the minion won't start. +#whitelist_modules: +# - cmdmod +# - test +# - config + +# Modules can be loaded from arbitrary paths. This enables the easy deployment +# of third party modules. Modules for returners and minions can be loaded. +# Specify a list of extra directories to search for minion modules and +# returners. These paths must be fully qualified! +#module_dirs: [] +#returner_dirs: [] +#states_dirs: [] +#render_dirs: [] +#utils_dirs: [] +# +# A module provider can be statically overwritten or extended for the minion +# via the providers option, in this case the default module will be +# overwritten by the specified module. In this example the pkg module will +# be provided by the yumpkg5 module instead of the system default. +#providers: +# pkg: yumpkg5 +# +# Enable Cython modules searching and loading. (Default: False) +#cython_enable: False +# +# Specify a max size (in bytes) for modules on import. This feature is currently +# only supported on *nix operating systems and requires psutil. +# modules_max_memory: -1 + + +##### State Management Settings ##### +########################################### +# The state management system executes all of the state templates on the minion +# to enable more granular control of system state management. The type of +# template and serialization used for state management needs to be configured +# on the minion, the default renderer is yaml_jinja. This is a yaml file +# rendered from a jinja template, the available options are: +# yaml_jinja +# yaml_mako +# yaml_wempy +# json_jinja +# json_mako +# json_wempy +# +#renderer: yaml_jinja +# +# The failhard option tells the minions to stop immediately after the first +# failure detected in the state execution. Defaults to False. +#failhard: False +# +# Reload the modules prior to a highstate run. +#autoload_dynamic_modules: True +# +# clean_dynamic_modules keeps the dynamic modules on the minion in sync with +# the dynamic modules on the master, this means that if a dynamic module is +# not on the master it will be deleted from the minion. By default, this is +# enabled and can be disabled by changing this value to False. +#clean_dynamic_modules: True +# +# Normally, the minion is not isolated to any single environment on the master +# when running states, but the environment can be isolated on the minion side +# by statically setting it. Remember that the recommended way to manage +# environments is to isolate via the top file. +#environment: None +# +# Isolates the pillar environment on the minion side. This functions the same +# as the environment setting, but for pillar instead of states. +#pillarenv: None +# +# If using the local file directory, then the state top file name needs to be +# defined, by default this is top.sls. +#state_top: top.sls +# +# Run states when the minion daemon starts. To enable, set startup_states to: +# 'highstate' -- Execute state.highstate +# 'sls' -- Read in the sls_list option and execute the named sls files +# 'top' -- Read top_file option and execute based on that file on the Master +#startup_states: '' +# +# List of states to run when the minion starts up if startup_states is 'sls': +#sls_list: +# - edit.vim +# - hyper +# +# Top file to execute if startup_states is 'top': +#top_file: '' + +# Automatically aggregate all states that have support for mod_aggregate by +# setting to True. Or pass a list of state module names to automatically +# aggregate just those types. +# +# state_aggregate: +# - pkg +# +#state_aggregate: False + +##### File Directory Settings ##### +########################################## +# The Salt Minion can redirect all file server operations to a local directory, +# this allows for the same state tree that is on the master to be used if +# copied completely onto the minion. This is a literal copy of the settings on +# the master but used to reference a local directory on the minion. + +# Set the file client. The client defaults to looking on the master server for +# files, but can be directed to look at the local file directory setting +# defined below by setting it to "local". Setting a local file_client runs the +# minion in masterless mode. +#file_client: remote + +# The file directory works on environments passed to the minion, each environment +# can have multiple root directories, the subdirectories in the multiple file +# roots cannot match, otherwise the downloaded files will not be able to be +# reliably ensured. A base environment is required to house the top file. +# Example: +# file_roots: +# base: +# - /usr/pkg/etc/salt/states/ +# dev: +# - /usr/pkg/etc/salt/states/dev/services +# - /usr/pkg/etc/salt/states/dev/states +# prod: +# - /usr/pkg/etc/salt/states/prod/services +# - /usr/pkg/etc/salt/states/prod/states +# +#file_roots: +# base: +# - /usr/pkg/etc/salt/states + +# Uncomment the line below if you do not want the file_server to follow +# symlinks when walking the filesystem tree. This is set to True +# by default. Currently this only applies to the default roots +# fileserver_backend. +#fileserver_followsymlinks: False +# +# Uncomment the line below if you do not want symlinks to be +# treated as the files they are pointing to. By default this is set to +# False. By uncommenting the line below, any detected symlink while listing +# files on the Master will not be returned to the Minion. +#fileserver_ignoresymlinks: True +# +# By default, the Salt fileserver recurses fully into all defined environments +# to attempt to find files. To limit this behavior so that the fileserver only +# traverses directories with SLS files and special Salt directories like _modules, +# enable the option below. This might be useful for installations where a file root +# has a very large number of files and performance is negatively impacted. Default +# is False. +#fileserver_limit_traversal: False + +# The hash_type is the hash to use when discovering the hash of a file in +# the local fileserver. The default is sha256, sha224, sha384 and sha512 are also supported. +# +# WARNING: While md5 and sha1 are also supported, do not use it due to the high chance +# of possible collisions and thus security breach. +# +# Warning: Prior to changing this value, the minion should be stopped and all +# Salt caches should be cleared. +#hash_type: sha256 + +# The Salt pillar is searched for locally if file_client is set to local. If +# this is the case, and pillar data is defined, then the pillar_roots need to +# also be configured on the minion: +#pillar_roots: +# base: +# - /usr/pkg/etc/salt/pillar + +# Set a hard-limit on the size of the files that can be pushed to the master. +# It will be interpreted as megabytes. Default: 100 +#file_recv_max_size: 100 +# +# +###### Security settings ##### +########################################### +# Enable "open mode", this mode still maintains encryption, but turns off +# authentication, this is only intended for highly secure environments or for +# the situation where your keys end up in a bad state. If you run in open mode +# you do so at your own risk! +#open_mode: False + +# Enable permissive access to the salt keys. This allows you to run the +# master or minion as root, but have a non-root group be given access to +# your pki_dir. To make the access explicit, root must belong to the group +# you've given access to. This is potentially quite insecure. +#permissive_pki_access: False + +# The state_verbose and state_output settings can be used to change the way +# state system data is printed to the display. By default all data is printed. +# The state_verbose setting can be set to True or False, when set to False +# all data that has a result of True and no changes will be suppressed. +#state_verbose: True + +# The state_output setting changes if the output is the full multi line +# output for each changed state if set to 'full', but if set to 'terse' +# the output will be shortened to a single line. +#state_output: full + +# The state_output_diff setting changes whether or not the output from +# successful states is returned. Useful when even the terse output of these +# states is cluttering the logs. Set it to True to ignore them. +#state_output_diff: False + +# The state_output_profile setting changes whether profile information +# will be shown for each state run. +#state_output_profile: True + +# Fingerprint of the master public key to validate the identity of your Salt master +# before the initial key exchange. The master fingerprint can be found by running +# "salt-key -F master" on the Salt master. +#master_finger: '' + + +###### Thread settings ##### +########################################### +# Disable multiprocessing support, by default when a minion receives a +# publication a new process is spawned and the command is executed therein. +#multiprocessing: True + + +##### Logging settings ##### +########################################## +# The location of the minion log file +# The minion log can be sent to a regular file, local path name, or network +# location. Remote logging works best when configured to use rsyslogd(8) (e.g.: +# ``file:///dev/log``), with rsyslogd(8) configured for network logging. The URI +# format is: ://:/ +#log_file: /var/log/salt/minion +#log_file: file:///dev/log +#log_file: udp://loghost:10514 +# +#log_file: /var/log/salt/minion +#key_logfile: /var/log/salt/key + +# The level of messages to send to the console. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# +# The following log levels are considered INSECURE and may log sensitive data: +# ['garbage', 'trace', 'debug'] +# +# Default: 'warning' +log_level: debug + +# The level of messages to send to the log file. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# If using 'log_granular_levels' this must be set to the highest desired level. +# Default: 'warning' +#log_level_logfile: + +# The date and time format used in log messages. Allowed date/time formatting +# can be seen here: http://docs.python.org/library/time.html#time.strftime +#log_datefmt: '%H:%M:%S' +#log_datefmt_logfile: '%Y-%m-%d %H:%M:%S' + +# The format of the console logging messages. Allowed formatting options can +# be seen here: http://docs.python.org/library/logging.html#logrecord-attributes +# +# Console log colors are specified by these additional formatters: +# +# %(colorlevel)s +# %(colorname)s +# %(colorprocess)s +# %(colormsg)s +# +# Since it is desirable to include the surrounding brackets, '[' and ']', in +# the coloring of the messages, these color formatters also include padding as +# well. Color LogRecord attributes are only available for console logging. +# +#log_fmt_console: '%(colorlevel)s %(colormsg)s' +#log_fmt_console: '[%(levelname)-8s] %(message)s' +# +#log_fmt_logfile: '%(asctime)s,%(msecs)03.0f [%(name)-17s][%(levelname)-8s] %(message)s' + +# This can be used to control logging levels more specificically. This +# example sets the main salt library at the 'warning' level, but sets +# 'salt.modules' to log at the 'debug' level: +# log_granular_levels: +# 'salt': 'warning' +# 'salt.modules': 'debug' +# +#log_granular_levels: {} + +# To diagnose issues with minions disconnecting or missing returns, ZeroMQ +# supports the use of monitor sockets to log connection events. This +# feature requires ZeroMQ 4.0 or higher. +# +# To enable ZeroMQ monitor sockets, set 'zmq_monitor' to 'True' and log at a +# debug level or higher. +# +# A sample log event is as follows: +# +# [DEBUG ] ZeroMQ event: {'endpoint': 'tcp://127.0.0.1:4505', 'event': 512, +# 'value': 27, 'description': 'EVENT_DISCONNECTED'} +# +# All events logged will include the string 'ZeroMQ event'. A connection event +# should be logged as the minion starts up and initially connects to the +# master. If not, check for debug log level and that the necessary version of +# ZeroMQ is installed. +# +#zmq_monitor: False + +###### Module configuration ##### +########################################### +# Salt allows for modules to be passed arbitrary configuration data, any data +# passed here in valid yaml format will be passed on to the salt minion modules +# for use. It is STRONGLY recommended that a naming convention be used in which +# the module name is followed by a . and then the value. Also, all top level +# data must be applied via the yaml dict construct, some examples: +# +# You can specify that all modules should run in test mode: +#test: True +# +# A simple value for the test module: +#test.foo: foo +# +# A list for the test module: +#test.bar: [baz,quo] +# +# A dict for the test module: +#test.baz: {spam: sausage, cheese: bread} +# +# +###### Update settings ###### +########################################### +# Using the features in Esky, a salt minion can both run as a frozen app and +# be updated on the fly. These options control how the update process +# (saltutil.update()) behaves. +# +# The url for finding and downloading updates. Disabled by default. +#update_url: False +# +# The list of services to restart after a successful update. Empty by default. +#update_restart_services: [] + + +###### Keepalive settings ###### +############################################ +# ZeroMQ now includes support for configuring SO_KEEPALIVE if supported by +# the OS. If connections between the minion and the master pass through +# a state tracking device such as a firewall or VPN gateway, there is +# the risk that it could tear down the connection the master and minion +# without informing either party that their connection has been taken away. +# Enabling TCP Keepalives prevents this from happening. + +# Overall state of TCP Keepalives, enable (1 or True), disable (0 or False) +# or leave to the OS defaults (-1), on Linux, typically disabled. Default True, enabled. +#tcp_keepalive: True + +# How long before the first keepalive should be sent in seconds. Default 300 +# to send the first keepalive after 5 minutes, OS default (-1) is typically 7200 seconds +# on Linux see /proc/sys/net/ipv4/tcp_keepalive_time. +#tcp_keepalive_idle: 300 + +# How many lost probes are needed to consider the connection lost. Default -1 +# to use OS defaults, typically 9 on Linux, see /proc/sys/net/ipv4/tcp_keepalive_probes. +#tcp_keepalive_cnt: -1 + +# How often, in seconds, to send keepalives after the first one. Default -1 to +# use OS defaults, typically 75 seconds on Linux, see +# /proc/sys/net/ipv4/tcp_keepalive_intvl. +#tcp_keepalive_intvl: -1 + + +###### Windows Software settings ###### +############################################ +# Location of the repository cache file on the master: +#win_repo_cachefile: 'salt://win/repo/winrepo.p' + + +###### Returner settings ###### +############################################ +# Which returner(s) will be used for minion's result: +#return: mysql + + +###### Miscellaneous settings ###### +############################################ +# Default match type for filtering events tags: startswith, endswith, find, regex, fnmatch +#event_match_type: startswith \ No newline at end of file diff --git a/states/salt_minion/salt-minion.service.j2 b/states/salt_minion/salt-minion.service.j2 new file mode 100644 index 0000000..8226908 --- /dev/null +++ b/states/salt_minion/salt-minion.service.j2 @@ -0,0 +1,15 @@ +{%- from "salt_minion/map.jinja" import salt_minion with context -%} +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +[Unit] +Description=The Salt Minion daemon +After=network.target + +[Service] +Type=notify +KillMode=process +NotifyAccess=all +LimitNOFILE=8192 +ExecStart=/usr/local/bin/salt-minion + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/samba/config.sls b/states/samba/config.sls new file mode 100644 index 0000000..4ae7e3d --- /dev/null +++ b/states/samba/config.sls @@ -0,0 +1,6 @@ +--- +{%- from "samba/map.jinja" import samba with context %} +samba-config: + ini_manage.options_present: + - name: /etc/samba/smb.conf + - sections: {{ samba.config }} \ No newline at end of file diff --git a/states/samba/defaults.yaml b/states/samba/defaults.yaml new file mode 100644 index 0000000..98df44b --- /dev/null +++ b/states/samba/defaults.yaml @@ -0,0 +1,4 @@ +--- +samba: + enabled: true + config: \ No newline at end of file diff --git a/states/samba/init.sls b/states/samba/init.sls new file mode 100644 index 0000000..6c7ba86 --- /dev/null +++ b/states/samba/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .users diff --git a/states/samba/install.sls b/states/samba/install.sls new file mode 100644 index 0000000..9019917 --- /dev/null +++ b/states/samba/install.sls @@ -0,0 +1,8 @@ +--- +{%- from "samba/map.jinja" import samba with context %} +samba-pkg: + pkg.latest: + - pkgs: + - samba + - samba-common + - smbclient \ No newline at end of file diff --git a/states/samba/map.jinja b/states/samba/map.jinja new file mode 100644 index 0000000..9fcb514 --- /dev/null +++ b/states/samba/map.jinja @@ -0,0 +1,6 @@ +{%- import_yaml "samba/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='samba') -%} + +{%- set samba = salt['pillar.get']('samba', default=defaults, merge=True) -%} +{%- set users = salt['pillar.get']('users') -%} \ No newline at end of file diff --git a/states/samba/users.sls b/states/samba/users.sls new file mode 100644 index 0000000..af182ac --- /dev/null +++ b/states/samba/users.sls @@ -0,0 +1,18 @@ +--- +{%- from "samba/map.jinja" import samba with context %} +{%- from "samba/map.jinja" import users with context %} + +{%- for user in users %} +samba-user-{{ user.name }}: +{%- if user.enabled %} + pdbedit.managed: +{%- else %} + pdbedit.absent: +{%- endif %} + - name: {{ user.name }} + - login: {{ user.name }} + - password: "{{ user.password }}" + - password_hashed: False + - require: + - pkg: samba-pkg +{%- endfor %} \ No newline at end of file diff --git a/states/sensu/agent.sls b/states/sensu/agent.sls new file mode 100644 index 0000000..68e131b --- /dev/null +++ b/states/sensu/agent.sls @@ -0,0 +1,76 @@ +--- +{%- from "sensu/map.jinja" import sensu with context %} +sensu-group: + group.present: + - name: sensu + - gid: 900 + +sensu-user: + user.present: + - name: sensu + - uid: 900 + - gid: 900 + - allow_uid_change: True + +sensu-agent-bin: + file.managed: + - name: /usr/sbin/sensu-agent + - source: {{ sensu.fetch_url }}/sensu-agent-{{ salt['grains.get']('kernel')|lower }}-{{ salt['grains.get']('osarch')|lower }} + - skip_verify: True + - user: root + - group: root + - mode: 0755 + - watch_in: + - service: sensu-agent-service + +sensu-agent-service-file: + file.managed: + - name: /etc/systemd/system/sensu-agent.service + - source: salt://sensu/sensu-agent.service + - user: root + - group: root + - mode: 0644 + +sensu-agent-cache-dir: + file.directory: + - name: /var/cache/sensu + - user: sensu + - group: sensu + - mode: 0750 + - recurse: + - user + - group + - require: + - user: sensu-user + - group: sensu-group + +sensu-agent-config-dir: + file.directory: + - name: /etc/sensu + - user: sensu + - group: sensu + - mode: 0750 + - require: + - user: sensu-user + - group: sensu-group + +sensu-agent-config-file: + file.managed: + - name: /etc/sensu/agent.yml + - source: salt://sensu/agent.yml.j2 + - user: sensu + - group: sensu + - mode: 0640 + - template: jinja + - watch_in: + - service: sensu-agent-service + - require: + - file: sensu-agent-config-dir + - file: sensu-agent-cache-dir + +sensu-agent-service: + service.running: + - name: sensu-agent + - enable: True + - require: + - file: sensu-agent-config-file \ No newline at end of file diff --git a/states/sensu/agent.yml.j2 b/states/sensu/agent.yml.j2 new file mode 100644 index 0000000..f5c05b0 --- /dev/null +++ b/states/sensu/agent.yml.j2 @@ -0,0 +1,4 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +--- +{%- from "sensu/map.jinja" import sensu with context %} +{{ sensu.agent.config|yaml(False) }} \ No newline at end of file diff --git a/states/sensu/defaults.yaml b/states/sensu/defaults.yaml new file mode 100644 index 0000000..26b28de --- /dev/null +++ b/states/sensu/defaults.yaml @@ -0,0 +1,28 @@ +--- +sensu: + fetch_url: https://paulbsd-pub.s3.fr-par.scw.cloud/sensu-agent + backend: + enabled: false + config: + url: https://sensu.paulbsd.com + user: "admin" + password: "P@ssw0rd!" + agent: + enabled: false + config: + backend-url: [] + name: {{ salt['grains.get']('fqdn') }} + subscriptions: + - {{ salt['grains.get']('type') }} + - {{ salt['grains.get']('country') }} + - {{ salt['grains.get']('location') }} + - {% filter lower %}{{ salt['grains.get']('os') }}{% endfilter %} + user: "admin" + password: "P@ssw0rd!" + labels: + arch: {% filter lower %}{{ salt['grains.get']('osarch') }}{% endfilter %} + check_load_warning: "3,2,1" + check_load_critical: "5,3,2" + goarch: {% filter lower %}{{ salt['grains.get']('osarch') }}{% endfilter %} + goos: {% filter lower %}{{ salt['grains.get']('kernel') }}{% endfilter %} + kernel: {% filter lower %}{{ salt['grains.get']('kernel') }}{% endfilter %} \ No newline at end of file diff --git a/states/sensu/init.sls b/states/sensu/init.sls new file mode 100644 index 0000000..b4585cc --- /dev/null +++ b/states/sensu/init.sls @@ -0,0 +1,6 @@ +--- +{%- from "sensu/map.jinja" import sensu with context %} +include: +{%- if sensu.agent.enabled %} + - .agent +{%- endif %} \ No newline at end of file diff --git a/states/sensu/map.jinja b/states/sensu/map.jinja new file mode 100644 index 0000000..8809f67 --- /dev/null +++ b/states/sensu/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "sensu/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='sensu') -%} + +{%- set sensu = salt['pillar.get']('sensu', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/sensu/sensu-agent.service b/states/sensu/sensu-agent.service new file mode 100644 index 0000000..bbbce0f --- /dev/null +++ b/states/sensu/sensu-agent.service @@ -0,0 +1,17 @@ +[Unit] +Description=The Sensu Agent process. +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=sensu +Group=sensu +EnvironmentFile=-/etc/default/sensu-agent +EnvironmentFile=-/etc/sysconfig/sensu-agent +LimitNOFILE=65535 +ExecStart=/usr/sbin/sensu-agent start +WorkingDirectory=/ + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/services/init.sls b/states/services/init.sls new file mode 100644 index 0000000..d9cfe5b --- /dev/null +++ b/states/services/init.sls @@ -0,0 +1,23 @@ +--- +include: + - pkg + +{%- if salt['pillar.get']('services:enable') != None -%} +{%- for service in salt['pillar.get']('services:enable') %} +service-{{ service }}: + service.running: + - name: {{ service }} + - enable: True + - require: + - pkg: pkg-install +{%- endfor %} +{%- endif %} + +{%- if salt['pillar.get']('services:disable') != None -%} +{%- for service in salt['pillar.get']('services:disable') %} +service-{{ service }}: + service.dead: + - name: {{ service }} + - enable: False +{%- endfor %} +{%- endif %} \ No newline at end of file diff --git a/states/ssh/config.sls b/states/ssh/config.sls new file mode 100644 index 0000000..4308de0 --- /dev/null +++ b/states/ssh/config.sls @@ -0,0 +1,10 @@ +--- +ssh-sshd-config: + file.managed: + - name: /etc/ssh/sshd_config + - source: salt://ssh/sshd_config.j2 + - template: jinja + - user: root + - mode: 0644 + - watch_in: + - service: ssh-sshd-service \ No newline at end of file diff --git a/states/ssh/defaults.yaml b/states/ssh/defaults.yaml new file mode 100644 index 0000000..2f19c6a --- /dev/null +++ b/states/ssh/defaults.yaml @@ -0,0 +1,15 @@ +--- +ssh: + enabled: true + pkgs: + - 'openssh-server' + config: + LoginGraceTime: 60 + PermitRootLogin: 'no' + MaxAuthTries: 3 + AddressFamily: any + PasswordAuthentication: 'no' + VersionAddendum: none + Subsystem: sftp /usr/lib/openssh/sftp-server + AllowGroups: root + X11Forwarding: 'yes' diff --git a/states/ssh/init.sls b/states/ssh/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/ssh/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/ssh/install.sls b/states/ssh/install.sls new file mode 100644 index 0000000..dca78d7 --- /dev/null +++ b/states/ssh/install.sls @@ -0,0 +1,7 @@ +{%- from "ssh/map.jinja" import ssh with context %} + +{% for pkg in ssh.pkgs %} +ssh-pkg-{{ pkg }}: + pkg.installed: + - name: {{ pkg }} +{% endfor %} diff --git a/states/ssh/map.jinja b/states/ssh/map.jinja new file mode 100644 index 0000000..bc2a2c5 --- /dev/null +++ b/states/ssh/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "ssh/defaults.yaml" as default_settings %} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='ssh') -%} + +{%- set ssh = salt['pillar.get']('ssh', default=defaults, merge=True) %} diff --git a/states/ssh/old.txt b/states/ssh/old.txt new file mode 100644 index 0000000..6dd5ca5 --- /dev/null +++ b/states/ssh/old.txt @@ -0,0 +1,15 @@ +#sshd-config-permitrootlogin: +# file.replace: +# - name: /etc/ssh/sshd_config +# - pattern: "^PermitRootLogin.*$" +# - repl: "PermitRootLogin no" +# - watch_in: +# - service-sshd +# +#sshd-config-passwordauthentifcation: +# file.replace: +# - name: /etc/ssh/sshd_config +# - pattern: "^PasswordAuthentication.*$" +# - repl: "PasswordAuthentication yes" +# - watch_in: +# - service-sshd \ No newline at end of file diff --git a/states/ssh/service.sls b/states/ssh/service.sls new file mode 100644 index 0000000..ca17696 --- /dev/null +++ b/states/ssh/service.sls @@ -0,0 +1,6 @@ +--- +ssh-sshd-service: + service.running: + - name: sshd + - enable: True + - reload: True \ No newline at end of file diff --git a/states/ssh/sshd_config.j2 b/states/ssh/sshd_config.j2 new file mode 100644 index 0000000..47542d0 --- /dev/null +++ b/states/ssh/sshd_config.j2 @@ -0,0 +1,20 @@ +{%- from "ssh/map.jinja" import ssh with context -%} + +{% set net4=[] -%} +{%- for key, value in salt['pillar.get']('net:ipv4_networks').items() -%} +{%- do net4.append( value.ip + "/" + value.mask ) -%} +{%- endfor -%} + +{%- set net6=[] -%} +{%- for key, value in salt['pillar.get']('net:ipv6_networks').items() -%} +{%- do net6.append( value.ip + "/" + value.mask ) -%} +{%- endfor -%} + +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- for key, value in ssh.config.items() %} +{{ key }} {{ value }} +{%- endfor %} +Match Address {{ net4|join(',') }} + PasswordAuthentication yes +Match Address {{ net6|join(',') }} + PasswordAuthentication yes \ No newline at end of file diff --git a/states/states/defaults.yaml b/states/states/defaults.yaml new file mode 100644 index 0000000..a4e0ea2 --- /dev/null +++ b/states/states/defaults.yaml @@ -0,0 +1,2 @@ +--- +states: {} \ No newline at end of file diff --git a/states/states/init.sls b/states/states/init.sls new file mode 100644 index 0000000..d779f10 --- /dev/null +++ b/states/states/init.sls @@ -0,0 +1,13 @@ +--- +{%- from "states/map.jinja" import states with context %} + +{%- if states is defined and states | length > 0 %} +include: +{%- for state, args in states.items() %} +{%- if args != None -%} +{%- for sls in args %} + - {{ sls }} +{%- endfor %} +{%- endif -%} +{%- endfor %} +{%- endif %} \ No newline at end of file diff --git a/states/states/map.jinja b/states/states/map.jinja new file mode 100644 index 0000000..2f5d851 --- /dev/null +++ b/states/states/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "states/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='states') -%} + +{%- set states = salt['pillar.get']('states', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/sublimetext/defaults.yaml b/states/sublimetext/defaults.yaml new file mode 100644 index 0000000..1880af9 --- /dev/null +++ b/states/sublimetext/defaults.yaml @@ -0,0 +1,5 @@ +--- +sublimetext: + fetch_url: https://repo.paulbsd.com/sublime_text + archive_name: sublime_text_3_build_3176_x64.tar.bz2 + install_dir: /opt \ No newline at end of file diff --git a/states/sublimetext/init.sls b/states/sublimetext/init.sls new file mode 100644 index 0000000..0240648 --- /dev/null +++ b/states/sublimetext/init.sls @@ -0,0 +1,37 @@ +--- +{%- from "sublimetext/map.jinja" import sublimetext with context %} +sublime-text-extract-archive: + archive.extracted: + - name: {{ sublimetext.install_dir }} + - source: {{ sublimetext.fetch_url }}/{{ sublimetext.archive_name }} + - skip_verify: True + - user: root + - group: root + - mode: 0755 + - if_missing: {{ sublimetext.install_dir }}/sublime_text_3 + +sublime-text-licence-key: + file.managed: + - name: {{ sublimetext.install_dir }}/sublime_text_3/sublime_text_keys.txt + - source: salt://sublimetext/sublime_text_keys.txt.j2 + - template: jinja + - user: root + - group: root + - mode: 0644 + +sublime-text-desktop-entry: + file.managed: + - name: /usr/share/applications/sublime_text.desktop + - source: salt://sublimetext/sublime_text.desktop.j2 + - template: jinja + - user: root + - group: root + - mode: 0644 + +sublime-text-symlink: + file.symlink: + - name: /usr/bin/sublime_text + - target: {{ sublimetext.install_dir }}/sublime_text_3/sublime_text + - user: root + - group: root + - mode: 0755 \ No newline at end of file diff --git a/states/sublimetext/kernelmap.yaml b/states/sublimetext/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/sublimetext/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/sublimetext/map.jinja b/states/sublimetext/map.jinja new file mode 100644 index 0000000..d5b6e76 --- /dev/null +++ b/states/sublimetext/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "sublimetext/defaults.yaml" as default_settings %} + +{%- import_yaml "sublimetext/kernelmap.yaml" as kernelmap %} +{%- import_yaml "sublimetext/osarchmap.yaml" as osarchmap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='sublimetext', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +%} + +{%- set sublimetext = salt['pillar.get']('sublimetext', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/sublimetext/osarchmap.yaml b/states/sublimetext/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/sublimetext/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/sublimetext/sublime_text.desktop.j2 b/states/sublimetext/sublime_text.desktop.j2 new file mode 100644 index 0000000..e8129f0 --- /dev/null +++ b/states/sublimetext/sublime_text.desktop.j2 @@ -0,0 +1,24 @@ +{%- from "sublimetext/map.jinja" import sublimetext with context -%} +[Desktop Entry] +Version=1.0 +Type=Application +Name=Sublime Text +GenericName=Text Editor +Comment=Sophisticated text editor for code, markup and prose +Exec={{ sublimetext.install_dir }}/sublime_text_3/sublime_text %F +Terminal=false +MimeType=text/plain; +Icon={{ sublimetext.install_dir }}/sublime_text_3/Icon/48x48/sublime-text.png +Categories=TextEditor;Development; +StartupNotify=true +Actions=Window;Document; + +[Desktop Action Window] +Name=New Window +Exec={{ sublimetext.install_dir }}/sublime_text_3/sublime_text -n +OnlyShowIn=Unity; + +[Desktop Action Document] +Name=New File +Exec={{ sublimetext.install_dir }}/sublime_text_3/sublime_text --command new_file +OnlyShowIn=Unity; \ No newline at end of file diff --git a/states/sublimetext/sublime_text_keys.txt.j2 b/states/sublimetext/sublime_text_keys.txt.j2 new file mode 100644 index 0000000..f5a9b73 --- /dev/null +++ b/states/sublimetext/sublime_text_keys.txt.j2 @@ -0,0 +1,29 @@ +-- 3143 +----- BEGIN LICENSE ----- +TwitterInc +200 User License +EA7E-890007 +1D77F72E 390CDD93 4DCBA022 FAF60790 +61AA12C0 A37081C5 D0316412 4584D136 +94D7F7D4 95BC8C1C 527DA828 560BB037 +D1EDDD8C AE7B379F 50C9D69D B35179EF +2FE898C4 8E4277A8 555CE714 E1FB0E43 +D5D52613 C3D12E98 BC49967F 7652EED2 +9D2D2E61 67610860 6D338B72 5CF95C69 +E36B85CC 84991F19 7575D828 470A92AB +------ END LICENSE ------ + +-- 3176 +----- BEGIN LICENSE ----- +sgbteam +Single User License +EA7E-1153259 +8891CBB9 F1513E4F 1A3405C1 A865D53F +115F202E 7B91AB2D 0D2A40ED 352B269B +76E84F0B CD69BFC7 59F2DFEF E267328F +215652A3 E88F9D8F 4C38E3BA 5B2DAAE4 +969624E7 DC9CD4D5 717FB40C 1B9738CF +20B3C4F1 E917B5B3 87C38D9C ACCE7DD8 +5F7EF854 86B9743C FADC04AA FB0DA5C0 +F913BE58 42FEA319 F954EFDD AE881E0B +------ END LICENSE ------ \ No newline at end of file diff --git a/states/sudo/config.sls b/states/sudo/config.sls new file mode 100644 index 0000000..c56e36c --- /dev/null +++ b/states/sudo/config.sls @@ -0,0 +1,11 @@ +--- +{%- from "sudo/map.jinja" import sudo with context %} +sudo-sudoers: + file.managed: + - name: /etc/sudoers + - source: salt://sudo/sudoers.j2 + - user: root + - group: root + - mode: 0660 + - template: jinja + - check_cmd: /usr/sbin/visudo -c -f diff --git a/states/sudo/defaults.yaml b/states/sudo/defaults.yaml new file mode 100644 index 0000000..dbec4cd --- /dev/null +++ b/states/sudo/defaults.yaml @@ -0,0 +1,25 @@ +--- +sudo: + config: + defaults: + - 'env_reset' + - 'mail_badpass' + - 'secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"' + - 'env_keep += "EDITOR"' + - 'always_set_home' + acls: + root: + group: False + host: ALL + who: ALL:ALL + command: ALL + admin: + group: True + host: ALL + who: ALL + command: ALL + sudo: + group: True + host: ALL + who: ALL:ALL + command: ALL \ No newline at end of file diff --git a/states/sudo/init.sls b/states/sudo/init.sls new file mode 100644 index 0000000..b91d8ec --- /dev/null +++ b/states/sudo/init.sls @@ -0,0 +1,4 @@ +--- +include: + - .install + - .config \ No newline at end of file diff --git a/states/sudo/install.sls b/states/sudo/install.sls new file mode 100644 index 0000000..4ccb116 --- /dev/null +++ b/states/sudo/install.sls @@ -0,0 +1,5 @@ +--- +{%- from "sudo/map.jinja" import sudo with context %} +sudo-pkg: + pkg.installed: + - name: sudo \ No newline at end of file diff --git a/states/sudo/map.jinja b/states/sudo/map.jinja new file mode 100644 index 0000000..d16be86 --- /dev/null +++ b/states/sudo/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "sudo/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='sudo') -%} + +{%- set sudo = salt['pillar.get']('sudo', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/sudo/sudoers.j2 b/states/sudo/sudoers.j2 new file mode 100644 index 0000000..5743b34 --- /dev/null +++ b/states/sudo/sudoers.j2 @@ -0,0 +1,16 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "sudo/map.jinja" import sudo with context %} + +{%- if sudo.config.defaults is defined -%} +{%- for default in sudo.config.defaults %} +Defaults {{ default }} +{%- endfor %} +{%- endif %} + +{%- if sudo.config.acls is defined -%} +{%- for key, acl in sudo.config.acls.items() %} +{% if acl.group %}%{% endif %}{{ key }} {{ acl.host|default('ALL') }}=({{ acl.who|default('ALL') }}) {{ acl.command|default('ALL') }} +{%- endfor %} +{%- endif %} + +#includedir /etc/sudoers.d diff --git a/states/syncthing/config.sls b/states/syncthing/config.sls new file mode 100644 index 0000000..00917d9 --- /dev/null +++ b/states/syncthing/config.sls @@ -0,0 +1,8 @@ +--- +{%- from "syncthing/map.jinja" import syncthing with context %} +syncthing-config: + syncthing.config: + - name: syncthing-config + - url: {{ syncthing.url }} + - cfg: {{ syncthing.config }} + - verify: {{ syncthing.verify }} \ No newline at end of file diff --git a/states/syncthing/config_old.sls b/states/syncthing/config_old.sls new file mode 100644 index 0000000..ebb16e5 --- /dev/null +++ b/states/syncthing/config_old.sls @@ -0,0 +1,24 @@ +--- +{%- from "syncthing/map.jinja" import syncthing with context %} +{%- set configdir=salt['user.info'](syncthing.user)['home'] + '/.config/syncthing' %} +#syncthing-config-dir: +# file.directory: +# - name: {{ configdir }} +# - makedirs: True + # - watch_in: + # - service: syncthing-service + +#syncthing-config-file: +# file.managed: +# - name: {{ configdir }}/config.xml +# - source: salt://syncthing/config.xml.j2 +# - user: root +# - group: root +# - template: jinja +# - watch_in: +# - service: syncthing-service + +{%- set config = salt['http.query'](url="http://localhost:8384/rest/system/config", header_dict={"X-API-Key":syncthing.apikey},decode=True, decode_type='json') %} +#{{ config['dict']['gui'] }} + +{%- do salt['http.query'](method='POST', url="http://localhost:8384/rest/system/config", header_dict={"X-API-Key":syncthing.apikey}, decode=True, decode_type='json', data=json.dumps(syncthing.config)) %} \ No newline at end of file diff --git a/states/syncthing/defaults.yaml b/states/syncthing/defaults.yaml new file mode 100644 index 0000000..726c186 --- /dev/null +++ b/states/syncthing/defaults.yaml @@ -0,0 +1,17 @@ +--- +syncthing: + enabled: true + install_dir: "/usr/local/apps" + release_dir: "/usr/local/apps/releases" + mirror: "https://github.com/syncthing/syncthing/releases/download" + version: "1.3.4" + os: "linux" + arch: "amd64" + user: "root" + url: "http://localhost:8384" + verify: false + config: + gui: + address: "0.0.0.0:8384" + user: "paul" + password: "$2a$10$NeZ3cfyOgZcdMGy9ixB7LOAP6z8tCOVjico6ZGLoK2QIQy734qPw." \ No newline at end of file diff --git a/states/syncthing/init.sls b/states/syncthing/init.sls new file mode 100644 index 0000000..cbeee7c --- /dev/null +++ b/states/syncthing/init.sls @@ -0,0 +1,6 @@ +--- +{%- from "syncthing/map.jinja" import syncthing with context %} +include: + - .install + - .service + - .config \ No newline at end of file diff --git a/states/syncthing/install.sls b/states/syncthing/install.sls new file mode 100644 index 0000000..42a66ec --- /dev/null +++ b/states/syncthing/install.sls @@ -0,0 +1,19 @@ +--- +{%- from "syncthing/map.jinja" import syncthing with context %} +syncthing-archive-extract: + archive.extracted: + - name: {{ syncthing.release_dir }} + - source: {{ syncthing.mirror }}/v{{ syncthing.version }}/syncthing-{{ syncthing.os }}-{{ syncthing.arch }}-v{{ syncthing.version }}.tar.gz + - enforce_toplevel: False + - skip_verify: True + - archive_format: tar + - if_missing: {{ syncthing.release_dir }}/syncthing-{{ syncthing.os }}-{{ syncthing.arch }}-v{{ syncthing.version }} + - watch_in: + - service: syncthing-service + +syncthing-bin-symlink: + file.symlink: + - name: {{ syncthing.install_dir }}/syncthing + - target: {{ syncthing.release_dir }}/syncthing-{{ syncthing.os }}-{{ syncthing.arch }}-v{{ syncthing.version }} + - watch_in: + - service: syncthing-service \ No newline at end of file diff --git a/states/syncthing/kernelmap.yaml b/states/syncthing/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/syncthing/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/syncthing/map.jinja b/states/syncthing/map.jinja new file mode 100644 index 0000000..64b8631 --- /dev/null +++ b/states/syncthing/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "syncthing/defaults.yaml" as default_settings -%} + +{%- import_yaml "syncthing/kernelmap.yaml" as kernelmap %} +{%- import_yaml "syncthing/osarchmap.yaml" as osarchmap %} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='syncthing', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set syncthing = salt['pillar.get']('syncthing', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/syncthing/osarchmap.yaml b/states/syncthing/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/syncthing/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/syncthing/service.sls b/states/syncthing/service.sls new file mode 100644 index 0000000..b31c567 --- /dev/null +++ b/states/syncthing/service.sls @@ -0,0 +1,16 @@ +--- +{%- from "syncthing/map.jinja" import syncthing with context %} +syncthing-service-file: + file.managed: + - name: /etc/systemd/system/syncthing@.service + - source: salt://syncthing/syncthing.service.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: syncthing-service + +syncthing-service: + service.running: + - name: syncthing@{{ syncthing.user }} + - enable: True \ No newline at end of file diff --git a/states/syncthing/syncthing.service.j2 b/states/syncthing/syncthing.service.j2 new file mode 100644 index 0000000..aeb8be7 --- /dev/null +++ b/states/syncthing/syncthing.service.j2 @@ -0,0 +1,15 @@ +{%- from "syncthing/map.jinja" import syncthing with context -%} +[Unit] +Description=Syncthing - Open Source Continuous File Synchronization for %I +Documentation=man:syncthing(1) +After=network.target + +[Service] +User=%i +ExecStart={{ syncthing.install_dir }}/syncthing/syncthing -no-browser -no-restart -logflags=0 +Restart=on-failure +SuccessExitStatus=3 4 +RestartForceExitStatus=3 4 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/telegraf/config.sls b/states/telegraf/config.sls new file mode 100644 index 0000000..9155a97 --- /dev/null +++ b/states/telegraf/config.sls @@ -0,0 +1,18 @@ +--- +{%- from "telegraf/map.jinja" import telegraf with context %} +telegraf-config-dir: + file.directory: + - name: /etc/telegraf + - watch_in: + - service: telegraf-service + +telegraf-config-file: + file.managed: + - name: /etc/telegraf/telegraf.conf + - source: salt://telegraf/telegraf.conf.j2 + - user: root + - group: root + - mode: 600 + - template: jinja + - watch_in: + - service: telegraf-service \ No newline at end of file diff --git a/states/telegraf/defaults.yaml b/states/telegraf/defaults.yaml new file mode 100644 index 0000000..af28594 --- /dev/null +++ b/states/telegraf/defaults.yaml @@ -0,0 +1,75 @@ +--- +telegraf: + enabled: true + release_dir: /usr/local/apps/releases + install_dir: /usr/local/apps + mirror: https://dl.influxdata.com/telegraf/releases + version: 1.13.3 + influxdb_urls: + - '"http://localhost:8086"' + influxdb_username: username + influxdb_password: password + influxdb_database: telegraf + os: linux + arch: amd64 + config: + outputs: + inputs: + cpu: + name: "cpu" + params: + percpu: true + totalcpu: true + collect_cpu_time: false + report_active: false + disk: + name: "disk" + params: + ignore_fs: + - '"tmpfs"' + - '"devtmpfs"' + - '"devfs"' + - '"iso9660"' + - '"overlay"' + - '"aufs"' + - '"squashfs"' + diskio: + name: "diskio" + kernel: + name: "kernel" + kernel_vmstat: + name: "kernel_vmstat" + mem: + name: "mem" + net: + name: "net" + netstat: + name: "netstat" + nginx: + name: "nginx" + params: + urls: + - '"http://localhost/status"' + response_timeout: "5s" + ntpq: + name: "ntpq" + params: + dns_lookup: true + postfix: + name: "postfix" + processes: + name: "processes" + swap: + name: "swap" + sensors: + name: "sensors" + smart: + name: "smart" + system: + name: "system" + systemd_units: + name: "systemd_units" + syslog: + name: "syslog" + params: + server: "udp://:6514" \ No newline at end of file diff --git a/states/telegraf/init.sls b/states/telegraf/init.sls new file mode 100644 index 0000000..63261f2 --- /dev/null +++ b/states/telegraf/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/telegraf/install.sls b/states/telegraf/install.sls new file mode 100644 index 0000000..4621ea3 --- /dev/null +++ b/states/telegraf/install.sls @@ -0,0 +1,26 @@ +--- +{%- from "telegraf/map.jinja" import telegraf with context %} +telegraf-archive-extract: + archive.extracted: + - name: {{ telegraf.release_dir }}/telegraf-{{ telegraf.version }} + - source: {{ telegraf.mirror }}/telegraf-{{ telegraf.version }}_{{ salt['grains.get']('kernel')|lower }}_{{ salt['grains.get']('osarch') }}.tar.gz + - enforce_toplevel: False + - options: --transform 's|^\./telegraf|/|g' --exclude './telegraf/etc' --exclude './telegraf/usr/lib' --exclude './telegraf/var' --strip 2 + - skip_verify: True + - archive_format: tar + - if_missing: {{ telegraf.release_dir }}/telegraf-{{ telegraf.version }}/telegraf + +telegraf-bin-symlink: + file.symlink: + - name: /usr/local/bin/telegraf + - target: {{ telegraf.release_dir }}/telegraf-{{ telegraf.version }}/telegraf + +telegraf-defaults-file: + file.managed: + - name: /etc/default/telegraf + - source: salt://telegraf/telegraf_default.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: telegraf-service \ No newline at end of file diff --git a/states/telegraf/kernelmap.yaml b/states/telegraf/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/telegraf/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/telegraf/map.jinja b/states/telegraf/map.jinja new file mode 100644 index 0000000..769366f --- /dev/null +++ b/states/telegraf/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "telegraf/defaults.yaml" as default_settings -%} + +{%- import_yaml "telegraf/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "telegraf/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='telegraf', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set telegraf = salt['pillar.get']('telegraf', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/telegraf/osarchmap.yaml b/states/telegraf/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/telegraf/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/telegraf/service.sls b/states/telegraf/service.sls new file mode 100644 index 0000000..48ec4bf --- /dev/null +++ b/states/telegraf/service.sls @@ -0,0 +1,16 @@ +--- +{%- from "telegraf/map.jinja" import telegraf with context %} +telegraf-service-file: + file.managed: + - name: /etc/systemd/system/telegraf.service + - source: salt://telegraf/telegraf.service.j2 + - user: root + - group: root + - template: jinja + - watch_in: + - service: telegraf-service + +telegraf-service: + service.running: + - name: telegraf + - enable: True \ No newline at end of file diff --git a/states/telegraf/telegraf.conf.j2 b/states/telegraf/telegraf.conf.j2 new file mode 100644 index 0000000..a7cdd39 --- /dev/null +++ b/states/telegraf/telegraf.conf.j2 @@ -0,0 +1,30 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "telegraf/map.jinja" import telegraf with context %} + +[global_tags] +[agent] + interval = "1m" + round_interval = true + metric_batch_size = 1000 + metric_buffer_limit = 10000 + collection_jitter = "0s" + flush_interval = "10s" + flush_jitter = "0s" + precision = "" + hostname = "" + omit_hostname = false + +[[outputs.influxdb]] + urls = [{{ telegraf.influxdb_urls|join(",") }}] + username = "{{ telegraf.influxdb_username }}" + password = "{{ telegraf.influxdb_password }}" + database = "{{ telegraf.influxdb_database }}" + +{% for name, value in telegraf.config.inputs.items() %} +[[inputs.{{ name }}]] +{%- if value['params'] is defined %} +{%- for paramname, paramvalue in value['params'].items() %} + {{ paramname }} = {% if paramvalue is sameas True or paramvalue is sameas False %}{{ paramvalue|string|lower }}{% elif paramvalue is iterable and paramvalue is not string %}[{{ paramvalue|join(",") }}]{% else %}"{{ paramvalue }}"{% endif %} +{%- endfor %} +{%- endif %} +{% endfor %} \ No newline at end of file diff --git a/states/telegraf/telegraf.service.j2 b/states/telegraf/telegraf.service.j2 new file mode 100644 index 0000000..8904723 --- /dev/null +++ b/states/telegraf/telegraf.service.j2 @@ -0,0 +1,17 @@ +{%- from "telegraf/map.jinja" import telegraf with context -%} +[Unit] +Description=The plugin-driven server agent for reporting metrics into InfluxDB +Documentation=https://github.com/influxdata/telegraf +After=network.target + +[Service] +EnvironmentFile=-/etc/default/telegraf +#User=telegraf +ExecStart=/usr/local/bin/telegraf --config /etc/telegraf/telegraf.conf +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-failure +RestartForceExitStatus=SIGPIPE +KillMode=control-group + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/states/telegraf/telegraf_default.j2 b/states/telegraf/telegraf_default.j2 new file mode 100644 index 0000000..cafac8e --- /dev/null +++ b/states/telegraf/telegraf_default.j2 @@ -0,0 +1,3 @@ +#INFLUX_CONFIG="http://host:9999/api/v2/telegrafs/0401c1afe319d000" +#INFLUX_TOKEN="test" +INFLUX_CONFIG=/etc/telegraf/telegraf.conf \ No newline at end of file diff --git a/states/telegram/defaults.yaml b/states/telegram/defaults.yaml new file mode 100644 index 0000000..d6b68a2 --- /dev/null +++ b/states/telegram/defaults.yaml @@ -0,0 +1,7 @@ +--- +telegram: + enabled: true + mirror: "https://github.com/telegramdesktop/tdesktop/releases/download" + install_dir: "/usr/local/apps" + dest_path: "/usr/local/apps/telegram-" + version: "2.1.0" \ No newline at end of file diff --git a/states/telegram/init.sls b/states/telegram/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/telegram/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/telegram/install.sls b/states/telegram/install.sls new file mode 100644 index 0000000..0f1fb3a --- /dev/null +++ b/states/telegram/install.sls @@ -0,0 +1,33 @@ +--- +{%- from "telegram/map.jinja" import telegram with context %} +telegram-archive-extract: + archive.extracted: + - name: {{ telegram.dest_path }}{{ telegram.version }} + - source: {{ telegram.mirror }}/v{{ telegram.version }}/tsetup.{{ telegram.version }}.tar.xz + - skip_verify: True + - archive_format: tar + - enforce_toplevel: False + - options: --transform 's/Telegram/telegram/g' --transform 's/Updater/updater/g' --strip 1 + - keep: True + - if_missing: {{ telegram.dest_path }}{{ telegram.version }}/telegram + +telegram-symlink: + file.symlink: + - name: {{ telegram.install_dir }}/telegram + - target: {{ telegram.dest_path }}{{ telegram.version }} + - force: True + +telegram-bin-symlink: + file.symlink: + - name: /usr/bin/telegram + - target: {{ telegram.dest_path }}{{ telegram.version }}/telegram + - force: True + +telegram-shortcut: + file.managed: + - name: /usr/share/applications/telegram.desktop + - source: salt://telegram/telegram.desktop.j2 + - user: root + - group: root + - mode: 644 + - template: jinja \ No newline at end of file diff --git a/states/telegram/map.jinja b/states/telegram/map.jinja new file mode 100644 index 0000000..45b7c02 --- /dev/null +++ b/states/telegram/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "telegram/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='telegram') -%} + +{%- set telegram = salt['pillar.get']('telegram', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/telegram/telegram.desktop.j2 b/states/telegram/telegram.desktop.j2 new file mode 100644 index 0000000..02b380c --- /dev/null +++ b/states/telegram/telegram.desktop.j2 @@ -0,0 +1,15 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "telegram/map.jinja" import telegram with context %} +[Desktop Entry] +Encoding=UTF-8 +Version=1.0 +Name=Telegram Desktop +Comment=Official desktop version of Telegram messaging app +Exec=/usr/bin/telegram -- %u +Icon=telegram +Terminal=false +StartupWMClass=Telegram +Type=Application +Categories=Network; +MimeType=x-scheme-handler/tg; +X-Desktop-File-Install-Version=0.22 \ No newline at end of file diff --git a/states/tests/repo.sls b/states/tests/repo.sls new file mode 100644 index 0000000..e33ffcd --- /dev/null +++ b/states/tests/repo.sls @@ -0,0 +1,22 @@ +--- +#pkg-repo-bareos: + # pkgrepo.absent: + # - humanname: Bareos + # - name: deb http://download.bareos.org/bareos/release/17.2/xUbuntu_16.04 / + # - gpgcheck: 1 + # - file: /etc/apt/sources.list.d/bareos.list + # - clean_file: True + # - key_url: http://download.bareos.org/bareos/release/17.2/xUbuntu_16.04/Release.key + # - refresh_db: True + +pkg-repo-test-absent: + pkgrepo.absent: + - name: deb http://repository.spotify.com stable non-free + +#pkg-bareos: +# pkg.purged: +# - pkgs: +# - bareos-common +# - bareos-filedaemon +# - bareos-traymonitor +# - bareos-bconsole \ No newline at end of file diff --git a/states/tests/tmp.sls b/states/tests/tmp.sls new file mode 100644 index 0000000..57510be --- /dev/null +++ b/states/tests/tmp.sls @@ -0,0 +1,10 @@ +--- +test1: + file.managed: + - name: /tmp/test + +test2: + file.replace: + - name: /tmp/test + - pattern: "^444" + - repl: "5555" \ No newline at end of file diff --git a/states/time/config.sls b/states/time/config.sls new file mode 100644 index 0000000..aaab6d4 --- /dev/null +++ b/states/time/config.sls @@ -0,0 +1,12 @@ +--- +{%- from "time/map.jinja" import time with context %} +time-ntp-config-file: + file.managed: + - name: /etc/ntp.conf + - source: salt://time/ntp.conf.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: ntp-service \ No newline at end of file diff --git a/states/time/defaults.yaml b/states/time/defaults.yaml new file mode 100644 index 0000000..8a803d5 --- /dev/null +++ b/states/time/defaults.yaml @@ -0,0 +1,4 @@ +--- +time: + zone: Europe/Paris + server: fr.pool.ntp.org \ No newline at end of file diff --git a/states/time/init.sls b/states/time/init.sls new file mode 100644 index 0000000..cddde2e --- /dev/null +++ b/states/time/init.sls @@ -0,0 +1,8 @@ +--- +include: + - .timezone + - .config + - .service +{%- if not salt['grains.get']('container') %} + - .timeupdate +{%- endif %} \ No newline at end of file diff --git a/states/time/map.jinja b/states/time/map.jinja new file mode 100644 index 0000000..fb6223d --- /dev/null +++ b/states/time/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "time/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='time') -%} + +{%- set time = salt['pillar.get']('time', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/time/ntp.conf.j2 b/states/time/ntp.conf.j2 new file mode 100644 index 0000000..cf8ae1b --- /dev/null +++ b/states/time/ntp.conf.j2 @@ -0,0 +1,9 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "time/map.jinja" import time with context %} +disable monitor +restrict -4 default kod nomodify notrap nopeer noquery +restrict -6 default kod nomodify notrap nopeer noquery +restrict 127.0.0.1 +restrict ::1 +server {{ time.server }} iburst +driftfile /var/lib/ntp/drift \ No newline at end of file diff --git a/states/time/service.sls b/states/time/service.sls new file mode 100644 index 0000000..5731159 --- /dev/null +++ b/states/time/service.sls @@ -0,0 +1,6 @@ +--- +{%- from "time/map.jinja" import time with context %} +ntp-service: + service.running: + - name: ntp + - enable: True \ No newline at end of file diff --git a/states/time/timeupdate.sls b/states/time/timeupdate.sls new file mode 100644 index 0000000..abfff35 --- /dev/null +++ b/states/time/timeupdate.sls @@ -0,0 +1,5 @@ +--- +{%- from "time/map.jinja" import time with context %} +time-ntp-update: + cmd.run: + - name: ntpdate -u {{ time.server }} \ No newline at end of file diff --git a/states/time/timezone.sls b/states/time/timezone.sls new file mode 100644 index 0000000..96b9dc5 --- /dev/null +++ b/states/time/timezone.sls @@ -0,0 +1,6 @@ +--- +{%- from "time/map.jinja" import time with context %} +time-timezone: + timezone.system: + - name: {{ time.zone }} + - utc: False \ No newline at end of file diff --git a/states/tmux/defaults.yaml b/states/tmux/defaults.yaml new file mode 100644 index 0000000..4ab9ef6 --- /dev/null +++ b/states/tmux/defaults.yaml @@ -0,0 +1,13 @@ +--- +tmux: + enabled: true + config: + binds: + - "v": "split-window" + - "h": "split-window -h" + sets: + - "status-bg": "blue" + - "pane-active-border-style": "fg=blue" + - "pane-border-style": "fg=blue" + - "default-terminal": "screen-256color" + - "history-limit": "1000000" \ No newline at end of file diff --git a/states/tmux/init.sls b/states/tmux/init.sls new file mode 100644 index 0000000..e2e3c83 --- /dev/null +++ b/states/tmux/init.sls @@ -0,0 +1,15 @@ +--- +{%- from "tmux/map.jinja" import tmux with context %} +tmux-pkg: + pkg.latest: + - name: tmux + +tmux-config: + file.managed: + - name: /etc/tmux.conf + - source: salt://tmux/tmux.conf.j2 + - user: root + - group: root + - template: jinja + - require: + - pkg: tmux-pkg \ No newline at end of file diff --git a/states/tmux/map.jinja b/states/tmux/map.jinja new file mode 100644 index 0000000..7b8e4ca --- /dev/null +++ b/states/tmux/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "tmux/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='tmux') -%} + +{%- set tmux = salt['pillar.get']('tmux', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/tmux/tmux.conf.j2 b/states/tmux/tmux.conf.j2 new file mode 100644 index 0000000..affe96d --- /dev/null +++ b/states/tmux/tmux.conf.j2 @@ -0,0 +1,15 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "tmux/map.jinja" import tmux with context %} + +{%- for ent in tmux.config.binds %} +{%- for key,value in ent.items() %} +bind {{ key }} {{ value }} +{%- endfor %} +{%- endfor %} + +{%- for ent in tmux.config.sets %} +{%- for key,value in ent.items() %} +set -g {{ key }} {{ value }} +{%- endfor %} +{%- endfor %} \ No newline at end of file diff --git a/states/top.sls b/states/top.sls new file mode 100644 index 0000000..670c0f4 --- /dev/null +++ b/states/top.sls @@ -0,0 +1,7 @@ +--- +base: + '*': + - provision +{%- if salt['pillar.get']('specs:' + salt['grains.get']('fqdn')) is defined %} + - states +{%- endif %} diff --git a/states/tor/defaults.yaml b/states/tor/defaults.yaml new file mode 100644 index 0000000..63b94df --- /dev/null +++ b/states/tor/defaults.yaml @@ -0,0 +1,10 @@ +--- +tor: + enabled: false + config: + client_host: '0.0.0.0' + client_port: '8081' + exit_port: '4443' + exit_policy: 'reject *:*' + nickname: 'anonymous' + syscontact: 'anonymous@example.com' \ No newline at end of file diff --git a/states/tor/init.sls b/states/tor/init.sls new file mode 100644 index 0000000..9f204f7 --- /dev/null +++ b/states/tor/init.sls @@ -0,0 +1,29 @@ +--- +{%- from "tor/map.jinja" import tor with context %} +tor-pkg: + pkg.latest: + - name: tor + +tor-config: + file.managed: + - name: /etc/tor/torrc + - source: salt://tor/torrc.j2 + - user: root + - group: root + - mode: 0660 + - template: jinja + - watch_in: + - service: tor-service + - require: + - pkg: tor-pkg + +tor-service: +{%- if tor.enabled %} + service.running: +{%- else %} + service.dead: +{%- endif %} + - name: tor + - enable: {{ tor.enabled }} + - require: + - pkg: tor-pkg \ No newline at end of file diff --git a/states/tor/map.jinja b/states/tor/map.jinja new file mode 100644 index 0000000..6bdf3ae --- /dev/null +++ b/states/tor/map.jinja @@ -0,0 +1,11 @@ +{%- import_yaml "tor/defaults.yaml" as defaults -%} + +{%- set tor = salt['pillar.get']( + 'tor', + default=defaults.tor, + merge=True + ) +-%} + +{%- set nickname = salt['pillar.get']('nickname',default='anonymous') -%} +{%- set syscontact = salt['pillar.get']('syscontact',default='anonymous@example.com') -%} \ No newline at end of file diff --git a/states/tor/torrc.j2 b/states/tor/torrc.j2 new file mode 100644 index 0000000..2ab5a00 --- /dev/null +++ b/states/tor/torrc.j2 @@ -0,0 +1,8 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{% from "tor/map.jinja" import tor with context %} + +ORPort {{ tor.config.exit_port }} +SocksPort {{ tor.config.client_host }}:{{ tor.config.client_port }} +ExitPolicy {{ tor.config.exit_policy }} +Nickname {{ tor.config.nickname }} +ContactInfo {{ tor.config.syscontact }} \ No newline at end of file diff --git a/states/transmission/config.sls b/states/transmission/config.sls new file mode 100644 index 0000000..d5a2953 --- /dev/null +++ b/states/transmission/config.sls @@ -0,0 +1,34 @@ +--- +{%- from "transmission/map.jinja" import transmission with context %} + +transmission-dl-dir: + file.directory: + - name: {{ transmission['config']['download-dir'] }} + - makedirs: True + +transmission-settings-directory: + file.directory: + - name: /etc/transmission-daemon + - user: root + - group: debian-transmission + - mode: 770 + +transmission-settings-master: + file.managed: + - name: /etc/transmission-daemon/settings.json.master + - source: salt://transmission/settings.json.j2 + - user: root + - group: debian-transmission + - mode: 0660 + - template: jinja + - watch_in: + - service: transmission-service + +transmission-settings: + file.managed: + - name: /etc/transmission-daemon/settings.json + - source: salt://transmission/settings.json.j2 + - user: root + - group: debian-transmission + - mode: 0660 + - template: jinja \ No newline at end of file diff --git a/states/transmission/defaults.yaml b/states/transmission/defaults.yaml new file mode 100644 index 0000000..0555f59 --- /dev/null +++ b/states/transmission/defaults.yaml @@ -0,0 +1,73 @@ +--- +transmission: + config: + alt-speed-down: 50 + alt-speed-enabled: false + alt-speed-time-begin: 540 + alt-speed-time-day: 127 + alt-speed-time-enabled: false + alt-speed-time-end: 1020 + alt-speed-up: 50 + bind-address-ipv4: "0.0.0.0" + bind-address-ipv6: "::" + blocklist-enabled: true + blocklist-url: "http://john.bitsurge.net/public/biglist.p2p.gz" + cache-size-mb: 4 + dht-enabled: true + download-dir: "/mnt/PAULBSDPOOL/downloads" + download-limit: 100 + download-limit-enabled: 0 + download-queue-enabled: true + download-queue-size: 5 + downloads-dir: "/tmp" + encryption: 2 + idle-seeding-limit: 30 + idle-seeding-limit-enabled: false + incomplete-dir: "/mnt/PAULBSDPOOL/downloads/incomplete" + incomplete-dir-enabled: false + lpd-enabled: true + max-peers-global: 200 + message-level: 1 + peer-congestion-algorithm: "" + peer-id-ttl-hours: 6 + peer-limit-global: 200 + peer-limit-per-torrent: 80 + peer-port: 51413 + peer-port-random-high: 65535 + peer-port-random-on-start: false + peer-socket-tos: "default" + peerport-random-low: 49152 + pex-enabled: true + port-forwarding-enabled: false + preallocation: 1 + prefetch-enabled: 1 + queue-stalled-enabled: true + queue-stalled-minutes: 30 + ratio-limit: 2 + ratio-limit-enabled: false + rename-partial-files: true + rpc-authentication-required: true + rpc-bind-address: "127.0.0.1" + rpc-enabled: true + rpc-password: "{b21d09fef2131b59bb2179668106b06757a3f9679R1Am2k7" + rpc-port: 9091 + rpc-url: "/transmission/" + rpc-username: "unknown" + rpc-whitelist: "*" + rpc-whitelist-enabled: true + scrape-paused-torrents-enabled: true + script-torrent-done-enabled: false + script-torrent-done-filename: "" + seed-queue-enabled: false + seed-queue-size: 10 + speed-limit-down: 100 + speed-limit-down-enabled: false + speed-limit-up: 100 + speed-limit-up-enabled: false + start-added-torrents: true + trash-original-torrent-files: false + umask: 2 + upload-limit: 100 + upload-limit-enabled: 0 + upload-slots-per-torrent: 14 + utp-enabled: true \ No newline at end of file diff --git a/states/transmission/init.sls b/states/transmission/init.sls new file mode 100644 index 0000000..b2edc09 --- /dev/null +++ b/states/transmission/init.sls @@ -0,0 +1,7 @@ +--- +{%- from "transmission/map.jinja" import transmission with context %} + +include: + - .install + - .config + - .service \ No newline at end of file diff --git a/states/transmission/install.sls b/states/transmission/install.sls new file mode 100644 index 0000000..d28cbe9 --- /dev/null +++ b/states/transmission/install.sls @@ -0,0 +1,9 @@ +--- +{%- from "transmission/map.jinja" import transmission with context %} + +transmission-install-server: + pkg.latest: + - pkgs: + - transmission-cli + - transmission-common + - transmission-daemon \ No newline at end of file diff --git a/states/transmission/map.jinja b/states/transmission/map.jinja new file mode 100644 index 0000000..f4955bc --- /dev/null +++ b/states/transmission/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "transmission/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='transmission') -%} + +{%- set transmission = salt['pillar.get']('transmission', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/transmission/service.sls b/states/transmission/service.sls new file mode 100644 index 0000000..41bdef4 --- /dev/null +++ b/states/transmission/service.sls @@ -0,0 +1,5 @@ +--- +transmission-service: + service.running: + - name: transmission-daemon + - enable: True \ No newline at end of file diff --git a/states/transmission/settings.json.j2 b/states/transmission/settings.json.j2 new file mode 100644 index 0000000..0c9b629 --- /dev/null +++ b/states/transmission/settings.json.j2 @@ -0,0 +1,2 @@ +{%- from "transmission/map.jinja" import transmission with context -%} +{{ transmission.config|json }} \ No newline at end of file diff --git a/states/users/defaults.yaml b/states/users/defaults.yaml new file mode 100644 index 0000000..9067c8e --- /dev/null +++ b/states/users/defaults.yaml @@ -0,0 +1,3 @@ +--- +users: [] +groups: [] \ No newline at end of file diff --git a/states/users/groups.sls b/states/users/groups.sls new file mode 100644 index 0000000..38e9e74 --- /dev/null +++ b/states/users/groups.sls @@ -0,0 +1,12 @@ +--- +{%- from "users/map.jinja" import groups with context -%} + +{%- for group in groups %} +group-{{ group.name }}: +{%- if group.enabled %} + group.present: +{%- else %} + group.absent: +{%- endif %} + - name: {{ group.name }} +{% endfor %} diff --git a/states/users/init.sls b/states/users/init.sls new file mode 100644 index 0000000..dbdf2af --- /dev/null +++ b/states/users/init.sls @@ -0,0 +1,5 @@ +--- +include: + - .groups + - .users + - .ssh-keys diff --git a/states/users/map.jinja b/states/users/map.jinja new file mode 100644 index 0000000..4022504 --- /dev/null +++ b/states/users/map.jinja @@ -0,0 +1,6 @@ +{%- import_yaml "users/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='users') -%} + +{%- set users = salt['pillar.get']('users', default=defaults, merge=True) -%} +{%- set groups = salt['pillar.get']('groups', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/users/ssh-keys.sls b/states/users/ssh-keys.sls new file mode 100644 index 0000000..d50c520 --- /dev/null +++ b/states/users/ssh-keys.sls @@ -0,0 +1,16 @@ +--- +{%- from "users/map.jinja" import users with context -%} + +{%- for user in users %} +{%- if user.sshkeys is defined %} +{%- for key in user.sshkeys %} +ssh-key-{{ user.name }}-{{ key.name }}: + ssh_auth.{{ key.state }}: + - user: {{ user.name }} + - names: + - {{ key.value }} + - require: + - user: user-{{ user.name }} +{% endfor %} +{%- endif -%} +{% endfor %} diff --git a/states/users/users.sls b/states/users/users.sls new file mode 100644 index 0000000..ae9ad2f --- /dev/null +++ b/states/users/users.sls @@ -0,0 +1,31 @@ +--- +{%- from "users/map.jinja" import users with context -%} + +{%- for user in users %} +{%- if not user.enabled %} +user-{{ user.name }}: + user.absent: + - name: {{ user.name }} +{%- endif %} +{%- endfor %} + +{%- for user in users %} +{%- if user.enabled %} +user-{{ user.name }}: + user.present: + - name: {{ user.name }} + - fullname: {{ user.fullname }} + - shell: {{ user.shell }} + - home: {{ user.home }} + - password: {{ user.password }} + - hash_password: True + - gid: {{ user.gid }} + - allow_gid_change: True + {%- if user.optional_groups is defined %} + - optional_groups: + {%- for opt_group in user.optional_groups %} + - {{ opt_group }} + {%- endfor %} + {%- endif %} + {%- endif %} +{% endfor %} diff --git a/states/vim/config.sls b/states/vim/config.sls new file mode 100644 index 0000000..75fc6cf --- /dev/null +++ b/states/vim/config.sls @@ -0,0 +1,12 @@ +--- +{%- from "vim/map.jinja" import vim with context %} +vim-vimrc-local: + file.managed: + - name: /etc/vim/vimrc.local + - source: salt://vim/vimrc.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - require: + - pkg: vim-pkg \ No newline at end of file diff --git a/states/vim/defaults.yaml b/states/vim/defaults.yaml new file mode 100644 index 0000000..1aa72c3 --- /dev/null +++ b/states/vim/defaults.yaml @@ -0,0 +1,61 @@ +--- +vim: + enabled: true + vimfiles_dir: /usr/share/vim/vimfiles + colors_dir: /usr/share/vim/vimfiles/colors + plugins_dir: /usr/share/vim/vimfiles/pack/plugins/start + config: + options: {} + lets: + defaults_vim: + name: "g:skip_defaults_vim" + value: 1 + sets: + nocompatible: + name: nocompatible + mouse: + name: mouse= + ttymouse: + name: ttymouse= + number: + name: number + viminfo: + name: viminfo + value: "'50,<1000,s100,h" + backspace: + name: backspace + value: indent,eol,start + autoindent: + name: autoindent + nocindent: + name: nocindent + ic: + name: ic + incsearch: + name: incsearch + tabstop: + name: tabstop + value: 2 + shiftwidth: + name: shiftwidth + value: 2 + softtabstop: + name: softtabstop + value: 2 + expandtab: + name: expandtab + pastetoggle: + name: pastetoggle + value: "" + t_Co: + name: t_Co + value: 256 + term: + name: term + value: xterm-256color + t_ut: + name: t_ut + value: "" + use_syntax: true + themes: {} + plugins: {} diff --git a/states/vim/init.sls b/states/vim/init.sls new file mode 100644 index 0000000..26b777b --- /dev/null +++ b/states/vim/init.sls @@ -0,0 +1,6 @@ +--- +include: + - .install + - .config + - .plugins + - .themes \ No newline at end of file diff --git a/states/vim/install.sls b/states/vim/install.sls new file mode 100644 index 0000000..fe10a54 --- /dev/null +++ b/states/vim/install.sls @@ -0,0 +1,15 @@ +--- +{%- from "vim/map.jinja" import vim with context %} +vim-pkg: + pkg.latest: + - name: vim + +vim-vimfiles-directory: + file.directory: + - name: {{ vim.plugins_dir }} + - makedirs: True + +vim-colors-directory: + file.directory: + - name: {{ vim.colors_dir }} + - makedirs: True \ No newline at end of file diff --git a/states/vim/map.jinja b/states/vim/map.jinja new file mode 100644 index 0000000..0a252a0 --- /dev/null +++ b/states/vim/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "vim/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='vim') -%} + +{%- set vim = salt['pillar.get']('vim', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/vim/plugins.sls b/states/vim/plugins.sls new file mode 100644 index 0000000..f930646 --- /dev/null +++ b/states/vim/plugins.sls @@ -0,0 +1,13 @@ +--- +{%- from "vim/map.jinja" import vim with context %} +vim-plugin-dirs: + file.directory: + - name: {{ vim.plugins_dir }} + - makedirs: True + +{%- for key, value in vim.plugins.items() %} +{{ value.name }}: + git.latest: + - name: {{ value.repo }} + - target: {{ vim.plugins_dir}}/{{ value.name }} +{%- endfor %} \ No newline at end of file diff --git a/states/vim/themes.sls b/states/vim/themes.sls new file mode 100644 index 0000000..9369774 --- /dev/null +++ b/states/vim/themes.sls @@ -0,0 +1,15 @@ +--- +{%- from "vim/map.jinja" import vim with context %} +{%- for key, value in vim.themes.items() %} +vim-{{ value.name }}-theme: + file.managed: + - name: {{ vim.colors_dir }}/{{ value.name }}.vim + - source: {{ value.url }} + - skip_verify: True + - user: root + - group: root + - mode: 0644 + - require: + - pkg: vim-pkg + - file: vim-colors-directory +{%- endfor %} \ No newline at end of file diff --git a/states/vim/vimrc.j2 b/states/vim/vimrc.j2 new file mode 100644 index 0000000..61678ea --- /dev/null +++ b/states/vim/vimrc.j2 @@ -0,0 +1,24 @@ +"{{ salt['pillar.get']('salt_managed', default='Salt Managed') }} +{%- from "vim/map.jinja" import vim with context %} +colorscheme {{ vim.config.use_theme }} +filetype plugin on +{%- if vim.config.use_syntax %} +syntax on +{%- endif %} +{% for key, value in vim.config.lets.items() %} +let {{ value.name }}{% if value.value is defined %}={{ value.value }}{% endif %} +{%- endfor %} +{% for key, value in vim.config.sets.items() %} +set {{ value.name }}{% if value.value is defined %}={{ value.value }}{% endif %} +{%- endfor %} + +if has("autocmd") + au VimEnter,InsertLeave * silent execute '!echo -ne "\e[2 q"' | redraw! + au InsertEnter,InsertChange * + \ if v:insertmode == 'i' | + \ silent execute '!echo -ne "\e[6 q"' | redraw! | + \ elseif v:insertmode == 'r' | + \ silent execute '!echo -ne "\e[4 q"' | redraw! | + \ endif + au VimLeave * silent execute '!echo -ne "\e[ q"' | redraw! +endif \ No newline at end of file diff --git a/states/vsftpd/defaults.yaml b/states/vsftpd/defaults.yaml new file mode 100644 index 0000000..86ad1ab --- /dev/null +++ b/states/vsftpd/defaults.yaml @@ -0,0 +1,18 @@ +--- +vsftpd: + enabled: true + config: + listen: "YES" + listen_ipv6: "NO" + anonymous_enable: "YES" + local_enable: "YES" + dirmessage_enable: "YES" + use_localtime: "YES" + xferlog_enable: "YES" + secure_chroot_dir: /var/run/vsftpd/empty + pam_service_name: vsftpd + ssl_enable: "NO" + pasv_enable: "YES" + pasv_min_port: 50000 + pasv_max_port: 50001 + port_enable: "YES" \ No newline at end of file diff --git a/states/vsftpd/init.sls b/states/vsftpd/init.sls new file mode 100644 index 0000000..feb2485 --- /dev/null +++ b/states/vsftpd/init.sls @@ -0,0 +1,16 @@ +--- +vsftpd-config: + file.managed: + - name: /etc/vsftpd.conf + - source: salt://vsftpd/vsftpd.conf.j2 + - user: root + - group: root + - mode: 644 + - template: jinja + - watch_in: + - service: vsftpd-service + +vsftpd-service: + service.running: + - name: vsftpd + - enable: True \ No newline at end of file diff --git a/states/vsftpd/map.jinja b/states/vsftpd/map.jinja new file mode 100644 index 0000000..524d668 --- /dev/null +++ b/states/vsftpd/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "vsftpd/defaults.yaml" as default_settings %} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='vsftpd') %} + +{%- set vsftpd = salt['pillar.get']('vsftpd', default=defaults, merge=True) %} \ No newline at end of file diff --git a/states/vsftpd/vsftpd.conf.j2 b/states/vsftpd/vsftpd.conf.j2 new file mode 100644 index 0000000..3c804ae --- /dev/null +++ b/states/vsftpd/vsftpd.conf.j2 @@ -0,0 +1,6 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "vsftpd/map.jinja" import vsftpd with context %} +{%- for key, value in vsftpd.config.items() %} +{{ key }}={{ value }} +{%- endfor %} \ No newline at end of file diff --git a/states/weather/defaults.yaml b/states/weather/defaults.yaml new file mode 100644 index 0000000..ea0a28e --- /dev/null +++ b/states/weather/defaults.yaml @@ -0,0 +1,9 @@ +--- +weather: + enabled: true + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + mirror: https://git.paulbsd.com/paulbsd/weather/releases/download + version: 1.0.0 + os: linux + arch: amd64 \ No newline at end of file diff --git a/states/weather/init.sls b/states/weather/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/weather/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/weather/install.sls b/states/weather/install.sls new file mode 100644 index 0000000..8956ebd --- /dev/null +++ b/states/weather/install.sls @@ -0,0 +1,16 @@ +--- +{%- from "weather/map.jinja" import weather with context %} +weather-archive-extract: + archive.extracted: + - name: {{ weather.release_dir }}/weather-{{ weather.version }} + - source: {{ weather.mirror }}/{{ weather.version }}/weather-{{ weather.version }}-{{ weather.os }}-{{ weather.arch }}.tar.gz + - skip_verify: True + - enforce_toplevel: False + - if_missing: {{ weather.release_dir }}/weather-{{ weather.version }} + +weather-binary-symlink: + file.symlink: + - name: {{ weather.install_dir }}/weather + - target: {{ weather.release_dir }}/weather-{{ weather.version }} + - require: + - archive: weather-archive-extract \ No newline at end of file diff --git a/states/weather/kernelmap.yaml b/states/weather/kernelmap.yaml new file mode 100644 index 0000000..e368b24 --- /dev/null +++ b/states/weather/kernelmap.yaml @@ -0,0 +1,3 @@ +--- +Linux: + os: "linux" \ No newline at end of file diff --git a/states/weather/map.jinja b/states/weather/map.jinja new file mode 100644 index 0000000..da1af88 --- /dev/null +++ b/states/weather/map.jinja @@ -0,0 +1,14 @@ +{%- import_yaml "weather/defaults.yaml" as default_settings -%} + +{%- import_yaml "weather/kernelmap.yaml" as kernelmap -%} +{%- import_yaml "weather/osarchmap.yaml" as osarchmap -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, + default='weather', + merge=salt['grains.filter_by'](osarchmap, grain='osarch', + merge=salt['grains.filter_by'](kernelmap, grain='kernel') + ) + ) +-%} + +{%- set weather = salt['pillar.get']('weather', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/weather/osarchmap.yaml b/states/weather/osarchmap.yaml new file mode 100644 index 0000000..c12e349 --- /dev/null +++ b/states/weather/osarchmap.yaml @@ -0,0 +1,21 @@ +--- +amd64: + arch: "amd64" + +x86_64: + arch: "amd64" + +386: + arch: "386" + +arm64: + arch: "arm64" + +armv6l: + arch: "arm" + +armv7l: + arch: "arm" + +armhf: + arch: "arm" \ No newline at end of file diff --git a/states/website/defaults.yaml b/states/website/defaults.yaml new file mode 100644 index 0000000..7a153c7 --- /dev/null +++ b/states/website/defaults.yaml @@ -0,0 +1,7 @@ +--- +website: + enabled: true + install_dir: /usr/local/apps + release_dir: /usr/local/apps/releases + mirror: https://git.paulbsd.com/paulbsd/website/releases/download + version: 1.0.0 \ No newline at end of file diff --git a/states/website/init.sls b/states/website/init.sls new file mode 100644 index 0000000..10ad9a6 --- /dev/null +++ b/states/website/init.sls @@ -0,0 +1,3 @@ +--- +include: + - .install \ No newline at end of file diff --git a/states/website/install.sls b/states/website/install.sls new file mode 100644 index 0000000..36aa11a --- /dev/null +++ b/states/website/install.sls @@ -0,0 +1,16 @@ +--- +{%- from "website/map.jinja" import website with context %} +website-archive-extract: + archive.extracted: + - name: {{ website.release_dir }}/website-{{ website.version }} + - source: {{ website.mirror }}/{{ website.version }}/website-{{ website.version }}.tar.gz + - skip_verify: True + - enforce_toplevel: False + - if_missing: {{ website.release_dir }}/website-{{ website.version }} + +website-binary-symlink: + file.symlink: + - name: {{ website.install_dir }}/website + - target: {{ website.release_dir }}/website-{{ website.version }} + - require: + - archive: website-archive-extract \ No newline at end of file diff --git a/states/website/map.jinja b/states/website/map.jinja new file mode 100644 index 0000000..f0bf327 --- /dev/null +++ b/states/website/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "website/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='website')-%} + +{%- set website = salt['pillar.get']('website', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/winpkg/bootstrap.sls b/states/winpkg/bootstrap.sls new file mode 100644 index 0000000..ea97ec6 --- /dev/null +++ b/states/winpkg/bootstrap.sls @@ -0,0 +1,4 @@ +--- +chocolatey_bootstrap: + module.run: + - name: chocolatey.bootstrap \ No newline at end of file diff --git a/states/winpkg/defaults.yaml b/states/winpkg/defaults.yaml new file mode 100644 index 0000000..58faa87 --- /dev/null +++ b/states/winpkg/defaults.yaml @@ -0,0 +1,3 @@ +--- +winpkg: + pkgs: [] \ No newline at end of file diff --git a/states/winpkg/init.sls b/states/winpkg/init.sls new file mode 100644 index 0000000..aaba48e --- /dev/null +++ b/states/winpkg/init.sls @@ -0,0 +1,4 @@ +--- +include: + - .bootstrap + - .install \ No newline at end of file diff --git a/states/winpkg/install.sls b/states/winpkg/install.sls new file mode 100644 index 0000000..8b49aaf --- /dev/null +++ b/states/winpkg/install.sls @@ -0,0 +1,9 @@ +--- +{%- from "winpkg/map.jinja" import winpkg with context %} +{%- for pkg in winpkgs.pkgs %} +winpkg-{{ pkg }}: + chocolatey.upgraded: + - name: {{ pkg }} + - require: + - module: chocolatey_bootstrap +{%- endfor %} \ No newline at end of file diff --git a/states/winpkg/map.jinja b/states/winpkg/map.jinja new file mode 100644 index 0000000..f0bf327 --- /dev/null +++ b/states/winpkg/map.jinja @@ -0,0 +1,5 @@ +{%- import_yaml "website/defaults.yaml" as default_settings -%} + +{%- set defaults = salt['grains.filter_by'](default_settings, default='website')-%} + +{%- set website = salt['pillar.get']('website', default=defaults, merge=True) -%} \ No newline at end of file diff --git a/states/wintse/init.sls b/states/wintse/init.sls new file mode 100644 index 0000000..661a037 --- /dev/null +++ b/states/wintse/init.sls @@ -0,0 +1,12 @@ +--- +wintse-firewall-rule: + win_firewall.add_rule: + - localport: 3389 + - protocol: tcp + - action: allow + +wintse-enable: + cmd.run: + - name: | + REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurentControlSet\Control\Terminal Server" /v + fDenyTSConnections /t REG_DWORD /d 0 /f diff --git a/states/youtubedl/defaults.yaml b/states/youtubedl/defaults.yaml new file mode 100644 index 0000000..b3062bf --- /dev/null +++ b/states/youtubedl/defaults.yaml @@ -0,0 +1,4 @@ +--- +youtubedl: + install_dir: "/usr/bin" + version: "2020.03.24" \ No newline at end of file diff --git a/states/youtubedl/init.sls b/states/youtubedl/init.sls new file mode 100644 index 0000000..817d083 --- /dev/null +++ b/states/youtubedl/init.sls @@ -0,0 +1,11 @@ +--- +{%- from "youtubedl/map.jinja" import youtubedl with context %} +youtubedl-bin: + file.managed: + - name: {{ youtubedl.install_dir}}/youtube-dl + - source: https://github.com/ytdl-org/youtube-dl/releases/download/{{ youtubedl.version }}/youtube-dl + - user: root + - group: root + - mode: 0775 + - template: jinja + - skip_verify: True \ No newline at end of file diff --git a/states/youtubedl/map.jinja b/states/youtubedl/map.jinja new file mode 100644 index 0000000..e348736 --- /dev/null +++ b/states/youtubedl/map.jinja @@ -0,0 +1,6 @@ +{%- import_yaml "youtubedl/defaults.yaml" as defaults %} + +{%- set youtubedl = salt['pillar.get']('youtubedl', default=defaults.youtubedl, merge=True) %} + +{%- set nickname = salt['pillar.get']('nickname',default='anonymous') %} +{%- set syscontact = salt['pillar.get']('syscontact',default='anonymous@example.com') %} \ No newline at end of file diff --git a/states/zsh/config.sls b/states/zsh/config.sls new file mode 100644 index 0000000..be9bef0 --- /dev/null +++ b/states/zsh/config.sls @@ -0,0 +1,18 @@ +--- +zsh-omz-repo: + git.latest: + - name: https://github.com/robbyrussell/oh-my-zsh.git + - target: /usr/share/oh-my-zsh + - require: + - pkg: zsh-pkg + +zsh-omz-profile: + file.managed: + - name: /usr/share/zsh/zprofile + - source: salt://zsh/zprofile.j2 + - user: root + - group: root + - mode: 0644 + - template: jinja + - require: + - pkg: zsh-pkg \ No newline at end of file diff --git a/states/zsh/defaults.yaml b/states/zsh/defaults.yaml new file mode 100644 index 0000000..81cf240 --- /dev/null +++ b/states/zsh/defaults.yaml @@ -0,0 +1,4 @@ +--- +zsh: + enabled: true + config: \ No newline at end of file diff --git a/states/zsh/init.sls b/states/zsh/init.sls new file mode 100644 index 0000000..533e4d1 --- /dev/null +++ b/states/zsh/init.sls @@ -0,0 +1,6 @@ +--- +include: + - users + - .pkg + - .config + - .users \ No newline at end of file diff --git a/states/zsh/misc.txt b/states/zsh/misc.txt new file mode 100644 index 0000000..4f66c11 --- /dev/null +++ b/states/zsh/misc.txt @@ -0,0 +1,4 @@ +#autoload -Uz promptinit +#set autorehash +#promptinit +#prompt_redhat_setup \ No newline at end of file diff --git a/states/zsh/pkg.sls b/states/zsh/pkg.sls new file mode 100644 index 0000000..2b3fa81 --- /dev/null +++ b/states/zsh/pkg.sls @@ -0,0 +1,6 @@ +--- +zsh-pkg: + pkg.latest: + - pkgs: + - zsh + - zsh-syntax-highlighting \ No newline at end of file diff --git a/states/zsh/users.sls b/states/zsh/users.sls new file mode 100644 index 0000000..a527463 --- /dev/null +++ b/states/zsh/users.sls @@ -0,0 +1,17 @@ +--- +{%- from "users/map.jinja" import users with context -%} +{%- for user in users %} +{%- if user.enabled %} +zshrc-user-{{ user.name }}: + file.managed: + - name: {{ user.home }}/.zshrc + - source: salt://zsh/zshrc.j2 + - user: {{ user.name }} + - group: {{ user.gid }} + - mode: 0644 + - template: jinja + - require: + - pkg: zsh-pkg + - user: user-{{ user.name }} +{%- endif %} +{%- endfor %} \ No newline at end of file diff --git a/states/zsh/zprofile.j2 b/states/zsh/zprofile.j2 new file mode 100644 index 0000000..f492c57 --- /dev/null +++ b/states/zsh/zprofile.j2 @@ -0,0 +1,35 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +# Main environments variables +export EDITOR=vim +export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee' + + +# Golang settings +export GOPATH=~/go +export GOROOT=/usr/local/go +export PATH=$PATH:$GOROOT/bin:$GOPATH/bin + + +# Oh my ZSH settings +export ZSH=/usr/share/oh-my-zsh +ZSH_THEME="jreese" +DISABLE_AUTO_UPDATE="true" +plugins=(common-aliases sudo docker salt git) + +if [[ -f $ZSH/oh-my-zsh.sh ]] +then + source $ZSH/oh-my-zsh.sh +fi + + +# Acme settings +if [[ -f /root/.acme.sh/acme.sh.env ]] +then + . /root/.acme.sh/acme.sh.env +fi + + +# Misc settings +bindkey -e +unsetopt share_history \ No newline at end of file diff --git a/states/zsh/zshrc.j2 b/states/zsh/zshrc.j2 new file mode 100644 index 0000000..603f823 --- /dev/null +++ b/states/zsh/zshrc.j2 @@ -0,0 +1,3 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +source /usr/share/zsh/zprofile \ No newline at end of file