Compare commits

..

29 Commits

Author SHA1 Message Date
da79c9264a Unattend-upgrades upgrade also debian-updates and debian-backports
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-09 10:54:16 +02:00
34c7601cf7 Don't use password for nullmailer
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-09 10:50:47 +02:00
fb1b19bcfd testing server got deleted, minecraft server is temporary down
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 14:38:43 +02:00
37ccc19e04 Drop useless step
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 14:38:43 +02:00
41c9135dfe Galène uses backports
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 14:38:43 +02:00
d320cc0a44 Configure unattended-upgrades
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 14:38:43 +02:00
0d560218e2 Add Belenios and Galène
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 14:38:43 +02:00
f56276b15b Fix URL in header
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 13:33:27 +02:00
cf37b94440 Add Belenios and Galène
Signed-off-by: Emmy D'Anello <ynerant@emy.lu>
2023-04-03 13:18:41 +02:00
9169d8e6c6 Add tgvmax
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
2023-02-12 13:45:35 +01:00
9eb88e6417 nupes is on srv-nat, not adh
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
2023-02-12 13:45:29 +01:00
7cfd15a08f Drop deleted hosts
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
2023-01-12 12:52:55 +01:00
414950f4b5 Remove laptop-specific code
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
2023-01-12 12:50:19 +01:00
7f4f846408 Lot of stuff
Signed-off-by: Emmy D'Anello <ynerant@crans.org>
2023-01-12 12:36:32 +01:00
de76ae0085 There is no VM < Bullseye
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2022-07-30 17:34:42 +02:00
a686970b0f [sudo] Replace # by @
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2022-06-27 16:33:42 +02:00
4fe3babc83 bullseye-security exists
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-11-10 11:46:53 +01:00
a1683dbf19 Synapse has Internet
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-22 23:01:17 +02:00
88ac609897 Replace template_path by template_fullpath in Ansible header
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-08 17:03:22 +02:00
2a5f6621b6 Add monitoring
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-08 16:59:10 +02:00
f7de61b6e2 Fix base playbook order
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 17:32:50 +02:00
f57b1f1b3e network_interfaces is working for my router
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 17:14:30 +02:00
f1ac6f269b Deploy network interfaces from LDAP
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 17:02:54 +02:00
50cb4cfc75 Reorder hosts
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:59:33 +02:00
aef3070586 Welcome Gitea/Nextcloud
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:57:48 +02:00
89bbc6c070 Add some machines to test Babel/re6stnet
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:57:08 +02:00
361125e4a5 Deploy nullmailer
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:56:40 +02:00
b592afcd38 Add some packages
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:52:24 +02:00
145dccac2d Deploy root password
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2021-06-04 15:51:04 +02:00
129 changed files with 1693 additions and 1677 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
__pycache__
debug.yml

View File

@@ -1,6 +1,7 @@
[defaults]
# Explicitely redefined some defaults to make play execution work
roles_path = ./roles
lookup_plugins = ./lookup_plugins
vars_plugins = ./vars_plugins
inventory = ./hosts

View File

@@ -1,14 +1,14 @@
---
# Custom header
dirty: "{% if template_path is defined %}{{ lookup('pipe', 'git diff --quiet -- ' + template_path | quote + ' || echo dirty') }}{% else %}{{ lookup('pipe', 'git diff --quiet || echo dirty') }}{% endif %}"
dirty: "{% if template_fullpath is defined %}{{ lookup('pipe', 'git diff --quiet -- ' + template_fullpath | quote + ' || echo dirty') }}{% else %}{{ lookup('pipe', 'git diff --quiet || echo dirty') }}{% endif %}"
ansible_header: |
+++++++++++++++++++++++++++++++++++++++++++++++++++
Ansible managed, don't modify the file locally.
See https://gitlab.crans.org/ynerant/templier-ansible.
{% if template_path is defined %}{% set _, rpath = template_path.split('roles/', 1) %}Commit: {% if dirty %}({{dirty}}) {% endif %}{{ lookup('pipe', 'git log -n 1 --pretty=format:%H -- ' + template_path | quote) }}
See https://git.ynerant.fr/ynerant/templier-ansible.
{% if template_fullpath is defined %}{% set _, rpath = template_fullpath.split('roles/', 1) %}Commit: {% if dirty %}({{dirty}}) {% endif %}{{ lookup('pipe', 'git log -n 1 --pretty=format:%H -- ' + template_fullpath | quote) }}
{% if dirty %}Run by: {{ ansible_env.SUDO_USER }}
{% else %}Author: {{ lookup('pipe', 'git log -n 1 --pretty=format:%an -- ' + template_path | quote) }}
{% else %}Author: {{ lookup('pipe', 'git log -n 1 --pretty=format:%an -- ' + template_fullpath | quote) }}
{% endif %}Template: roles/{{ rpath }}
{% else %}
Run by: {{ ansible_env.SUDO_USER }}
@@ -23,18 +23,6 @@ glob_ldap:
base: 'dc=ynerant,dc=fr'
pass:
upstream: 'ssh://git@git.ynerant.fr:2222/ynerant/pass.git'
dest: '.password-store/'
cliutils:
bash:
bogus_dirs: []
git:
email: ynerant@crans.org
name: Yohann D'ANELLO
signingkey: 3A75C55819C8CF85
bind:
domains:
- name: ynerant.fr

View File

@@ -1,4 +1,4 @@
---
glob_home:
ip: 172.16.42.1
mountpoint: /rpool/home
mountpoint: /vm/home

View File

@@ -0,0 +1,20 @@
glob_network_interfaces:
vlan:
- name: adh
id: 12
gateway: "185.230.78.99"
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'adh') | ipv4 | first }}"
gateway_v6: "2a0c:700:12::ff:fe00:9912"
- name: adm
id: 42
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'adm') | ipv4 | first }}"
- name: srv_nat
id: 43
gateway: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv4 | first }}"
dns: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv4 | first }}"
gateway_v6: "{{ query('ldap', 'ip', 'routeur-templier', 'srv-nat') | ipv6 | first }}"
# Deploy only adm by default
interfaces:
adm: eth0

View File

@@ -0,0 +1,6 @@
---
glob_nullmailer:
root: root@ynerant.fr
smtp_server: smtp.adm.ynerant.fr
defaulthost: ynerant.fr
allmailfrom: root@ynerant.fr

View File

@@ -0,0 +1,3 @@
---
glob_prometheus_node_exporter:
listen_addr: "{{ query('ldap', 'ip', ansible_hostname, 'adm') | ipv4 | first }}"

View File

@@ -2,6 +2,9 @@
glob_apt:
mirror: "http://mirror.adm.ynerant.fr/"
backports: false
monitoring_mail: "ynerant+apt@emy.lu"
extra_repositories: []
pin:
bullseye: []
pin: {}
glob_root:
passwd_hash: '{{ vault.root_passwd_hash }}'

7
group_vars/grafana.yml Normal file
View File

@@ -0,0 +1,7 @@
---
glob_grafana:
root_url: https://grafana.ynerant.fr
icon: crans_icon_white.svg
ldap_base: "{{ glob_ldap.base }}"
ldap_master_ipv4: "{{ glob_ldap.servers[0] }}"
ldap_user_tree: "ou=passwd,{{ glob_ldap.base }}"

View File

@@ -1,4 +0,0 @@
---
user:
name: ynerant
root: yes

View File

@@ -30,3 +30,6 @@ glob_nginx:
- "172.16.0.0/16"
- "fd00:0:0:42::/64"
deploy_robots_file: false
glob_prometheus_nginx_exporter:
listen_addr: "{{ query('ldap', 'ip', ansible_hostname, 'adm') | ipv4 | first }}"

View File

@@ -0,0 +1,9 @@
---
glob_prometheus: {}
glob_ninjabot:
config:
nick: templier
server: irc.crans.org
port: 6667
channel: "#/dev/null"

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,3 @@
---
interfaces:
adm: ens18

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -1,4 +0,0 @@
---
user:
name: ynerant
root: yes

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,7 @@
---
interfaces:
adm: ens18
srv_nat: ens19
loc_apt:
backports: true

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -1 +0,0 @@
ynerant-thinkpad.wifi.sand.auro.re.yml

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,70 @@
---
interfaces:
adm: eth0
srv_nat: eth1
loc_prometheus:
node:
file: targets_node.json
targets: "{{ groups['server'] | select('match', '^.*\\.adm\\.ynerant\\.fr$') | list | sort }}"
config:
- job_name: servers
file_sd_configs:
- files:
- '/etc/prometheus/targets_node.json'
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- source_labels: [__param_target]
target_label: __address__
replacement: '$1:9100'
nginx:
file: targets_nginx.json
targets:
- proxy.adm.ynerant.fr
config:
- job_name: nginx
file_sd_configs:
- files:
- '/etc/prometheus/targets_nginx.json'
relabel_configs:
- source_labels: [__address__]
target_label: instance
- source_labels: [instance]
target_label: __address__
replacement: '$1:9117'
blackbox:
file: targets_blackbox.json
targets:
- https://ynerant.fr/
- https://bibliogram.ynerant.fr/
- https://element.ynerant.fr/
- https://gitea.ynerant.fr/
- https://grafana.ynerant.fr/
- https://hydrogen.ynerant.fr/
- https://nextcloud.ynerant.fr/
- https://mailu.ynerant.fr/
- http://notls.ynerant.fr/
- https://reddit.ynerant.fr/
- https://thelounge.ynerant.fr/
- https://translate.ynerant.fr/
- https://kfet.saperlistpopette.fr/
config:
- job_name: blackbox
file_sd_configs:
- files:
- '/etc/prometheus/targets_blackbox.json'
metrics_path: /probe
params:
module: [http_2xx] # Look for a HTTP 200 response.
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9115

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: eth0
srv_nat: eth1

View File

@@ -0,0 +1,3 @@
---
interfaces:
adm: eth0

View File

@@ -0,0 +1,5 @@
---
interfaces:
adm: ens18
adh: ens19
srv_nat: ens20

View File

@@ -1,4 +0,0 @@
---
user:
name: ynerant
root: no

View File

@@ -1,4 +0,0 @@
---
user:
name: ynerant
root: yes

View File

@@ -0,0 +1,8 @@
---
loc_certbot:
- dns_rfc2136_server: '172.16.42.103'
dns_rfc2136_name: certbot_challenge.
dns_rfc2136_secret: "{{ vault.certbot_dns_secret }}"
mail: ynerant@crans.org
certname: adm.ynerant.fr
domains: "*.adm.ynerant.fr"

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -0,0 +1,4 @@
---
interfaces:
adm: ens18
srv_nat: ens19

View File

@@ -1,9 +0,0 @@
---
user:
name: ynerant
root: yes
laptop:
numpad: true
resolution: 1440p
gpu: true

View File

@@ -1,10 +0,0 @@
---
user:
name: ynerant
root: yes
laptop:
numpad: false
resolution: 1080p
touchscreen: true
gpu: false

View File

@@ -1,4 +0,0 @@
---
user:
name: ynerant
root: no

56
hosts
View File

@@ -1,26 +1,38 @@
[archlinux:children]
perso
[blackbox]
monitoring.adm.ynerant.fr
[certbot]
proxy.adm.ynerant.fr
templier.adm.ynerant.fr
[debian:children]
server
[grafana]
monitoring.adm.ynerant.fr
[nginx]
nupes.adm.ynerant.fr
tgvmax.adm.ynerant.fr
[nginx:children]
reverseproxy
[ntp_server]
routeur-templier.adm.ynerant.fr
[perso]
ynerant-pc.fil.sand.auro.re
ynerant-thinkpad.wifi.sand.auro.re
localhost
[postfix]
mailu.adm.ynerant.fr
[prometheus]
monitoring.adm.ynerant.fr
[reverseproxy]
proxy.adm.ynerant.fr
[routeur]
routeur-templier.adm.ynerant.fr
[server:children]
virtu
vm
@@ -29,19 +41,27 @@ vm
templier.adm.ynerant.fr
[virtu]
# dt.adh.crans.org
templier.adm.ynerant.fr
[vm]
routeur-templier.adm.ynerant.fr
proxy.adm.ynerant.fr
dns.adm.ynerant.fr
mailu.adm.ynerant.fr
psql.adm.ynerant.fr
synapse.adm.ynerant.fr
belenios.adm.ynerant.fr
borg.adm.ynerant.fr
dendrite.adm.ynerant.fr
docker.adm.ynerant.fr
# candilib.adm.ynerant.fr
[all:vars]
# Force remote to use Python 3
ansible_python_interpreter=/usr/bin/env python3
dns.adm.ynerant.fr
fosscord.adm.ynerant.fr
galene.adm.ynerant.fr
gitea.adm.ynerant.fr
mailu.adm.ynerant.fr
mastodon.adm.ynerant.fr
#minecraft.adm.ynerant.fr
monitoring.adm.ynerant.fr
nextcloud.adm.ynerant.fr
nupes.adm.ynerant.fr
pad.adm.ynerant.fr
peertube.adm.ynerant.fr
psql.adm.ynerant.fr
proxy.adm.ynerant.fr
routeur-templier.adm.ynerant.fr
tgvmax.adm.ynerant.fr
wireguard.adm.ynerant.fr

Binary file not shown.

206
lookup_plugins/ldap.py Normal file
View File

@@ -0,0 +1,206 @@
"""
To use this lookup plugin, you need to pass ldap:
ssh -L 1636:172.16.10.1:636 172.16.10.1
"""
import ipaddress
from ansible.errors import AnsibleError, AnsibleParserError
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
try:
import ldap
except ImportError:
raise AnsibleError("You need to install python3-ldap")
display = Display()
def decode_object(object):
return {attribute: [value.decode('utf-8') for value in object[attribute]] for attribute in object}
class LookupModule(LookupBase):
def __init__(self, **kwargs):
self.base = ldap.initialize('ldaps://localhost:1636/')
self.base.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
self.base.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
self.base_dn = 'dc=ynerant,dc=fr'
def query(self, base, scope, filter='(objectClass=*)', attr=None):
"""
Make a LDAP query
query('ldap', 'query', BASE, SCOPE[, FILTER[, ATTR]])
BASE: base dn
SCOPE: 'base', 'one' or 'sub'
FILTER: ldap filter (optional)
ATTR: list of attributes (optional)
"""
scope = { 'base': ldap.SCOPE_BASE, 'one': ldap.SCOPE_ONELEVEL, 'sub': ldap.SCOPE_SUBTREE }[scope]
query_id = self.base.search(f"{base}", scope, filter, attr)
result = self.base.result(query_id)[1]
result = { dn: decode_object(entry) for dn, entry in result }
return result
def ip(self, host, vlan):
"""
Retrieve IP addresses of an interface of a device
query('ldap', 'ip', HOST, VLAN)
"""
if isinstance(vlan, int):
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
network_result = self.base.result(network_query_id)
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
if vlan == 'adh':
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
else:
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
result = self.base.result(query_id)
result = result[1][0][1]
result = [res.decode('utf-8') for res in result['ipHostNumber']]
return result
def all_ip(self, host):
"""
Retrieve all IP addresses of a device
query('ldap', 'all_ip', HOST)
"""
interfaces_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL)
interfaces_result = self.base.result(interfaces_query_id)
result = []
for dn, interface in interfaces_result[1]:
for ip in interface['ipHostNumber']:
result.append(ip.decode('utf-8'))
return result
def cn(self, host, vlan):
"""
Retrieve aliases of an interface of a device
query('ldap', 'cn', HOST, VLAN)
"""
if isinstance(vlan, int):
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
network_result = self.base.result(network_query_id)
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
if vlan == 'adh':
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
else:
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
result = self.base.result(query_id)
result = result[1][0][1]
result = [res.decode('utf-8') for res in result['cn']]
return result
def all_cn(self, host):
"""
Retrieve all aliases addresses of a device
query('ldap', 'all_cn', HOST)
"""
interfaces_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL)
interfaces_result = self.base.result(interfaces_query_id)
result = []
for dn, interface in interfaces_result[1]:
for cn in interface['cn']:
result.append(cn.decode('utf-8'))
return result
def ssh_keys(self, host):
"""
Retrieve SSH keys of a host
query('ldap', 'ssh_keys', HOST)
"""
host_query_id = self.base.search(f"cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
host_result = self.base.result(host_query_id)[1][0][1]
result = []
if 'description' not in host_result:
return result
for description in host_result['description']:
description = description.decode('utf-8')
key, value = description.split(':', 1)
if key in {'ecdsa-sha2-nistp256', 'ssh-ed25519', 'ssh-dss', 'ssh-rsa'}:
result.append(f'{key} {value}')
return result
def subnet_ipv4(self, subnet):
"""
Retrieve used IP addresses on a subnet
query('ldap', 'subnet_ipv4', SUBNET)
"""
network_query_id = self.base.search(f"cn={subnet},ou=networks,{self.base_dn}", ldap.SCOPE_BASE)
network_result = self.base.result(network_query_id)
network = network_result[1][0][1]
network, hostmask = network['ipNetworkNumber'][0].decode('utf-8'), network['ipNetmaskNumber'][0].decode('utf-8')
subnet = ipaddress.IPv4Network(f"{network}/{hostmask}")
query_id = self.base.search(f"ou=hosts,{self.base_dn}", ldap.SCOPE_SUBTREE, "objectClass=ipHost")
result = self.base.result(query_id)
result = [ip.decode('utf-8') for dn, entry in result[1] for ip in entry['ipHostNumber'] if ipaddress.ip_address(ip.decode('utf-8')) in subnet]
return result
def run(self, terms, variables=None, **kwargs):
if terms[0] == 'query':
result = self.query(*terms[1:])
elif terms[0] == 'ip':
result = self.ip(*terms[1:])
elif terms[0] == 'all_ip':
result = self.all_ip(*terms[1:])
elif terms[0] == 'cn':
result = self.cn(*terms[1:])
elif terms[0] == 'all_cn':
result = self.all_cn(*terms[1:])
elif terms[0] == 'subnet_ipv4':
result = self.subnet_ipv4(*terms[1:])
elif terms[0] == 'ssh_keys':
result = self.ssh_keys(*terms[1:])
elif terms[0] == 'group':
query_id = self.base.search(f"ou=group,{self.base_dn}", ldap.SCOPE_SUBTREE, "objectClass=posixGroup")
result = self.base.result(query_id)
result = result[1]
# query interface attribute
# query('ldap', 'hosts', HOST, VLAN, ATTR)
# HOST: device name
# VLAN: vlan name
# ATTR: attribute
elif terms[0] == 'hosts':
host = terms[1]
vlan = terms[2]
attr = terms[3]
if isinstance(vlan, int):
network_query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description={vlan}")
network_result = self.base.result(network_query_id)
vlan = network_result[1][0][1]['cn'][0].decode('utf-8')
if vlan == 'adh':
query_id = self.base.search(f"cn={host}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
else:
query_id = self.base.search(f"cn={host}.{vlan}.ynerant.fr,cn={host},ou=hosts,{self.base_dn}", ldap.SCOPE_BASE)
result = self.base.result(query_id)
result = result[1][0][1]
result = [res.decode('utf-8') for res in result[attr]]
elif terms[0] == 'network':
network = terms[1]
query_id = self.base.search(f"cn={network},ou=networks,{self.base_dn}", ldap.SCOPE_BASE, "objectClass=ipNetwork")
result = self.base.result(query_id)
result = result[1][0][1]
return str(ipaddress.ip_network('{}/{}'.format(result['ipNetworkNumber'][0].decode('utf-8'), result['ipNetmaskNumber'][0].decode('utf-8'))))
elif terms[0] == 'zones':
query_id = self.base.search(f"ou=networks,{self.base_dn}", ldap.SCOPE_ONELEVEL, "objectClass=ipNetwork")
result = self.base.result(query_id)
res = []
for _, network in result[1]:
network = network['cn'][0].decode('utf-8')
if network == 'adh':
res.append('ynerant.fr')
else:
res.append(f"{network}.ynerant.fr")
result = res
elif terms[0] == 'vlanid':
network = terms[1]
query_id = self.base.search(f"cn={network},ou=networks,{self.base_dn}", ldap.SCOPE_BASE, "objectClass=ipNetwork")
result = self.base.result(query_id)
result = result[1][0][1]
return int(result['description'][0])
elif terms[0] == 'role':
role = terms[1]
query_id = self.base.search(f"ou=hosts,{self.base_dn}", ldap.SCOPE_ONELEVEL, f"description=role:{role}")
result = self.base.result(query_id)
result = [cn.decode('utf-8') for res in result[1] for cn in res[1]['cn']]
return result

View File

@@ -1,42 +1,23 @@
#!/usr/bin/env ansible-playbook
---
- import_playbook: root.yml
- import_playbook: apt.yml
- import_playbook: network_interfaces.yml
- import_playbook: ntp.yml
- import_playbook: ldap-client.yml
- import_playbook: home.yml
- import_playbook: nullmailer.yml
- import_playbook: monitoring.yml
- hosts: debian
roles:
- sudo
- hosts: all
roles:
- qemu-guest-agent
- cli-utils
- vim
- ssh
#- hosts: templier.adh.crans.org
# roles:
# - bind
# - docker
# become: yes
- hosts: perso
roles:
# - sudo
- systemd
- pacman
- ntp-client-arch
- texlive
- xorg
- i3
- terminal
- notification
- mime
- audio
- multimedia
- pass
- communication
- browser
# - scripts

38
plays/monitoring.yml Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env ansible-playbook
---
# Deploy Prometheus on monitoring server
- hosts: prometheus
vars:
prometheus: "{{ glob_prometheus | default({}) | combine(loc_prometheus | default({})) }}"
alertmanager: "{{ glob_alertmanager | default({}) | combine(loc_alertmanager | default({})) }}"
ninjabot: "{{ glob_ninjabot | default({}) | combine(loc_ninjabot | default({})) }}"
roles:
- prometheus
- prometheus-alertmanager
- ninjabot
# Deploy Grafana on monitoring server
- hosts: grafana
vars:
grafana: "{{ glob_grafana | default({}) | combine(loc_grafana | default({})) }}"
roles:
- grafana
- hosts: blackbox
roles:
- prometheus-blackbox-exporter
# Monitor all hosts
- hosts: server
vars:
prometheus_node_exporter: "{{ glob_prometheus_node_exporter | default({}) | combine(loc_prometheus_node_exporter | default({})) }}"
roles:
- prometheus-node-exporter
# Export nginx metrics
- hosts: nginx
vars:
prometheus_nginx_exporter: "{{ glob_prometheus_nginx_exporter | default({}) | combine(loc_prometheus_nginx_exporter | default({})) }}"
roles:
- prometheus-nginx-exporter

7
plays/network_interfaces.yml Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env ansible-playbook
---
- hosts: vm
vars:
network_interfaces: "{{ glob_network_interfaces | default({}) | combine(loc_network_interfaces | default({})) }}"
roles:
- network-interfaces

7
plays/nullmailer.yml Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env ansible-playbook
---
- hosts: debian,!postfix
vars:
nullmailer: "{{ glob_nullmailer | default({}) | combine(loc_nullmailer | default({})) }}"
roles:
- nullmailer

7
plays/root.yml Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env ansible-playbook
---
- hosts: debian
vars:
root: "{{ glob_root | default({}) | combine(loc_root | default({})) }}"
roles:
- root

View File

@@ -0,0 +1,32 @@
---
# Install apt-listchanges
- name: Install apt-listchanges
when: ansible_os_family == "Debian"
apt:
name: apt-listchanges
state: present
update_cache: true
register: apt_result
retries: 3
until: apt_result is succeeded
# Send email when there is something new
- name: Configure apt-listchanges
ini_file:
path: /etc/apt/listchanges.conf
no_extra_spaces: true
section: apt
option: "{{ item.option }}"
value: "{{ item.value }}"
state: present
mode: 0644
loop:
- option: confirm
value: "true"
- option: email_address
value: "{{ apt.monitoring_mail }}"
- option: which
value: both
...

View File

@@ -0,0 +1,20 @@
---
- name: Install unattended-upgrades
when: ansible_os_family == "Debian"
apt:
name: unattended-upgrades
state: present
update_cache: true
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Configure unattended-upgrades
template:
src: "apt/apt.conf.d/{{ item }}.j2"
dest: "/etc/apt/apt.conf.d/{{ item }}"
owner: root
mode: u=rw,g=r,o=r
loop:
- 50unattended-upgrades
- 20auto-upgrades

View File

@@ -1,14 +1,5 @@
---
- name: Clear charybde configuration
lineinfile:
state: absent
path: /etc/hosts
regex: "^{{ item }}"
loop:
- "185.230.79.30"
- "2a0c:700:2:0:ea39:35ff:fef0:48c9"
- name: Add mirror.crans.org in /etc/hosts
- name: Add mirror.adm.ynerant.fr in /etc/hosts
lineinfile:
state: present
path: /etc/hosts
@@ -36,6 +27,7 @@
loop: "{{ apt.extra_repositories }}"
- name: Configure pin from future distributions
when: item[2].key != ansible_distribution_release
template:
src: "apt/{{ item[0] }}.d/pin{{ item[1] }}.j2"
dest: "/etc/apt/{{ item[0] }}.d/{{ item[2].key }}{{ item[1] }}"
@@ -46,6 +38,21 @@
- [["sources.list", ".list"], ["preferences", ""]]
- "{{ apt.pin|dict2items }}"
- name: Clear useless pinned configuration
when: item[2].key == ansible_distribution_release
file:
path: "/etc/apt/{{ item[0] }}.d/{{ item[2].key }}{{ item[1] }}"
state: absent
with_nested:
- [["sources.list", ".list"], ["preferences", ""]]
- "{{ apt.pin|dict2items }}"
- name: Update APT cache
apt:
update_cache: true
# APT-List Changes : send email with changelog
- include_tasks: apt-listchanges.yml
# APT Unattended upgrades
- include_tasks: apt-unattended.yml

View File

@@ -0,0 +1,4 @@
{{ ansible_header | comment }}
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

View File

@@ -0,0 +1,175 @@
{{ ansible_header | comment }}
// Unattended-Upgrade::Origins-Pattern controls which packages are
// upgraded.
//
// Lines below have the format "keyword=value,...". A
// package will be upgraded only if the values in its metadata match
// all the supplied keywords in a line. (In other words, omitted
// keywords are wild cards.) The keywords originate from the Release
// file, but several aliases are accepted. The accepted keywords are:
// a,archive,suite (eg, "stable")
// c,component (eg, "main", "contrib", "non-free")
// l,label (eg, "Debian", "Debian-Security")
// o,origin (eg, "Debian", "Unofficial Multimedia Packages")
// n,codename (eg, "jessie", "jessie-updates")
// site (eg, "http.debian.net")
// The available values on the system are printed by the command
// "apt-cache policy", and can be debugged by running
// "unattended-upgrades -d" and looking at the log file.
//
// Within lines unattended-upgrades allows 2 macros whose values are
// derived from /etc/debian_version:
// ${distro_id} Installed origin.
// ${distro_codename} Installed codename (eg, "buster")
Unattended-Upgrade::Origins-Pattern {
// Codename based matching:
// This will follow the migration of a release through different
// archives (e.g. from testing to stable and later oldstable).
// Software will be the latest available for the named release,
// but the Debian release itself will not be automatically upgraded.
"origin=Debian,codename=${distro_codename},label=Debian";
"origin=Debian,codename=${distro_codename}-updates";
"origin=Debian,codename=${distro_codename}-proposed-updates";
"origin=Debian,codename=${distro_codename},label=Debian-Security";
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
"origin=Debian Backports,codename=${distro_codename}-backports,label=Debian Backports"
// Archive or Suite based matching:
// Note that this will silently match a different release after
// migration to the specified archive (e.g. testing becomes the
// new stable).
// "o=Debian,a=stable";
// "o=Debian,a=stable-updates";
// "o=Debian,a=proposed-updates";
// "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports";
};
// Python regular expressions, matching packages to exclude from upgrading
Unattended-Upgrade::Package-Blacklist {
// The following matches all packages starting with linux-
// "linux-";
// Use $ to explicitely define the end of a package name. Without
// the $, "libc6" would match all of them.
// "libc6$";
// "libc6-dev$";
// "libc6-i686$";
// Special characters need escaping
// "libstdc\+\+6$";
// The following matches packages like xen-system-amd64, xen-utils-4.1,
// xenstore-utils and libxenstore3.0
// "(lib)?xen(store)?";
// For more information about Python regular expressions, see
// https://docs.python.org/3/howto/regex.html
};
// This option allows you to control if on a unclean dpkg exit
// unattended-upgrades will automatically run
// dpkg --force-confold --configure -a
// The default is true, to ensure updates keep getting installed
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
// Split the upgrade into the smallest possible chunks so that
// they can be interrupted with SIGTERM. This makes the upgrade
// a bit slower but it has the benefit that shutdown while a upgrade
// is running is possible (with a small delay)
//Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::MinimalSteps "true";
// Install all updates when the machine is shutting down
// instead of doing it in the background while the machine is running.
// This will (obviously) make shutdown slower.
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
// This allows more time for unattended-upgrades to shut down gracefully
// or even install a few packages in InstallOnShutdown mode, but is still a
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
// Users enabling InstallOnShutdown mode are advised to increase
// InhibitDelayMaxSec even further, possibly to 30 minutes.
//Unattended-Upgrade::InstallOnShutdown "false";
// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
//Unattended-Upgrade::Mail "";
Unattended-Upgrade::Mail "{{ apt.monitoring_mail }}";
// Set this value to one of:
// "always", "only-on-error" or "on-change"
// If this is not set, then any legacy MailOnlyOnError (boolean) value
// is used to chose between "only-on-error" and "on-change"
//Unattended-Upgrade::MailReport "on-change";
// Remove unused automatically installed kernel-related packages
// (kernel images, kernel headers and kernel version locked tools).
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
// Do automatic removal of newly unused dependencies after the upgrade
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Do automatic removal of unused packages after the upgrade
// (equivalent to apt-get autoremove)
//Unattended-Upgrade::Remove-Unused-Dependencies "false";
Unattended-Upgrade::Remove-Unused-Dependencies "false";
// Automatically reboot *WITHOUT CONFIRMATION* if
// the file /var/run/reboot-required is found after the upgrade
//Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot "true";
// Automatically reboot even if there are users currently logged in
// when Unattended-Upgrade::Automatic-Reboot is set to true
//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
// Default: "now"
//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
//Acquire::http::Dl-Limit "70";
// Enable logging to syslog. Default is False
// Unattended-Upgrade::SyslogEnable "false";
Unattended-Upgrade::SyslogEnable "true";
// Specify syslog facility. Default is daemon
// Unattended-Upgrade::SyslogFacility "daemon";
// Download and install upgrades only on AC power
// (i.e. skip or gracefully stop updates on battery)
// Unattended-Upgrade::OnlyOnACPower "true";
// Download and install upgrades only on non-metered connection
// (i.e. skip or gracefully stop updates on a metered connection)
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
// Verbose logging
// Unattended-Upgrade::Verbose "false";
// Print debugging information both in unattended-upgrades and
// in unattended-upgrade-shutdown
// Unattended-Upgrade::Debug "false";
// Allow package downgrade if Pin-Priority exceeds 1000
// Unattended-Upgrade::Allow-downgrade "false";
// When APT fails to mark a package to be upgraded or installed try adjusting
// candidates of related packages to help APT's resolver in finding a solution
// where the package can be upgraded or installed.
// This is a workaround until APT's resolver is fixed to always find a
// solution if it exists. (See Debian bug #711128.)
// The fallback is enabled by default, except on Debian's sid release because
// uninstallable packages are frequent there.
// Disabling the fallback speeds up unattended-upgrades when there are
// uninstallable packages at the expense of rarely keeping back packages which
// could be upgraded or installed.
// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";

View File

@@ -1,11 +1,8 @@
{{ ansible_header | comment }}
{% if ansible_distribution_release != "bullseye" %}
{# Debian security does not exist yet for bullseye #}
# Mises à jour de sécurité
deb {{ apt.mirror }}debian-security {{ ansible_distribution_release }}/updates main contrib non-free
deb {{ apt.mirror }}debian-security {{ ansible_distribution_release }}-security main contrib non-free
{% endif %}
# Dépôt classique
deb {{ apt.mirror }}debian {{ ansible_distribution_release }} main contrib non-free

View File

@@ -1,11 +0,0 @@
---
- name: Queries package manager for audio installation
package:
name:
- alsa-utils
- pulseaudio
- pulsemixer
register: pkg_result
retries: 3
until: pkg_result is succeeded

View File

@@ -1,9 +0,0 @@
---
- name: Queries package manager for browser installation
package:
name:
- firefox
- firefox-i18n-fr
register: pkg_result
retries: 3
until: pkg_result is succeeded

View File

@@ -1,48 +1,26 @@
---
- name: Install cli utilities
- name: Install useful utilities
package:
name:
- bash
- bash-completion
- bat
- curl
- "{% if ansible_os_family == 'Debian' %}dnsutils{% else %}bind-tools{% endif %}"
- dnsutils
- git
- man
- "mtr{% if ansible_os_family == 'Debian' %}-tiny{% endif %}"
- sl
- htop
- man
- molly-guard
- mtr-tiny
- needrestart
- patch
- rsync
- sl
- sudo
- tmux
- traceroute
- tree
- vim
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Create directory hierarchy
file:
path: '.config/{{ item }}'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0755
with_items:
- 'git/'
- 'bash/'
become_user: "{{ user.name }}"
- name: Deploying config files
template:
src: '{{ item.src }}'
dest: '{{ item.dest }}'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0644
with_items:
- { src: bashrc.j2, dest: .bashrc }
- { src: inputrc.j2, dest: .inputrc }
- { src: bash_aliases.j2, dest: .config/bash/bash_aliases }
- { src: gitconfig.j2, dest: .config/git/config }
- { src: tmux.conf.j2, dest: .tmux.conf }
become_user: '{{ user.name }}'

View File

@@ -1,56 +0,0 @@
#!/bin/bash
{{ ansible_header | comment }}
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
alias grep='grep --color=always'
alias fgrep='fgrep --color=always'
alias egrep='egrep --color=always'
fi
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias cd='cd -P'
alias ip='ip -c'
alias less='less -R'
{% if ansible_os_family == "Archlinux" -%}
alias startx='exec startx'
{% endif %}
alias gst='git status -s'
alias proxy='ssh -q -C -N -D 8080'
alias wip='watch -c ip -c'
# Shortcuts to open ports
alias ldap_tealc="ssh -L 1636:tealc.adm.crans.org:636 tealc.adm.crans.org"
alias sam="ssh -L 8006:sam.adm.crans.org:8006 sam.adm.crans.org"
alias jack="ssh -L 8006:jack.adm.crans.org:8006 jack.adm.crans.org"
alias daniel="ssh -L 8006:daniel.adm.crans.org:8006 daniel.adm.crans.org"
alias vi=vim
{% if ansible_os_family == "Debian" -%}
alias bat=batcat
{% endif -%}
alias cat=bat
# Add some emoji aliases
alias 🦇=bat
alias 🐈=cat
alias 🚆=sl
alias 🚂=sl
alias 🚅=sl
alias 💿=cd
{% if ansible_os_family == "Archlinux" -%}
{# Personal computer #}
alias 🐿️="cd /home/ynerant/PycharmProjects/SquirrelBattle && venv/bin/python main.py"
{% endif -%}

View File

@@ -1,59 +0,0 @@
{{ ansible_header | comment }}
[ -z "$PS1" ] && return
HISTCONTROL=ignoredups:ignorespace
HISTFILE=/dev/null
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe.sh ] && eval "$(SHELL=/bin/sh lesspipe.sh)"
PROMPT_COMMAND=__prompt
__prompt() {
retline=$?
gitline=$(git branch 2> /dev/null | grep '^*' | awk '{print $2}')
# COLORS
RED='\[\e[01;31m\]'
GREEN='\[\e[01;32m\]'
ORANGE='\[\e[01;33m\]'
BLUE='\[\e[01;34m\]'
NC='\[\e[0m\]'
PS1=""
PS1+="$GREEN\u@\h$NC" # user@host
PS1+=" $BLUE\W$NC" # pwd
[ -z $gitline ] || PS1+=" $ORANGE$gitline$NC"
PS1="[ $PS1 ]"
[ $retline -ne 0 ] && PS1+=" $RED$retline$NC "
PS1+="\$ "
return $ret
}
if [ -f ~/.config/bash/bash_aliases ]; then
. ~/.config/bash/bash_aliases
fi
rm -rf {{ cliutils.bash.bogus_dirs | join(" ") }}
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
fi
export XDG_CONFIG_HOME=~/.config/
grep -q '/\.local/bin'<<<$PATH || export PATH=$PATH:~/.local/bin/
## REMOVING LESSHST
LESSHISTFILE=/dev/null
export EDITOR='vim'
export PASSWORD_STORE_ENABLE_EXTENSIONS=true

View File

@@ -1,15 +0,0 @@
{{ ansible_header | comment }}
[user]
email = {{ cliutils.git.email }}
name = {{ cliutils.git.name }}
signingkey = {{ cliutils.git.signingkey }}
[commit]
gpgsign = true
[core]
autocrlf = input
editor = vim
[format]
signoff = true
[pull]
ff = only

View File

@@ -1,3 +0,0 @@
{{ ansible_header | comment }}
set mark-symlinked-directories on

View File

@@ -1,34 +0,0 @@
{{ ansible_header | comment }}
unbind r
bind r source-file ~/.tmux.conf
set -g mouse on
## set the default TERM
set -g default-terminal screen
## update the TERM variable of terminal emulator when creating a new session or attaching a existing session
set -g update-environment 'DISPLAY SSH_ASKPASS SSH_AGENT_PID SSH_CONNECTION WINDOWID XAUTHORITY TERM'
## determine if we should enable 256-colour support
if "[[ ${TERM} =~ 256color || ${TERM} == fbterm ]]" 'set -g default-terminal screen-256color'
# use the vim motion keys to move between panes
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
setw -g mode-keys vi
bind < resize-pane -L 10
bind > resize-pane -R 10
bind - resize-pane -D 10
bind + resize-pane -U 10
bind-key -T copy-mode-vi 'v' send -X begin-selection;
bind-key -T copy-mode-vi 'V' send -X select-line;
bind-key -T copy-mode-vi 'r' send -X rectangle-toggle;
bind-key -T copy-mode-vi 'y' send -X copy-pipe-and-cancel 'xclip -in -selection clipboard'
set -g base-index 1
set -g status-bg colour41

View File

@@ -1,51 +0,0 @@
---
- name: Queries package manager for communication installation
package:
name:
- discord
- element-desktop
- evolution
- gnome-keyring
- gnome-themes-extra
- lxappearance
- seahorse
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Create lxappearance directory hierarchy
file:
path: '{{ item }}'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0700
with_items:
- '.config/gtk-3.0/'
- '.icons/default/'
become_user: '{{ user.name }}'
- name: Enable dark mode for evolution
template:
src: '{{ item.src }}'
dest: '{{ item.dest }}'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0644
with_items:
- { src: 'gtkrc.j2', dest: '.gtkrc-2.0' }
- { src: 'settings.ini.j2', dest: '.config/gtk-3.0/settings.ini' }
- { src: 'index.theme.j2', dest: '.icons/default/index.theme'}
become_user: '{{ user.name }}'
- name: Create evolution config and cache parent directories
file:
path: '{{ item }}'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0700
with_items:
- '.config/'
- '.local/share/'
become_user: '{{ user.name }}'

View File

@@ -1,20 +0,0 @@
{{ ansible_header | comment }}
# DO NOT EDIT! This file will be overwritten by LXAppearance.
# Any customization should be done in ~/.gtkrc-2.0.mine instead.
include "/home/ynerant/.gtkrc-2.0.mine"
gtk-theme-name="Adwaita-dark"
gtk-icon-theme-name="Adwaita"
gtk-cursor-theme-name="Adwaita"
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_TEXT
gtk-toolbar-icon-size=GTK_ICON_SIZE_SMALL_TOOLBAR
gtk-button-images=0
gtk-menu-images=0
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=0
gtk-xft-hintstyle="hintnone"
gtk-xft-rgba="none"

View File

@@ -1,6 +0,0 @@
{{ ansible_header | comment }}
[Icon Theme]
Name=Default
Comment=Default Cursor Theme
Inherits=Adwaita

View File

@@ -1,17 +0,0 @@
{{ ansible_header | comment }}
[Settings]
gtk-theme-name=Adwaita
gtk-icon-theme-name=Adwaita
gtk-cursor-theme-name=Adwaita
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_TEXT
gtk-toolbar-icon-size=GTK_ICON_SIZE_SMALL_TOOLBAR
gtk-button-images=0
gtk-menu-images=0
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=0
gtk-xft-hintstyle=hintnone
gtk-xft-rgba=none

View File

@@ -0,0 +1,5 @@
---
- name: Restart grafana
service:
name: grafana-server
state: restarted

View File

@@ -0,0 +1,100 @@
---
- name: Install GPG
apt:
name: gnupg
state: present
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Import Grafana GPG signing key
apt_key:
url: https://packages.grafana.com/gpg.key
state: present
validate_certs: false
register: apt_key_result
retries: 3
until: apt_key_result is succeeded
- name: Add Grafana repository
apt_repository:
repo: deb http://mirror.adm.ynerant.fr/grafana/oss/deb stable main
state: present
update_cache: true
- name: Install Grafana
apt:
name: grafana
state: present
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Configure Grafana
ini_file:
path: /etc/grafana/grafana.ini
section: "{{ item.section }}"
option: "{{ item.option }}"
value: "{{ item.value }}"
mode: 0640
loop:
- section: server
option: root_url
value: "{{ grafana.root_url }}"
- section: analytics
option: reporting_enabled
value: "false"
- section: analytics
option: check_for_updates
value: "false"
- section: security
option: disable_initial_admin_creation
value: "true"
- section: security
option: cookie_secure
value: "true"
- section: snapshots
option: external_enabled
value: "false"
- section: users
option: allow_sign_up
value: "false"
- section: users
option: allow_org_create
value: "false"
- section: auth.anonymous
option: enabled
value: "true"
- section: auth.anonymous
option: hide_version
value: "true"
- section: auth.basic # Only LDAP auth
option: enabled
value: "false"
- section: auth.ldap
option: enabled
value: "true"
- section: alerting
option: enabled
value: "false"
notify: Restart grafana
- name: Configure Grafana LDAP
template:
src: ldap.toml.j2
dest: /etc/grafana/ldap.toml
mode: 0640
notify: Restart grafana
- name: Enable and start Grafana
systemd:
name: grafana-server
enabled: true
state: started
daemon_reload: true
- name: Indicate role in motd
template:
src: update-motd.d/05-service.j2
dest: /etc/update-motd.d/05-grafana
mode: 0755

View File

@@ -0,0 +1,47 @@
{{ ansible_header | comment }}
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
# [log]
# filters = ldap:debug
[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "{{ grafana.ldap_master_ipv4 }}"
# Default port is 389 or 636 if use_ssl = true
port = 636
# Set to true if ldap server supports TLS
use_ssl = true
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = false
# set to true if you want to skip ssl cert validation
ssl_skip_verify = true
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert = "/path/to/certificate.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert = "/path/to/client.crt"
# client_key = "/path/to/client.key"
# Use direct bind
bind_dn = "uid=%s,{{ grafana.ldap_user_tree }}"
# Useless as we are doing direct bind,
# but without LDAP auth hang
search_filter = "(uid=%s)"
search_base_dns = ["ou=passwd,dc=ynerant,dc=fr"]
## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
group_search_base_dns = ["ou=group,{{ grafana.ldap_base }}"]
group_search_filter_user_attribute = "cn"
# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "uid"
email = "mail"
# All LDAP members can edit
[[servers.group_mappings]]
group_dn = "*"
org_role = "Admin"

View File

@@ -0,0 +1,3 @@
#!/usr/bin/tail +14
{{ ansible_header | comment }}
> grafana a été déployé sur cette machine. Voir /etc/grafana/.

View File

@@ -1,35 +0,0 @@
---
- name: Queries package manager for graphical instalation
package:
name:
- i3-wm
- i3blocks
- i3status
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Create i3 configuration folder hierarchy
file:
path: '.config/{{ item }}'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0755
with_items:
- i3/
- i3status/
become_user: '{{ user.name }}'
- name: Copy i3 configuration files
template:
src: '{{ item }}.j2'
dest: '.config/{{ item }}/config'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0755
with_items:
- i3
- i3status
become_user: '{{ user.name }}'

View File

@@ -1,241 +0,0 @@
{{ ansible_header | comment }}
# This file has been auto-generated by i3-config-wizard(1).
# It will not be overwritten, so edit it as you like.
#
# Should you change your keyboard layout some time, delete
# this file and re-run i3-config-wizard(1).
#
# i3 config file (v4)
#
# Please see https://i3wm.org/docs/userguide.html for a complete reference!
exec /home/ynerant/.fehbg
exec dunst
exec nm-applet
exec battery
exec mpd
exec mpd_reader
{% if laptop.numpad %}
exec numlockx
{% endif %}
set $mod Mod4
set $refresh killall -SIGUSR1 i3status
floating_modifier $mod
# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
font pango:monospace 8
# Center window title and remove edges from windows
title_align center
hide_edge_borders both
# Bindings for volume and light
bindsym XF86MonBrightnessDown exec light -U 1
bindsym XF86MonBrightnessUp exec light -A 1
bindsym XF86AudioRaiseVolume exec volume -A 5 && $refresh
bindsym XF86AudioLowerVolume exec volume -U 5 && $refresh
bindsym Shift+XF86MonBrightnessDown exec light -U 1
bindsym Shift+XF86MonBrightnessUp exec light -A 1
bindsym Shift+XF86AudioRaiseVolume exec volume -A 1 && $refresh
bindsym Shift+XF86AudioLowerVolume exec volume -U 1 && $refresh
bindsym XF86AudioMute exec volume -T && $refresh
bindsym XF86AudioMicMute exec volume -M && $refresh
{% if not laptop.numpad %}
# Binding for mpd
bindsym KP_Add exec mpc next && $refresh
bindsym KP_Subtract exec mpc prev && $refresh
bindsym KP_Multiply exec mpc toggle && $refresh
bindsym $mod+F3 exec mpc volume +5
bindsym $mod+F2 exec mpc volume -5
{% endif %}
# Binding to toggle mouse tapping
bindsym XF86TouchpadToggle exec mouse_tap toggle
# start a terminal
bindsym $mod+Return exec xfce4-terminal -x tmux
bindsym $mod+Shift+Return exec xfce4-terminal
# kill focused window
bindsym $mod+Shift+q kill
# start dmenu (a program launcher)
bindsym $mod+d exec dmenu_run -l 1 -p '[ ynerant@morgoth ~ ]'
bindsym XF86Search exec dmenu_run -l 1
# Launch passmenu
bindsym $mod+t exec passmenu
# Screenshots
bindsym --release Print exec screenshot
bindsym --release Control+Print exec screenshot -c
bindsym --release Shift+Print exec screenshot -s
bindsym --release Control+Shift+Print exec screenshot -s -c
# Binding to lock screen
bindsym $mod+Escape exec physlock
# alternatively, you can use the cursor keys:
bindsym $mod+Left focus left
bindsym $mod+h focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right
bindsym $mod+l focus right
# Move through output
bindsym $mod+j focus output down
bindsym $mod+k focus output up
# alternatively, you can use the cursor keys:
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+h move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right
bindsym $mod+Shift+l move right
# Move workspace between output
bindsym $mod+Shift+j move workspace to output down
bindsym $mod+Shift+k move workspace to output up
# split in horizontal orientation
bindsym $mod+s split h
# split in vertical orientation
bindsym $mod+v split v
# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle
# change container layout (stacked, tabbed, toggle split)
bindsym $mod+w layout tabbed
bindsym $mod+e layout toggle split
# focus the parent container
bindsym $mod+a focus parent
# focus the child container
bindsym $mod+y focus child
# Define names for default workspaces for which we configure key bindings later on.
# We use variables to avoid repeating the names in multiple places.
set $ws0 "0"
set $ws1 "1"
set $ws2 "2"
set $ws3 "3"
set $ws4 "4"
set $ws5 "5"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"
# Screen workspace
workspace $ws0 output eDP-1
workspace $ws1 output eDP-1
workspace $ws2 output eDP-1
workspace $ws3 output eDP-1
workspace $ws4 output eDP-1
workspace $ws5 output eDP-1
workspace $ws6 output eDP-1
workspace $ws7 output eDP-1
workspace $ws8 output eDP-1
workspace $ws9 output eDP-1
workspace $ws10 output eDP-1
# switch to workspace
bindsym $mod+0xb2 workspace $ws0
bindsym $mod+1 workspace $ws1
bindsym $mod+2 workspace $ws2
bindsym $mod+3 workspace $ws3
bindsym $mod+4 workspace $ws4
bindsym $mod+5 workspace $ws5
bindsym $mod+6 workspace $ws6
bindsym $mod+7 workspace $ws7
bindsym $mod+8 workspace $ws8
bindsym $mod+9 workspace $ws9
bindsym $mod+0 workspace $ws10
# move focused container to workspace
bindsym $mod+Shift+0xb2 move container to workspace $ws0
bindsym $mod+Shift+1 move container to workspace $ws1
bindsym $mod+Shift+2 move container to workspace $ws2
bindsym $mod+Shift+3 move container to workspace $ws3
bindsym $mod+Shift+4 move container to workspace $ws4
bindsym $mod+Shift+5 move container to workspace $ws5
bindsym $mod+Shift+6 move container to workspace $ws6
bindsym $mod+Shift+7 move container to workspace $ws7
bindsym $mod+Shift+8 move container to workspace $ws8
bindsym $mod+Shift+9 move container to workspace $ws9
bindsym $mod+Shift+0 move container to workspace $ws10
# Leave fullscreen on new window
popup_during_fullscreen leave_fullscreen
# Cycle through workspace
bindsym $mod+Tab workspace next_on_output
bindsym $mod+Shift+Tab workspace prev_on_output
# Dont focus discord (for thunderbird passwd)
no_focus [class="(?i)discord"]
# reload the configuration file
bindsym $mod+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym $mod+Shift+r restart
# exit i3 (logs you out of your X session)
bindsym $mod+Shift+e exec "i3-msg exit"
# resize window (you can also use the mouse for that)
mode "resize" {
bindsym Left resize shrink width 1 px or 1 ppt
bindsym Down resize grow height 1 px or 1 ppt
bindsym Up resize shrink height 1 px or 1 ppt
bindsym Right resize grow width 1 px or 1 ppt
# back to normal: Enter or Escape or $mod+r
bindsym Return mode "default"
bindsym Escape mode "default"
bindsym $mod+r mode "default"
}
bindsym $mod+r mode "resize"
# Window thickness
new_window 1pixel
# Toogle bar-1 visibility
bindsym $mod+x bar mode invisible bar-1
bindsym $mod+Shift+x bar mode toggle bar-1
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
bar {
output eDP-1
tray_output eDP-1
mode hide
status_command i3status
strip_workspace_numbers yes
}
bar {
output HDMI-2
mode hide
status_command i3status
strip_workspace_numbers yes
}
{% if laptop.touchscreen %}
exec xinput --set-prop 14 "libinput Natural Scrolling Enabled" 1
{% endif %}

View File

@@ -1,63 +0,0 @@
{{ ansible_header | comment }}
# i3status configuration file.
# see "man i3status" for documentation.
# It is important that this file is edited as UTF-8.
# The following line should contain a sharp s:
# ß
# If the above line is not correctly displayed, fix your editor first!
general {
output_format="i3bar"
colors = true
interval = 1
}
# order += "ipv6"
order += "read_file mpd"
order += "volume master"
order+= "ipv6"
order += "wireless _first_"
order += "ethernet _first_"
order += "battery all"
order += "tztime local"
ipv6 {
format_up = "IPV6: %ip"
format_down = ""
}
wireless _first_ {
format_up = "W:%essid, %ip"
format_down = ""
}
ethernet _first_ {
format_up = "E: %ip, %speed"
format_down = ""
}
battery all {
format = "%status %percentage %remaining"
last_full_capacity = true
color_good="#00FFFF"
color_bad="#00FFFF"
}
tztime local {
format = "%d-%m %H:%M:%S"
}
volume master {
format = "♪: %volume"
format_muted = "♪: muted (%volume)"
device = "pulse"
}
read_file mpd {
path = "/tmp/mpd.current"
color_good = "#00FF99"
format_bad = ""
}

View File

@@ -1,27 +0,0 @@
---
- name: Queries package manager to install xdg
package:
name: xdg-utils
register: pkg_result
retries: 3
until: pkg_result is succeeded
become: yes
- name: Create default applications config folder
file:
path: '.config/'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0700
become_user: '{{ user.name }}'
- name: Install default applications configuration file
template:
src: 'mimeapps.list.j2'
dest: '.config/mimeapps.list'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0644
become_user: '{{ user.name }}'

View File

@@ -1,17 +0,0 @@
{{ ansible_header | comment }}
[Default Applications]
text/html=firefox.desktop
x-scheme-handler/http=firefox.desktop
x-scheme-handler/https=firefox.desktop
x-scheme-handler/ftp=firefox.desktop
x-scheme-handler/about=firefox.desktop
x-scheme-handler/unknown=firefox.desktop
application/x-extension-htm=firefox.desktop
application/x-extension-html=firefox.desktop
application/x-extension-shtml=firefox.desktop
application/xhtml+xml=firefox.desktop
application/x-extension-xhtml=firefox.desktop
application/x-extension-xht=firefox.desktop
application/pdf=org.pwmt.zathura.desktop

View File

@@ -1,38 +0,0 @@
---
- name: Queries package manager for multimedia installation
package:
name:
- feh
- mpv
- obs-studio
- vlc
- zathura
- zathura-pdf-poppler
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Create multimedia folder hierarchy
file:
path: '.config/{{ item }}'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0700
with_items :
- 'mpv/'
- 'zathura/'
become_user: '{{ user.name }}'
- name: Copy multimedia configuration files
template:
src: '{{ item.src }}'
dest: '.config/{{ item.dest }}'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0644
with_items:
- { src: 'zathurarc.j2', dest: 'zathura/zathurarc' }
- { src: 'mpv.conf.j2', dest: 'mpv/mpv.conf' }
become_user: '{{ user.name }}'

View File

@@ -1,30 +0,0 @@
{{ ansible_header | comment }}
##################
# video settings #
##################
# force starting with centered window
geometry=50%:50%
# no window title bar
no-border
##################
# audio settings #
##################
# Specify pulse audio as audio output
ao=pulse
##################
# other settings #
##################
# Display English subtitles if available.
slang=fr,en
# Play Finnish audio if available, fall back to English otherwise.
alang=fr,en
force-window=yes

View File

@@ -1,3 +0,0 @@
{{ ansible_header | comment }}
set selection-clipboard clipboard

View File

@@ -0,0 +1,28 @@
---
- name: Install vlan support
apt:
update_cache: true
name: vlan
state: present
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Deploy default interfaces config
template:
src: network/interfaces.j2
dest: /etc/network/interfaces
mode: 0644
- name: Remove cloud-init interface configuration
file:
path: /etc/network/interfaces.d/50-cloud-init
state: absent
- name: Deploy interfaces config
template:
src: "network/interfaces.d/ifalias.j2"
dest: "/etc/network/interfaces.d/{{ '%02d' | format(item.id) }}-{{ item.name | replace('_', '-') }}"
mode: 0644
when: item.name in interfaces
loop: "{{ network_interfaces.vlan }}"

View File

@@ -0,0 +1,55 @@
{{ ansible_header | comment }}
{% set vlan_name = (item.name | replace('_', '-')) %}
{% set subnet_network = (query('ldap', 'network', vlan_name) | ipaddr('network')) %}
{% set subnet_netmask = (query('ldap', 'network', vlan_name) | ipaddr('netmask')) %}
{% set ips = query('ldap', 'ip', ansible_hostname, vlan_name) %}
{% if (ips | ipv4 | length) > 0 %}
auto {{ interfaces[item.name] }}
iface {{ interfaces[item.name] }} inet static
{% for ip in (ips | ipv4) %}
address {{ ip }}
{% endfor %}
network {{ subnet_network }}
netmask {{ subnet_netmask }}
{% if item.gateway is defined and item.gateway not in (ips | ipv4) %}
gateway {{ item.gateway }}
{% endif %}
{% if item.metric is defined %}
metric {{ item.metric }}
{% endif %}
{% if item.dns is defined %}
dns-nameservers {{ item.dns }}
{% endif %}
{% if vlan_name == 'srv' %}
dns-search ynerant.fr
{% else %}
dns-search {{ vlan_name }}.ynerant.fr
{% endif %}
up /sbin/ip link set $IFACE alias {{ vlan_name }}
{% if ansible_local.interfaces.sup_if_4 is defined %}
{% if interfaces[item.name] in ansible_local.interfaces.sup_if_4 %}
{% for line in ansible_local.interfaces.sup_if_4[interfaces[item.name]] %}
{{ line }}
{% endfor %}
{% endif %}
{% endif %}
{% endif %}
{% if (ips | ipv6 | length) > 0 %}
iface {{ interfaces[item.name] }} inet6 static
{% for ip in (ips | ipv6) %}
address {{ ip }}/64
{% endfor %}
{% if item.gateway_v6 is defined and item.gateway_v6 not in (ips | ipv6) %}
gateway {{ item.gateway_v6 }}
{% endif %}
accept_ra 0
{% if ansible_local.interfaces.sup_if_6 is defined %}
{% if interfaces[item.name] in ansible_local.interfaces.sup_if_6 %}
{% for line in ansible_local.interfaces.sup_if_6[interfaces[item.name]] %}
{{ line }}
{% endfor %}
{% endif %}
{% endif %}
{% endif %}

View File

@@ -0,0 +1,10 @@
{{ ansible_header | comment }}
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback

View File

@@ -0,0 +1,48 @@
---
- name: Install python3 IRC library
apt:
name: python3-irc
state: present
update_cache: true
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Install Flask for python3
apt:
name: python3-flask
state: present
update_cache: true
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Clone NinjaBot code
git:
repo: https://gitlab.crans.org/nounous/NinjaBot.git
dest: /var/local/ninjabot
version: master
- name: Deploy NinjaBot configuration
template:
src: ninjabot/ninjabot.json.j2
dest: /var/local/ninjabot/ninjabot.json
- name: Deploy NinjaBot systemd unit
template:
src: systemd/system/ninjabot.service.j2
dest: /etc/systemd/system/ninjabot.service
mode: 0644
- name: Load and activate NinjaBot service
systemd:
name: ninjabot
daemon_reload: true
enabled: true
state: started
- name: Indicate NinjaBot in motd
template:
src: update-motd.d/05-service.j2
dest: /etc/update-motd.d/05-ninjabot
mode: 0755

View File

@@ -0,0 +1 @@
{{ ninjabot.config | to_nice_json(indent=2) }}

View File

@@ -0,0 +1,15 @@
{{ ansible_header | comment }}
[Unit]
Description=NinjaBot IRC bot
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/local/ninjabot
User=nobody
Group=nogroup
ExecStart=/usr/bin/python3 /var/local/ninjabot/ninjabot.py
Restart=always
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,3 @@
#!/usr/bin/tail +14
{{ ansible_header | comment }}
> NinjaBot a été déployé sur cette machine. Voir /var/local/ninjabot/.

View File

@@ -1,30 +0,0 @@
---
- name: Queries package manager for notification installation
package:
name:
- dunst
- gnome-icon-theme
- gnome-icon-theme-extras
- gnome-icon-theme-symbolic
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Create dunst config directory
file:
path: '.config/dunst/'
state: directory
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0755
become_user: '{{ user.name }}'
- name: Copy dunst configuration file
template:
src: 'dunstrc.j2'
dest: '.config/dunst/dunstrc'
owner: '{{ user.name }}'
group: '{{ user.name }}'
mode: 0644
become_user: '{{ user.name }}'

View File

@@ -1,294 +0,0 @@
{{ ansible_header | comment }}
[global]
### Display ###
# Which monitor should the notifications be displayed on.
monitor = 0
# Display notification on focused monitor. Possible modes are:
# mouse: follow mouse pointer
# keyboard: follow window with keyboard focus
# none: don't follow anything
#
# "keyboard" needs a window manager that exports the
# _NET_ACTIVE_WINDOW property.
# This should be the case for almost all modern window managers.
#
# If this option is set to mouse or keyboard, the monitor option
# will be ignored.
follow = none
# The geometry of the window:
# [{width}]x{height}[+/-{x}+/-{y}]
# The geometry of the message window.
# The height is measured in number of notifications everything else
# in pixels. If the width is omitted but the height is given
# ("-geometry x2"), the message window expands over the whole screen
# (dmenu-like). If width is 0, the window expands to the longest
# message displayed. A positive x is measured from the left, a
# negative from the right side of the screen. Y is measured from
# the top and down respectively.
# The width can be negative. In this case the actual width is the
# screen width minus the width defined in within the geometry option.
geometry = "300x5-30+20"
# Show how many messages are currently hidden (because of geometry).
indicate_hidden = yes
# Shrink window if it's smaller than the width. Will be ignored if
# width is 0.
shrink = no
# The transparency of the window. Range: [0; 100].
# This option will only work if a compositing window manager is
# present (e.g. xcompmgr, compiz, etc.).
transparency = 0
# The height of the entire notification. If the height is smaller
# than the font height and padding combined, it will be raised
# to the font height and padding.
notification_height = 0
# Draw a line of "separator_height" pixel height between two
# notifications.
# Set to 0 to disable.
separator_height = 2
# Padding between text and separator.
padding = 8
# Horizontal padding.
horizontal_padding = 8
# Defines width in pixels of frame around the notification window.
# Set to 0 to disable.
frame_width = 3
# Defines color of the frame around the notification window.
frame_color = "#aaaaaa"
# Define a color for the separator.
# possible values are:
# * auto: dunst tries to find a color fitting to the background;
# * foreground: use the same color as the foreground;
# * frame: use the same color as the frame;
# * anything else will be interpreted as a X color.
separator_color = frame
# Sort messages by urgency.
sort = yes
# Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds.
# Set to 0 to disable.
# A client can set the 'transient' hint to bypass this. See the rules
# section for how to disable this if necessary
idle_threshold = 120
### Text ###
font = Monospace 9
# The spacing between lines. If the height is smaller than the
# font height, it will get raised to the font height.
line_height = 0
# Possible values are:
# full: Allow a small subset of html markup in notifications:
# <b>bold</b>
# <i>italic</i>
# <s>strikethrough</s>
# <u>underline</u>
#
# For a complete reference see
# <http://developer.gnome.org/pango/stable/PangoMarkupFormat.html>.
#
# strip: This setting is provided for compatibility with some broken
# clients that send markup even though it's not enabled on the
# server. Dunst will try to strip the markup but the parsing is
# simplistic so using this option outside of matching rules for
# specific applications *IS GREATLY DISCOURAGED*.
#
# no: Disable markup parsing, incoming notifications will be treated as
# plain text. Dunst will not advertise that it has the body-markup
# capability if this is set as a global setting.
#
# It's important to note that markup inside the format option will be parsed
# regardless of what this is set to.
markup = full
# The format of the message. Possible variables are:
# %a appname
# %s summary
# %b body
# %i iconname (including its path)
# %I iconname (without its path)
# %p progress value if set ([ 0%] to [100%]) or nothing
# %n progress value if set without any extra characters
# %% Literal %
# Markup is allowed
format = "<b>%s</b>\n%b"
# Alignment of message text.
# Possible values are "left", "center" and "right".
alignment = left
# Show age of message if message is older than show_age_threshold
# seconds.
# Set to -1 to disable.
show_age_threshold = 60
# Split notifications into multiple lines if they don't fit into
# geometry.
word_wrap = yes
# When word_wrap is set to no, specify where to make an ellipsis in long lines.
# Possible values are "start", "middle" and "end".
ellipsize = middle
# Ignore newlines '\n' in notifications.
ignore_newline = no
# Stack together notifications with the same content
stack_duplicates = true
# Hide the count of stacked notifications with the same content
hide_duplicate_count = false
# Display indicators for URLs (U) and actions (A).
show_indicators = yes
### Icons ###
# Align icons left/right/off
icon_position = left
# Scale larger icons down to this size, set to 0 to disable
max_icon_size = 32
# Paths to default icons.
icon_path = /usr/share/icons/gnome/32x32/status/:/usr/share/icons/gnome/32x32/devices/
### History ###
# Should a notification popped up from history be sticky or timeout
# as if it would normally do.
sticky_history = yes
# Maximum amount of notifications kept in history
history_length = 20
### Misc/Advanced ###
# dmenu path.
dmenu = /usr/bin/dmenu -p dunst:
# Browser for opening urls in context menu.
browser = /usr/bin/firefox -new-tab
# Always run rule-defined scripts, even if the notification is suppressed
always_run_script = true
# Define the title of the windows spawned by dunst
title = Dunst
# Define the class of the windows spawned by dunst
class = Dunst
# Print a notification on startup.
# This is mainly for error detection, since dbus (re-)starts dunst
# automatically after a crash.
startup_notification = false
# Manage dunst's desire for talking
# Can be one of the following values:
# crit: Critical features. Dunst aborts
# warn: Only non-fatal warnings
# mesg: Important Messages
# info: all unimportant stuff
# debug: all less than unimportant stuff
verbosity = mesg
# Define the corner radius of the notification window
# in pixel size. If the radius is 0, you have no rounded
# corners.
# The radius will be automatically lowered if it exceeds half of the
# notification height to avoid clipping text and/or icons.
corner_radius = 0
### Legacy
# Use the Xinerama extension instead of RandR for multi-monitor support.
# This setting is provided for compatibility with older nVidia drivers that
# do not support RandR and using it on systems that support RandR is highly
# discouraged.
#
# By enabling this setting dunst will not be able to detect when a monitor
# is connected or disconnected which might break follow mode if the screen
# layout changes.
force_xinerama = false
### mouse
# Defines action of mouse event
# Possible values are:
# * none: Don't do anything.
# * do_action: If the notification has exactly one action, or one is marked as default,
# invoke it. If there are multiple and no default, open the context menu.
# * close_current: Close current notification.
# * close_all: Close all notifications.
mouse_left_click = close_current
mouse_middle_click = do_action
mouse_right_click = close_all
# Experimental features that may or may not work correctly. Do not expect them
# to have a consistent behaviour across releases.
[experimental]
# Calculate the dpi to use on a per-monitor basis.
# If this setting is enabled the Xft.dpi value will be ignored and instead
# dunst will attempt to calculate an appropriate dpi value for each monitor
# using the resolution and physical size. This might be useful in setups
# where there are multiple screens with very different dpi values.
per_monitor_dpi = false
[shortcuts]
# Shortcuts are specified as [modifier+][modifier+]...key
# Available modifiers are "ctrl", "mod1" (the alt-key), "mod2",
# "mod3" and "mod4" (windows-key).
# Xev might be helpful to find names for keys.
# Close notification.
close = ctrl+space
# Close all notifications.
close_all = ctrl+shift+space
# Context menu.
context = ctrl+shift+period
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the "#" and following would be interpreted as a comment.
background = "#222222"
foreground = "#888888"
timeout = 10
# Icon for notifications with low urgency, uncomment to enable
#icon = /path/to/icon
[urgency_normal]
background = "#0091FF"
foreground = "#ffffff"
timeout = 10
# Icon for notifications with normal urgency, uncomment to enable
#icon = /path/to/icon
[urgency_critical]
background = "#900000"
foreground = "#ffffff"
frame_color = "#ff0000"
timeout = 0
# Icon for notifications with critical urgency, uncomment to enable
#icon = /path/to/icon

View File

@@ -1,7 +0,0 @@
---
- name: restart ntpd.service
service:
name: ntpd
state: restarted
become: true

View File

@@ -1,23 +0,0 @@
---
- name: Queries package manager for ntp installation
package:
name: ntp
register: pkg_result
retries: 3
until: pkg_result is succeeded
notify: restart ntpd.service
- name: Deploy ntp configuration
template:
src: 'ntp.conf.j2'
dest: '/etc/ntp.conf'
owner: root
group: root
mode: 0644
notify: restart ntpd.service
- name: Enable ntp service
service:
name: ntpd
enabled: yes

View File

@@ -1,27 +0,0 @@
{{ ansible_header | comment }}
# Please consider joining the pool:
#
# http://www.pool.ntp.org/join.html
#
# For additional information see:
# - https://wiki.archlinux.org/index.php/Network_Time_Protocol_daemon
# - http://support.ntp.org/bin/view/Support/GettingStarted
# - the ntp.conf man page
# Associate to Arch's NTP pool
server charybde.crans.org
server 0.fr.pool.ntp.org
server 1.fr.pool.ntp.org
server 2.fr.pool.ntp.org
server 3.fr.pool.ntp.org
# By default, the server allows:
# - all queries from the local host
# - only time queries from remote hosts, protected by rate limiting and kod
restrict default kod limited nomodify nopeer noquery notrap
restrict 127.0.0.1
restrict ::1
# Location of drift file
driftfile /var/lib/ntp/ntp.drift

View File

@@ -9,7 +9,7 @@
until: apt_result is succeeded
when: "'ntp_server' not in group_names"
- name: Install systemd-timesyncd (bullseye)
- name: Install systemd-timesyncd
apt:
name: systemd-timesyncd
update_cache: true
@@ -19,7 +19,6 @@
until: apt_result is succeeded
when:
- "'ntp_server' not in group_names"
- ansible_distribution_release == "bullseye"
- name: Configure NTP
template:

View File

@@ -0,0 +1,34 @@
---
- name: Install nullmailer
apt:
update_cache: true
name:
- nullmailer
- bsd-mailx
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Set nullmailer remotes
copy:
content: "{{ nullmailer.smtp_server }} smtp'\n"
dest: /etc/nullmailer/remotes
mode: 0644
- name: Set nullmailer adminaddr
copy:
content: "{{ nullmailer.root }}\n"
dest: /etc/nullmailer/adminaddr
mode: 0644
- name: Set nullmailer defaulthost
copy:
content: "{{ nullmailer.defaulthost }}\n"
dest: /etc/nullmailer/defaulthost
mode: 0644
- name: Set nullmailer allmailfrom
copy:
content: "{{ nullmailer.allmailfrom }}\n"
dest: /etc/nullmailer/allmailfrom
mode: 0644

View File

@@ -1,28 +0,0 @@
---
- name: Ensure pacman is installed
package:
name:
- pacman
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Use Crans mirror
template:
src: pacman.d/mirrorlist.j2
dest: /etc/pacman.d/mirrorlist
owner: root
group: root
mode: 0644
- name: Enable colors and sugar
lineinfile:
regex: "{{ item }}"
line: "{{ item }}"
insertafter: "[options]"
path: /etc/pacman.conf
loop:
- Color
- TotalDownload
- CheckSpace
- ILoveCandy

View File

@@ -1,4 +0,0 @@
{{ ansible_header | comment }}
Server = https://ftps.crans.org/archlinux/$repo/os/$arch
Server = http://mirror.crans.org/archlinux/$repo/os/$arch

View File

@@ -1,18 +0,0 @@
---
- name: Queries package manager to install pass
package:
name:
- jq
- git
- pass
register: pkg_result
retries: 3
until: pkg_result is succeeded
- name: Clone git pass repository
git:
repo: '{{ pass.upstream }}'
dest: '{{ pass.dest }}'
umask: '0066'
become_user: '{{ user.name }}'

View File

@@ -0,0 +1,5 @@
---
- name: Restart Prometheus Alertmanager
service:
name: prometheus-alertmanager
state: restarted

View File

@@ -0,0 +1,14 @@
---
- name: Install Prometheus Alertmanager
apt:
update_cache: true
name: prometheus-alertmanager
register: apt_result
retries: 3
until: apt_result is succeeded
- name: Configure Prometheus Alertmanager
template:
src: prometheus/alertmanager.yml.j2
dest: /etc/prometheus/alertmanager.yml
notify: Restart Prometheus Alertmanager

View File

@@ -0,0 +1,60 @@
{{ ansible_header | comment }}
# See https://prometheus.io/docs/alerting/configuration/ for documentation.
global:
# The smarthost and SMTP sender used for mail notifications.
smtp_smarthost: 'localhost:25'
smtp_from: 'alertmanager@example.org'
#smtp_auth_username: 'alertmanager'
#smtp_auth_password: 'password'
# The directory from which notification templates are read.
templates:
- '/etc/prometheus/alertmanager_templates/*.tmpl'
# The root route on which each incoming alert enters.
route:
# The labels by which incoming alerts are grouped together. For example,
# multiple alerts coming in for cluster=A and alertname=LatencyHigh would
# be batched into a single group.
group_by: ['instance'] # group per instance
# When a new group of alerts is created by an incoming alert, wait at
# least 'group_wait' to send the initial notification.
# This way ensures that you get multiple alerts for the same group that start
# firing shortly after another are batched together on the first
# notification.
group_wait: 30s
# When the first notification was sent, wait 'group_interval' to send a batch
# of new alerts that started firing for that group.
group_interval: 5m
# If an alert has successfully been sent, wait 'repeat_interval' to
# resend them.
repeat_interval: 24h
# A default receiver
receiver: webhook-ninjabot
# Inhibition rules allow to mute a set of alerts given that another alert is
# firing.
# We use this to mute any warning-level notifications if the same alert is
# already critical.
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
# Apply inhibition if the alertname is the same.
equal: ['alertname', 'cluster', 'service']
receivers:
- name: 'webhook-ninjabot'
webhook_configs:
- url: 'http://localhost:5000/'
send_resolved: true
- url: 'http://localhost:8000/'
send_resolved: true

View File

@@ -0,0 +1,5 @@
---
- name: Restart prometheus-blackbox-exporter
service:
name: prometheus-blackbox-exporter
state: restarted

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