feat: rework ansible & secrets

This commit is contained in:
auricom
2022-07-03 15:45:26 +02:00
parent 2f8c22a53c
commit 12736a97de
160 changed files with 3210 additions and 1785 deletions

View File

@@ -1,5 +1,11 @@
creation_rules:
- encrypted_regex: "^(data|stringData)$"
pgp: >-
19B850FBA7685A526CF11E5F9BBE834259976EE8,
5749D0AE39445C1CCA6006DF8913091C690BDD69
- path_regex: cluster/.*\.sops\.ya?ml
encrypted_regex: "^(data|stringData)$"
key_groups:
- age:
- age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
- path_regex: ansible/.*\.sops\.ya?ml
unencrypted_regex: "^(kind)$"
key_groups:
- age:
- age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg

View File

@@ -27,25 +27,20 @@ flux bootstrap github \
--network-policy=false
```
## SOPS secret from GPG key
## SOPS secret from age key
```bash
gpg \
--export-secret-keys \
--armor <GPG_KEY_ID> | \
kubectl create secret generic sops-gpg \
--namespace=flux-system \
--from-file=sops.asc=/dev/stdin
age-keygen -o $HOME/sops/age/key.txt
cat $HOME/sops/age/key.txt |
kubectl create secret generic sops-age \
--namespace=flux-system \
--from-file=$HOME/sops/age/key.txt=/dev/stdin
```
## Encrypt kubernetes resources with sops binary
```bash
sops \
--encrypt \
--pgp=<GPG_KEY_ID> \
--encrypted-regex '^(data|stringData)$' \
--in-place <FILE_PATH>
sops --encrypt --in-place <FILE_PATH>
```
## Install pre-commit hooks

2
ansible/.envrc Normal file
View File

@@ -0,0 +1,2 @@
#shellcheck disable=SC2148,SC2155
export ANSIBLE_CONFIG=$(expand_path ./ansible.cfg)

35
ansible/ansible.cfg Normal file
View File

@@ -0,0 +1,35 @@
[defaults]
# General settings
nocows = True
executable = /bin/bash
stdout_callback = yaml
force_valid_group_names = ignore
# File/Directory settings
log_path = ~/.ansible/ansible.log
inventory = ./inventory
roles_path = ~/.ansible/roles:./roles
collections_path = ~/.ansible/collections
remote_tmp = ~/.ansible/tmp
local_tmp = ~/.ansible/tmp
# Fact Caching settings
fact_caching = jsonfile
fact_caching_connection = ~/.ansible/facts_cache
# SSH settings
remote_port = 22
timeout = 60
host_key_checking = False
# Plugin settings
vars_plugins_enabled = host_group_vars,community.sops.sops
[inventory]
unparsed_is_failed = true
[privilege_escalation]
become = True
[ssh_connection]
scp_if_ssh = smart
retries = 3
ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o Compression=yes -o ServerAliveInterval=15s
pipelining = True
control_path = %(directory)s/%%h-%%r

View File

@@ -0,0 +1,24 @@
kind: Secret
SECRET_DOMAIN: ENC[AES256_GCM,data:n+Lk4Mw+/akb1XA=,iv:5kXTjxflpwZM3vlkZde4S8O9RM8V0Ij5zHhmt67IKXg=,tag:AXQguN0ZVM89qpNQDXDKXA==,type:str]
SECRET_CLUSTER_DOMAIN: ENC[AES256_GCM,data:nzhB4YHDYvQwTjRdTUGj,iv:emxp70PPzGPJP2x3LlCRRzh0gTNohnvI9Nr+f+PFZwo=,tag:m44ScVH/9hNxiYRdVx2xrA==,type:str]
SECRET_EMAIL_DOMAIN: ENC[AES256_GCM,data:Xu0RNCdH+AUHpoq2c9Q=,iv:RxBNXZU2tXqv78Orkf/aWTrKVTHVDurnX/YldvNRl/o=,tag:DJZk/5QAnUUzeEwsRidUCQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0dGgya0lVNUtvMEhmWFpm
dE8wdkppSEZiMjVteS9pZkxFaUltQ0VlUzNFCk1oVzVHTVIxVnIvL21YemtZVmJz
a3lmMnJaNGI2NXlUKzduS1ZVa1o5amcKLS0tICtLS2pRZjk4U285TzJnV0J3MUkw
c3JkOFZzYnpINjQ5QnNkaE9IYUdXL3MKsBelDv/z5nTYC6/1Zm8kmzqEoLBVPnhy
v0v/6n1GksmzslbNdKhy+xtxHYrqouhc2P4hNi0R8p8u76RXERN5fg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:39:29Z"
mac: ENC[AES256_GCM,data:Ny+6wcVbhfKt3lrB8mJTH29VS0ikuTBvU4Rf7dSXVWx/8y/RB+NlhY8Ul9frxH9J0QxCB3sKw0ur3OLg5FS+cuDa8QjO0MLgSDLcleHDwF7t2uiKX1RPMR1uvAlJzD/c9Meord+xfHv1XSjs80mPXuApr03o+pV1pSpf/0XgntY=,iv:Uq3+LEvQAoH1O0EYFX/gxuaIEjycPbik/Etdhpz8h2k=,tag:Btvd9va/CmOY6ruYXvdPVQ==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,34 @@
---
timezone: Europe/Paris
public_ssh_keys:
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+GMHgvbtf6f7xUMAQR+vZFfD/mIIfIDNX5iP8tDRXZ claude@claude-thinkpad-fedora"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINo7E0oAOzaq0XvUHkWvZSC8u1XxX8dDCq3bSyK2BCen claude@claude-fixe-fedora"
packages:
- "https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm"
- "https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm"
- dnf-automatic
- dnf-utils
- fish
- hdparm
- htop
- intel-gpu-tools
- ipvsadm
# TODO(ansible): Might be required for newer Intel CPU generations
# https://ask.fedoraproject.org/t/intel-graphics-best-practices-and-settings-for-hardware-acceleration/21119
# - intel-media-driver
# - mesa-dri-drivers
# - libva-intel-driver
# - libva-intel-hybrid-driver
# - libva-utils
# - libva-vdpau-driver
# - libvdpau-va-gl
- lm_sensors
- nano
- nvme-cli
- socat
- cockpit-pcp
k3s_registration_address: 192.168.9.100
k3s_become: true

View File

@@ -0,0 +1,71 @@
---
# https://rancher.com/docs/k3s/latest/en/installation/install-options/server-config/
# https://github.com/PyratLabs/ansible-role-k3s#server-control-plane-configuration
# Define the host as control plane nodes
k3s_control_node: true
k3s_etcd_datastore: false
# k3s settings for all control-plane nodes
k3s_server:
node-ip: "{{ ansible_host }}"
tls-san:
# # kube-vip
# - "{{ kubevip_address }}"
# haproxy
- "{{ k3s_registration_address }}"
docker: false
flannel-backend: "none" # This needs to be in quotes
disable:
- flannel
- traefik
- servicelb
- metrics-server
- local-storage
disable-network-policy: true
disable-cloud-controller: true
# Network CIDR to use for pod IPs
cluster-cidr: "10.95.0.0/16"
# Network CIDR to use for service IPs
service-cidr: "10.96.0.0/16"
# Required to monitor component with kube-prometheus-stack
#etcd-expose-metrics: true
kubelet-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Allow pods to be rescheduled quicker in the case of a node failure
# https://github.com/k3s-io/k3s/issues/1264
- "node-status-update-frequency=4s"
kube-controller-manager-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Required to monitor component with kube-prometheus-stack
- "bind-address=0.0.0.0"
# Allow pods to be rescheduled quicker in the case of a node failure
# https://github.com/k3s-io/k3s/issues/1264
- "node-monitor-period=4s"
- "node-monitor-grace-period=16s"
- "pod-eviction-timeout=20s"
kube-proxy-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Required to monitor component with kube-prometheus-stack
- "metrics-bind-address=0.0.0.0"
kube-scheduler-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Required to monitor component with kube-prometheus-stack
- "bind-address=0.0.0.0"
kube-apiserver-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Required for HAProxy health-checks
- "anonymous-auth=true"
# Allow pods to be rescheduled quicker in the case of a node failure
# https://github.com/k3s-io/k3s/issues/1264
- "default-not-ready-toleration-seconds=20"
- "default-unreachable-toleration-seconds=20"
# Stop k3s control plane having workloads scheduled on them
node-taint:
- "node-role.kubernetes.io/control-plane:NoSchedule"

View File

@@ -8,6 +8,9 @@ k3s_control_node: false
# k3s settings for all worker nodes
k3s_agent:
node-ip: "{{ ansible_host }}"
node-label:
#- "kubernetes.io/role=worker"
- "k3s-upgrade=true"
kubelet-arg:
# Enable Alpha/Beta features
- "feature-gates=EphemeralContainers=true,MixedProtocolLBService=true,ReadWriteOncePod=true"
# Allow pods to be rescheduled quicker in the case of a node failure
# https://github.com/k3s-io/k3s/issues/1264
- "node-status-update-frequency=4s"

View File

@@ -0,0 +1,23 @@
kind: Secret
ansible_password: ENC[AES256_GCM,data:NTaCi8mqE7kAQA==,iv:yfHBgrBCf2CqWPyuVTKSwH/WUy6bkgiSoyL4hWQHG7s=,tag:e3311IReXe0RHGgttNg3pg==,type:str]
ansible_become_pass: ENC[AES256_GCM,data:ChsZxKZ1qvICFA==,iv:vuc4eZG4Ls2CiSP/vLazCy/sZkiPjjpGPZr97CvIoX4=,tag:onYhcvFkmAMN6PTFSp0Ikg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5azdoWUV2SWdxaDl1NXVF
U1pvRjBncEpzM2E4TEs1MGlRbTRseG1zS0dNCnF6QmRmNU1iZ0J5K28rSlB4emFF
ODlnU1lXVFZrTHlyTEg5VlFXUERJNGcKLS0tIGhMQUhsa0xaUVU0RTRpbkx0Vk5r
NjJBcHVOSmUvNkt3b3I3dmJwTlJWS3MKw/hRA/oh1fiWts2aqbzTV3TTTcnSk3mi
fsw9jQF3QRL5PGbdT6iz7j58IokV32ilJubQHtfrxus29hd/qAn0yQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:40:36Z"
mac: ENC[AES256_GCM,data:c5yyBdFVs1wqDe8nsQOLeSzFv4QJ2n+VbrSf0dP5oW8593WBcdI8fXn9Q8fdY+wN2BOLn5vRdXBx7btlw0OrEIOOZ/Wz9tUxqIEUFZU6tT4TIB9g5jEqMgs2eKJmgLUoW/fcPC6QJ8ATApF6y8lI4RIV2LOItqK4AUpiVy4E2SU=,iv:kfrYGRaKY37OEl8ilrFFkRkItHpz/1VuAgWimjhujGA=,tag:STGaUOdwNlOAMcbU3Po1HQ==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,23 @@
kind: Secret
ansible_password: ENC[AES256_GCM,data:AihMvIUjgEpCjg==,iv:Bk9uFrbhOvlQvoYaJz+JhtMJTAiQ0u9TcaS8eKO0+fE=,tag:R2sLCjH/my9kcsu4Ddg9jg==,type:str]
ansible_become_pass: ENC[AES256_GCM,data:nR/Wkn8NqM3vaA==,iv:iV8c6Qg59qKtHoaQReUTX+KDB+iSboxpSM/K8+gcZvQ=,tag://89MQ4jmQPib/D595YTbA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlZSs4aVZ5VGdyVllEMXl3
c2NGS2d0dkd4NVZlSVlBd2V3RVEzQ2FiaHlrCld0SkNKUjcvRHNEQ1dZZFUzM014
ejd5QW5uUzJmMERLR2h4R2M3UmdKWU0KLS0tIFdYOStkVG40TXIzVjRkK0RzZStj
UmhGcmVidTVKbWQ5VVpHSklYN2NyWGMKsfv/KG02qk3EJoNJQ9HNl1iyfyic6Puf
5owrc62PfohWnLVQby9SaVK80PJVaMRU/kcHIJvbt1Iv2f47qpKczg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:40:40Z"
mac: ENC[AES256_GCM,data:6BqgWJTOzQKwu6Mr7/2WemzOmFNnIilSLH9LPG01UtvaO7FnOQXV1ezgYntKdSXGJWza/pvvqDURaBT7O7Rwv5kR25B6Fo3XWdVSuTLf+N4fGnWKiINaa6UjZhosm5KLs7VB0I3eiBTcHrxqb9jupgPkUErwy0H0LT8yLYRGpe8=,iv:kXeAB7zUoZoZPgEntWV80DNKSEiFiH4xQtbYpStO36U=,tag:gWusG9MGl+bYcjYfQGMbWA==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,23 @@
kind: Secret
ansible_password: ENC[AES256_GCM,data:495JSVNY5Rn0hg==,iv:ZvJb1M4Ys8FkQpekm5jnGWKE5q63Z44OUhhtYWsJUvQ=,tag:KxgvJbsEMsdYu59yCOCjMg==,type:str]
ansible_become_pass: ENC[AES256_GCM,data:O8lTma7A2n6+5g==,iv:ggmSecFPtTI9vy81of5I6AHnRX2YWOw0VtVldv4PZmo=,tag:IfIuN8xcKHBF6Ojlmki5Tw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0d21nNHZQRkloNnd1M2xF
RlJCUzBZK04rQ1RSa0hFSXUrVTlzK0V1dEdjCkg0ZnVJNGJOZjN3RlZ2RGRmRFdV
akRPQzhwN3NqNHJlK0o1VVFncDVnd1kKLS0tIDhhRGlhNXJmanM5amR6eHZERElj
RndiYkJFaWZuUmVIU3JwSWYzTFZlS3cKHFe4yce/091eEvtrSBYggNgyO88eHA4s
3TvjHmS7tLv7BnBAT9LLcQVSIW0UOszzF3PvVWIqFqzB/wn0j370kw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:40:42Z"
mac: ENC[AES256_GCM,data:qFIsrbqI+c3fe88H40KkWhwOnZ2aePoorpfxeTjhBtPviT4jBMvIGYZKULCehcdULNMxe7QWuPWsdYY/o5ruqZC49/OrV9qI0XVU6gdiCsM1jcXXiyFkVFfMoMhj5c5yAIMoUKRWbZe2kFtJxaG7ng8VusMgCc9f7LofWiFToVo=,iv:BI2hEL/AsaZoZ4RL7QNy4vins877XgZwxCdJ0ciFEUo=,tag:7tOEfmkFEApTy5wIgJLEBA==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,23 @@
kind: Secret
ansible_password: ENC[AES256_GCM,data:n0ASYgah4hAFvw==,iv:P0OPjAGh4AWkw0HUpBNEom6twa3sAXsh0Ei+2UDj/qo=,tag:GNcmaw2BQr5TV755NL/0vw==,type:str]
ansible_become_pass: ENC[AES256_GCM,data:a2wZnzPgf91HvQ==,iv:8wIjFmwSkYZIZmLLhvZTG1EnMmNffuSoPkpao6Kk9wI=,tag:gta1yPH1tRzBdViIO9WOAg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQL2pJWVRDU0lBVVgxNkd6
MStqdFRFNGdwTEpUWUxEaVVMUVBkY2RXWFUwCmJmbGZnMzVPZjhQMWh0eWhybXdi
K1FIa1YrNDZjMnhONDBiSEFtTW80WlkKLS0tIHJJTFpINUowclNUZXVsa2I1Vjdw
NkhyZm5SVnlBYWxlajh6NjV0OVBCSE0Kl6ovgsGkzq4XetwG5b77mvztpa3bD5ej
mWlPbSV66yw4eENVuDtZRX5/lrnbW7EqkwjfGoEJ9YGA7ya0G6IVQw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:40:44Z"
mac: ENC[AES256_GCM,data:/AA8sbAxsYhGAad8/ymYq0YgzwmNvnnwK+p9J7+NUpFC9YGWwuR/dV8oxKzqOs/zEzFTwyBTvOrGeQ59xyJ/Id/xSt5Av0FTmrOXQxFwIOsMUsH5RP8khQpp9yO1c2cvxwNLi1oWGzLLE63Zl2JwutQdTVH0KgibPhtdL0sV8eQ=,iv:rTpWgrMAZrCymFqKGcEGOyQJdPAw/SmeW8vdVNX/Ptg=,tag:rlg3dcQhVwcXUKkEc4Jdww==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,23 @@
kind: Secret
root_api_key: ENC[AES256_GCM,data:e+g6jvxD9kBSYVbzGXR0QZZMAnxndPu04Dhs3UjNsjHyq+GQRlapPJDQmnTWFa11KaEK3lOiSmU4yxcRjbgG2t3a,iv:mLG+dFHrmndRm5fT4KU+TIOMiAg/urQ4Zv3YaRaoVlg=,tag:DXTWollNdF4o2Pe2qdyufw==,type:str]
ansible_host: ENC[AES256_GCM,data:ldsDTnydWPMnAnOiSlVrkiiL6w==,iv:luNgXdV3uBRaGzBIlw4E5UrZqKBaakgwc+9YC9xXInM=,tag:MldHmJpsOqe7oJMA83Xm9g==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPVy9DRjhqOW05Wm4rNXZo
bFJxem9UZjNSQW5UaTRZaWQ1clZQSHJrNHpVCmo3Y0RPd1BRRC9ZZHJ0SndSUXJv
UkpPWTNOUWFPL1hCUGJrTFBPZml5QncKLS0tIGI5UUJKMXR0d1d3ZzRDSURuWVFl
ZFlyQ1lGbnVPaSs4cytQYzNwRnJabmcKP0ogZqsaoD6heCqmObwttBgE039aLqe2
R55NPkQJJyFSbDbdDmPApE4IwtXay54QGw2RR4AxOZW4G2dWhdzP3w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-04T18:20:37Z"
mac: ENC[AES256_GCM,data:IzuN61G8NkZwqNDkIQQPNVODoxgPQieRlSTcInajbBUdHHdVkFRlyLI2INoGd1RDDV06NsmJPM3Yj6fRlWlF4iRCO60cEHgnSyq3FRcFa6oKe9f5p5hmIBin8KMIAQOinNf8/4kqUpkZOFeY/fViBayin1cYgJ2MlMYtZRFVt0A=,iv:2DNQdjHRbtTlTgSVOrS/UTeSaVOhldbf+ek2e1gNv5s=,tag:ef/4Xtbf/021Z5NHv8Up9A==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,3 @@
main_nas: false
pool_name: vol1
snapshots_interval: "daily:14,weekly:12,monthly:12,yearly:3"

View File

@@ -0,0 +1,22 @@
kind: Secret
root_api_key: ENC[AES256_GCM,data:Fhj1MGeHxe/A6O7uVjMrCEu7J4rsiWrhbXgbAenb5CunoRPu0XLV/227WAFc4wFkboFNnt3bjzugvdvM5w/0JSry,iv:7uuHkrSKGShhIso8RgIJsOSYOxBiyyM/D5Dg+IGDh1Y=,tag:dP4gfIIUAEBUm91h5IHSug==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtVllLOFcwWXVoNXZobFF1
VGJmczlkL1V3blhvcnFzN2V6S1B1Ui81alRNClVEUWFmSWxKbENBRVZJN01PSWM5
d2M3OHFhOGpadEdrWUIxZGpMNTR2aVkKLS0tIE84ZkxzTlBpZVlqR2xQRmM0V0ZR
aG5zWW1XclBOS2cxMkwzZ3c1R1psNGsKzeSHHV7AYXCUNiiXJlBRFVWMZtfK3naj
VRtF22+DYfjumQuwam2ZzhdLQ//1ciHnkJc58dKeTbYUHzC+fWpaZQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:40:48Z"
mac: ENC[AES256_GCM,data:ple3qtcoOwSBg0AbkZSFAwySlvBYvk5/6jx3rsj1lptNDNGQyGd+X9oYqtAN+f58Q8y2Wbn+KwVWpKTvFzX6lEedv6iR0rFpPW6mMTX8Py8vboD2hCp96hpBMtNqf4JLIzPQoc5WG5kK88KDc17/M2HaQFPX56YSCHn0ABnH8Vg=,iv:o5WZqE3doTnpbFmBP77U6yKRvmCPgXVCjYQ0Z2VaR0I=,tag:e72lHlzwLX90pz36RJXsuw==,type:str]
pgp: []
unencrypted_regex: ^(kind)$
version: 3.7.3

View File

@@ -0,0 +1,4 @@
main_nas: true
pool_name: storage
service_s3: true
snapshots_interval: "daily:14,weekly:12,monthly:3"

View File

@@ -0,0 +1,40 @@
---
all:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: /usr/bin/python3
coreelec:
ansible_user: root
children:
truenas-instances:
hosts:
truenas:
truenas-remote:
ansible_port: 35875
vars:
ansible_user: homelab
kubernetes:
children:
master:
hosts:
k3s-master:
ansible_host: 192.168.9.100
ansible_user: fedora
ansible_ssh_port: 22
worker:
hosts:
k3s-worker1:
ansible_host: 192.168.9.105
rook_devices:
- /dev/nvme0n1
k3s-worker2:
ansible_host: 192.168.9.106
rook_devices:
- /dev/nvme0n1
k3s-worker3:
ansible_host: 192.168.9.107
rook_devices:
- /dev/nvme0n1
vars:
ansible_user: fedora

View File

@@ -0,0 +1,17 @@
---
- name: Boostrap host to enable Ansible playbooks
hosts: all
become: true
become_user: root
vars:
python_pwd: /usr/bin/python
python_package: python3
tasks:
- name: Check for Python
raw: test -e {{ python_pwd }}
changed_when: false
failed_when: false
register: check_python
- name: Install Python
raw: pkg install -y {{ python_package }}
when: check_python.rc != 0

View File

@@ -1,13 +1,13 @@
---
- hosts:
- server-nodes
- worker-nodes
- master
- worker
become: true
gather_facts: true
any_errors_fatal: true
pre_tasks:
- name: Pausing for 5 seconds...
- name: Pausing for 2 seconds...
pause:
seconds: 5
seconds: 2
roles:
- ubuntu
- installation.k3s

View File

@@ -0,0 +1,29 @@
---
- hosts:
- master
- worker
become: true
gather_facts: true
any_errors_fatal: true
pre_tasks:
- name: Pausing for 2 seconds...
pause:
seconds: 2
- name: Uninstall k3s
include_role:
name: xanmanning.k3s
public: true
vars:
k3s_state: uninstalled
tasks:
- name: Gather list of CNI files
ansible.builtin.find:
paths: /etc/cni/net.d
patterns: "*"
hidden: true
register: directory_contents
- name: Delete CNI files
ansible.builtin.file:
path: "{{ item.path }}"
state: absent
loop: "{{ directory_contents.files }}"

View File

@@ -0,0 +1,167 @@
---
- hosts:
- master
- worker
become: true
gather_facts: true
any_errors_fatal: true
pre_tasks:
- name: Pausing for 2 seconds...
pause:
seconds: 2
tasks:
- name: Locale
block:
- name: Locale | Set timezone
community.general.timezone:
name: "{{ timezone | default('America/New_York') }}"
- name: Networking
block:
- name: Networking | Set hostname to inventory hostname
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
when:
- ansible_hostname != inventory_hostname
- name: Networking | Update /etc/hosts to include inventory hostname
ansible.builtin.blockinfile:
path: /etc/hosts
block: |
127.0.1.1 {{ inventory_hostname }}
- name: Packages
block:
- name: Packages | Improve dnf performance
ansible.builtin.blockinfile:
path: /etc/dnf/dnf.conf
block: |
defaultyes=True
deltarpm=True
install_weak_deps=False
max_parallel_downloads={{ ansible_processor_vcpus | default('8') }}
- name: Packages | Import rpmfusion keys
ansible.builtin.rpm_key:
state: present
key: "{{ item }}"
loop:
- https://rpmfusion.org/keys?action=AttachFile&do=get&target=RPM-GPG-KEY-rpmfusion-free-fedora-2020
- https://rpmfusion.org/keys?action=AttachFile&do=get&target=RPM-GPG-KEY-rpmfusion-nonfree-fedora-2020
- name: Packages | Install required packages
ansible.builtin.dnf:
name: "{{ packages | default([]) }}"
state: present
update_cache: true
- name: Packages | Remove leaf packages
ansible.builtin.dnf:
autoremove: true
- name: Packages | Enable automatic downloads of updates
ansible.builtin.systemd:
service: dnf-automatic-download.timer
enabled: true
state: started
- name: User Configuration
block:
- name: User Configuration | Change shell to fish
ansible.builtin.user:
name: "{{ item }}"
shell: /usr/bin/fish
loop:
- root
- fedora
- name: User Configuration | Disable password sudo
ansible.builtin.lineinfile:
dest: /etc/sudoers
state: present
regexp: "^%wheel"
line: "%wheel ALL=(ALL) NOPASSWD: ALL"
validate: visudo -cf %s
become: true
- name: User Configuration | Add additional SSH public keys
ansible.posix.authorized_key:
user: "{{ ansible_user }}"
key: "{{ item }}"
loop: "{{ public_ssh_keys | default([]) }}"
- name: System Configuration (1)
block:
- name: System Configuration (1) | Configure smartd
ansible.builtin.copy:
dest: /etc/smartd.conf
mode: 0644
content: DEVICESCAN -a -o on -S on -n standby,q -s (S/../.././02|L/../../6/03) -W 4,35,40
notify: Restart smartd
- name: System Configuration (1) | Disable firewalld
ansible.builtin.systemd:
service: firewalld.service
enabled: false
masked: true
state: stopped
- name: System Configuration (1) | Enable fstrim
ansible.builtin.systemd:
service: fstrim.timer
enabled: true
- name: System Configuration (1) | Enable chronyd
ansible.builtin.systemd:
service: chronyd
enabled: true
- name: System Configuration (2)
block:
- name: System Configuration (2) | Enable kernel modules now
community.general.modprobe:
name: "{{ item }}"
state: present
loop: [br_netfilter, overlay, rbd]
- name: System Configuration (2) | Enable kernel modules on boot
ansible.builtin.copy:
mode: 0644
content: "{{ item }}"
dest: "/etc/modules-load.d/{{ item }}.conf"
loop: [br_netfilter, overlay, rbd]
- name: System Configuration (2) | Set sysctls
ansible.posix.sysctl:
name: "{{ item.key }}"
value: "{{ item.value }}"
sysctl_file: /etc/sysctl.d/99-kubernetes.conf
reload: true
with_dict: "{{ sysctl_config }}"
vars:
sysctl_config:
net.ipv4.ip_forward: 1
net.ipv4.conf.all.forwarding: 1
net.ipv4.conf.all.rp_filter: 0
net.ipv4.conf.default.rp_filter: 0
net.ipv6.conf.all.forwarding: 1
net.bridge.bridge-nf-call-iptables: 1
net.bridge.bridge-nf-call-ip6tables: 1
fs.inotify.max_user_watches: 524288
fs.inotify.max_user_instances: 512
- name: System Configuration (2) | Disable swap
ansible.builtin.dnf:
name: zram-generator-defaults
state: absent
- name: System Configuration (2) | Disable SELinux
ansible.posix.selinux:
state: disabled
- name: System Configuration (2) | Disable mitigations
ansible.builtin.replace:
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX=(?:(?![" ]{{ item.key | regex_escape }}=).)*)(?:[" ]{{ item.key | regex_escape }}=\S+)?(.*")$'
replace: '\1 {{ item.key }}={{ item.value }}\2'
with_dict: "{{ grub_config }}"
vars:
grub_config:
mitigations: "off"
register: grub_status
- name: System Configuration (2) | Reconfigure grub and initramfs
ansible.builtin.command: "{{ item }}"
loop:
- grub2-mkconfig -o /boot/grub2/grub.cfg
- dracut --force --regenerate-all -v
when: grub_status.changed
notify: Reboot
handlers:
- name: Reboot
ansible.builtin.reboot:
- name: Restart smartd
ansible.builtin.service:
name: smartd.service
enabled: true
state: restarted

View File

@@ -0,0 +1,7 @@
---
- hosts: coreelec
become: true
gather_facts: true
any_errors_fatal: true
roles:
- role: coreelec

View File

@@ -0,0 +1,33 @@
---
- hosts:
- worker
become: true
gather_facts: true
any_errors_fatal: true
pre_tasks:
- name: Pausing for 5 seconds...
pause:
seconds: 5
tasks:
- name: Reset disks
block:
- name: Remove /var/lib/rook
ansible.builtin.file:
state: absent
path: "/var/lib/rook"
- name: Zap the drives
ansible.builtin.shell: >
sgdisk --zap-all {{ item }} || true
loop:
- "{{ rook_devices | default([]) }}"
- name: Remove lvm partitions
ansible.builtin.shell: "{{ item }}"
loop:
- ls /dev/mapper/ceph--* | xargs -I% -- fuser --kill %
- ls /dev/mapper/ceph--* | xargs -I% -- dmsetup clear %
- ls /dev/mapper/ceph--* | xargs -I% -- dmsetup remove -f %
- ls /dev/mapper/ceph--* | xargs -I% -- rm -rf %
- name: Wipe the block device
ansible.builtin.command: "wipefs -af {{ item }}"
with_items:
- "{{ rook_devices | default([]) }}"

View File

@@ -0,0 +1,7 @@
---
- hosts: truenas-instances
become: false
gather_facts: true
any_errors_fatal: true
roles:
- role: truenas

View File

@@ -0,0 +1,7 @@
---
- hosts: localhost
become: false
gather_facts: true
any_errors_fatal: true
roles:
- role: workstation

13
ansible/requirements.yml Normal file
View File

@@ -0,0 +1,13 @@
---
collections:
- name: ansible.posix
version: 1.4.0
- name: community.general
version: 5.2.0
- name: kubernetes.core
version: 2.3.2
- name: community.sops
version: 1.2.3
roles:
- src: xanmanning.k3s
version: v3.2.0

View File

@@ -0,0 +1,6 @@
---
root_path: /storage
nfs_shares:
- music
- photo
- video

View File

@@ -0,0 +1,16 @@
#!/bin/bash
# Variables
FLAG_NOTIF=false
DATE=`date +%Y%m%d%H%M`
BACKUP_PATH="/storage/backup"
cd /
tar cvf ${BACKUP_PATH}/${DATE}.tar \
storage/.kodi storage/.config storage/.cache storage/.ssh \
--exclude=storage/.kodi/userdata/Thumbnails
# Keep the last 5 backups on disk
find ${BACKUP_PATH}/*.tar -mtime +5 -type f -delete

View File

@@ -0,0 +1,13 @@
---
- name: backup | copy script
ansible.builtin.copy:
src: backup.bash
dest: /storage/backup.bash
mode: 0755
- name: backup | crontab
ansible.builtin.cron:
name: "daily backup"
minute: "14"
hour: "4"
job: "/storage/backup.bash && curl -fsS -m 10 --retry 5 -o /dev/null https://healthchecks.{{ SECRET_CLUSTER_DOMAIN }}/ping/aae30879-cfdf-4b90-889f-d4ff69dd8aad"

View File

@@ -0,0 +1,8 @@
---
- ansible.builtin.include_tasks: backup.yml
tags:
- backup
- ansible.builtin.include_tasks: nfs.yml
tags:
- nfs

View File

@@ -0,0 +1,19 @@
---
- name: nfs | create directories
ansible.builtin.file:
path: "{{ root_path }}/mnt/{{ item }}"
state: directory
loop: "{{ nfs_shares }}"
- name: nfs | create system.d services
ansible.builtin.template:
src: "storage-nfs.mount"
dest: "/storage/.config/system.d/storage-mnt-{{ item }}.mount"
loop: "{{ nfs_shares }}"
- name: nfs | activate system.d services
ansible.builtin.systemd:
name: storage-mnt-{{ item }}.mount
state: started
enabled: yes
loop: "{{ nfs_shares }}"

View File

@@ -0,0 +1,16 @@
#====================================================
[Unit]
Description=TrueNAS nfs share {{ item }}
Requires=network-online.service
After=network-online.service
Before=kodi.service
[Mount]
What=truenas:/mnt/storage/{{ item }}
Where=/storage/mnt/{{ item }}
Options=
Type=nfs
[Install]
WantedBy=multi-user.target
#====================================================

View File

@@ -0,0 +1,2 @@
---
k3s_etcd_s3: false

View File

@@ -0,0 +1,50 @@
---
- name: Check if cluster is installed
ansible.builtin.stat:
path: /etc/rancher/k3s/config.yaml
register: k3s_check_installed
check_mode: false
- name: Set manifest facts
ansible.builtin.set_fact:
k3s_server_manifests_templates: []
k3s_server_manifests_urls: []
when: k3s_check_installed.stat.exists
- name: Install Kubernetes
include_role:
name: xanmanning.k3s
public: true
vars:
k3s_state: installed
- name: Copy kubeconfig to provision folder
run_once: true
ansible.builtin.fetch:
src: "/etc/rancher/k3s/k3s.yaml"
dest: "{{ playbook_dir }}/../../../cluster/kubeconfig"
flat: true
when:
- k3s_control_node is defined
- k3s_control_node
- name: Update kubeconfig with the right IPv4 address
delegate_to: localhost
become: false
run_once: true
ansible.builtin.replace:
path: "{{ playbook_dir }}/../../../cluster/kubeconfig"
regexp: "https://127.0.0.1:6443"
replace: "https://{{ k3s_registration_address }}:6443"
- name: Remove deployed manifest templates
ansible.builtin.file:
path: "{{ k3s_server_manifests_dir }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
state: absent
loop: "{{ k3s_server_manifests_templates | default([]) }}"
- name: Remove deployed manifest urls
ansible.builtin.file:
path: "{{ k3s_server_manifests_dir }}/{{ item.filename }}"
state: absent
loop: "{{ k3s_server_manifests_urls | default([]) }}"

View File

@@ -0,0 +1,4 @@
---
- import_tasks: k3s.yml
tags:
- k3s

View File

@@ -4,5 +4,6 @@ kind: BGPConfiguration
metadata:
name: default
spec:
asNumber: {{ calico_bgp_as_number }}
serviceExternalIPs:
- cidr: {{ calico.bgp.externalIPs }}
- cidr: "{{ calico_bgp_external_ips }}"

View File

@@ -4,5 +4,5 @@ kind: BGPPeer
metadata:
name: global
spec:
peerIP: {{ calico.bgp.peer }}
asNumber: {{ calico.bgp.as }}
peerIP: {{ calico_bgp_peer_ip }}
asNumber: {{ calico_bgp_as_number }}

View File

@@ -0,0 +1,18 @@
---
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
registry: quay.io
imagePath: calico
calicoNetwork:
# Note: The ipPools section cannot be modified post-install.
ipPools:
- blockSize: 26
cidr: "{{ k3s_server['cluster-cidr'] }}"
encapsulation: "{{ calico_encapsulation }}"
natOutgoing: Enabled
nodeSelector: all()
nodeMetricsPort: 9091
typhaMetricsPort: 9093

View File

@@ -0,0 +1,14 @@
---
# -- Encapsulation type
calico_encapsulation: "None"
# -- BGP Peer IP
# -- (usually your router IP address)
calico_bgp_peer_ip: 192.168.8.1
# -- BGP Autonomous System Number
# -- (must be the same across all BGP peers)
calico_bgp_as_number: 64512
# -- BGP Network you want services to consume
# -- (this network should not exist or be defined anywhere in your network)
calico_bgp_external_ips: 192.168.169.0/24
# -- CIDR of the host node interface Calico should use
calico_node_cidr: 10.69.0.0/16

View File

@@ -0,0 +1,53 @@
---
#
# Below vars are for the xanmanning.k3s role
# ...see https://github.com/PyratLabs/ansible-role-k3s#globalcluster-variables
#
# Use a specific version of k3s
# renovate: datasource=github-releases depName=k3s-io/k3s
k3s_release_version: "v1.24.2+k3s1"
# -- Install using hard links rather than symbolic links.
# ...if you are using the system-upgrade-controller you will need to
# use hard links rather than symbolic links as the controller will
# not be able to follow symbolic links.
k3s_install_hard_links: true
# -- Escalate user privileges for all tasks.
k3s_become: true
# -- Enable debugging
k3s_debug: false
# -- Enabled embedded etcd
# k3s_etcd_datastore: false
# -- Enable for single or even number of masters
k3s_use_unsupported_config: false
# -- /var/lib/rancher/k3s/server/manifests
k3s_server_manifests_templates:
- "calico/calico-installation.yaml.j2"
- "calico/calico-bgpconfiguration.yaml.j2"
- "calico/calico-bgppeer.yaml.j2"
# -- /var/lib/rancher/k3s/server/manifests
k3s_server_manifests_urls:
- url: https://docs.projectcalico.org/archive/v3.23/manifests/tigera-operator.yaml
filename: tigera-operator.yaml
# -- /etc/rancher/k3s/registries.yaml
# k3s_registries:
# mirrors:
# "docker.io":
# endpoint:
# - "https://mirror.{{ SECRET_PRIVATE_DOMAIN }}"
# "*":
# endpoint:
# - "https://mirror.{{ SECRET_PRIVATE_DOMAIN }}"
# config:
# "https://registry.{{ SECRET_PRIVATE_DOMAIN }}":
# auth:
# username: "{{ SECRET_NEXUS_USERNAME }}"
# password: "{{ SECRET_NEXUS_PASSWORD }}"

View File

@@ -0,0 +1,9 @@
homelab_homedir: "/mnt/{{ pool_name }}/home/homelab"
backups_dir: "/mnt/{{ pool_name }}/backups/"
telegraf_dir: "{{ homelab_homedir }}/telegraf"
scripts_dir: "{{ homelab_homedir }}/scripts"
certificates_dir: "{{ homelab_homedir }}/letsencrypt/{{ SECRET_DOMAIN }}"
ping_ip: 192.168.8.1
wg_interface: wg0-client
dns_hostname: services.{{ SECRET_DOMAIN }}

View File

@@ -0,0 +1,240 @@
#!/usr/bin/env python3
"""
Import and activate a SSL/TLS certificate into FreeNAS 11.1 or later
Uses the FreeNAS API to make the change, so everything's properly saved in the config
database and captured in a backup.
Requires paths to the cert (including the any intermediate CA certs) and private key,
and username, password, and FQDN of your FreeNAS system.
Your private key should only be readable by root, so this script must run with root
privileges. And, since it contains your root password, this script itself should
only be readable by root.
Source: https://github.com/danb35/deploy-freenas
"""
import argparse
import os
import sys
import json
import requests
import time
import configparser
import socket
from datetime import datetime, timedelta
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
parser = argparse.ArgumentParser(description='Import and activate a SSL/TLS certificate into FreeNAS.')
parser.add_argument('-c', '--config', default=(os.path.join(os.path.dirname(os.path.realpath(__file__)),
'deploy_config')), help='Path to config file, defaults to deploy_config.')
args = parser.parse_args()
if os.path.isfile(args.config):
config = configparser.ConfigParser()
config.read(args.config)
deploy = config['deploy']
else:
print("Config file", args.config, "does not exist!")
exit(1)
# We'll use the API key if provided
API_KEY = deploy.get('api_key')
# Otherwise fallback to basic password authentication
USER = "root"
PASSWORD = deploy.get('password')
DOMAIN_NAME = deploy.get('cert_fqdn',socket.gethostname())
FREENAS_ADDRESS = deploy.get('connect_host','localhost')
VERIFY = deploy.getboolean('verify',fallback=False)
PRIVATEKEY_PATH = deploy.get('privkey_path',"/root/.acme.sh/" + DOMAIN_NAME + "/" + DOMAIN_NAME + ".key")
FULLCHAIN_PATH = deploy.get('fullchain_path',"/root/.acme.sh/" + DOMAIN_NAME + "/fullchain.cer")
PROTOCOL = deploy.get('protocol','http://')
PORT = deploy.get('port','80')
FTP_ENABLED = deploy.getboolean('ftp_enabled',fallback=False)
S3_ENABLED = deploy.getboolean('s3_enabled',fallback=False)
now = datetime.now()
cert = "letsencrypt-%s-%s-%s-%s" %(now.year, now.strftime('%m'), now.strftime('%d'), ''.join(c for c in now.strftime('%X') if
c.isdigit()))
# Set some general request params
session = requests.Session()
session.headers.update({
'Content-Type': 'application/json'
})
if API_KEY:
session.headers.update({
'Authorization': f'Bearer {API_KEY}'
})
elif PASSWORD:
session.auth = (USER, PASSWORD)
else:
print ("Unable to authenticate. Specify 'api_key' or 'password' in the config.")
exit(1)
# Load cert/key
with open(PRIVATEKEY_PATH, 'r') as file:
priv_key = file.read()
with open(FULLCHAIN_PATH, 'r') as file:
full_chain = file.read()
# Update or create certificate
r = session.post(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/certificate/',
verify=VERIFY,
data=json.dumps({
"create_type": "CERTIFICATE_CREATE_IMPORTED",
"name": cert,
"certificate": full_chain,
"privatekey": priv_key,
})
)
if r.status_code == 200:
print ("Certificate import successful")
else:
print ("Error importing certificate!")
print (r.text)
sys.exit(1)
# Sleep for a few seconds to let the cert propagate
time.sleep(5)
# Download certificate list
limit = {'limit': 0} # set limit to 0 to disable paging in the event of many certificates
r = session.get(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/certificate/',
verify=VERIFY,
params=limit
)
if r.status_code == 200:
print ("Certificate list successful")
else:
print ("Error listing certificates!")
print (r.text)
sys.exit(1)
# Parse certificate list to find the id that matches our cert name
cert_list = r.json()
new_cert_data = None
for cert_data in cert_list:
if cert_data['name'] == cert:
new_cert_data = cert_data
cert_id = new_cert_data['id']
break
if not new_cert_data:
print ("Error searching for newly imported certificate in certificate list.")
sys.exit(1)
# Set our cert as active
r = session.put(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/system/general/',
verify=VERIFY,
data=json.dumps({
"ui_certificate": cert_id,
})
)
if r.status_code == 200:
print ("Setting active certificate successful")
else:
print ("Error setting active certificate!")
print (r.text)
sys.exit(1)
if FTP_ENABLED:
# Set our cert as active for FTP plugin
r = session.put(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/ftp/',
verify=VERIFY,
data=json.dumps({
"ssltls_certfile": cert,
}),
)
if r.status_code == 200:
print ("Setting active FTP certificate successful")
else:
print ("Error setting active FTP certificate!")
print (r.text)
sys.exit(1)
if S3_ENABLED:
# Set our cert as active for S3 plugin
r = session.put(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/s3/',
verify=VERIFY,
data=json.dumps({
"certificate": cert_id,
}),
)
if r.status_code == 200:
print ("Setting active S3 certificate successful")
else:
print ("Error setting active S3 certificate!")
print (r)
sys.exit(1)
# Get expired and old certs with same SAN
cert_ids_same_san = set()
cert_ids_expired = set()
for cert_data in cert_list:
if set(cert_data['san']) == set(new_cert_data['san']):
cert_ids_same_san.add(cert_data['id'])
issued_date = datetime.strptime(cert_data['from'], "%c")
lifetime = timedelta(days=cert_data['lifetime'])
expiration_date = issued_date + lifetime
if expiration_date < now:
cert_ids_expired.add(cert_data['id'])
# Remove new cert_id from lists
if cert_id in cert_ids_expired:
cert_ids_expired.remove(cert_id)
if cert_id in cert_ids_same_san:
cert_ids_same_san.remove(cert_id)
# Delete expired and old certificates with same SAN from freenas
for cid in (cert_ids_same_san | cert_ids_expired):
r = session.delete(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/certificate/id/' + str(cid),
verify=VERIFY
)
for c in cert_list:
if c['id'] == cid:
cert_name = c['name']
if r.status_code == 200:
print ("Deleting certificate " + cert_name + " successful")
else:
print ("Error deleting certificate " + cert_name + "!")
print (r.text)
sys.exit(1)
# Reload nginx with new cert
# If everything goes right, the request fails with a ConnectionError
try:
r = session.post(
PROTOCOL + FREENAS_ADDRESS + ':' + PORT + '/api/v2.0/system/general/ui_restart',
verify=VERIFY
)
if r.status_code == 200:
print ("Reloading WebUI successful")
print ("deploy_freenas.py executed successfully")
else:
print ("Error reloading WebUI!")
print ("{}: {}".format(r.status_code, r.text))
sys.exit(1)
except requests.exceptions.ConnectionError:
print ("Error reloading WebUI!")
sys.exit(1)

View File

@@ -0,0 +1,107 @@
#!/usr/bin/env python3
# clearempty.py - Koen Vermeer <k.vermeer@eyehospital.nl>
# Inspired by rollup.py by Arno Hautala <arno@alum.wpi.edu>
# modifications by Arno Hautala
# This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
# (CC BY-SA-3.0) http://creativecommons.org/licenses/by-sa/3.0/
# This script removes empty snapshots, based on their 'used' property.
# Note that one snapshot's 'used' value may change when another snapshot is
# destroyed. This script iteratively destroys the oldest empty snapshot. It
# does not remove the latest snapshot of each dataset or manual snapshots
import subprocess
import argparse
import sys
from collections import defaultdict
parser = argparse.ArgumentParser(description='Removes empty auto snapshots.')
parser.add_argument('datasets', nargs='+', help='the root dataset(s) from which to remove snapshots')
parser.add_argument('--test', '-t', action="store_true", default=False, help='only display the snapshots that would be deleted, without actually deleting them. Note that due to dependencies between snapshots, this may not match what would really happen.')
parser.add_argument('--recursive', '-r', action="store_true", default=False, help='recursively removes snapshots from nested datasets')
parser.add_argument('--prefix', '-p', action='append', help='list of snapshot name prefixes that will be considered')
args = parser.parse_args()
if not args.prefix:
args.prefix = ['auto']
args.prefix = [prefix+"-" for prefix in set(args.prefix)]
deleted = defaultdict(lambda : defaultdict(lambda : defaultdict(int)))
snapshot_was_deleted = True
while snapshot_was_deleted:
snapshot_was_deleted = False
snapshots = defaultdict(lambda : defaultdict(lambda : defaultdict(int)))
# Get properties of all snapshots of the selected datasets
for dataset in args.datasets:
subp = subprocess.Popen(["zfs", "get", "-Hrpo", "name,property,value", "type,creation,used,freenas:state", dataset], stdout=subprocess.PIPE)
zfs_snapshots = subp.communicate()[0]
if subp.returncode:
print("zfs get failed with RC=%s" % subp.returncode)
sys.exit(1)
for snapshot in zfs_snapshots.splitlines():
name,property,value = snapshot.decode().split('\t',3)
# if the rollup isn't recursive, skip any snapshots from child datasets
if not args.recursive and not name.startswith(dataset+"@"):
continue
try:
dataset,snapshot = name.split('@',2)
except ValueError:
continue
snapshots[dataset][snapshot][property] = value
# Ignore non-snapshots and not-auto-snapshots
# Remove already destroyed snapshots
for dataset in list(snapshots.keys()):
latest = None
latestNEW = None
for snapshot in sorted(snapshots[dataset], key=lambda snapshot: snapshots[dataset][snapshot]['creation'], reverse=True):
if not any(map(snapshot.startswith, args.prefix)) \
or snapshots[dataset][snapshot]['type'] != "snapshot":
del snapshots[dataset][snapshot]
continue
if not latest:
latest = snapshot
del snapshots[dataset][snapshot]
continue
if not latestNEW and snapshots[dataset][snapshot]['freenas:state'] == 'NEW':
latestNEW = snapshot
del snapshots[dataset][snapshot]
continue
if snapshots[dataset][snapshot]['freenas:state'] == 'LATEST':
del snapshots[dataset][snapshot]
continue
if snapshots[dataset][snapshot]['used'] != '0' \
or snapshot in list(deleted[dataset].keys()):
del snapshots[dataset][snapshot]
continue
# Stop if no snapshots are in the list
if not snapshots[dataset]:
del snapshots[dataset]
continue
# destroy the most recent empty snapshot
snapshot = max(snapshots[dataset], key=lambda snapshot: snapshots[dataset][snapshot]['creation'])
if not args.test:
# destroy the snapshot
subprocess.call(["zfs", "destroy", dataset+"@"+snapshot])
deleted[dataset][snapshot] = snapshots[dataset][snapshot]
snapshot_was_deleted = True
for dataset in sorted(deleted.keys()):
if not deleted[dataset]:
continue
print(dataset)
for snapshot in sorted(deleted[dataset].keys()):
print("\t", snapshot, deleted[dataset][snapshot]['used'])

View File

@@ -0,0 +1,262 @@
#!/usr/bin/env python3
# rollup.py - Arno Hautala <arno@alum.wpi.edu>
# This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
# (CC BY-SA-3.0) http://creativecommons.org/licenses/by-sa/3.0/
# For the latest version, visit:
# https://github.com/fracai/zfs-rollup
# https://bitbucket.org/fracai/zfs-rollup
# A snapshot pruning script, similar in behavior to Apple's TimeMachine
# Keep hourly snapshots for the last day, daily for the last week, and weekly thereafter.
# TODO:
# rollup based on local time, not UTC
# requires pytz, or manually determining and converting time offsets
# improve documentation
# TEST:
import datetime
import calendar
import time
import subprocess
import argparse
import sys
from collections import defaultdict
intervals = {}
intervals['hourly'] = { 'max':24, 'abbreviation':'h', 'reference':'%Y-%m-%d %H' }
intervals['daily'] = { 'max': 7, 'abbreviation':'d', 'reference':'%Y-%m-%d' }
intervals['weekly'] = { 'max': 0, 'abbreviation':'w', 'reference':'%Y-%W' }
intervals['monthly'] = { 'max':12, 'abbreviation':'m', 'reference':'%Y-%m' }
intervals['yearly'] = { 'max':10, 'abbreviation':'y', 'reference':'%Y' }
modifiers = {
'M' : 1,
'H' : 60,
'h' : 60,
'd' : 60*24,
'w' : 60*24*7,
'm' : 60*24*28,
'y' : 60*24*365,
}
used_intervals = {
'hourly': intervals['hourly'],
'daily' : intervals['daily'],
'weekly': intervals['weekly']
}
parser = argparse.ArgumentParser(description='Prune excess snapshots, keeping hourly for the last day, daily for the last week, and weekly thereafter.')
parser.add_argument('datasets', nargs='+', help='The root dataset(s) from which to prune snapshots')
parser.add_argument('-t', '--test', action="store_true", default=False, help='Only display the snapshots that would be deleted, without actually deleting them')
parser.add_argument('-v', '--verbose', action="store_true", default=False, help='Display verbose information about which snapshots are kept, pruned, and why')
parser.add_argument('-r', '--recursive', action="store_true", default=False, help='Recursively prune snapshots from nested datasets')
parser.add_argument('--prefix', '-p', action='append', help='list of snapshot name prefixes that will be considered')
parser.add_argument('-c', '--clear', action="store_true", default=False, help='remove all snapshots')
parser.add_argument('-i', '--intervals',
help="Modify and define intervals with which to keep and prune snapshots. Either name existing intervals ("+
", ".join(sorted(intervals, key=lambda interval: modifiers[intervals[interval]['abbreviation']]))+"), "+
"modify the number of those to store (hourly:12), or define new intervals according to interval:count (2h:12). "+
"Multiple intervals may be specified if comma seperated (hourly,daily:30,2h:12). Available modifier abbreviations are: "+
", ".join(sorted(modifiers, key=modifiers.get))
)
args = parser.parse_args()
if not args.prefix:
args.prefix = ['auto']
args.prefix = [prefix+"-" for prefix in set(args.prefix)]
if args.test:
args.verbose = True
if args.intervals:
used_intervals = {}
for interval in args.intervals.split(','):
if interval.count(':') == 1:
period,count = interval.split(':')
try:
int(count)
except ValueError:
print("invalid count: "+count)
sys.exit(1)
if period in intervals:
used_intervals[period] = intervals[period]
used_intervals[period]['max'] = count
else:
try:
if period[-1] in modifiers:
used_intervals[interval] = { 'max' : count, 'interval' : int(period[:-1]) * modifiers[period[-1]] }
else:
used_intervals[interval] = { 'max' : count, 'interval' : int(period) }
except ValueError:
print("invalid period: "+period)
sys.exit(1)
elif interval.count(':') == 0 and interval in intervals:
used_intervals[interval] = intervals[interval]
else:
print("invalid interval: "+interval)
sys.exit(1)
for interval in used_intervals:
if 'abbreviation' not in used_intervals[interval]:
used_intervals[interval]['abbreviation'] = interval
snapshots = defaultdict(lambda : defaultdict(lambda : defaultdict(int)))
for dataset in args.datasets:
subp = subprocess.Popen(["zfs", "get", "-Hrpo", "name,property,value", "creation,type,used,freenas:state", dataset], stdout=subprocess.PIPE)
zfs_snapshots = subp.communicate()[0]
if subp.returncode:
print("zfs get failed with RC=%s" % subp.returncode)
sys.exit(1)
for snapshot in zfs_snapshots.splitlines():
name,property,value = snapshot.decode().split('\t',3)
# if the rollup isn't recursive, skip any snapshots from child datasets
if not args.recursive and not name.startswith(dataset+"@"):
continue
try:
dataset,snapshot = name.split('@',2)
except ValueError:
continue
# enforce that this is a snapshot starting with one of the requested prefixes
if not any(map(snapshot.startswith, args.prefix)):
if property == 'creation':
print("will ignore:\t", dataset+"@"+snapshot)
snapshots[dataset][snapshot][property] = value
for dataset in list(snapshots.keys()):
latestNEW = None
latest = None
for snapshot in sorted(snapshots[dataset], key=lambda snapshot: snapshots[dataset][snapshot]['creation'], reverse=True):
if not latest:
latest = snapshot
snapshots[dataset][snapshot]['keep'] = 'RECENT'
continue
if not any(map(snapshot.startswith, args.prefix)) \
or snapshots[dataset][snapshot]['type'] != "snapshot":
snapshots[dataset][snapshot]['keep'] = '!PREFIX'
continue
if not latestNEW and snapshots[dataset][snapshot]['freenas:state'] == 'NEW':
latestNEW = snapshot
snapshots[dataset][snapshot]['keep'] = 'NEW'
continue
if snapshots[dataset][snapshot]['freenas:state'] == 'LATEST':
snapshots[dataset][snapshot]['keep'] = 'LATEST'
continue
if not len(list(snapshots[dataset].keys())):
del snapshots[dataset]
for dataset in sorted(snapshots.keys()):
print(dataset)
sorted_snapshots = sorted(snapshots[dataset], key=lambda snapshot: snapshots[dataset][snapshot]['creation'])
most_recent = sorted_snapshots[-1]
rollup_intervals = defaultdict(lambda : defaultdict(int))
for snapshot in sorted_snapshots:
prune = True
if args.clear:
continue
epoch = snapshots[dataset][snapshot]['creation']
for interval in list(used_intervals.keys()):
if 'reference' in used_intervals[interval]:
reference = time.strftime(used_intervals[interval]['reference'], time.gmtime(float(epoch)))
if reference not in rollup_intervals[interval]:
if int(used_intervals[interval]['max']) != 0 and len(rollup_intervals[interval]) >= int(used_intervals[interval]['max']):
rollup_intervals[interval].pop(sorted(rollup_intervals[interval].keys())[0])
rollup_intervals[interval][reference] = epoch
elif 'interval' in used_intervals[interval]:
if int(used_intervals[interval]['max']) != 0 and len(rollup_intervals[interval]) >= int(used_intervals[interval]['max']):
rollup_intervals[interval].pop(sorted(rollup_intervals[interval].keys())[0])
if (not rollup_intervals[interval]) or int(sorted(rollup_intervals[interval].keys())[-1]) + (used_intervals[interval]['interval']*60*.9) < int(epoch):
rollup_intervals[interval][epoch] = epoch
ranges = list()
ranges.append(list())
for snapshot in sorted_snapshots:
prune = True
epoch = snapshots[dataset][snapshot]['creation']
if 'keep' in snapshots[dataset][snapshot]:
prune = False
ranges.append(list())
for interval in list(used_intervals.keys()):
if 'reference' in used_intervals[interval]:
reference = time.strftime(used_intervals[interval]['reference'], time.gmtime(float(epoch)))
if reference in rollup_intervals[interval] and rollup_intervals[interval][reference] == epoch:
prune = False
ranges.append(list())
elif 'interval' in used_intervals[interval]:
if epoch in rollup_intervals[interval]:
prune = False
ranges.append(list())
if prune or args.verbose:
print("\t","pruning\t" if prune else " \t", "@"+snapshot, end=' ')
if args.verbose:
for interval in list(used_intervals.keys()):
if 'reference' in used_intervals[interval]:
reference = time.strftime(used_intervals[interval]['reference'], time.gmtime(float(epoch)))
if reference in rollup_intervals[interval] and rollup_intervals[interval][reference] == epoch:
print(used_intervals[interval]['abbreviation'], end=' ')
else:
print('-', end=' ')
if 'interval' in used_intervals[interval]:
if epoch in rollup_intervals[interval]:
print(used_intervals[interval]['abbreviation'], end=' ')
else:
print('-', end=' ')
if 'keep' in snapshots[dataset][snapshot]:
print(snapshots[dataset][snapshot]['keep'][0], end=' ')
else:
print('-', end=' ')
print(snapshots[dataset][snapshot]['used'])
else:
print()
if prune:
ranges[-1].append(snapshot)
for range in ranges:
if not range:
continue
to_delete = dataset+'@'+range[0]
if len(range) > 1:
to_delete += '%' + range[-1]
to_delete = to_delete.replace(' ', '')
if not to_delete:
continue
if args.verbose:
print('zfs destroy ' + to_delete)
if not args.test:
# destroy the snapshot
subprocess.call(['zfs', 'destroy', to_delete])

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# Runs smartctl to report current temperature of all disks.
JSON="["
DISKS=$(/sbin/sysctl -n kern.disks | cut -d= -f2)
for i in ${DISKS}
do
# Get temperature from smartctl (requires root).
[[ "${i}" = *"ada"* ]] && TEMP=$(/usr/local/sbin/smartctl -l scttemp /dev/$i | grep '^Current Temperature:' | awk '{print $3}')
[[ "${i}" = *"nvd"* ]] && DEVICE_NUMBER=$(echo ${i} | cut -c 4) && TEMP=$(smartctl -a /dev/nvme${DEVICE_NUMBER} | grep Temperature: | head -1 | awk '{print $2}')
if [ ${TEMP:-0} -gt 0 ]
then
JSON=$(echo "${JSON}{")
JSON=$(echo "${JSON}\"temperature\":${TEMP},")
JSON=$(echo "${JSON}\"disk\":\"${i}\"")
JSON=$(echo "${JSON}},")
fi
done
# Remove trailing "," on last field.
JSON=$(echo ${JSON} | sed 's/,$//')
echo -e "${JSON}]"

View File

@@ -0,0 +1,19 @@
---
- name: directories | create
ansible.builtin.file:
state: directory
path: "{{ item }}"
loop:
- "{{ homelab_homedir }}/letsencrypt"
- "{{ telegraf_dir }}"
- "{{ backups_dir }}servers/{{ ansible_facts['nodename'] }}"
- "{{ scripts_dir }}"
- name: directories | truenas
ansible.builtin.file:
state: directory
path: "{{ item }}"
loop:
- "{{ backups_dir }}servers/coreelec.{{ SECRET_DOMAIN }}"
- "{{ backups_dir }}servers/opnsense.{{ SECRET_DOMAIN }}"
when: "main_nas == true"

View File

@@ -0,0 +1,9 @@
---
- ansible.builtin.include_tasks: directories.yml
- ansible.builtin.include_tasks: scripts.yml
- ansible.builtin.include_tasks: telegraf.yml
- ansible.builtin.include_tasks: wireguard.yml
when: "main_nas == false"

View File

@@ -0,0 +1,25 @@
---
- name: scripts | copy scripts
ansible.builtin.copy:
src: "scripts/{{ item }}"
dest: "{{ scripts_dir }}/{{ item }}"
mode: 0755
loop:
- certificates_deploy.py
- snapshots_clearempty.py
- snapshots_prune.py
- telegraf_hddtemp.bash
- name: scripts | template scripts
ansible.builtin.template:
src: "scripts/{{ item.name }}"
dest: "{{ scripts_dir }}/{{ item.name }}"
mode: "{{ item.mode }}"
loop:
- { name: "backupconfig_cloudsync_pre.bash", mode: "0775" }
- { name: "certificates_deploy.bash", mode: "0775" }
- { name: "certificates_deploy.conf", mode: "0664" }
- { name: "snapshots_prune.sh", mode: "0775" }
- { name: "report_pools.sh", mode: "0775" }
- { name: "report_smart.sh", mode: "0775" }
- { name: "report_ups.sh", mode: "0775" }

View File

@@ -0,0 +1,10 @@
---
- name: telegraf | clone git repository
ansible.builtin.git:
repo: https://github.com/samuelkadolph/truenas-telegraf
dest: "{{ telegraf_dir }}"
- name: telegraf | copy configuration
ansible.builtin.template:
src: telegraf/telegraf.conf
dest: "{{ telegraf_dir }}/telegraf.conf"

View File

@@ -0,0 +1,17 @@
---
- name: wireguard | configuration
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
loop:
- {
src: "wireguard/{{ ansible_facts['nodename'] }}.conf",
dest: "{{ homelab_homedir }}/{{ wg_interface }}.conf",
mode: 400,
}
- {
src: "wireguard/ip-check.bash",
dest: "{{ homelab_homedir }}/wireguard-ip-check.bash",
mode: 700,
}

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# DEBUG
# set -x
# Configuration backup Cloud Sync pre-script
# Variables
SOURCE_FOLDER="/var/db/system/configs"
BACKUP_FOLDER="{{ backups_dir }}servers/{{ ansible_facts['nodename'] }}"
cd ${SOURCE_FOLDER}*
rsync --archive --delete --human-readable --delete ./ ${BACKUP_FOLDER}
test $? -ne 0 && FLAG_NOTIF=true
chmod -R 775 ${BACKUP_FOLDER}/*
chown -R homelab:homelab ${BACKUP_FOLDER}/*
# Keep the last 90 backups on disk
# find ${BACKUP_FOLDER}/* -mtime +90 -type f -delete

View File

@@ -0,0 +1,22 @@
#!/bin/bash
# DEBUG
# set -x
# Get certificates from remote server
# Variables
SCRIPT_PATH="{{ scripts_dir }}"
CERTIFICATE_PATH="{{ certificates_dir }}"
CONFIG_FILE="${SCRIPT_PATH}/certificates_deploy.conf"
# Check if cert has been uploaded last week
result=$(find ${CERTIFICATE_PATH}/cert.pem -mtime -7)
if [[ "$result" == "${CERTIFICATE_PATH}/cert.pem" ]]; then
# Deploy certificate
python ${SCRIPT_PATH}/certificates_deploy.py -c ${CONFIG_FILE}
test $? -ne 0 && FLAG_NOTIF=true
fi

View File

@@ -0,0 +1,48 @@
# Configuration file for deploy_certificates.py
[deploy]
# Choose one of the following authentication methods, "api_key" or "password" (comment out the other one).
# Auth via API keys is highly recommended, but is only available from TrueNAS (Core) 12.0 up.
# You can generate a new API key in the web interface under "Settings" (upper right) > "API Keys".
api_key = {{ root_api_key }}
# If you are on FreeNAS 11 or lower, set this to your FreeNAS root password
# password =
# Everything below here is optional
# cert_fqdn specifies the FQDN used for your certificate. Default is your system hostname
# cert_fqdn = foo.bar.baz
# connect_host specifies the hostname the script should attempt to connect to, to deploy the cert.
# Default is localhost (assuming the script is running on your FreeNAS box)
# connect_host = baz.bar.foo
# verify sets whether the script will attempt to verify the server's certificate with a HTTPS
# connection. Set to true if you're using a HTTPS connection to a remote host. If connect_host
# is set to localhost (or is unset), set to false. Default is false.
# verify = false
# privkey_path is the path to the certificate private key on your system. Default
# assumes you're using acme.sh:
# /root/.acme.sh/cert_fqdn/cert_fqdn.key
privkey_path = {{ certificates_dir }}/key.pem
# fullchain_path is the path to the full chain (leaf cert + intermediate certs)
# on your system. Default assumes you're using acme.sh:
# /root/.acme.sh/cert_fqdn/fullchain.cer
fullchain_path = {{ certificates_dir }}/fullchain.pem
# protocol sets the connection protocol, http or https. Include '://' at the end.
# Default is http
# protocol = https://
# port sets the port to use to connect. Default is 80. If protocol is https,
# this MUST be set to your https port.
# port = 443
# set ftp_enabled to true if you have the FTP service enabled on your FreeNAS. Default is false.
# ftp_enabled = true
{% if service_s3 is defined %}
s3_enabled = true
{% endif %}

View File

@@ -0,0 +1,162 @@
#!/bin/sh
### Parameters ###
# Specify your email address here:
email="truenas@{{ SECRET_EMAIL_DOMAIN }}"
# zpool output changed from FreeNAS version 11.0 to 11.1, breaking
# our parsing of the scrubErrors and scrubDate variables. Added a
# conditional to test for the FreeNAS version and parse accordingly.
# This changed again with the release of TrueNAS. Ironically, back to
# the way parsing worked with older versions of FreeNAS.
#
# We obtain the FreeBSD version using uname, as suggested by user
# Chris Moore on the FreeBSD forum.
#
# 'uname -K' gives 7-digit OS release and version, e.g.:
#
# FreeBSD 11.0 1100512
# FreeBSD 11.1 1101505
# FreeBSD 12.2 1202000
fbsd_relver=$(uname -K)
freenashost=$(hostname -s | tr '[:lower:]' '[:upper:]')
boundary="===== MIME boundary; FreeNAS server ${freenashost} ====="
logfile="/tmp/zpool_report.tmp"
subject="ZPool Status Report for ${freenashost}"
pools=$(zpool list -H -o name)
usedWarn=75
usedCrit=90
scrubAgeWarn=30
warnSymbol="?"
critSymbol="!"
### Set email headers ###
printf "%s\n" "To: ${email}
Subject: ${subject}
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary=\"$boundary\"
--${boundary}
Content-Type: text/html; charset=\"US-ASCII\"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<html><head></head><body><pre style=\"font-size:14px; white-space:pre\">" >> ${logfile}
###### summary ######
(
echo "########## ZPool status report summary for all pools on server ${freenashost} ##########"
echo ""
echo "+--------------+--------+------+------+------+----+----+--------+------+-----+"
echo "|Pool Name |Status |Read |Write |Cksum |Used|Frag|Scrub |Scrub |Last |"
echo "| | |Errors|Errors|Errors| | |Repaired|Errors|Scrub|"
echo "| | | | | | | |Bytes | |Age |"
echo "+--------------+--------+------+------+------+----+----+--------+------+-----+"
) >> ${logfile}
for pool in $pools; do
if [ "$fbsd_relver" -ge 1101000 ]; then
frag="$(zpool list -H -o frag "$pool")"
else
if [ "${pool}" = "freenas-boot" ] || [ "${pool}" = "boot-pool" ]; then
frag=""
else
frag="$(zpool list -H -o frag "$pool")"
fi
fi
status="$(zpool list -H -o health "$pool")"
errors="$(zpool status "$pool" | grep -E "(ONLINE|DEGRADED|FAULTED|UNAVAIL|REMOVED)[ \t]+[0-9]+")"
readErrors=0
for err in $(echo "$errors" | awk '{print $3}'); do
if echo "$err" | grep -E -q "[^0-9]+"; then
readErrors=1000
break
fi
readErrors=$((readErrors + err))
done
writeErrors=0
for err in $(echo "$errors" | awk '{print $4}'); do
if echo "$err" | grep -E -q "[^0-9]+"; then
writeErrors=1000
break
fi
writeErrors=$((writeErrors + err))
done
cksumErrors=0
for err in $(echo "$errors" | awk '{print $5}'); do
if echo "$err" | grep -E -q "[^0-9]+"; then
cksumErrors=1000
break
fi
cksumErrors=$((cksumErrors + err))
done
if [ "$readErrors" -gt 999 ]; then readErrors=">1K"; fi
if [ "$writeErrors" -gt 999 ]; then writeErrors=">1K"; fi
if [ "$cksumErrors" -gt 999 ]; then cksumErrors=">1K"; fi
used="$(zpool list -H -p -o capacity "$pool")"
scrubRepBytes="N/A"
scrubErrors="N/A"
scrubAge="N/A"
if [ "$(zpool status "$pool" | grep "scan" | awk '{print $2}')" = "scrub" ]; then
scrubRepBytes="$(zpool status "$pool" | grep "scan" | awk '{print $4}')"
if [ "$fbsd_relver" -gt 1101000 ] && [ "$fbsd_relver" -lt 1200000 ]; then
scrubErrors="$(zpool status "$pool" | grep "scan" | awk '{print $10}')"
scrubDate="$(zpool status "$pool" | grep "scan" | awk '{print $17"-"$14"-"$15"_"$16}')"
else
scrubErrors="$(zpool status "$pool" | grep "scan" | awk '{print $8}')"
scrubDate="$(zpool status "$pool" | grep "scan" | awk '{print $15"-"$12"-"$13"_"$14}')"
fi
scrubTS="$(date -j -f "%Y-%b-%e_%H:%M:%S" "$scrubDate" "+%s")"
currentTS="$(date "+%s")"
scrubAge=$((((currentTS - scrubTS) + 43200) / 86400))
fi
if [ "$status" = "FAULTED" ] || [ "$used" -gt "$usedCrit" ]; then
symbol="$critSymbol"
elif [ "$scrubErrors" != "N/A" ] && [ "$scrubErrors" != "0" ]; then
symbol="$critSymbol"
elif [ "$status" != "ONLINE" ] \
|| [ "$readErrors" != "0" ] \
|| [ "$writeErrors" != "0" ] \
|| [ "$cksumErrors" != "0" ] \
|| [ "$used" -gt "$usedWarn" ] \
|| [ "$(echo "$scrubAge" | awk '{print int($1)}')" -gt "$scrubAgeWarn" ]; then
symbol="$warnSymbol"
elif [ "$scrubRepBytes" != "0" ] && [ "$scrubRepBytes" != "0B" ] && [ "$scrubRepBytes" != "N/A" ]; then
symbol="$warnSymbol"
else
symbol=" "
fi
(
printf "|%-12s %1s|%-8s|%6s|%6s|%6s|%3s%%|%4s|%8s|%6s|%5s|\n" \
"$pool" "$symbol" "$status" "$readErrors" "$writeErrors" "$cksumErrors" \
"$used" "$frag" "$scrubRepBytes" "$scrubErrors" "$scrubAge"
) >> ${logfile}
done
(
echo "+--------------+--------+------+------+------+----+----+--------+------+-----+"
) >> ${logfile}
###### for each pool ######
for pool in $pools; do
(
echo ""
echo "########## ZPool status report for ${pool} ##########"
echo ""
zpool status -v "$pool"
) >> ${logfile}
done
printf "%s\n" "</pre></body></html>
--${boundary}--" >> ${logfile}
### Send report ###
if [ -z "${email}" ]; then
echo "No email address specified, information available in ${logfile}"
else
sendmail -t -oi < ${logfile}
rm ${logfile}
fi

View File

@@ -0,0 +1,267 @@
#!/bin/sh
### Parameters ###
# Specify your email address here:
email="truenas@{{ SECRET_EMAIL_DOMAIN }}"
# Full path to 'smartctl' program:
smartctl=/usr/local/sbin/smartctl
freenashost=$(hostname -s | tr '[:lower:]' '[:upper:]')
boundary="===== MIME boundary; FreeNAS server ${freenashost} ====="
logfile="smart_report.tmp"
subject="SMART Status Report for ${freenashost}"
tempWarn=40
tempCrit=45
sectorsCrit=10
testAgeWarn=1
warnSymbol="?"
critSymbol="!"
Drive_count=0
SATA_count=0
SAS_count=0
Drive_list=""
SATA_list=""
SAS_list=""
# Get list of SMART-enabled drives
get_smart_drives()
{
gs_drives=$("$smartctl" --scan | awk '{print $1}')
for gs_drive in $gs_drives; do
gs_smart_flag=$("$smartctl" -i "$gs_drive" | grep -E "SMART support is:[[:blank:]]+Enabled" | awk '{print $4}')
if [ "$gs_smart_flag" = "Enabled" ]; then
Drive_list="$Drive_list $gs_drive"
Drive_count=$((Drive_count + 1))
fi
done
}
# Get list of SATA disks, including older drives that only report an ATA version
get_sata_drives()
{
for drive in $Drive_list; do
lFound=0
gsata_smart_flag=$("$smartctl" -i "$drive" | grep -E "SATA Version is:[[:blank:]]" | awk '{print $4}')
if [ "$gsata_smart_flag" = "SATA" ]; then
lFound=$((lFound + 1))
else
gsata_smart_flag=$("$smartctl" -i "$drive" | grep -E "ATA Version is:[[:blank:]]" | awk '{print $1}')
if [ "$gsata_smart_flag" = "ATA" ]; then
lFound=$((lFound + 1))
fi
fi
if [ $lFound -gt 0 ]; then
SATA_list="$SATA_list $drive"
SATA_count=$((SATA_count + 1))
fi
done
}
# Get list of SAS disks
get_sas_drives()
{
for drive in $Drive_list; do
gsas_smart_flag=$("$smartctl" -i "$drive" | grep -E "Transport protocol:[[:blank:]]+SAS" | awk '{print $3}')
if [ "$gsas_smart_flag" = "SAS" ]; then
SAS_list="$SAS_list $drive"
SAS_count=$((SAS_count + 1))
fi
done
}
### Fetch drive lists ###
get_smart_drives
get_sata_drives
get_sas_drives
### Set email headers ###
printf "%s\n" "To: ${email}
Subject: ${subject}
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary=\"$boundary\"
--${boundary}
Content-Type: text/html; charset=\"US-ASCII\"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<html><head></head><body><pre style=\"font-size:14px; white-space:pre\">" > ${logfile}
if [ $Drive_count -eq 0 ]; then
echo "##### No SMART-enabled disks found on this system #####" >> "$logfile"
fi
###### Summary for SATA drives ######
if [ $SATA_count -gt 0 ]; then
(
echo "########## SMART status report summary for all SATA drives on server ${freenashost} ##########"
echo ""
echo "+------+------------------------+----+------+-----+-----+-------+-------+--------+------+----------+------+-----------+----+"
echo "|Device|Serial |Temp| Power|Start|Spin |ReAlloc|Current|Offline |Seek |Total |High | Command|Last|"
echo "| |Number | | On |Stop |Retry|Sectors|Pending|Uncorrec|Errors|Seeks |Fly | Timeout|Test|"
echo "| | | | Hours|Count|Count| |Sectors|Sectors | | |Writes| Count |Age |"
echo "+------+------------------------+----+------+-----+-----+-------+-------+--------+------+----------+------+-----------+----+"
) >> "$logfile"
###### Detail information for each SATA drive ######
for drive in $SATA_list; do
(
devid=$(basename "$drive")
lastTestHours=$("$smartctl" -l selftest "$drive" | grep "# 1" | awk '{print $9}')
"$smartctl" -A -i -v 7,hex48 "$drive" | \
awk -v device="$devid" -v tempWarn="$tempWarn" -v tempCrit="$tempCrit" -v sectorsCrit="$sectorsCrit" \
-v testAgeWarn="$testAgeWarn" -v warnSymbol="$warnSymbol" -v critSymbol="$critSymbol" \
-v lastTestHours="$lastTestHours" '
/Serial Number:/{serial=$3}
/190 Airflow_Temperature/{temp=$10}
/194 Temperature/{temp=$10}
/Power_On_Hours/{split($10,a,"+");sub(/h/,"",a[1]);onHours=a[1];}
/Start_Stop_Count/{startStop=$10}
/Spin_Retry_Count/{spinRetry=$10}
/Reallocated_Sector/{reAlloc=$10}
/Current_Pending_Sector/{pending=$10}
/Offline_Uncorrectable/{offlineUnc=$10}
/Seek_Error_Rate/{seekErrors=("0x" substr($10,3,4));totalSeeks=("0x" substr($10,7))}
/High_Fly_Writes/{hiFlyWr=$10}
/Command_Timeout/{cmdTimeout=$10}
END {
testAge=sprintf("%.0f", (onHours - lastTestHours) / 24);
if (temp > tempCrit || reAlloc > sectorsCrit || pending > sectorsCrit || offlineUnc > sectorsCrit)
device=device " " critSymbol;
else if (temp > tempWarn || reAlloc > 0 || pending > 0 || offlineUnc > 0 || testAge > testAgeWarn)
device=device " " warnSymbol;
seekErrors=sprintf("%d", seekErrors);
totalSeeks=sprintf("%d", totalSeeks);
if (totalSeeks == "0") {
seekErrors="N/A";
totalSeeks="N/A";
}
if (temp > tempWarn || temp > tempCrit) temp=temp"*"
if (reAlloc > 0 || reAlloc > sectorsCrit) reAlloc=reAlloc"*"
if (pending > 0 || pending > sectorsCrit) pending=pending"*"
if (offlineUnc > 0 || offlineUnc > sectorsCrit) offlineUnc=offlineUnc"*"
if (testAge > testAgeWarn) testAge=testAge"*"
if (hiFlyWr == "") hiFlyWr="N/A";
if (cmdTimeout == "") cmdTimeout="N/A";
printf "|%-6s|%-24s|%-4s|%6s|%5s|%5s|%7s|%7s|%8s|%6s|%10s|%6s|%11s|%4s|\n",
device, serial, temp, onHours, startStop, spinRetry, reAlloc, pending, offlineUnc,
seekErrors, totalSeeks, hiFlyWr, cmdTimeout, testAge;
}'
) >> "$logfile"
done
(
echo "+------+------------------------+----+------+-----+-----+-------+-------+--------+------+----------+------+-----------+----+"
) >> "$logfile"
fi
###### Summary for SAS drives ######
if [ $SAS_count -gt 0 ]; then
(
if [ $SATA_count -gt 0 ]; then
echo ""
fi
echo "########## SMART status report summary for all SAS drives on server ${freenashost} ##########"
echo ""
echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
echo "|Device|Serial |Temp|Start|Load |Defect|Uncorr|Uncorr|Uncorr|Non |"
echo "| |Number | |Stop |Unload|List |Read |Write |Verify|Medium|"
echo "| | | |Count|Count |Elems |Errors|Errors|Errors|Errors|"
echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
) >> "$logfile"
###### Detail information for each SAS drive ######
for drive in $SAS_list; do
(
devid=$(basename "$drive")
"$smartctl" -a "$drive" | \
awk -v device="$devid" -v tempWarn="$tempWarn" -v tempCrit="$tempCrit" \
-v warnSymbol="$warnSymbol" -v critSymbol="$critSymbol" '\
/Serial number:/{serial=$3}
/Current Drive Temperature:/{temp=$4} \
/start-stop cycles:/{startStop=$4} \
/load-unload cycles:/{loadUnload=$4} \
/grown defect list:/{defectList=$6} \
/read:/{readErrors=$8} \
/write:/{writeErrors=$8} \
/verify:/{verifyErrors=$8} \
/Non-medium error count:/{nonMediumErrors=$4} \
END {
if (temp > tempCrit)
device=device " " critSymbol;
else if (temp > tempWarn)
device=device " " warnSymbol;
printf "|%-6s|%-24s| %3s|%5s|%6s|%6s|%6s|%6s|%6s|%6s|\n",
device, serial, temp, startStop, loadUnload, defectList, \
readErrors, writeErrors, verifyErrors, nonMediumErrors;
}'
) >> "$logfile"
done
(
echo "+------+------------------------+----+-----+------+------+------+------+------+------+"
) >> "$logfile"
fi
if [ $SATA_count -gt 0 ] || [ $SAS_count -gt 0 ]; then
###### Emit SATA drive information ######
for drive in $SATA_list; do
vendor=$("$smartctl" -i "$drive" | grep "Vendor:" | awk '{print $NF}')
if [ -z "$vendor" ]; then
dfamily=$("$smartctl" -i "$drive" | grep "Model Family" | awk '{print $3, $4, $5, $6, $7}' | sed -e 's/[[:space:]]*$//')
dmodel=$("$smartctl" -i "$drive" | grep "Device Model" | awk '{print $3, $4, $5, $6, $7}' | sed -e 's/[[:space:]]*$//')
if [ -z "$dfamily" ]; then
dinfo=$dmodel
else
dinfo="$dfamily ($dmodel)"
fi
else
product=$("$smartctl" -i "$drive" | grep "Product:" | awk '{print $NF}')
revision=$("$smartctl" -i "$drive" | grep "Revision:" | awk '{print $NF}')
dinfo="$vendor $product $revision"
fi
serial=$("$smartctl" -i "$drive" | grep "Serial Number" | awk '{print $3}')
(
echo ""
echo "########## SATA drive $drive Serial: $serial"
echo "########## ${dinfo}"
"$smartctl" -n never -H -A -l error "$drive"
"$smartctl" -n never -l selftest "$drive" | grep "# 1 \\|Num" | cut -c6-
) >> "$logfile"
done
###### Emit SAS drive information ######
for drive in $SAS_list; do
devid=$(basename "$drive")
brand=$("$smartctl" -i "$drive" | grep "Product" | sed "s/^.* //")
serial=$("$smartctl" -i "$drive" | grep "Serial number" | sed "s/^.* //")
(
echo ""
echo "########## SMART status for SAS drive $drive $serial (${brand}) ##########"
"$smartctl" -n never -H -A -l error "$drive"
"$smartctl" -n never -l selftest "$drive" | grep "# 1 \\|Num" | cut -c6-
) >> "$logfile"
done
fi
sed -i '' -e '/smartctl 7.*/d' "$logfile"
sed -i '' -e '/smartctl 6.*/d' "$logfile"
sed -i '' -e '/smartctl 5.*/d' "$logfile"
sed -i '' -e '/smartctl 4.*/d' "$logfile"
sed -i '' -e '/Copyright/d' "$logfile"
sed -i '' -e '/=== START OF READ/d' "$logfile"
sed -i '' -e '/SMART Attributes Data/d' "$logfile"
sed -i '' -e '/Vendor Specific SMART/d' "$logfile"
sed -i '' -e '/SMART Error Log Version/d' "$logfile"
printf "%s\n" "</pre></body></html>
--${boundary}--" >> ${logfile}
### Send report ###
if [ -z "${email}" ]; then
echo "No email address specified, information available in ${logfile}"
else
sendmail -t -oi < "$logfile"
rm "$logfile"
fi

View File

@@ -0,0 +1,93 @@
#!/bin/sh
# Send UPS report to designated email address
# Reference: http://networkupstools.org/docs/developer-guide.chunked/apas01.html
### Parameters ###
# Specify your email address here:
email="truenas@{{ SECRET_EMAIL_DOMAIN }}"
# Set to a value greater than zero to include all available UPSC
# variables in the report:
senddetail=0
freenashost=$(hostname -s)
freenashostuc=$(hostname -s | tr '[:lower:]' '[:upper:]')
boundary="===== MIME boundary; FreeNAS server ${freenashost} ====="
logfile="/tmp/ups_report.tmp"
subject="UPS Status Report for ${freenashostuc}"
### Set email headers ###
printf "%s\n" "To: ${email}
Subject: ${subject}
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary=\"$boundary\"
--${boundary}
Content-Type: text/html; charset=\"US-ASCII\"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
<html><head></head><body><pre style=\"font-size:14px; white-space:pre\">" >> ${logfile}
# Get a list of all ups devices installed on the system:
upslist=$(upsc -l "${freenashost}")
### Set email body ###
(
date "+Time: %Y-%m-%d %H:%M:%S"
echo ""
for ups in $upslist; do
ups_type=$(upsc "${ups}" device.type 2> /dev/null | tr '[:lower:]' '[:upper:]')
ups_mfr=$(upsc "${ups}" ups.mfr 2> /dev/null)
ups_model=$(upsc "${ups}" ups.model 2> /dev/null)
ups_serial=$(upsc "${ups}" ups.serial 2> /dev/null)
ups_status=$(upsc "${ups}" ups.status 2> /dev/null)
ups_load=$(upsc "${ups}" ups.load 2> /dev/null)
ups_realpower=$(upsc "${ups}" ups.realpower 2> /dev/null)
ups_realpowernominal=$(upsc "${ups}" ups.realpower.nominal 2> /dev/null)
ups_batterycharge=$(upsc "${ups}" battery.charge 2> /dev/null)
ups_batteryruntime=$(upsc "${ups}" battery.runtime 2> /dev/null)
ups_batteryvoltage=$(upsc "${ups}" battery.voltage 2> /dev/null)
ups_inputvoltage=$(upsc "${ups}" input.voltage 2> /dev/null)
ups_outputvoltage=$(upsc "${ups}" output.voltage 2> /dev/null)
printf "=== %s %s, model %s, serial number %s\n\n" "${ups_mfr}" "${ups_type}" "${ups_model}" "${ups_serial} ==="
echo "Name: ${ups}"
echo "Status: ${ups_status}"
echo "Output Load: ${ups_load}%"
if [ ! -z "${ups_realpower}" ]; then
echo "Real Power: ${ups_realpower}W"
fi
if [ ! -z "${ups_realpowernominal}" ]; then
echo "Real Power: ${ups_realpowernominal}W (nominal)"
fi
if [ ! -z "${ups_inputvoltage}" ]; then
echo "Input Voltage: ${ups_inputvoltage}V"
fi
if [ ! -z "${ups_outputvoltage}" ]; then
echo "Output Voltage: ${ups_outputvoltage}V"
fi
echo "Battery Runtime: ${ups_batteryruntime}s"
echo "Battery Charge: ${ups_batterycharge}%"
echo "Battery Voltage: ${ups_batteryvoltage}V"
echo ""
if [ $senddetail -gt 0 ]; then
echo "=== ALL AVAILABLE UPS VARIABLES ==="
upsc "${ups}"
echo ""
fi
done
) >> ${logfile}
printf "%s\n" "</pre></body></html>
--${boundary}--" >> ${logfile}
### Send report ###
if [ -z "${email}" ]; then
echo "No email address specified, information available in ${logfile}"
else
sendmail -t -oi < ${logfile}
rm ${logfile}
fi

View File

@@ -0,0 +1,17 @@
#!/bin/sh
# DEBUG
# set -x
# Variables
SCRIPT_PATH="{{ scripts_dir }}"
INTERVAL="{{ snapshots_interval }}"
POOL_NAME="{{ pool_name }}"
# Prune
${SCRIPT_PATH}/snapshots_prune.py --recursive --intervals ${INTERVAL} ${POOL_NAME}
${SCRIPT_PATH}/snapshots_clearempty.py --recursive ${POOL_NAME}
{% if ansible_facts['nodename'] == "truenas.{{ SECRET_DOMAIN }}" %}
${SCRIPT_PATH}/snapshots_prune.py --recursive --intervals daily:14 storage/video
{% endif %}

View File

@@ -0,0 +1,49 @@
[agent]
interval = "20s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "0s"
flush_interval = "30s"
flush_jitter = "0s"
precision = ""
debug = false
quiet = false
hostname = "{{ ansible_facts['nodename'] }}"
omit_hostname = false
[[outputs.prometheus_client]]
listen = ":9273"
metric_version = 2
path = "/metrics"
string_as_label = true
expiration_interval = "60m"
[[inputs.cpu]]
percpu = true
totalcpu = true
[[inputs.diskio]]
[[inputs.exec]]
commands = ["{{ telegraf_dir }}/cputemp"]
data_format = "influx"
[[inputs.exec]]
commands = ["{{ scripts_dir }}/telegraf_hddtemp.bash"]
name_override = "disktemp"
timeout = "5s"
data_format = "json"
tag_keys = ["disk"]
[[inputs.mem]]
[[inputs.net]]
interfaces = ["em0", "igb0"]
[[inputs.system]]
[[inputs.netstat]]
[[inputs.zfs]]
poolMetrics = true

View File

@@ -0,0 +1,24 @@
#!/bin/bash
# Check status of interface
# {{ wg_interface }}: name of the interface to check
# {{ dns_hostname }}: the name of the peer whose IP should be checked
cip=$(wg show {{ wg_interface }} endpoints | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}")
echo "Wireguard peer IP from Interface: $cip"
pingip=$(ping -c 1 {{ ping_ip }} &> /dev/null && echo success || echo fail) #change ip to target server
digIP=$(dig +short {{ dns_hostname }}) #the peer address must be set
echo "$digIP"
if [ "$digIP" != "$cip" ]
then
echo "IPs doesn't match, restarting wireguard"
wg-quick down {{ homelab_homedir }}/{{ wg_interface }}.conf
wg-quick up {{ homelab_homedir }}/{{ wg_interface }}.conf
elif [ "$pingip" != "success" ]
then
echo "Ping failed, restarting wireguard..."
wg-quick down {{ homelab_homedir }}/{{ wg_interface }}.conf
wg-quick up {{ homelab_homedir }}/{{ wg_interface }}.conf
else
echo "OK"
#nothing else todo
fi

View File

@@ -0,0 +1,11 @@
[Interface]
Address = 10.10.0.2/32
ListenPort = 51820
PrivateKey = 8Gw/9MJpo8AwSmEY8W/zgPu6z0Lvn7E2LvRRDpkMhFo=
DNS = 192.168.8.1, {{ SECRET_DOMAIN }}
[Peer]
PublicKey = K7kgSuPwH2NA7FeLHwvGMX02kvhD8DxHgL/wflsgx34=
AllowedIPs = 0.0.0.0/0
Endpoint = services.{{ SECRET_DOMAIN }}:51820
PersistentKeepalive = 25

View File

@@ -0,0 +1,42 @@
fonts_dir: ~/.local/share/fonts
icons_dir: ~/.local/share/icons
newaita_iconset_url: "https://github.com/cbrnix/Newaita/archive/1.09.20a.tar.gz"
nas_hostname: truenas
mnt_dir: /mnt
nas_dir: ~/NAS
nfs_shares:
- {
src: "{{ nas_hostname }}:/mnt/storage/downloads",
path: "{{ mnt_dir }}/downloads",
link: "{{ nas_dir }}/downloads",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/shared-documents",
path: "{{ mnt_dir }}/shared-documents",
link: "{{ nas_dir }}/shared-documents",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/home/claude",
path: "{{ mnt_dir }}/home-claude",
link: "{{ nas_dir }}/home-claude",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/home/helene",
path: "{{ mnt_dir }}/home-helene",
link: "{{ nas_dir }}/home-helene",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/photo",
path: "{{ mnt_dir }}/photo",
link: "{{ nas_dir }}/photo",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/music",
path: "{{ mnt_dir }}/music",
link: "/home/claude/Music",
}
- {
src: "{{ nas_hostname }}:/mnt/storage/video",
path: "{{ mnt_dir }}/video",
link: "/home/claude/Videos",
}

View File

@@ -0,0 +1,11 @@
#!/bin/bash
mkdir -p /run/media/claude/local-backups/{backups,documents,downloads,photo,piracy,jails}
# Disk one (4TB)
sudo rsync -avhP /mnt/backups/ /run/media/claude/local-backups/backups/ --delete
sudo rsync -avhP /mnt/documents/ /run/media/claude/local-backups/documents/ --delete
sudo rsync -avhP /mnt/downloads/ /run/media/claude/local-backups/downloads/ --delete
sudo rsync -avhP /mnt/photo/ /run/media/claude/local-backups/photo/ --delete
sudo rsync -avhP /mnt/piracy/ /run/media/claude/local-backups/piracy/ --delete
sudo rsync -avhP /mnt/iocage/jails/ /run/media/claude/local-backups/jails/ --delete

View File

@@ -0,0 +1,9 @@
#!/bin/bash
# Disk two (2.5TB)
mkdir -p /run/media/claude/local-backups/music
mkdir -p /run/media/claude/local-backups/home/{claude,helene}
sudo rsync -avhP /mnt/home-claude/ /run/media/claude/local-backups/home/claude/ --delete
sudo rsync -avhP /mnt/home-helene/ /run/media/claude/local-backups/home/helene/ --delete
sudo rsync -avhP /mnt/music/ /run/media/claude/local-backups/music/ --delete

View File

@@ -0,0 +1,3 @@
#!/bin/bash
pip3 list --outdated --user --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip3 install -U --user

View File

@@ -0,0 +1,53 @@
[GENERAL]
# Enable or disable the script execution
Enabled: True
# SYSFS path for checking if the system is running on AC power
Sysfs_Power_Path: /sys/class/power_supply/AC*/online
## Settings to apply while connected to Battery power
[BATTERY]
# Update the registers every this many seconds
Update_Rate_s: 30
# Max package power for time window #1
PL1_Tdp_W: 29
# Time window #1 duration
PL1_Duration_s: 28
# Max package power for time window #2
PL2_Tdp_W: 44
# Time window #2 duration
PL2_Duration_S: 0.002
# Max allowed temperature before throttling
Trip_Temp_C: 85
# Set cTDP to normal=0, down=1 or up=2 (EXPERIMENTAL)
cTDP: 0
## Settings to apply while connected to AC power
[AC]
# Update the registers every this many seconds
Update_Rate_s: 5
# Max package power for time window #1
PL1_Tdp_W: 44
# Time window #1 duration
PL1_Duration_s: 28
# Max package power for time window #2
PL2_Tdp_W: 44
# Time window #2 duration
PL2_Duration_S: 0.002
# Max allowed temperature before throttling
Trip_Temp_C: 95
# Set HWP energy performance hints to 'performance' on high load (EXPERIMENTAL)
HWP_Mode: False
# Set cTDP to normal=0, down=1 or up=2 (EXPERIMENTAL)
cTDP: 0
[UNDERVOLT]
# CPU core voltage offset (mV)
CORE: -105
# Integrated GPU voltage offset (mV)
GPU: -85
# CPU cache voltage offset (mV)
CACHE: -105
# System Agent voltage offset (mV)
UNCORE: -85
# Analog I/O voltage offset (mV)
ANALOGIO: 0

View File

@@ -0,0 +1,10 @@
[Interface]
Address = 10.10.0.4/32
ListenPort = 51820
PrivateKey = kPbM3V+bV74avE/GXFwhOrmaRSf3p34bm/aR3A72GG4=
DNS = 10.10.0.1
[Peer]
PublicKey = K7kgSuPwH2NA7FeLHwvGMX02kvhD8DxHgL/wflsgx34=
AllowedIPs = 0.0.0.0/0
Endpoint = services.{{ SECRET_DOMAIN }}:51820

View File

@@ -0,0 +1,7 @@
[gitlab.com_paulcarroty_vscodium_repo]
name=gitlab.com_paulcarroty_vscodium_repo
baseurl=https://paulcarroty.gitlab.io/vscodium-deb-rpm-repo/rpms/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://gitlab.com/paulcarroty/vscodium-deb-rpm-repo/-/raw/master/pub.gpg

View File

@@ -0,0 +1,2 @@
#https://www.2daygeek.com/remove-delete-old-unused-kernels-centos-fedora-rhel/
installonly_limit=3

View File

@@ -0,0 +1,15 @@
---
- name: configuration | include vars
ansible.builtin.include_vars:
file: vars/{{ ansible_facts['nodename'] }}.yml
- name: configuration | create chezmoi directory
ansible.builtin.file:
state: directory
path: ~/.config/chezmoi
- name: configuration | templating chezmoi.toml
ansible.builtin.template:
src: chezmoi.toml.j2
dest: ~/.config/chezmoi/chezmoi.toml
mode: 0600

View File

@@ -0,0 +1,16 @@
---
- name: gnome | create directories
ansible.builtin.file:
state: directory
path: "{{ item }}"
loop:
- "{{ fonts_dir }}"
- "{{ icons_dir }}"
- name: gnome | download nerd fonts
ansible.builtin.get_url:
url: "{{ item }}"
dest: "{{ fonts_dir }}"
loop:
- https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/FiraCode/Retina/complete/Fira%20Code%20Retina%20Nerd%20Font%20Complete.ttf
- https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/FiraCode/Retina/complete/Fira%20Code%20Retina%20Nerd%20Font%20Complete%20Mono.ttf

View File

@@ -0,0 +1,13 @@
---
- name: gpg | create directory
ansible.builtin.file:
state: directory
path: ~/.gnupg
mode: 0700
# https://github.com/drduh/YubiKey-Guide#using-keys
- name: gpg | get gpg configuration
ansible.builtin.get_url:
url: https://raw.githubusercontent.com/drduh/config/master/gpg.conf
dest: ~/.gnupg/gpg.conf
mode: 0600

View File

@@ -0,0 +1,56 @@
---
- ansible.builtin.include_tasks: system.yml
tags:
- system
- ansible.builtin.include_tasks: repositories.yml
tags:
- packages
- ansible.builtin.include_tasks: packages-prerequisites.yml
tags:
- packages
- ansible.builtin.include_tasks: packages-common.yml
tags:
- packages
- ansible.builtin.include_tasks: packages-claude-fixe-fedora.yml
tags:
- packages
when: ansible_facts['nodename'] == "claude-fixe-fedora"
- ansible.builtin.include_tasks: packages-claude-thinkpad-fedora.yml
tags:
- packages
when: ansible_facts['nodename'] == "claude-thinkpad-fedora"
- ansible.builtin.include_tasks: packages-post.yml
tags:
- packages
- ansible.builtin.include_tasks: chezmoi.yml
tags:
- chezmoi
- ansible.builtin.include_tasks: gpg.yml
tags:
- gpg
- ansible.builtin.include_tasks: shell.yml
tags:
- shell
- ansible.builtin.include_tasks: gnome.yml
tags:
- gnome
- ansible.builtin.include_tasks: nfs.yml
tags:
- nfs
when: ansible_facts['nodename'] == "claude-fixe-fedora"
- ansible.builtin.include_tasks: wireguard.yml
tags:
- wireguard
when: ansible_facts['nodename'] == "claude-thinkpad-fedora"

View File

@@ -0,0 +1,63 @@
---
- name: nfs | create root directory
ansible.builtin.file:
state: directory
path: "{{ mnt_dir }}"
mode: 0777
become: true
- name: nfs | create directories
ansible.builtin.file:
state: directory
path: "{{ item.path }}"
loop: "{{ nfs_shares }}"
become: true
- name: nfs | mount shares
ansible.builtin.mount:
state: present
path: "{{ item.path }}"
src: "{{ item.src }}"
fstype: nfs4
opts: _netdev
with_items: "{{ nfs_shares }}"
become: true
- name: nfs | create links dir
ansible.builtin.file:
state: directory
path: "{{ nas_dir }}"
- name: nfs | stat music folder
ansible.builtin.stat:
path: ~/Music
register: music
- name: nfs | remove music folder
file:
path: ~/Music
state: absent
when: music.stat.isdir is defined and music.stat.isdir
- name: nfs | stat videos folder
ansible.builtin.stat:
path: ~/Videos
register: videos
- name: nfs | remove videos folder
file:
path: ~/Videos
state: absent
when: videos.stat.isdir is defined and videos.stat.isdir
- name: nfs | stat music folder
ansible.builtin.stat:
path: ~/Music
register: music
- name: nfs | create links
ansible.builtin.file:
state: link
src: "{{ item.path }}"
dest: "{{ item.link }}"
with_items: "{{ nfs_shares }}"

View File

@@ -0,0 +1,27 @@
---
- name: packages-claude-fixe-fedora | dnf
ansible.builtin.dnf:
name:
- akmod-nvidia
- libva-utils
- libva-vdpau-driver
- handbrake
- vdpauinfo
become: true
- name: packages-claude-fixe-fedora | flatpak
community.general.flatpak:
name: "{{ item }}"
state: present
loop:
- https://dl.flathub.org/repo/appstream/fr.handbrake.ghb.flatpakref
- https://dl.flathub.org/repo/appstream/org.bunkus.mkvtoolnix-gui.flatpakref
become: true
- name: packages-claude-fixe-fedora | brew
community.general.homebrew:
name:
- jpeg-archive
- parallel
path: /home/{{ lookup('env', 'USER') }}/.linuxbrew/bin
state: present

View File

@@ -0,0 +1,14 @@
---
- name: packages-claude-thinkpad-fedora | dnf
ansible.builtin.dnf:
name:
- tlp
- wireguard-tools
become: true
- name: packages-claude-thinkpad-fedora | tlp-ui
ansible.builtin.pip:
name:
- git+https://github.com/d4nj1/TLPUI.git
state: present
become: true

View File

@@ -0,0 +1,99 @@
---
- name: packages-common | dnf
ansible.builtin.dnf:
name:
- codium
- mpv
- resilio-sync
- gnome-tweak-tool
- la-capitaine-cursor-theme
- git
- fish
- alacritty
- redhat-rpm-config
- python3-devel
- python3-virtualenv
- ffmpeg-libs
- nano
- nfs-utils
- libgtop2-devel
- fuse-exfat
- exfat-utils
- openssl
- openssl-devel
- libacl-devel
- gcc-c++
- picard
- pinta
- calibre
- mediawriter
- hugo
- stress
- vlc
- p7zip
- p7zip-plugins
- lsd
- bat
- fzf
- fd-find
- remmina
- yp-tools
- ffmpeg
- deadbeef
- nmap
- jq
- gnupg
- steam
- npm
- ShellCheck
- gnome-extensions-app
- neovim
- brave-browser
- starship
- tmux
- cawbird
- age
state: present
update_cache: yes
become: true
- name: packages-common | python
ansible.builtin.pip:
name:
- borgbackup
- yt-dlp
- s-tui
- pylint
- pre-commit
- comictagger
state: present
extra_args: --user
- name: packages-common | flatpak
community.general.flatpak:
name: "{{ item }}"
state: present
loop:
- https://dl.flathub.org/repo/appstream/com.borgbase.Vorta.flatpakref
- https://dl.flathub.org/repo/appstream/com.discordapp.Discord.flatpakref
- https://dl.flathub.org/repo/appstream/com.bitwarden.desktop.flatpakref
- https://dl.flathub.org/repo/appstream/net.mediaarea.MediaInfo.flatpakref
- https://dl.flathub.org/repo/appstream/net.cozic.joplin_desktop.flatpakref
- https://dl.flathub.org/repo/appstream/uk.co.ibboard.cawbird.flatpakref
become: true
- name: packages-common | brew
community.general.homebrew:
name:
- minio/stable/mc
- kubectl
- helm
- kustomize
- fluxcd/tap/flux
- sops
- gh
- derailed/popeye/popeye
- chezmoi
path: /home/{{ lookup('env', 'USER') }}/.linuxbrew/bin
state: present
update_homebrew: yes

View File

@@ -0,0 +1,14 @@
---
- name: packages-post | modify resilio-sync service file
ansible.builtin.replace:
path: /usr/lib/systemd/user/resilio-sync.service
regexp: "multi-user"
replace: "default"
become: true
- name: packages-post | activate resilio-sync service
ansible.builtin.systemd:
name: resilio-sync
scope: user
state: started
enabled: yes

View File

@@ -0,0 +1,18 @@
---
- name: packages-prerequisites | clone homebrew GitHub repo
ansible.builtin.git:
repo: "https://github.com/Homebrew/brew"
dest: "/home/{{ lookup('env', 'USER') }}/.linuxbrew/Homebrew"
version: "master"
- name: packages-prerequisites | create bin directory for homebrew
ansible.builtin.file:
path: "/home/{{ lookup('env', 'USER') }}/.linuxbrew/bin"
state: directory
- name: packages-prerequisites | create a symbolic link for brew
ansible.builtin.file:
src: "/home/{{ lookup('env', 'USER') }}/.linuxbrew/Homebrew/bin/brew"
dest: "/home/{{ lookup('env', 'USER') }}/.linuxbrew/bin/brew"
state: link

View File

@@ -0,0 +1,65 @@
---
- name: repositories | enable the RPM Fusion repository
ansible.builtin.dnf:
name: "{{ item }}"
state: present
disable_gpg_check: True
loop:
- https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm
- https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm
become: true
- name: repositories | enable copr repositories
ansible.builtin.command:
cmd: dnf copr enable -y {{ item.repo }}
creates: "{{ item.file }}"
loop:
- {
repo: "tomaszgasior/mushrooms",
file: "/etc/yum.repos.d/_copr:copr.fedorainfracloud.org:tomaszgasior:mushrooms.repo",
}
become: true
when: ansible_facts['nodename'] == "claude-fixe-fedora"
- name: repositories | copy yum repo files
ansible.builtin.copy:
src: "yum/{{ item }}"
dest: "/etc/yum.repos.d/{{ item }}"
loop:
- vscodium.repo
become: true
- name: repositories | resilio sync - import repository GPG key
ansible.builtin.rpm_key:
state: present
key: https://linux-packages.resilio.com/resilio-sync/key.asc
become: true
- name: repositories | resilio sync - add repository
ansible.builtin.yum_repository:
name: rslsync
description: Resilio Sync Repository
baseurl: https://linux-packages.resilio.com/resilio-sync/rpm/$basearch
gpgcheck: yes
become: true
- name: repositories | brave - check presence
ansible.builtin.stat:
path: /etc/yum.repos.d/brave-browser-rpm-release.s3.brave.com_x86_64_.repo
register: brave
- name: repositories | brave - add repository
ansible.builtin.command:
cmd: dnf config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/x86_64/
warn: false
args:
creates: /etc/yum.repos.d/brave-browser-rpm-release.s3.brave.com_x86_64_.repo
become: true
when: brave.stat.exists == False
- name: repositories | brave - import asc
ansible.builtin.command:
cmd: rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
warn: false
become: true
when: brave.stat.exists == False

View File

@@ -0,0 +1,14 @@
---
- name: scripts | create directory
ansible.builtin.file:
state: directory
path: "~/.local/scripts"
- name: scripts | copy scripts
ansible.builtin.copy:
src: "scripts/{{ item }}"
dest: "~/.local/scripts"
mode: 0755
with_items:
- backup-local-usb-disk-one.bash
- backup-local-usb-disk-two.bash

View File

@@ -0,0 +1,6 @@
---
- name: shell | make Fish default shell
ansible.builtin.user:
name: claude
shell: /usr/bin/fish
become: true

View File

@@ -0,0 +1,27 @@
---
- name: system | disable password sudo
ansible.builtin.lineinfile:
dest: /etc/sudoers
state: present
regexp: "^%wheel"
line: "%wheel ALL=(ALL) NOPASSWD: ALL"
validate: visudo -cf %s
become: true
- name: system | remove old unused kernels
ansible.builtin.lineinfile:
dest: /etc/yum.conf
state: present
line: "installonly_limit=3"
create: true
become: true
- name: system | get better download speed with DNF
ansible.builtin.blockinfile:
path: /etc/dnf/dnf.conf
block: |
defaultyes=True
deltarpm=True
install_weak_deps=False
max_parallel_downloads={{ ansible_processor_vcpus | default('8') }}
become: true

View File

@@ -0,0 +1,6 @@
---
- name: wireguard | copy wireguard configuration
ansible.builtin.copy:
src: wireguard/{{ ansible_facts['nodename'] }}.conf
dest: ~/wireguard.conf
mode: 0600

View File

@@ -0,0 +1,11 @@
encryption = "age"
[age]
identity = "/home/claude/.config/sops/age/keys.txt"
recipient = "age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg"
[data]
alacritty_font_size = {{ alacritty.font_size }}
alacritty_window_columns = {{ alacritty.window_columns }}
alacritty_window_lines = {{ alacritty.window_lines }}
remmina_font_size = {{ remmina.font_size }}

View File

@@ -0,0 +1,7 @@
---
alacritty:
font_size: 11.0
window_columns: 150
window_lines: 40
remmina:
font_size: 11

View File

@@ -0,0 +1,7 @@
---
alacritty:
font_size: 9.0
window_columns: 100
window_lines: 28
remmina:
font_size: 9

View File

@@ -1,7 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- secrets.yaml
- secrets.sops.yaml
- volume.yaml
- export-job.yaml
- helm-release.yaml

View File

@@ -0,0 +1,27 @@
kind: Secret
apiVersion: v1
metadata:
name: bookstack-secrets
namespace: data
stringData:
deployment_rsa_priv_key: ENC[AES256_GCM,data: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,iv:vMdKKCnWBgTDiqvJdXAN9QJeoBEMucPFQlF634QLV9M=,tag:iJ3dUexqwiEfT/mboY7HZA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtQUJSSUc3K1hxZ1d1Q3dI
SENqMUlaVkJEN3RkMXpsTnUyN05hN0ZuZ0d3CkYvVVdkNDF1WkRMREM1U3FtNzZk
NGxtM25oaUMzeEYwNFA4TW4xTG1ENVEKLS0tIG1vY3JQRUplR1VBUzQ5VTR0L3Ro
cG5JYXp0cllxTXVnY1ZOL1RlNWRaK2sK76zdi1HuLcoHEc0JTVLsenoa7JQv0DGz
y/yDIArOoocUryeb62DuSKQNZmcZLhHbJUWvFIkacDi82CcxuvdDLw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:41:17Z"
mac: ENC[AES256_GCM,data:kIa5+mV0ZY9XR/6zb5INz8bUaPCMHSaE0s7R697ogrnYufx971Nr8TVA7X4dgNpvYC6HUgdRbUxWr/TbtJCq+z1hkXdIiFZKJBBy7gcgJRXCleduMi4IikrkW7fAcQZmeHqvd+MNUXBiebGWCpGe0PCij5xnjq/K4pJ4qJX1OdY=,iv:PfuJ+VSxKzhJGGwN+WQ9KGwF2aJITKT4CAmPCP/8DCg=,tag:JCk32OUKBIweJoO9FpwFGA==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.3

View File

@@ -1,58 +0,0 @@
kind: Secret
apiVersion: v1
metadata:
name: bookstack-secrets
namespace: data
stringData:
deployment_rsa_priv_key: ENC[AES256_GCM,data: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,iv:majin48BvzBk04GDahOnaxkDcxLsFKVEtijncxfKkl0=,tag:J7M/IYKppIXG4LDPpY+8Bw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-07-03T12:13:13Z"
mac: ENC[AES256_GCM,data:fx1wBJU77yblwu76N5LD2HoAE0dYTEWGIB48cYAPBjRdYMFmL7JQMk6sdT4KmcGZy/0IpVaC9ZwFfVR9VapPpzKnUUY/8V189e1GYu/cRpy3q4W7l6KU0jHLbasBERV4QZI8HF3vrAxNI3zd7TUprqQ8DZCTpX/QZ3sThO5QG1c=,iv:M2wxwzEjxZRxdW6WTsWjMueN8yl3Hi0B++axkNSSqgo=,tag:pfxppxufXeXfvqe2EW+Clw==,type:str]
pgp:
- created_at: "2021-07-17T21:15:45Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA6nQR2zACjUjAQ//fQ863OpprkOuu7ZzjHoq9ereZ+wu7jYg/rQ/1VbI9QL2
WzC8o/Csc2qrN1adnTx9s61HPGkAyqzsSJLmBrVufc+I1sGcJsCg8kzezO0HYau9
xV30mazw2sPca80fjbqeUY6hcp4oPcDg8METk9/TZ955UILit2nUWdCTOX+C6yxw
R206DfKb/UvQ3zLKpbeSvarf8+pyp7TpEmPnPjC9jYMzftD+lhqwRmaFjeeGjWIJ
NyeybL50kFBFJYou7AHxhLT7Ona2IASJCYvUj8kjwMc/MedjjcHdh+CysYlRgt0D
Ces7cUI+PVRdvWY2hi/EO/VCaD60bDEfy6zB8KHPRE+E53A4GlMvnvYF7QI5z4qC
HdCsQ8v2IOpU0/e/32eiAKtJmMqy+v1hVFavh+5u4epc5iFuJzoTAEdDg45FfQap
Kq6tDFWXP30Y3HfOc+7BBz9lep49zJB5cK47WvNM8Tfazb3DpHFXDbFgLyAkWuaq
QvZIijHeH2P5advD2gONUY9gDlVV8/HxYHNQVgwWyaVdmXXvzFtgpZQtIvIHA+Di
EhNrw8L/qtOW6B/uM+FzvcuGVTF3nnU4g43Y0XkTOd7JxP/l7CC78pcjl4IdgGbK
nb+1+/ShzjRJA3n0fvlkrbiMdep9hMQUWJlzsG15rRlvtLTxTZjNHX0kacn/4yTS
XgGKX2C4ZX3Pxdq/Mkr7muGZbLZIOHXL0OPouDzs8E64UPR0u8ayDDlsX9SYZ8hq
kvAL3ktnKNf1R3shWGKMcra8skjIKIoSmzEXf7RgCoNnewjt8wAqBY3+RGiaBUA=
=jwm/
-----END PGP MESSAGE-----
fp: 19B850FBA7685A526CF11E5F9BBE834259976EE8
- created_at: "2021-07-17T21:15:45Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA98IrODHuiZ9ARAAk2hc8IbzfVSagc4qeymEpDBwME2MpzYv7a6RPK7vS/VR
8PGYJT4DuJ0op4N/IiTKUeO1DVlqfZvzKBfAKDNdpojzaheNdy/L4nIKMN2klfx+
7BAXljRpqzyRjC2lyMFbDWgMMWcJG4PZIuCRQCm6ej0LOFwkoL4EitpfltdHj5tt
/qUWGICXSlgN882axw23Z9ZpfKmLLn2tKplFmgKErrPaXQxiqRHjPFzXh1JkGnaG
wtxBMdgX4eMDWGcSgiVqPFzMuecIA34u2bSnCrU4xmLGglHgm2oWpL9PZcdWBR1U
H9OzDrFNDD2X3Hey5jv5v3h64YwbFnZ89Y51lUbP8fbv65OrVGMQKE0ZQ7ueVwLk
H/IM9FnVDfkQ615ykPxUtr0AT47l9mffi6Iy1/XBmrqiCnaKhT5PEbSywmaKzOD9
9B7UG4l6kLh9F/bqNRsQWkarYlSmGf8BvAQNFH7ZtzyfRxTAP2wKxvaHA5/sqMO8
em0WDxvdeVtHSVYx/Kbu50RW0eDJRDD21P5neb2Jj7rZTVYD+L5Dxne+JXpTbI+8
jKesyEk3RYGzpthHHyWPZAo76cidqYVRvENfPFJljaRHpxcQLkYECTvyDmgyRNz0
uMHnQ76ZqeyGQ9NrYflcqd3XakTOvAmrwKz0p1zhmTlSgrUmGCUaZT8VXwRjsnDS
XgF3B6c9YDZz8f7wmtJqj0DTgxdgWGoQBrJowkyHhTxQetj++7EYaH0hdzrI+5bt
ZTM5I8y6zRrCAfvLKzKlMeh0R4XRREmNCyVzRuAfwjnVzXRVtcxRN8IAJR2mCNQ=
=vETF
-----END PGP MESSAGE-----
fp: 5749D0AE39445C1CCA6006DF8913091C690BDD69
encrypted_regex: ^(data|stringData)$
version: 3.7.3

View File

@@ -59,7 +59,7 @@ spec:
DISABLE_REGISTRATION: true
REQUIRE_SIGNIN_VIEW: true
webhook:
ALLOWED_HOST_LIST: "drone.k3s.xpander.ovh"
ALLOWED_HOST_LIST: "drone.${SECRET_CLUSTER_DOMAIN}"
postgresql:
enabled: false

View File

@@ -1,7 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- secrets.yaml
- secrets.sops.yaml
- volume.yaml
- helm-release.yaml
- backup-job.yaml

View File

@@ -0,0 +1,27 @@
kind: Secret
apiVersion: v1
metadata:
name: gitea-secrets
namespace: development
stringData:
deployment_rsa_priv_key: ENC[AES256_GCM,data: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,iv:PKmf+mytOTMdVitS5avOAi5yChAx44mG2YNnaDFLTlw=,tag:0ejHj1EpeXqRF686ZsmVmA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5UnFTTUZTT2dxV1JFY2R0
aS9yUWNHeDdnVStyTTV1ZjRXU1hQYVVQRTFvCktjL0VwNjdsczdmcFI2TnhXMHU1
RXRhQnhhYjc4ZHNzN0wyN1ErcVkvNXcKLS0tIE1WNTBhV0xwSk9rcklLWkVESElS
ZVpwVVRmV2VHU0NJcFptYXJPZnhXT28KIQgCy66P7kb1hc9TxEolPBaP68Pp116Y
5cxfpbXZYnsDItjB1FtwrIxFRjDBHrpHoEb2e6AC47pHvai+OflqCg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:41:34Z"
mac: ENC[AES256_GCM,data:dQ7zJWFeZboFrR1pbKHoXcnqv6yjZVrHahb79bfdfJiXt7qbnr1w+WSTbcv78zsN9y0pZ6hPyzc8+QzwFH5xbBSdi8TkHifcuvQqTMtmrMnHZM6GMXyiN8BUvPEq8iT5OO0UFwbXitQSavn9Ib52j+HSvyDzLy9MkGbmLHrKA88=,iv:YywQ58kygqVBKQ4BxIVkGMgi8SoL842qsuJ4q7hZikY=,tag:17wpoXBlhOdHnls7uU5IQA==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.3

View File

@@ -1,58 +0,0 @@
kind: Secret
apiVersion: v1
metadata:
name: gitea-secrets
namespace: development
stringData:
deployment_rsa_priv_key: ENC[AES256_GCM,data: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,iv:majin48BvzBk04GDahOnaxkDcxLsFKVEtijncxfKkl0=,tag:J7M/IYKppIXG4LDPpY+8Bw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-07-03T12:11:25Z"
mac: ENC[AES256_GCM,data:b0JPukzFNt2KJ4xLiPqZu1jXqPMozJMm7q5mUiPUtiCZTBDz8ixKvYSh0d2fIb7mj33rewCE5oWZT+brK+lwDRiHLshzyxh4/2foPsHzkl2Sf7mbFUsSTtMSPulwZw1geMX2L2//41CpDDhettIlla9obMsrdW8EI2nqGL0nqfQ=,iv:rrTUj9HIPx23+LQ3gtSMTB5/kIXQuvZ/GbPMx6FqBTQ=,tag:EAEV0GEBXpV9IIJOav3qvg==,type:str]
pgp:
- created_at: "2021-07-17T21:15:45Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA6nQR2zACjUjAQ//fQ863OpprkOuu7ZzjHoq9ereZ+wu7jYg/rQ/1VbI9QL2
WzC8o/Csc2qrN1adnTx9s61HPGkAyqzsSJLmBrVufc+I1sGcJsCg8kzezO0HYau9
xV30mazw2sPca80fjbqeUY6hcp4oPcDg8METk9/TZ955UILit2nUWdCTOX+C6yxw
R206DfKb/UvQ3zLKpbeSvarf8+pyp7TpEmPnPjC9jYMzftD+lhqwRmaFjeeGjWIJ
NyeybL50kFBFJYou7AHxhLT7Ona2IASJCYvUj8kjwMc/MedjjcHdh+CysYlRgt0D
Ces7cUI+PVRdvWY2hi/EO/VCaD60bDEfy6zB8KHPRE+E53A4GlMvnvYF7QI5z4qC
HdCsQ8v2IOpU0/e/32eiAKtJmMqy+v1hVFavh+5u4epc5iFuJzoTAEdDg45FfQap
Kq6tDFWXP30Y3HfOc+7BBz9lep49zJB5cK47WvNM8Tfazb3DpHFXDbFgLyAkWuaq
QvZIijHeH2P5advD2gONUY9gDlVV8/HxYHNQVgwWyaVdmXXvzFtgpZQtIvIHA+Di
EhNrw8L/qtOW6B/uM+FzvcuGVTF3nnU4g43Y0XkTOd7JxP/l7CC78pcjl4IdgGbK
nb+1+/ShzjRJA3n0fvlkrbiMdep9hMQUWJlzsG15rRlvtLTxTZjNHX0kacn/4yTS
XgGKX2C4ZX3Pxdq/Mkr7muGZbLZIOHXL0OPouDzs8E64UPR0u8ayDDlsX9SYZ8hq
kvAL3ktnKNf1R3shWGKMcra8skjIKIoSmzEXf7RgCoNnewjt8wAqBY3+RGiaBUA=
=jwm/
-----END PGP MESSAGE-----
fp: 19B850FBA7685A526CF11E5F9BBE834259976EE8
- created_at: "2021-07-17T21:15:45Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA98IrODHuiZ9ARAAk2hc8IbzfVSagc4qeymEpDBwME2MpzYv7a6RPK7vS/VR
8PGYJT4DuJ0op4N/IiTKUeO1DVlqfZvzKBfAKDNdpojzaheNdy/L4nIKMN2klfx+
7BAXljRpqzyRjC2lyMFbDWgMMWcJG4PZIuCRQCm6ej0LOFwkoL4EitpfltdHj5tt
/qUWGICXSlgN882axw23Z9ZpfKmLLn2tKplFmgKErrPaXQxiqRHjPFzXh1JkGnaG
wtxBMdgX4eMDWGcSgiVqPFzMuecIA34u2bSnCrU4xmLGglHgm2oWpL9PZcdWBR1U
H9OzDrFNDD2X3Hey5jv5v3h64YwbFnZ89Y51lUbP8fbv65OrVGMQKE0ZQ7ueVwLk
H/IM9FnVDfkQ615ykPxUtr0AT47l9mffi6Iy1/XBmrqiCnaKhT5PEbSywmaKzOD9
9B7UG4l6kLh9F/bqNRsQWkarYlSmGf8BvAQNFH7ZtzyfRxTAP2wKxvaHA5/sqMO8
em0WDxvdeVtHSVYx/Kbu50RW0eDJRDD21P5neb2Jj7rZTVYD+L5Dxne+JXpTbI+8
jKesyEk3RYGzpthHHyWPZAo76cidqYVRvENfPFJljaRHpxcQLkYECTvyDmgyRNz0
uMHnQ76ZqeyGQ9NrYflcqd3XakTOvAmrwKz0p1zhmTlSgrUmGCUaZT8VXwRjsnDS
XgF3B6c9YDZz8f7wmtJqj0DTgxdgWGoQBrJowkyHhTxQetj++7EYaH0hdzrI+5bt
ZTM5I8y6zRrCAfvLKzKlMeh0R4XRREmNCyVzRuAfwjnVzXRVtcxRN8IAJR2mCNQ=
=vETF
-----END PGP MESSAGE-----
fp: 5749D0AE39445C1CCA6006DF8913091C690BDD69
encrypted_regex: ^(data|stringData)$
version: 3.7.3

View File

@@ -3,5 +3,5 @@ kind: Kustomization
resources:
- helm-release.yaml
- volume.yaml
- token.yaml
- token.sops.yaml
- podmonitor.yaml

View File

@@ -0,0 +1,27 @@
apiVersion: v1
kind: Secret
metadata:
name: home-automation
namespace: home-automation
stringData:
prometheus-token: ENC[AES256_GCM,data:XQS2cNao60Cw3oWPBG3qRs69u4ZhBB8qWm5s6z13CDomfcdfA60YSSU7Vtcdb8E7wnI2t/X3Kul8Vlt8evYv/Tkh5UN1oiqa+upFQ/tOlIHFmRfz1snE5XlREc/sB2FN8xUIDRdHObfwz9NcfEcrt0MP+1mXN1IUIA5BDAAFT05TALeUjdY3CTfht6idIFlqs3YN2uvfDYoq5nKIN4J3uN0rWJI46BD+FnmpE243ChM+Cn1NS2sa,iv:lcCmW8TASJHWgOjs9qRh1XaGqPpCHn9HkU+Ma+Iqyv0=,tag:bRNDK8TEyHIMZlixYRDGGw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1hhurqwmfvl9m3vh3hk8urulfzcdsrep2ax2neazqt435yhpamu3qj20asg
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQWjZ1RG9QZnBQSUNNSHN4
MTdwMDlvaGk4NEVxdmdZOGR1QnpLNFkzOTNZCjhZeEloeWQzemp1cVJrbEpxbWJB
T3NXRkRxTU54MGxUbk45YTJoQkl2dWMKLS0tIFkzQ0hvQWdxK2NKQlVlNWhUODQ3
RDRiUkRFSVI4S29mdWRMbE9RNFhLQlUKcx+FKlWUqt5YOxIKlvNiexCarLnW3FXU
M+lPXuGDvjo2Pg5InhPCheuxSVxea85uRRmROTWWOfjMKNYyfMiXLw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-07-03T14:41:50Z"
mac: ENC[AES256_GCM,data:rCAXrXozuI+YJwCDMWQeMvzC3Aoa/Eb89AQEBbLeOQMp7z5p7VCuzaSP52vsW50ii/Rr+VjgDEhoyVSiRAw9IoqcQCjNFZfW6nbXyKZIQGgSfiDKg5DrZLsLOJEg5JUX9u8zzVB2VyIpuDAtDrZHgmvBq+t/gSncSNzb7UW2Aw4=,iv:nkSndVS3YbIGPLMvPWwjgfRL8L5Qac71Jls1OBvX3s8=,tag:nmCKDjXBURMtQpQ5WfjHSg==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.3

View File

@@ -1,58 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: home-automation
namespace: home-automation
stringData:
prometheus-token: ENC[AES256_GCM,data:NiP3ioOYLz+DEeo39/Guk1iyxw9eMzHv/x4L/hq+LRDfpPnxlmWixuq2yOmhaW8bZSFDXudr2eGUZwBMXXmTUVTL/RgVg6yDy70kJ53YGLcRCWI3GntlwZqF1xqMkUXk+4Ap663cYFM15pS18s9SaWogJ3N/SXrC3uD0l7aPxlF5O+MNoTiK+CNogXS0/QAAnvaop3Y3MN6i81qp5owHATV2SOorXlatgQxR0pxf0ZEfU36NoIBQ,iv:PSvU8RUnULu5Wm/F8jSLb2ESH2QTx3UZUUJgzUPEyio=,tag:bnSVYptDVsWAfvEvo6nJwg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2022-02-08T14:42:41Z"
mac: ENC[AES256_GCM,data:ZdNG4+tlVJgi7KYQDEJZ01rzjscrgX2Pel/kneV9kZqbukmJi5yWLFdPM9Ll0xO89hLGW/Aa2PCvA5Kwpa8x5itGODiY6LimCWqX1YQ5/nZ4eUMHjXorWcduxHD8qc5zFkDbvUwhCyZ1mmhgN5sI0pFBDWtkVbQd7nfDCnxHwLE=,iv:GH81+X9bbww4o+eAMp6+yosUX3R77SXW8xFlTzOFv34=,tag:pDT+ybsa1UgWRNSFzGtw1g==,type:str]
pgp:
- created_at: "2021-08-20T16:21:08Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA6nQR2zACjUjAQ/9FbK6Z+2UwtViXJmelHPuttQoNM85U3V4RCoRcalp9z73
Y5Jcum3plDPf7E9bsqiJtt4xWvxZWXFtFp6s2mTTRTfy8OBbM+xLpFXrvSXqE3Ug
YUBiMWI5QnEqC0eo2NKey53DRxOzqsMoVMwp/2FEAUYwC2pkT7XjMiAn8X54QMjj
MlNM8JAfjdEvaZ4Blk5egdvmBNm8Em7DzJ3LGyTfksyWA66W+qbTkEH46n4DZHv/
0X8AtjU+dWILW0SA/DUXkmUEccrM40ZfD0Rm70TvvKGeCNM0zaDv+ikeq8muklIn
oDSRUQm9aZ7NB5xP8mC7AULHwHN6jvHGymNEJEjl10tmEsI0Y4eEEer3MAEBH93V
w0rPOOPVZPYXD/rFQF6f4nvimT0/dlrQYFepIFZbwmQYPcbXAP9OhngMgNM71Oeb
qKf0KorRL4VT3K6NPZxu05QhIsTFPM4pZrHA6ZotZ7+JW9pZe1LCE7ROm0AzPp3b
btlEr/MKwrkSouBI0aO866pxSpbHjHZU4m8Y7NWelwSy8cY35dXbCudC5ScMT5Y/
5dccmaLEfSpu6eiwi6bfrGIpROlbbj1dINJKJOCeoXRtvXyADao4AKfa2c28fqwM
Mx9Fn8O76/YfyRqO1dFbd896OwqSRstq1nVB2+xl/7Infch8NkBCIkb4Xe1zSmLS
XAG1UPCsQfjt3BI8b+5BmeJHdKAHtZ3w7Bb96AGaWn7wh7c8+QZugPbsxm2+l+8H
wEgYrTMvk6BP4zzA15T6iOKh2qw5qlxi+k9zN5rmOsjmP+0SwUr8mfCL/Ze0
=9u2m
-----END PGP MESSAGE-----
fp: 19B850FBA7685A526CF11E5F9BBE834259976EE8
- created_at: "2021-08-20T16:21:08Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA98IrODHuiZ9AQ//cs99xtkOc9d9nbiGmirNkUsWZGzhxaLZ7SUDY6mQvtj7
ibV7fkG5kf/uNu9mw+DRA8M3PBM5j+y3Hv0xt+1fBAhttra1GU127DwSAHChbWJT
BMnx2Bm5zAmeoh4ksMphuggOsLL2x1IYiTk7dnaMuPo/5CUPxXpTpPrJYHf0Pg1b
1j8l0N+t2hUWj93Mh392mggf28w+PLD5ty/d6a0Eyky6UG62LbyjhJaJt5nBMvfS
jvRW1QXb7iQ7ljbml1X2FHK/vzYtiMh5OUfYCzHRK6u5yTQybghNSVr8L0N2MgvC
unNp/PEvfvpzU34hInmi1zdW6BZK3iAvuiKHfgrJy2iZnjGZahBN7tLcKyHrAKpe
Q+hMQ1+neHvcgJAl50jRrUAbJJ1ssypwW6+zz3Bj1b+6IvZ/tuV31dZkKozsi4Y4
UKyds4IOEMLHv8FOlHfkOrvkTmij+6bqj1UoQIO7qTSuxI6M5jFmJ7vNnpYWS6IC
944JPbmX5hzDLrqMICzsetIxXNS0uTbvTo2APVIHjDkgX8ukcNw0YKfIQFgMi8Fc
/Sp8wCaUULkotlEb4Bvdq+yTrj1mQCpHaz6m1w/8RnSzLUecD0hVMUUPGctZ5IKl
3ZJrdMAJdad2Zjf7GVXwxNXtKaH9gCjZ1n4zqMg3Ob1l5BmUQI4M5IlZlPGAqhDS
XAFdxfYkHPbKWXDUPWcj6P+FUqDjdCV++z5kpeIXmtW8eouxIrV3DvwhdO+H3yKc
KkdnXPjCzSPf9AzYhgpGXKG70yh4gtMeLeDAPpDjguu6Eskd8VoQBus6tZ4F
=6Ilp
-----END PGP MESSAGE-----
fp: 5749D0AE39445C1CCA6006DF8913091C690BDD69
encrypted_regex: ^(data|stringData)$
version: 3.7.1

View File

@@ -36,9 +36,9 @@ spec:
- |
#!/bin/bash
curl --location raw.githubusercontent.com/auricom/home-ops/main/server/scripts/transcode_music/transcode.bash --output /tmp/transcode.bash
curl --location raw.githubusercontent.com/auricom/home-ops/main/scripts/transcode_music/transcode.bash --output /tmp/transcode.bash
chmod a+x /tmp/transcode.bash
curl --location raw.githubusercontent.com/auricom/home-ops/main/server/scripts/transcode_music/transcode_exclude.cfg --output /tmp/transcode_exclude.cfg
curl --location raw.githubusercontent.com/auricom/home-ops/main/scripts/transcode_music/transcode_exclude.cfg --output /tmp/transcode_exclude.cfg
cd /tmp
./transcode.bash -c
./transcode.bash -r

View File

@@ -1,50 +0,0 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: terra-exporter
namespace: monitoring
labels:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter
template:
metadata:
labels:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter
spec:
imagePullSecrets:
- name: regcred
containers:
- image: registry.${SECRET_CLUSTER_DOMAIN}/homelab/terra-exporter:develop
imagePullPolicy: Always
name: terra-exporter
ports:
- containerPort: 9000
name: http
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter
name: terra-exporter
namespace: monitoring
spec:
ports:
- name: http
port: 9000
protocol: TCP
targetPort: 9000
selector:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter
type: ClusterIP
---

View File

@@ -1,5 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- podmonitor.yaml

View File

@@ -1,16 +0,0 @@
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: terra-exporter
namespace: monitoring
spec:
podMetricsEndpoints:
- interval: 5m
path: /
port: http
scrapeTimeout: 30s
selector:
matchLabels:
app.kubernetes.io/instance: terra-exporter
app.kubernetes.io/name: terra-exporter

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