27 Commits

Author SHA1 Message Date
43c3a3cb13 apps: add obsidian-livesync (couchdb) 2025-02-25 18:03:20 -08:00
c0103496a1 refactor: upgrade ansible, remove clean_desired flag, add separate clean playbook 2025-01-05 16:05:42 -08:00
73c370b360 apps: add pgrok 2025-01-04 20:12:17 -08:00
2d96ed9348 traefik: refactor macro, remove old traefik network remnants 2025-01-04 20:12:17 -08:00
e86533701a apps: add woodpecker 2025-01-04 20:12:09 -08:00
b03628f8de monitoring: dashboard improvements, add network and disc panels to node exporter 2025-01-01 14:11:30 -08:00
278839fdba authentik: add vpgen group, change default enrollment group to vpgen 2024-12-31 18:37:38 -08:00
2b265620d4 authentik: enrollment flow improvements, add option to use GitHub/Google OAuth 2024-12-31 18:04:59 -08:00
57e47231bf authentik: add initial enrollment by invitation flow 2024-12-25 03:22:48 -08:00
d79f09499e apps: add vpgen 2024-12-25 03:20:13 -08:00
9b1ff29ce1 traefik: updates and logs to stdout instead of files 2024-12-23 22:26:20 -08:00
4c9955b104 fix: grafana admin group to match authentik 2024-12-23 22:25:52 -08:00
74eaf94c7e authentik, minio: initial integration with blueprints for admin policy 2024-12-21 01:21:57 -08:00
1a23928109 authentik: refactor oauth2 app blueprints, add group policies 2024-12-21 01:21:57 -08:00
010c108f6a authentik: add default groups, refactor proxied apps blueprints 2024-12-21 01:21:56 -08:00
263f7eea17 updates: nextcloud 2024-12-20 15:25:42 -08:00
3006e3e424 monitoring: container, node dashboard improvements; separate common.py logic 2024-10-30 18:24:34 -07:00
0e43a68754 monitoring: add grafanalib, containers dashboard 2024-10-30 18:24:28 -07:00
fc6e485a61 refactor: separate templating for j2 and normal files 2024-10-30 18:11:26 -07:00
dd0330c85a monitoring: loki, cadvisor config optimizations 2024-10-23 15:35:54 -07:00
40fbdc414e monitoring: update loki schema 2024-10-22 23:16:41 -07:00
aaca0f94f8 monitoring: remove jaeger
Possible to add it back with a proper database, but all-in-one keeps everything in memory.
2024-07-25 13:16:52 -07:00
97b812eb10 updates: nextcloud refactor to apache image instead of nginx 2024-06-30 18:57:41 -07:00
97d1db61d8 updates: postgres upgrade, data migration process 2024-06-30 13:53:46 -07:00
a8bc344aa2 updates: traefik to v3 2024-06-29 17:28:17 -07:00
f9d590170d refactor: switch deployment from command to community.docker.docker_compose_v2 2024-06-28 22:55:05 -07:00
e1f3a22a23 refactor: simplify stack templates, move vars into group_vars/alpina
this vault setup for injective sensitive variables uses the approach described in https://docs.ansible.com/ansible/10/tips_tricks/ansible_tips_tricks.html#keep-vaulted-variables-safely-visible
2024-06-28 22:39:49 -07:00
93 changed files with 1948 additions and 1135 deletions

3
.idea/alpina.iml generated
View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Poetry (alpina) (3)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Poetry (alpina)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
@@ -24,6 +24,7 @@
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/roles/docker_host/templates" />
<option value="$MODULE_DIR$/roles/alpina/templates" />
</list>
</option>
</component>

34
.idea/jsonSchemas.xml generated
View File

@@ -31,7 +31,7 @@
<list>
<Item>
<option name="directory" value="true" />
<option name="path" value="roles/alpina/collections/services/authentik/templates/blueprints" />
<option name="path" value="roles/alpina/templates/services/authentik/blueprints" />
<option name="mappingKind" value="Directory" />
</Item>
</list>
@@ -39,6 +39,22 @@
</SchemaInfo>
</value>
</entry>
<entry key="Loki">
<value>
<SchemaInfo>
<option name="name" value="Loki" />
<option name="relativePathToSchema" value="https://json.schemastore.org/loki.json" />
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/loki_config/loki-config.yaml.j2" />
</Item>
</list>
</option>
</SchemaInfo>
</value>
</entry>
<entry key="Traefik v2">
<value>
<SchemaInfo>
@@ -74,6 +90,9 @@
<Item>
<option name="path" value="file:///run/user/1000/kio-fuse-kipURF/sftp/root@debbi.lab.home/mnt/dock/traefik/rules/hello-world.yml" />
</Item>
<Item>
<option name="path" value="roles/alpina/templates/services/traefik/rules/traefik-dash.yml.j2" />
</Item>
</list>
</option>
</SchemaInfo>
@@ -87,6 +106,16 @@
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="pattern" value="true" />
<option name="path" value="*/compose.yml" />
<option name="mappingKind" value="Pattern" />
</Item>
<Item>
<option name="pattern" value="true" />
<option name="path" value="*/compose.yml.j2" />
<option name="mappingKind" value="Pattern" />
</Item>
<Item>
<option name="pattern" value="true" />
<option name="path" value="*/docker-compose.yml" />
@@ -113,6 +142,9 @@
<Item>
<option name="path" value="roles/alpina/collections/services/monitoring/templates/prometheus_config/prometheus.yml.j2" />
</Item>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/prometheus.yml.j2" />
</Item>
</list>
</option>
</SchemaInfo>

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Poetry (alpina) (2)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina) (3)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina)" project-jdk-type="Python SDK" />
</project>

View File

@@ -1,19 +1,23 @@
.POSIX:
.PHONY: *
.EXPORT_ALL_VARIABLES:
MAKEFLAGS += -r # no use of built-in rules
env ?= staging
vault_id ?= alpina@contrib/rbw-client.sh
clean_desired ?= false
playbook_cmd := poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env}
all: site
all: site services
setup:
poetry install --quiet
site: setup
poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} --extra-vars "clean_desired_arg=${clean_desired}" site.yml
$(playbook_cmd) site.yml
services: setup
poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} services.yml
$(playbook_cmd) services.yml
clean: setup
$(playbook_cmd) clean.yml

View File

@@ -3,8 +3,27 @@
A home for configuring all of my homelab containers on a Debian Linux machine.
This assumes a Debian Linux machine with Docker and Docker Compose installed.
My particular setup is based on a [jailmaker](https://github.com/Jip-Hop/jailmaker) container
running on top of TrueNAS SCALE, separating all the docker stuff from the appliance.
# Notes
## Monitoring
The monitoring stack is set up to monitor all the containers and the host.
This is a work in progress, Grafana is set up with grafanalib, a Python library that generates Grafana dashboards.
The dashboards are generated from Python scripts in
[grafana_config/dashboards](roles/alpina/templates/services/monitoring/grafana_config/dashboards).
This requires a custom grafana image, which is built from the
[Dockerfile](roles/alpina/templates/services/monitoring/Dockerfile).
This also means it has to be manually rebuilt whenever the dashboards are updated.
From the services/monitoring directory, run:
```bash
docker compose up -d --build --force-recreate grafana
```
## IPv6
The current configuration is designed to work with IPv6.
However, because of how (not properly) I'm doing the subnetting
@@ -16,3 +35,41 @@ that uses the IP of this host as the gateway.
This is a limitation of my current ISP, I only have a single /64 subnet for my lab network.
I'd like to get a /56 or /48, perhaps using Hurricane Electric's tunnel broker.
*Sigh* ISPs being stingy with the 2^48 prefixes they're afraid of running out of.
## Upgrading Postgres
Upgrading the postgres container for a given stack requires a dump and restore.
After making a snapshot or backup of postgres data directory,
in the compose directory for a given stack, run the following commands:
```bash
docker compose down
docker compose up -d <db_service>
docker compose exec -it <db_service> pg_dumpall -U <db_user> | tee /tmp/dump.sql
docker compose down
rm -r <postgres_data_dir>/* # as root
# Edit the docker-compose.yml file to use the new postgres image
docker compose up -d <db_service>
# For some reason, compose exec doesn't like the input redirection
docker exec -i <db_container_name> psql -U <db_user> < /tmp/dump.sql
docker compose up -d
rm /tmp/dump.sql
```
Additionally, if upgrading from postgres <= 13, it is necessary to upgrade the
password hashes. This can be done by running the following command:
```bash
docker compose exec -it <db_service> psql -U <db_user> -c "\password"
```
## Nextcloud
Nextcloud requires some additional work to set up notify_push.
- Initially, comment out the notify_push service in the docker compose.
- Set up nextcloud and install the Client Push (notify_push) app.
- Uncomment the notify_push service in the docker compose and `up -d` the stack.
- ```bash
docker compose exec app ./occ notify_push:setup https://nc.<domain>/push
```
I should probably get around to automating this at some point.

3
clean.yml Normal file
View File

@@ -0,0 +1,3 @@
- hosts: alpina
roles:
- clean

View File

@@ -6,23 +6,38 @@ default:
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, subnet_index) }}
{% endmacro %}
{% macro traefik_labels(host, service="", port="", auth=false) %}
{% macro traefik_labels(host, port='', path_prefix='', auth=false, wildcard=false) %}
{% set name = host ~ (wildcard * '-*') ~ path_prefix -%}
{% set tls_base = domain %}
{% if wildcard -%}
{% set tls_base = host ~ '.' ~ domain %}
{%- endif -%}
traefik.enable=true
- traefik.http.routers.{{ host }}.rule=Host(`{{ host }}.{{ domain }}`)
- traefik.http.routers.{{ host }}.entrypoints=web
- traefik.http.routers.{{ host }}-tls.rule=Host(`{{ host }}.{{ domain }}`)
- traefik.http.routers.{{ host }}-tls.entrypoints=websecure
- traefik.http.routers.{{ host }}-tls.tls=true
- traefik.http.routers.{{ host }}-tls.tls.certresolver=letsencrypt
- traefik.http.routers.{{ host }}-tls.tls.domains.0.main={{ domain }}
- traefik.http.routers.{{ host }}-tls.tls.domains.0.sans=*.{{ domain }}
{% if service -%}
- traefik.http.routers.{{ host }}.service={{ service }}
{% endif %}
- traefik.http.routers.r-{{ name }}.rule={{ host_rule(host, path_prefix, wildcard) }}
- traefik.http.routers.r-{{ name }}.entrypoints=websecure
- traefik.http.routers.r-{{ name }}.tls=true
- traefik.http.routers.r-{{ name }}.tls.certresolver=letsencrypt
- traefik.http.routers.r-{{ name }}.tls.domains.0.main={{ tls_base }}
- traefik.http.routers.r-{{ name }}.tls.domains.0.sans=*.{{ tls_base }}
{% if port -%}
- traefik.http.services.{{ host }}.loadbalancer.server.port={{ port }}
- traefik.http.routers.r-{{ name }}.service=svc-{{ name }}
- traefik.http.services.svc-{{ name }}.loadbalancer.server.port={{ port }}
{% endif %}
{% if auth -%}
- traefik.http.routers.{{ host }}-tls.middlewares=authentik@docker
- traefik.http.routers.r-{{ name }}.middlewares=authentik@docker
{% endif %}
{% endmacro %}
{% macro host_rule(host, path_prefix="", wildcard=false) %}
{% if wildcard %}
{# regular a.host prevents warnings from 'No domain found in rule HostRegexp' #}
{# TODO: figure out this stupidity properly #}
Host(`a.{{ host }}.{{ domain }}`) || HostRegexp(`^.+\.{{ host }}\.{{ domain | replace('.', '\.') }}$`)
{%- else %}
Host(`{{ host }}.{{ domain }}`)
{%- endif %}
{% if path_prefix -%}
&& PathPrefix(`{{ path_prefix }}`)
{%- endif %}
{% endmacro %}

View File

@@ -0,0 +1,75 @@
# Shared variables between environments
---
alpina_svc_path: ~/alpina
base_volume_path: /mnt/dock
media_volume_path: /mnt/media
docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
# Authentik
authentik_db_password: "{{ vault_authentik_db_password }}"
authentik_secret_key: "{{ vault_authentik_secret_key }}"
authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}"
auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}"
auth_minio_client_secret: "{{ vault_auth_minio_client_secret }}"
auth_gitea_client_secret: "{{ vault_auth_gitea_client_secret }}"
auth_nextcloud_client_secret: "{{ vault_auth_nextcloud_client_secret }}"
arrstack_password: "{{ vault_arrstack_password }}"
auth_vpgen_client_secret: "{{ vault_auth_vpgen_client_secret }}"
auth_pgrok_client_secret: "{{ vault_auth_pgrok_client_secret }}"
auth_default_enrollment_group: vpgen
# Minio
minio_password: "{{ vault_minio_password }}"
# Monitoring
influxdb_admin_password: "{{ vault_influxdb_admin_password }}"
influxdb_admin_token: "{{ vault_influxdb_admin_token }}"
# Traefik
acme_email: "{{ vault_acme_email }}"
cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
# Arrstack
wg_peer_pubkey: "{{ vault_wg_peer_pubkey }}"
vpn_server_names: "{{ vault_vpn_server_names }}"
# Gitea
gitea_db_password: "{{ vault_gitea_db_password }}"
gitea_sendgrid_api_key: "{{ vault_gitea_sendgrid_api_key }}"
## Security
secret_key: "{{ vault_secret_key }}"
internal_token: "{{ vault_internal_token }}"
jwt_secret: "{{ vault_jwt_secret }}"
# Jellyfin
# Nextcloud
nextcloud_db_password: "{{ vault_nextcloud_db_password }}"
redis_password: "{{ vault_redis_password }}"
nextcloud_sendgrid_api_key: "{{ vault_nextcloud_sendgrid_api_key }}"
# VPGen
vpgen_opnsense_api_url: https://opnsense.cazzzer.com
vpgen_opnsense_api_key: "{{ vault_vpgen_opnsense_api_key }}"
vpgen_opnsense_api_secret: "{{ vault_vpgen_opnsense_api_secret }}"
vpgen_opnsense_wg_ifname: wg2
vpgen_ipv6_client_prefix_size: 112
vpgen_ip_max_index: 100
vpgen_vpn_endpoint: "{{ vault_vpgen_vpn_endpoint }}"
vpgen_vpn_dns: "{{ vault_vpgen_vpn_dns }}"
vpgen_max_clients_per_user: 20
# Woodpecker
woodpecker_agent_secret: "{{ vault_woopecker_agent_secret }}"
# Pgrok
pgrok_db_password: "{{ vault_pgrok_db_password }}"

154
group_vars/alpina/vault.yml Normal file
View File

@@ -0,0 +1,154 @@
$ANSIBLE_VAULT;1.1;AES256
64326366396663613133333430356565636565363066383339646533623964613638613932633865
3435613234306336376565623861303864323735323533360a656533303734646630343964666666
65396638373733353833333736626465336663323934373461303564376531623066303062646630
6362633163653936390a626138656361663635336533376563373139663538663037306336333865
63393263646665663664333162656532373064336361346133383064383035333831653563393337
39306138623764366131303332653839653061393530353235613563376430666337656336386262
64363731656230323832616437633735343662376637303334343161343165636137623434613636
35666439383036633761353062613464363264633231306138636362643434333338303238616364
35636430626536633264616233303462363839653436323138613836633336383438393364373338
37623539306635636462363239396231663264613034646165393031343763643265363235623736
37383439313066386139373736396465323962663131383664393939373862336231306266653832
61663037613535663138333565613066663938616432356434323531383837363931393837323634
66353436303065323266386264353436393266363136326531646438326130613865663132353164
30366434373164623037613931393634613065383737643863343939373063376530633938346434
62633432636430366361616636313337366238303566303566616363653336643736333636663737
38316330646266636633323162346231353337626133663939306131653434326533326162663963
34666262313232663564356633393162653639653739323639396562613362313663383736393438
31373930393465356535303236343934663238373764303333663634666338643666646665326563
34376164303538336133613630623466656466663266326432343439613235376463326661663131
38373533313661333431343638346334303736306237653336633366313831626466633430373865
32646536643862646135653434343337373563666532333561316232393063306365363631623262
31313538306264623030353230326330666234303138646237613435633637373837656565623538
33616233623366346237376563613430663835653432653834353835376338643236663266646462
62316438356233383965616434393737306132306538396564396431376661323135353137316534
63353663343338353339373163343737333835363363316563393538353266653033383136646437
37626661383531363233656663616630316361373438616232313131316234386665653262313937
61366536613731663231616663393735303535326636383066333330386233306534656237653561
33336639356331313636363865313836306137333439613365636132356631653437316161346230
64643736323437396663653937633634633230386164333239616261616332323137643764383335
64613966653764623031323961386530383731316464386131393264346261356331666165623738
62643564323134393630336566343834356265316264393530356633356466313831623262363730
66373232353439616539643433653435643931623430633338623737643039306532343234646333
34393536333730626136313039646364626235616233323137386137383565326461393635353838
35616530383765373431626130386165663538663861653064646363633465326364353533646137
62326435353239363164383236333236643430396561396231323130376264646139666264356138
35353466396335336532363566323738373932643634363763633832353462663836636465626434
38656332626236626335386166333835306666643438376330373936656639313933373635333436
30633731376166376232363834346632633261353361323563376162343063343065643439306231
30666131373361633862363833373366313733626161643932306332613230393636636138363337
61666565633931376639613262666332363037373337663430343939333431303732636434633934
35386130386363333431636363336130336430633839653231363935313930393037306536336563
36653462383432366337646266313139346536666230386565333364383330653333353765326136
33626236333765333863363265346561643835373235393361643234386336656134353731393033
34316430383933626434343839333065333166386233316132373138666534653434653033356135
31366539346538336639626363396636646135386266386138356362616464316630313437386265
30353361626338633961366633333631383366316331333635613738366139633863376331333435
39376239336532343937346563646331366136666130646336366537366534323961363930663438
65333663613030336131663665343234616231306130663761643163646233353265333030396333
30326436396163343732313430373135323332326161623566633932303537666564633834623863
66353039626565646539313763373864623638323765313065646133646430666162616533323036
64313238633264623465313961656563643536313435313162376339353532363232613637343463
33343066303465643930613364356635333234363563653731663137306337346630653637656566
30323537356264356137643637646265643537303263373964346165656266623263636331323130
31396433346561666331616639306131623261353763343638663931623161343133616639633561
36646266643636613564346663666633313665386137323266633330333862313637386330643937
33393561376331316235323961636462363661383466663635323464366238386531393466316361
30396434666335346232643738396638633239323935636637343838353364656662663666303366
37663666373839613837313335366635363634623133653463626466316435303538303632633762
66366538303630336630663365663831313562383334666435383831376564333438633364343861
35343462653233636265336266386637636261666331316666663966313666383965303163656238
66343932323939363339323664366334386166373139363866353161396235366466306466636439
36313039313263643739353230313362353263626236393239656164656334653363623965653936
65386165663361313066646532393939383165316239653335623965346363613335396639653134
36346164383439636237306233333166383233376462633136383933666161643734303032313530
62343866316162393766626261393635643564366431383164626236653062336466343634323432
38343663623261343535616536613961636564376563303064623537303233373366326136353665
33336532633161623638303761383034306265613230323433326133653035303661626234353931
31646530383637626231313965343138303565303030316132613930306137313465616664646230
30353163626562396566653261643336653832663635333963343539396366346132353465386463
33666365363639343066653330326233373035313433316264373236366565643931616335643762
63306165393166396437646366303837316235643562366464326530373230633664653235363136
31333938616139653261656132663439323066636135303430383662333639306265633436326666
62353936663463343864383432636465373737666239613033383538396338303533636663393339
63633561343135343339393063636163373936323461303734613766626539343363363365643632
66306630303634353230393933353333346166303436333038303637313162626464373334373063
38313438633365316562363564316138393531633661323139343938633636373534386465643631
35396261643865393531366432343265663363336562643366623062343331306431663461393066
32633732333634383462383061623334306332326466306666626131363461343436393966633233
31656538633733303264663239643639326235316561386564613563383930383336386664363135
39616263313036646630373233636534376361386230386235363636643835636538663930633630
38656664383138373138626639666230623635613137666533353233333636323062666432313434
37666132303233353438346439653965626434663136386631313337633636653464396566323532
39366434373830343764346138613665373536656164363637663037663534633963336230663439
38373138336666633934643537383131333034316135343738623435643630653661633432363161
37373837303838343566626662656231306438613538333733323632616132343563376533663539
64653262646463613739313737356139666666623963636261336433396363636632333933393463
63653366666536323536666264343931373961356361646434623461316630626133376639613362
38333836653332346134616134313164313965613531343630383764636161653730656332616238
31393132363064663431316165346135343861653462383162353063653837393566356161333535
35343133646632343164336364623337393138343630643737643531346566636633646438396162
31393632303661323363346164636331626638326437383035363930656635316236366434623236
33633136303533636239666434323962333134366461363037343463623437363961353962346236
66313838643238323136356135346564363732656666363431653061663863616537663035373631
34613262363065333162353039613762386130353930316161613061633164383539623263323865
30313566613365656563353236386334636335366663643034316435376532333438643166663536
38363363373330326132336363363039396563396435366131353933393434373336363033343265
30613539366436643631303933376137386635366166663930303331623238633034326631656366
31356337303834356334633636333832363837343735396632356365613439383061366232383462
62613934373535626639363230366266343762643232623933613265356436656364363835323062
32393062386432323562313734346133393465316135316135366331653161636261316364643632
36326161653937336562643034636638666265386264623133626335616633353239333965656632
31323134393230303733623732313836373465383535626434383638666135313237633731613763
64343066336662643264663130363962626435626332626464396137386538333731373238616636
66313931666466306133643666363862626438343634353336376566333533393936363866626233
63616633373536633138393563323636343035343564626236383064376135656638616534353431
31643063346631636666333065386339663363623431653532643065363636303764666333393761
36313439303765356532393832633637636336643036306333663935393734663662346435396466
37376537323262653033356336363835666231363661653133666361383065343063643061376164
32333530376530326662373738333363373631663536373961373965373263346635643762396666
61396632343464343735623531653831393735666331316162353430353134383430393865383662
66656264376564343636386263333934313364373564616134623863613439636537613764376434
65313964303539376131396339356238363735363766616365306133393464613131643166646437
39353961393036646164663865633633373465653766386230333762643735363734633633363461
62613332346336633833663862333230363161663636646232343761356338393639613035646438
32663465303138613731303961633565616239633033333361613861623161353032353661363062
39316262363738383163366332373438636539623365353232316536363130333438613031653665
62366334653036353566333663353862303335656266613134633731633535313730303539306334
63393431306265373234313939373133363961626265626633343631613931636132653635376634
61366262336239656638343438646231653030666638383239313834363334663661316235366162
34346438386461633366353838346664663832323436333737306566333164323066313931643630
33363733356231326636646133366136663431343038643265633136626363343131656463373264
65363833353831656638303439623636373062383235363966356332343163616336643735306466
65663366643030626437326439633665333564623065633431636232393465623365636565363230
38393664653432383539376363366462386438663137363562323231663661353635383866373761
66303165323861626538353236366533336533333939376232313038343331663833303864356235
64383664376237346465626339336536393537323665653766363464393133323637646264643830
32376435623666383633383636323862376166623938346239363339336333373531376433383032
39656466363761376565653936366430363638623332636532383431373334386436373737323163
61616230396135353831343139346464623261303231633035353264626232393933393732393634
35353531626532626334613836623633636265613963613064626334363436336664363633653636
64366262336134653932386236663161623639626562303135386532366261396134613664653037
63656665393835653831366464386236303239363338623338653833653430323135333063616266
61383539613066623563616139666261373066316662636633613561366466623032386434366137
63643030653538623039353934373531633034386665303866623835356433353666653831326464
32323134323333386563316230656362396635656461643061393562393766633736613361373637
65663763373139343162643431353039613565333639336530666164343239653461623734303538
30613432363233353335373539653439313333353537343733616432316338343836336539613832
63353363373536333731636431336433333061336537353231656430343434613836383264663634
38346165373533663330373964303161373331316666633865333538656136656637346266313237
30376135656230353464643262633837336465376434323166663731346130626338613138656161
34623765316239363863626139333536376534396563623631643231616266656238383763386137
30313162373338653131623464396362666163656638656164656131616631373833373936373539
37633861306362383762363733333233623134616565383037336539343937633663356262376133
38656630343136613337663164643338323261613033383564353330306465663932653566376465
63613933626164303466366539303863366263366638663830333861663734616439316463373537
66396433663764336630643038323964656131393731623733393133653432663763326662643137
38323130336137356263303961363562623235343765356366353964396636306235616435663932
39663732313066663834616664336631376639336536323230333462386636333234373063336535
66633238666639643632383666666136383834313162396265386466643130313736653239653231
64613637646539626432613532633231343634363263363331346434613833376532323366643063
61386565316132386162663539623164626234383665336234653534336461623632636461323934
66653966656230366166363535656261363534636136376566333566313564363361316563653638
61643361383263643833636639643362613134623464346537386237616464626265

View File

@@ -1,6 +0,0 @@
---
my_svc_path: ~/alpina
base_volume_path: /mnt/dock
media_volume_path: /mnt/media
traefik_subnet: 172.16.122.0

View File

@@ -1,47 +0,0 @@
domain: cazzzer.com
wg_privkey: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
31663639306133623739366363353430303338656137386434303862346434633665333434613931
3430313162333937636234313761366337393431616630330a393962643962353234343431653439
35323966643531386538643636623439636633326638316233386266343964333563306330383437
6132333063626365330a353232366464636663633236383563343834316164636434613639363765
37653738663463303236333232663338623034363737643138303238663033323361373064343334
3762303565343765393332626565333637643462353631343833
wg_psk: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
31353436343638306237623864633533626662376362656531616665356333326238353533306438
3164646631633464313966353533633137643234333264650a666134613666613262323461306131
32383438363566653766613337363236616139616661343930656362636366346133353137366639
3762623635386330320a643465396563666562383261623964396431366466663766303939336434
61626434363763303637316165343566383064613663626339366635343537646130323731376461
6231346162313465323739623939306436656438336565336436
wg_addresses: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
66306130383462373166306561663431366262626537393330373061616636306433323734643632
6332363262346630353338626632353039636666636264340a616537363638386635383934303533
34376136636334616332626161386435333031363931616331363232313338346234316361383033
3236626331333032390a353466323863326565386531643335653565386433613431623337313666
32643065653763643563623232313262316534326266386135633463623966636532356463653765
32656333623032633263643539336537313536326263303465373066633738353832363064306465
353636666162393734333338653834366333
fw_vpn_input_ports: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
36353933613361353132366636386138616336323437616366613164633036343234313338303830
3662663462346134343338363264303030663935393865650a666161633163383437373139663362
35666633363762633135616630336239623065366266633335623832323762613565376166383131
6163646561353335360a386664386166626134366339393566613461626230323836646139316463
3938
github_consumer_key: 32d5cae58d744c56fcc9
github_consumer_secret: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
36353230356266303131333732363736383633313038326161346434303061633464393738383433
3933343436316530306439326237353265363333656264620a373036383835313733303561333233
33343834313163613037643734653535306365326536383532366166313261323265616133333865
3362663865666466320a363338303436626532393665663564313937366362326263396431316538
33396237333766666635333039643338333133346636363966326437646334636138353934333834
3139363661653364306231303966346333643166326536383164

View File

@@ -0,0 +1,26 @@
# Environment specific variables (prod)
---
domain: cazzzer.com
docker_ipv6_index: 255
# Arrstack VPN
wg_privkey: "{{ vault_wg_privkey }}"
wg_psk: "{{ vault_wg_psk }}"
wg_addresses: "{{ vault_wg_addresses }}"
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik External OAuth
github_consumer_key: 32d5cae58d744c56fcc9
github_consumer_secret: "{{ vault_github_consumer_secret }}"
google_consumer_key: 606830535764-9vc8mjta87g9974pb7qasp82cpoc1d3a.apps.googleusercontent.com
google_consumer_secret: "{{ vault_google_consumer_secret }}"
# VPGen
vpgen_ipv4_starting_addr: 10.18.11.100
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
# Woodpecker
woodpecker_gitea_client_id: 3b7515f3-6005-4512-a2ee-5464dba315f8
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"

View File

@@ -0,0 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256
36313835643238353932323631323439626432316436346533376365633332313963666433313333
6134633133636133623130376237373462383164396338380a316463396139653161366536636336
64346664356538366538363239306631326464633635316161663963326635656430326637333963
6462633236353132300a323062353639646238663737353461633733636530613036316364353864
34326534376639643734303137613866393464306334336566653134333765356361386436323939
35393535303635376162386266396431313739663961643061623037343463303637623130623131
31653761616639613964386432643561376637316435333064343837636463303033333432636234
39323735373161616133396566316266383165343033666530376333626264643531613334363634
35393766623361346461333764666139366632306362613362376133363239656562346263643066
65616538366532346537383432663766366161633234373562623531356339666661346164306563
35343339386631383462656466303563376237386137346437323634626163353464356462346364
35373061636237383335396231326563366230663566333665326338303564326263316630666233
65303930663862313137333630353837363265333532303133306466643462626662613166326132
66346439333739653965346236313766346532356233333164633538326135643662623533646561
65626530386333303362343830653430653866336261623566616362313739303939656364656363
37336331353766633534653936626139303061623531323362346564363665663438646533646166
62376534653562373138656465666133353235313935626534383537643436376665613865303363
62326562396361306131616363363866316232623635353663323537366563333239383636643763
35623366663463303831323730363036306363643364303532326339353633393739306366396331
33313230656431623462376135623438633164323064653866646165643263383832353138633931
66306463346361646561376334613837383762366365666638643434383034376339643239646463
66343461363233626635323535336462666339323032616136396239396534346434623238396330
37653665643366323362313136386231396532323035363963623738346564356435303263303832
37346532366432363638363330316464366361313461626535616165333433343835393565633766
32663162386562373035333335303332323136613233613431386265626337653939326435396262
61303631633838613962346663326232636438393563396230306361333335383462653432383766
35376662353262303635316635363130383032366530396439613861653037383234363831333562
37343332646534353838626366623361636261393865363633303631613837323733626264643835
63376430613234386463336234623062656534643863656434386134616265333666613939393331
39333166393538306135313431303831623063363533326330633062653333313733653831383736
613864303461323739336563356161353234

View File

@@ -1 +0,0 @@
docker_ipv6_index: 255

View File

@@ -1,2 +1,2 @@
[docker_hosts]
[alpina]
debbi.lab.home

View File

@@ -1,47 +0,0 @@
domain: lab.cazzzer.com
wg_privkey: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
31333936633664396332303835396261626463383139326538356363303832323533643636383364
3364613639616462313462313361363836396338623636660a376230646137346536393330393837
64363065396332316262386330313534636135303264636532373432356265383337306365363531
6533343563393062640a366364346136353361653033383731613764363762663865643031303663
62623562636563633038366465636430656231323431643236323461333134623633613464393439
3331663962646534353931336630333961616134343931343534
wg_psk: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
31393235386262363733633063393031396532336161613138353931616364616165613131336138
3861323766326233383836613233333332306166633138300a373164306664393061643135646662
30626536646562363263303238663430393361653566306134373633626534643038326566616237
3233363838343466640a306364663738346235323535643465663330616235373266383233646263
31373332613461376235343431396431633733653865636636363733303466366430316431663730
6537663563613233353838303738653532633136663430383961
wg_addresses: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
36613639386139353965346134663431343032626637326238303830653335633062633936373938
3633636637613033303362343038653262626165636537350a356136363730643738383264306662
34363731313730613164646138653235653363303033663637386230373161623965326265663439
6365643730373235320a323065336535356636646131666262636133643435633237396331653833
63393836393162623164633130393034643364373838313939346438623761326364316337343066
30643131636636643038366634663137643436323833326362373666393563316235306533373039
636233633762303639373239353661343162
fw_vpn_input_ports: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
39326564343633633465376363396633396332636664383539373230633033383161626434643435
3539336531356336663638626630613934323162313639610a626637393637363837636631666534
38663031306536323866336365373565633634666561663636653938643538336630393061326564
3863363030346530630a343138623664323336353036343430323261393036373563393762663530
3730
github_consumer_key: dbacb8621c37320eb745
github_consumer_secret: !vault |
$ANSIBLE_VAULT;1.2;AES256;alpina
65393439653532323865356337353164666331653438396564613663363865643233323666316537
6365303062326139366139623232366338663831333333610a343035313364383738396635633737
32616366393365643565636337633334363637356435386235373638653139326665353537363939
3936336336663264310a343137653436323831366237376539353231656463663164316133376333
37373937356438373335663234616165663739626663663635316335333534333566326632346437
3539656334346163663635376533376362626235343466303430

View File

@@ -0,0 +1,26 @@
# Environment specific variables (staging)
---
domain: lab.cazzzer.com
docker_ipv6_index: 254
# Arrstack VPN
wg_privkey: "{{ vault_wg_privkey }}"
wg_psk: "{{ vault_wg_psk }}"
wg_addresses: "{{ vault_wg_addresses }}"
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik External OAuth
github_consumer_key: dbacb8621c37320eb745
github_consumer_secret: "{{ vault_github_consumer_secret }}"
google_consumer_key: 606830535764-pec4b3sa2tohim3u9jl2jmnl1see46q1.apps.googleusercontent.com
google_consumer_secret: "{{ vault_google_consumer_secret }}"
# VPGen
vpgen_ipv4_starting_addr: 10.18.11.50
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
# Woodpecker
woodpecker_gitea_client_id: c7122416-b160-498b-8021-8f2837552588
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"

View File

@@ -0,0 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256
36343339366166383430383235626463376339653331333635623936653135633633353064613634
3263306161376232356634363532653266366665333364650a636365393465383165306563346132
37653564633630653635353464333939353266396562316663653933373065353536333130383065
3864353332303164320a316439313164663736636465366539643131303663343861333164613561
37383965373964313535313335643164376164323263613539643933333035323837373662303030
66636465303566313334386435326433653032383962353739643861346161323738636366396239
39623336336234376339343562656362323932383265313161396435346530663330353266323433
66396538313365653963323164306464663565303364386466666636346533633661333634313236
33623936616239613264613730363039366561646535633239633564656166343162303633373366
37656163333838656533363735383332626632353237613666396633363531666366336630613064
66626561663766376531313666663963643766393965653564333062653139336230356330383464
38343562383430303132663964303736623238386562323033623861303432363363373934643332
63363239323664333131306237336134613137653136633932356238343733393632616464366134
33623038363032653134626337663863366663383433633134326239616136656139366535613565
61646330356330396236303566363834613236653733643162666536303435643133346633353632
62386135303262353332643135636164303963616234626132356161663463366434323864626261
33356536626263626261343937386666396561306334346435316262333431353234303836356563
31343566373935396633636133616265346235396333396664333534336162323039623937656336
36656133383966613333646336613039626563353862646238376461373264633233313836333062
30343134363862626630393035643762376435346532306462363437646238333463396230666465
64386365393063613139313164366562643066323461313364393265393638643137386561633530
65643861386531323836306339386462656530383533363831323461303131396666626464303136
64343865616235616366633136393662623862383961323338366435396334653538303830616166
39636164613466313033643639366635323666666235653633333436613133343962353664313838
64356466393239666131363964643461346633313030643061643938643232343334313731636463
37396637643232353539626239306463623237623534366666396164613135356136313534663231
36613662653237343061316463386231656136383636393034333666633063613731316162333464
64313866633062623530326233633166343434636639346565346337396461393637383333366435
62393030383963396638653230613431623837353461313630343333376131616239313164336234
62323739316536353835613032303438623230626563303934626466303934613566656232323663
643265386333313065333737613438316532

View File

@@ -1 +0,0 @@
docker_ipv6_index: 254

View File

@@ -1,2 +1,2 @@
[docker_hosts]
[alpina]
etappi.lab.home

518
poetry.lock generated
View File

@@ -1,28 +1,28 @@
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
[[package]]
name = "ansible"
version = "10.1.0"
version = "11.1.0"
description = "Radically simple IT automation"
optional = false
python-versions = ">=3.10"
python-versions = ">=3.11"
files = [
{file = "ansible-10.1.0-py3-none-any.whl", hash = "sha256:05b761c4628a0fc216478a5e3c111613c61fd13280846fa84843a63c36c7b1b6"},
{file = "ansible-10.1.0.tar.gz", hash = "sha256:7d8c44557f570687306e19d0e3296ad230593cb12bda35dcfc9274a6063af22a"},
{file = "ansible-11.1.0-py3-none-any.whl", hash = "sha256:bbaf7073993f019fc0293fc8b76c7b215081831957c28eb020f12c270a16e8f0"},
{file = "ansible-11.1.0.tar.gz", hash = "sha256:d01b425990d960d2a33fc378e1b73dbca1c0e28bc22f4056ab6b3c8e9ae74fba"},
]
[package.dependencies]
ansible-core = ">=2.17.1,<2.18.0"
ansible-core = ">=2.18.1,<2.19.0"
[[package]]
name = "ansible-core"
version = "2.17.1"
version = "2.18.1"
description = "Radically simple IT automation"
optional = false
python-versions = ">=3.10"
python-versions = ">=3.11"
files = [
{file = "ansible_core-2.17.1-py3-none-any.whl", hash = "sha256:aaaccf6a9fe05968821a02079c5ec4c33a7fe5f02d9f5d94f7c3a69f71eab675"},
{file = "ansible_core-2.17.1.tar.gz", hash = "sha256:46449d71bbd17c3ce85fe379721d88d333fd23637b5c3798e83fae5fa38def00"},
{file = "ansible_core-2.18.1-py3-none-any.whl", hash = "sha256:4a312e416e09c7271188d6b8e2b1062fc6834fefd6a1814d0e02fb8aadb3e1ba"},
{file = "ansible_core-2.18.1.tar.gz", hash = "sha256:14cac1f92bbdae881cb0616eddeb17925e8cb507e486087975e724533d9de74f"},
]
[package.dependencies]
@@ -50,65 +50,99 @@ setuptools = "*"
dev = ["black", "flake8", "isort[pyproject]", "pytest"]
release = ["twine"]
[[package]]
name = "attrs"
version = "24.3.0"
description = "Classes Without Boilerplate"
optional = false
python-versions = ">=3.8"
files = [
{file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"},
{file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"},
]
[package.extras]
benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
[[package]]
name = "cffi"
version = "1.16.0"
version = "1.17.1"
description = "Foreign Function Interface for Python calling C code."
optional = false
python-versions = ">=3.8"
files = [
{file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
{file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
{file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
{file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
{file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
{file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
{file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
{file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
{file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
{file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
{file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
{file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
{file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
{file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
{file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
{file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
{file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
{file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
{file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
{file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
{file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
{file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
{file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
{file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
{file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
{file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"},
{file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"},
{file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"},
{file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"},
{file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"},
{file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"},
{file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"},
{file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"},
{file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"},
{file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"},
{file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"},
{file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"},
{file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"},
{file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"},
{file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"},
{file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"},
{file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"},
{file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"},
{file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"},
{file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"},
{file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"},
{file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"},
{file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"},
{file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"},
{file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"},
{file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"},
{file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"},
{file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"},
{file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"},
{file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"},
{file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"},
{file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"},
{file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"},
{file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"},
]
[package.dependencies]
@@ -116,67 +150,79 @@ pycparser = "*"
[[package]]
name = "cryptography"
version = "42.0.8"
version = "44.0.0"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = ">=3.7"
python-versions = "!=3.9.0,!=3.9.1,>=3.7"
files = [
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"},
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"},
{file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"},
{file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"},
{file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"},
{file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"},
{file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"},
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
{file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"},
{file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"},
{file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"},
{file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"},
{file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"},
{file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"},
{file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"},
{file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"},
{file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"},
{file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"},
{file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"},
]
[package.dependencies]
cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""}
[package.extras]
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"]
nox = ["nox"]
pep8test = ["check-sdist", "click", "mypy", "ruff"]
sdist = ["build"]
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"]
docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"]
nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"]
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
sdist = ["build (>=1.0.0)"]
ssh = ["bcrypt (>=3.1.5)"]
test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
test-randomorder = ["pytest-randomly"]
[[package]]
name = "grafanalib"
version = "0.7.1"
description = "Library for building Grafana dashboards"
optional = false
python-versions = "*"
files = [
{file = "grafanalib-0.7.1-py3-none-any.whl", hash = "sha256:6fab5d7b837a1f2d1322ef762cd52e565ec0422707a7512765c59f668bdceb58"},
{file = "grafanalib-0.7.1.tar.gz", hash = "sha256:3d92bb4e92ae78fe4e21c5b252ab51f4fdcacd8523ba5a44545b897b2a375b83"},
]
[package.dependencies]
attrs = ">=15.2.0"
[package.extras]
dev = ["flake8", "pytest"]
[[package]]
name = "jinja2"
version = "3.1.4"
version = "3.1.5"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
{file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
{file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
]
[package.dependencies]
@@ -187,71 +233,72 @@ i18n = ["Babel (>=2.7)"]
[[package]]
name = "markupsafe"
version = "2.1.5"
version = "3.0.2"
description = "Safely add untrusted strings to HTML/XML markup."
optional = false
python-versions = ">=3.7"
python-versions = ">=3.9"
files = [
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"},
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"},
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"},
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
]
[[package]]
@@ -270,13 +317,13 @@ nicer-shell = ["ipython"]
[[package]]
name = "packaging"
version = "24.1"
version = "24.2"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
]
[[package]]
@@ -292,62 +339,64 @@ files = [
[[package]]
name = "pyyaml"
version = "6.0.1"
version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.8"
files = [
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
@@ -369,20 +418,25 @@ test = ["commentjson", "packaging", "pytest"]
[[package]]
name = "setuptools"
version = "70.1.1"
version = "75.7.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
python-versions = ">=3.9"
files = [
{file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"},
{file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"},
{file = "setuptools-75.7.0-py3-none-any.whl", hash = "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183"},
{file = "setuptools-75.7.0.tar.gz", hash = "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "mypy (==1.10.0)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.3.2)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"]
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
cover = ["pytest-cov"]
doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "2b6819adc72a58e8d504a1ba77064b09a47ec69d1cd39542ee6e068091927cb3"
python-versions = "^3.11"
content-hash = "7c5b28e1b7fc5cf1c55fedf89a01f26e9246b9d1baa1441d51a8693697b6767a"

View File

@@ -6,11 +6,14 @@ authors = ["Iurii Tatishchev <itatishch@gmail.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
ansible = "^10.1.0"
python = "^3.11"
ansible = "^11.1.0"
ansible-vault = "^2.1.0"
netaddr = "^1.3.0"
[tool.poetry.dev-dependencies]
grafanalib = "^0.7.1"
[build-system]
requires = ["poetry-core"]

View File

@@ -1,8 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
66613933613334643836373939636238303035626535666161323634323837623565383337666232
6166363839626433636231323434633164643033633466650a393032356231306436663563613734
37316438306536316438383236373431333931373933323361623162323363623332333130653366
6363616430353835620a366666303230313239393430326538346436626239663431316639633139
33663261303864326162313235663536363332633731383636663165313061343863373333396536
31336234306337393730343861636232643561356165393664633537623662353830613338363833
306537353361653834656134383632306239

View File

@@ -1,27 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
35303032386566343430633238343936366234333434343763666231666232633539303232383534
3035346233346162373939333531613535353232626531640a646537616163353736653161326265
31336530316335623335353661373834613264326436303933326135396166346562343136353931
6439383039346465300a366266393130356630316630333336616565366562613038393239623738
65626664643630353236333932373337333363626337386163613464306638633964663264363964
30373661393531306662323134626664656233323762393037356434353066343830333033316365
65616636613437663737306263373066306361376630616331663031346434336663393862316464
62343339663461353934323063653566303932656264363562333136353665336263646230323832
35376666303531383961646234663230663634393135326664386665633538616233613866373965
64363361313232316336376631646662376565353536316438306361306261663532386564616566
61663534393035343233326562303863646165346538393761326335376165623964396130393831
64333665313461666335383134613831376138393061343238643661366439636534626265323865
35393035336632653038623438626366373733626331633866373935616531623664303063376562
31356332346164663364636235333461383437623161343338643839323765336237633266633864
64363234646533616439313638363865373364623637636537623666383664656630333533303233
64383734366666633832393230663739333435666138636462336332373061346239306136336263
39643666303863303035313738343664636536663939616335303834333834363739303938646665
66303637633239373461393434313036316563313132356432633337666537616363373830313034
61313538633663653230643262613333306361666131663036643162343966313365653566393235
36623832663034373734653664613038363137366437326565373761663963636336393536386435
30393831326134376639366661653439616138643438646363343632346131306532663439396534
32383661306539306635336262383563376561303862396532633362666266313562623336383235
36366565633734633639653239306331333237353233326563653930653739316230666362323931
39663931376562653530323434656436353166393836643238643632396430353034333034333665
62323338373839383132323537353431636537616366393965643463316164323034316536383961
6164333537633631646663333463306236613038326339643439

View File

@@ -1,3 +0,0 @@
POSTGRES_USER=gitea
POSTGRES_DB=gitea
POSTGRES_PASSWORD={{ db_password }}

View File

@@ -1,6 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
61626665353536663033663661393434616339396434383530306265363837313839303939623465
3634333839333530383464613966326238363738663637360a343837623832343232316565346131
66663831356162653363383131396665326531363430656539333866313031306537343864343262
3730643765633232620a643734623336646565663266656262343162613239306166386665333139
6366

View File

@@ -1,14 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
65313636646233613364363933616361346639653939346337303832646339316632383966666237
3766396134383434613534373937663162393134306536300a626139373732393037346630333838
63663439353238643532316231623866396434303034313130386635623363353263626362376334
3933346434633662320a386432373465646432343338666561366161646335636232353133393933
65313364666564353039626238383033343765323730316633356139326666623135326131353864
32386237643538636538356261393164633137636235346564393930346539623731386633336339
31303466653936343166366164383134306232613236663735623834393963306331376435616365
31313866383730393063353335626164303632636331303830636530656131636139376633623439
63663639323964623231343066373538633336353561646230363363643762393634643435306164
31366364326237636365336363343264343562353337303235633034383635373934376334353336
61373065386639643064303431623162373665363937353832313561386134613834613935653964
64656339316165313936333736643030356366663162316462636662326134396539356262666536
64336133393937396330353234316563356337623733326264363333373536633833

View File

@@ -1 +0,0 @@
NEXTCLOUD_VERSION=28-fpm-alpine

View File

@@ -1,182 +0,0 @@
# https://github.com/nextcloud/docker/blob/master/.examples/docker-compose/with-nginx-proxy/postgres/fpm/web/nginx.conf
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
# Prevent nginx HTTP Server Detection
server_tokens off;
keepalive_timeout 65;
upstream php-handler {
server app:9000;
}
server {
listen 80;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Path to the root of your installation
root /var/www/html;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
#fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ \.(?:css|js|svg|gif)$ {
try_files $uri /index.php$request_uri;
expires 6M; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
location ^~ /push/ {
proxy_pass http://notify_push:7867/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}

View File

@@ -1,27 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
34666662336362656236356334333333396363393966626563643264306538333865623964373561
3038373931313365383531333762616439396136633230610a626435336166633261323266656366
36323335633865663538326331393635313766333639643861383738633835316533666463666363
6139323764386533390a363361636361636163373162626135393662666436323265646233653039
61353439356331393564363232303734626431333239633930373431616261306537393762383261
64336234653536316236383065636364326433393334316531316438323430306437666431323063
61383036336536343831633134636437633830346463336132653737376231666630383766656230
37376137336264363765653535303166626138646366353466616333613964323762306166376537
39633534336366333333316664326262353964386134333138316466303030636633383137613862
32646332323039386365653736666435373436633531323034633064633033646466306331383835
34386636386334396262666531356534663136393639623863326338643531346537353833663166
35613438306432623731633566393661376533653731373130306262393137663533333230653165
30653531636534656636393832383139626330383234376636313162373462313762666439323031
39393063303566353733666237666165633562333962386331626164343434643964343735313265
62313739376138656163623836663864616539336362626166336362633032326264313766346561
62396132386333663030333639623130376130353837326630383162323931396638366331393632
37383864666561323566383936353935396232363532356462366135313066633037306534393638
33333439613065333432303466303635363933313036306364393434333737353361393830663032
37636335393361343166343361396235316465373665663533663135373863663837313135343262
66326539653033313431396163303135373462373564623863346630353964303061303434303137
61613330363366346131396630656565333539353231623939383132303138353566653732306463
64303961653865333738613834353333313063393064343535353562383862666561393465386135
36373633303262343034393431613938363338346163396233663939613565306430663061623130
66323464373438366265373937303636313530376138356433643632353461376365333535303531
37616662323033633834343366626166363536383830356638633465333233663631396133653036
3233323563333632303365333661386435353830313435666132

View File

@@ -1,50 +0,0 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - OAuth2 Apps
entries:
{% set apps = {
"Gitea": {
"redirect_uris": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
"icon": "https://gitea."~ domain ~"/assets/img/logo.svg",
},
"Nextcloud": {
"redirect_uris": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
"icon": "https://nc."~ domain ~"/apps/theming/favicon",
},
} -%}
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
model: authentik_providers_oauth2.oauth2provider
id: {{ app | lower }}
attrs:
access_code_validity: minutes=1
access_token_validity: minutes=5
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
client_type: confidential
issuer_mode: per_provider
sub_mode: hashed_user_id
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
redirect_uris: {{ apps[app]["redirect_uris"] }}
refresh_token_validity: days=30
signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
- identifiers:
slug: {{ app | lower }}
model: authentik_core.application
id: {{ app | lower }}
attrs:
name: {{ app }}
group: "Apps"
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
policy_engine_mode: any
provider: !KeyOf {{ app | lower }}
{% endfor %}

View File

@@ -1,25 +0,0 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - GitHub OAuth
entries:
- identifiers:
slug: github
model: authentik_sources_oauth.oauthsource
attrs:
name: GitHub
slug: github
access_token_url: https://github.com/login/oauth/access_token
additional_scopes: openid read:org
authentication_flow: !Find [authentik_flows.flow, [slug, default-source-authentication]]
authorization_url: https://github.com/login/oauth/authorize
consumer_key: {{ github_consumer_key }}
consumer_secret: {{ github_consumer_secret }}
enabled: true
enrollment_flow: !Find [authentik_flows.flow, [slug, default-source-enrollment]]
policy_engine_mode: any
profile_url: https://api.github.com/user
provider_type: github
user_matching_mode: email_link
user_path_template: goauthentik.io/sources/%(slug)s

View File

@@ -1,56 +0,0 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - OAuth2 Services
entries:
{% set apps = {
"Grafana": {
"redirect_uris": "https://grafana."~ domain ~"/login/generic_oauth",
"icon": "https://grafana."~ domain ~"/public/img/grafana_icon.svg",
"client_secret": auth_grafana_client_secret,
},
} -%}
# TODO: Add Minio
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
model: authentik_providers_oauth2.oauth2provider
id: {{ app | lower }}
attrs:
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
client_type: confidential
client_id: {{ app | lower }}
client_secret: {{ apps[app]["client_secret"] }}
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
redirect_uris: {{ apps[app]["redirect_uris"] }}
- identifiers:
slug: {{ app | lower }}
model: authentik_core.application
attrs:
name: {{ app }}
group: "Services"
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app | lower }}
- identifiers:
name: "{{ app }} Admins"
model: authentik_core.group
id: "{{ app }} Admins"
- identifiers:
group: !KeyOf "{{ app }} Admins"
target: !Find [authentik_core.application, [slug, {{ app | lower }}]]
model: authentik_policies.policybinding
attrs:
order: 0
{% endfor %}

View File

@@ -1,9 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
34333936316336663466376163333433336136386632356366363139343239393333623138623265
3234373031623162623161383832613737393938653533630a353937373463626532306562316461
62646637353039396536623735613931373230643135373964313232376561303530386566343266
3261366363393335620a373162303030626461666164313432383263616237383230313937653435
65346564653230643837613436633565363865616636303031636530623063646630623730383163
66333864393362326462356531343039613061613466356237336365633339356464626162646538
66633235613638653036326439333833306237626539653564653536376434666238383638376333
32383637333766636337

View File

@@ -1,15 +0,0 @@
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD={{ minio_password }}
MINIO_DOMAIN=s3.{{ domain }}
MINIO_SERVER_URL=https://s3.{{ domain }}
MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }}
#MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
#MINIO_IDENTITY_OPENID_CLIENT_ID=
#MINIO_IDENTITY_OPENID_CLIENT_SECRET=
#MINIO_IDENTITY_OPENID_CLAIM_NAME=
#MINIO_IDENTITY_OPENID_CLAIM_PREFIX=
#MINIO_IDENTITY_OPENID_SCOPES=
#MINIO_IDENTITY_OPENID_REDIRECT_URI=
#MINIO_IDENTITY_OPENID_COMMENT=

View File

@@ -1,32 +0,0 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(252) | indent(2) }}
traefik_traefik:
external: true
services:
minio:
image: minio/minio:latest
container_name: minio
labels:
- {{ helpers.traefik_labels('minio', port='9090') | indent(6) }}
- traefik.http.routers.minio.service=minio
- traefik.http.routers.minio-tls.service=minio
- traefik.http.routers.minio-s3.rule=HostRegexp(`s3.{{ domain }}`, `{subdomain:.+}.s3.{{ domain }}`)
- traefik.http.routers.minio-s3.entrypoints=websecure
- traefik.http.routers.minio-s3.tls=true
- traefik.http.routers.minio-s3.tls.certresolver=letsencrypt
- traefik.http.routers.minio-s3.tls.domains.0.main=s3.{{ domain }}
- traefik.http.routers.minio-s3.tls.domains.0.sans=*.s3.{{ domain }}
- traefik.http.routers.minio-s3.service=minio-s3
- traefik.http.services.minio-s3.loadbalancer.server.port=9000
restart: unless-stopped
command: server --console-address ":9090" /data
env_file:
- .env.minio
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/minio/data:/data

View File

@@ -1,19 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
61306635623363343430383032666564666533343661386663346334626137646137653533636461
6466643635383162343463303536323563646439323333390a366134333630373464666334333037
33303361383334353833633364313430636435326361343461616664623261616566306165663966
6262323130623766380a336135333361656665356433346366386664623361343832363537633237
34303437303035653136323964643761383261646131346466643663323665323166643364646262
37363564346639393765376630313361663835343736336361313365313234303935393066646561
61356432666130653230396435663064623462333537363962386534626566386630303638393332
66353165643032373766633564653237333663663465363431343132353738663636373037656136
39366430353632633461373939326330306530353762643764396233323835333030613165613334
35623361656638356462363264336565383133346533343666663532306139653965383831393733
30656462303234616566646336376234396430353466363062383935353162333363626565653665
64343234333132663138633935656565303235626235633562363566393861363436323331643935
33343030366563383735363233613830303930303762626365376338316436396238313565373562
36343737373164653836613436646638336638393636303534303262643336356533313630306632
64303138333834616662666332303266373932396263666239653133313936336531666536616338
37613764376232333438383465346463313531613030323463666532383666376238303161356136
39303236343837643039376266636334353530623764633161373434313962366430326166366333
3733656135343438393961663334653330646562643865303339

View File

@@ -1,10 +0,0 @@
$ANSIBLE_VAULT;1.2;AES256;alpina
36343837633635363835346435333839633930656434343636623861663930333231303563313339
6139343262316564306533396465393664356637666530310a616535376436323031386435643538
31643935373036373839363863653434643263613731346666626163376266383635343866613536
3835313930383238630a363138656533616337643839383330356432303236346335613464393565
62363864323031343361643862356136316339643332393830373133656638333234656263613631
63633837633965633033316338336338643937363131393338396661636331363538346131303564
63313134636635663636363933373733633439663335356633313963326538663733373064303936
37663461333664333631633838316661383733356366613531626134303236643739366361306262
64363137666265366262373562386138313934313436363631636337373038613737

View File

@@ -1,18 +1,15 @@
- name: Ensure {{ collection }} collection directory exists
file:
path: "{{ my_svc_path }}/{{ collection }}"
path: "{{ alpina_svc_path }}/{{ collection }}"
state: directory
mode: "700"
- name: Deploy docker compose stacks for {{ collection }}
vars:
current_stack_name: "{{ stack }}"
current_stack_dest: "{{ my_svc_path }}/{{ collection }}/{{ stack }}"
current_stack_source: "{{ role_path }}/collections/{{ collection }}/{{ stack }}"
current_stack_dest: "{{ alpina_svc_path }}/{{ collection }}/{{ stack }}"
current_stack_source: "{{ role_path }}/templates/{{ collection }}/{{ stack }}"
include_tasks: deploy_compose_stack.yml
loop: "{{ stacks }}"
loop_control:
loop_var: stack
- debug:
var: acme_email

View File

@@ -10,32 +10,33 @@
file:
path: "{{ current_stack_dest }}/{{ item.path }}"
state: directory
mode: "700"
loop: "{{ lookup('community.general.filetree', current_stack_source + '/templates') }}"
mode: "755"
loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "directory"
# TODO: This is not ideal as it leaks the variables between stacks
# But that's also not really a problem, as they won't conflict if everything is done right
- name: Include variables for stack {{ stack }}
include_vars:
file: "{{ current_stack_source }}/app_config.yml"
- name: Generate {{ current_stack_name }} deployment from templates
template:
src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}"
mode: "600"
loop: "{{ lookup('community.general.filetree', current_stack_source + '/templates') }}"
when: item.state == "file"
mode: "644"
loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and item.path | regex_search('\\.j2$')
- name: Generate {{ current_stack_name }} deployment from static files
copy:
src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path }}"
mode: "644"
loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and not item.path | regex_search('\\.j2$')
- name: Deploy docker-compose for {{ current_stack_name }}
command: docker compose -f "{{ current_stack_dest }}/docker-compose.yml" up -d --pull always --remove-orphans
community.docker.docker_compose_v2:
project_src: "{{ current_stack_dest }}"
state: present
pull: always
remove_orphans: yes
register: docker_compose_output
# Not perfect idempotency, but the built-in docker_compose module doesn't support docker-compose v2
# And of course there's an IPv6 bug in docker-compose v1, smh
# https://github.com/docker/compose/issues/7670
changed_when: "'created' in docker_compose_output.stderr.lower()"
failed_when: docker_compose_output.rc != 0
- debug:
var: docker_compose_output
# - debug:
# var: docker_compose_output

View File

@@ -10,7 +10,7 @@
- name: Ensure alpina directory exists
file:
state: directory
path: "{{ my_svc_path }}"
path: "{{ alpina_svc_path }}"
mode: "700"
- name: Deploy collection services
@@ -28,7 +28,11 @@
collection: apps
stacks:
- gitea
- woodpecker
- nextcloud
- jellyfin
- arrstack
- vpgen
- pgrok
- obsidian-livesync
import_tasks: deploy_collection.yml

View File

@@ -21,8 +21,7 @@
## AirVPN
VPN_SERVICE_PROVIDER=airvpn
VPN_TYPE=wireguard
SERVER_NAMES=Bunda,Imai,Saclateni
#SERVER_NAMES=Bunda
SERVER_NAMES={{ vpn_server_names }}
WIREGUARD_PUBLIC_KEY={{ wg_peer_pubkey }}
WIREGUARD_PRIVATE_KEY={{ wg_privkey }}
WIREGUARD_PRESHARED_KEY={{ wg_psk }}

View File

@@ -2,8 +2,6 @@
networks:
{{ helpers.default_network(249) | indent(2) }}
traefik_traefik:
external: true
services:
gluetun:
@@ -11,14 +9,13 @@ services:
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
env_file:
- .env.gluetun
restart: unless-stopped
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/arrstack/gluetun:/gluetun
@@ -49,9 +46,6 @@ services:
restart: unless-stopped
depends_on:
- qbittorrent
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/arrstack/config/prowlarr:/config
@@ -63,9 +57,6 @@ services:
restart: unless-stopped
depends_on:
- qbittorrent
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/arrstack/config/sonarr:/config
- {{ base_volume_path }}/arrstack/downloads:/downloads
@@ -79,9 +70,6 @@ services:
restart: unless-stopped
depends_on:
- qbittorrent
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/arrstack/config/radarr:/config
- {{ base_volume_path }}/arrstack/downloads:/downloads

View File

@@ -0,0 +1,3 @@
POSTGRES_USER=gitea
POSTGRES_DB=gitea
POSTGRES_PASSWORD={{ gitea_db_password }}

View File

@@ -3,9 +3,9 @@ GITEA____APP_NAME=CazGitea
# Database
GITEA__database__DB_TYPE=postgres
GITEA__database__HOST=db:5432
GITEA__database__NAME={{ db_user }}
GITEA__database__USER={{ db_name }}
GITEA__database__PASSWD={{ db_password }}
GITEA__database__NAME=gitea
GITEA__database__USER=gitea
GITEA__database__PASSWD={{ gitea_db_password }}
# Server
GITEA__server__ROOT_URL=https://gitea.{{ domain }}/
@@ -17,7 +17,7 @@ GITEA__mailer__SMTP_ADDR=smtp.sendgrid.net
GITEA__mailer__SMTP_PORT=587
GITEA__mailer__FROM=gitea@cazzzer.com
GITEA__mailer__USER=apikey
GITEA__mailer__PASSWD={{ sendgrid_api_key }}
GITEA__mailer__PASSWD={{ gitea_sendgrid_api_key }}
# Security
GITEA__security__SECRET_KEY={{ secret_key }}

View File

@@ -2,32 +2,25 @@
networks:
{{ helpers.default_network(199) | indent(2) }}
traefik_traefik:
external: true
services:
server:
image: gitea/gitea:1.21
image: gitea/gitea:1.22
container_name: gitea_server
labels:
- {{ helpers.traefik_labels('gitea', port='3000') | indent(6) }}
restart: unless-stopped
env_file:
- .env.gitea
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/gitea/gitea:/data
depends_on:
- db
db:
image: postgres:14-alpine
image: postgres:16-alpine
container_name: gitea_db
restart: unless-stopped
env_file:
- .env.db
networks:
- default
volumes:
- {{ base_volume_path }}/gitea/postgres:/var/lib/postgresql/data

View File

@@ -2,8 +2,6 @@
networks:
{{ helpers.default_network(197) | indent(2) }}
traefik_traefik:
external: true
services:
jellyfin:
@@ -14,9 +12,6 @@ services:
restart: unless-stopped
env_file:
- .env.jellyfin
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/jellyfin/config:/config
- {{ base_volume_path }}/jellyfin/cache:/cache

View File

@@ -1,3 +1,3 @@
POSTGRES_USER=nextcloud
POSTGRES_DB=nextcloud
POSTGRES_PASSWORD={{ db_password }}
POSTGRES_PASSWORD={{ nextcloud_db_password }}

View File

@@ -0,0 +1 @@
NEXTCLOUD_VERSION=30-apache

View File

@@ -1,6 +1,6 @@
POSTGRES_DB=nextcloud
POSTGRES_USER=nextcloud
POSTGRES_PASSWORD={{ db_password }}
POSTGRES_PASSWORD={{ nextcloud_db_password }}
POSTGRES_HOST=db
NEXTCLOUD_TRUSTED_DOMAINS=nc.{{ domain }}
@@ -13,11 +13,12 @@ SMTP_SECURE=tls
SMTP_PORT=587
SMTP_AUTHTYPE=LOGIN
SMTP_NAME=apikey
SMTP_PASSWORD={{ sendgrid_api_key }}
SMTP_PASSWORD={{ nextcloud_sendgrid_api_key }}
MAIL_FROM_ADDRESS=nc
MAIL_DOMAIN=cazzzer.com
TRUSTED_PROXIES={{ traefik_subnet }}
# host IPv4 and IPv6 addresses, loopback for notify_push
TRUSTED_PROXIES={{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }} {{ hostvars[inventory_hostname]['ansible_default_ipv6']['address'] }} 127.0.0.1 ::1
OVERWRITEHOST=nc.{{ domain }}
OVERWRITEPROTOCOL=https
OVERWRITECLIURL=https://nc.{{ domain }}

View File

@@ -0,0 +1,4 @@
DATABASE_URL=postgres://nextcloud:{{ nextcloud_db_password }}@db/nextcloud
DATABASE_PREFIX=oc_
REDIS_URL=redis://:{{ redis_password }}@redis
NEXTCLOUD_URL=http://localhost

View File

@@ -2,22 +2,19 @@
networks:
{{ helpers.default_network(198) | indent(2) }}
traefik_traefik:
external: true
services:
app:
image: nextcloud:${NEXTCLOUD_VERSION}
container_name: nextcloud_app
labels:
- {{ helpers.traefik_labels('nc', port='80') | indent(6) }}
restart: unless-stopped
depends_on:
- db
- redis
env_file:
- .env.nextcloud
networks:
- default
volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
@@ -30,8 +27,6 @@ services:
depends_on:
- app
entrypoint: /cron.sh
networks:
- default
volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
@@ -40,56 +35,34 @@ services:
notify_push:
image: nextcloud:${NEXTCLOUD_VERSION}
container_name: nextcloud_notify_push
labels:
- {{ helpers.traefik_labels('nc', port='7867', path_prefix='/push') | indent(6) }}
restart: unless-stopped
depends_on:
- app
user: www-data
env_file:
- .env.notify_push
network_mode: service:app
entrypoint:
- /var/www/html/custom_apps/notify_push/bin/x86_64/notify_push
- /var/www/html/config/config.php
networks:
- default
volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data
db:
image: postgres:13-alpine
image: postgres:16-alpine
container_name: nextcloud_db
restart: unless-stopped
env_file:
- .env.db
networks:
- default
volumes:
- {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data
redis:
image: redis:7-alpine
image: redis:alpine
container_name: nextcloud_redis
restart: unless-stopped
env_file:
- .env.redis
networks:
- default
command:
- sh
- -c
- redis-server --requirepass $$REDIS_PASSWORD
web:
image: nginx:1.23-alpine
container_name: nextcloud_web
labels:
- {{ helpers.traefik_labels('nc') | indent(6) }}
restart: unless-stopped
links:
- app
networks:
- traefik_traefik
- default
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data

View File

@@ -0,0 +1,30 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(199) | indent(2) }}
services:
couchdb:
image: couchdb
container_name: obsidian-livesync
# user: 1000:1000
environment:
- COUCHDB_USER=hi
- COUCHDB_PASSWORD=3hCtyJ3bPFjxxGu4
volumes:
- {{ base_volume_path }}/obsidian-livesync:/opt/couchdb/data
# Ports not needed when already passed to Traefik
#ports:
# - 5984:5984
restart: unless-stopped
labels:
- {{ helpers.traefik_labels('obsidian-livesync', port='5984') | indent(6) }}
- traefik.http.routers.r-obsidian-livesync.middlewares=obsidiancors
- # https://github.com/vrtmrz/obsidian-livesync/blob/main/docs/setup_own_server.md
# The part needed for CORS to work on Traefik 2.x starts here
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolalloworiginlist=app://obsidian.md,capacitor://localhost,http://localhost"
- "traefik.http.middlewares.obsidiancors.headers.accesscontrolmaxage=3600"
- "traefik.http.middlewares.obsidiancors.headers.addvaryheader=true"
- "traefik.http.middlewares.obsidiancors.headers.accessControlAllowCredentials=true"

View File

@@ -0,0 +1,31 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(194) | indent(2) }}
# https://github.com/pgrok/pgrok/blob/main/docs/admin/docker.md#docker-compose
services:
server:
image: ghcr.io/pgrok/pgrokd:latest
container_name: pgrok_server
labels:
- {{ helpers.traefik_labels('pgrok', port='3320') | indent(6) }}
- {{ helpers.traefik_labels('pgrok', port='3000', wildcard=true) | indent(6) }}
restart: unless-stopped
volumes:
- ./pgrokd.yml:/var/opt/pgrokd/pgrokd.yml
ports:
- "2222:2222"
depends_on:
- db
db:
image: postgres:17-alpine
container_name: pgrok_db
restart: unless-stopped
volumes:
- {{ base_volume_path }}/pgrok/postgres:/var/lib/postgresql/data
environment:
POSTGRES_DB: pgrok
POSTGRES_USER: pgrok
POSTGRES_PASSWORD: "{{ pgrok_db_password }}"

View File

@@ -0,0 +1,29 @@
external_url: "https://pgrok.{{ domain }}"
web:
port: 3320
proxy:
port: 3000
scheme: https
domain: "pgrok.{{ domain }}"
sshd:
port: 2222
database:
host: db
port: 5432
user: pgrok
password: "{{ pgrok_db_password }}"
database: pgrok
identity_provider:
type: oidc
display_name: Authentik
issuer: "https://auth.{{ domain }}/application/o/pgrok/"
client_id: "pgrok"
client_secret: "{{ auth_pgrok_client_secret }}"
field_mapping:
identifier: "preferred_username"
display_name: "name"
email: "email"
# # The required domain name, "field_mapping.email" is required to set for this to work.
# required_domain: "example.com"

View File

@@ -0,0 +1,20 @@
DATABASE_URL=file:/data/vpgen.db
AUTH_DOMAIN=auth.{{ domain }}
AUTH_CLIENT_ID=vpgen
AUTH_CLIENT_SECRET={{ auth_vpgen_client_secret }}
OPNSENSE_API_URL={{ vpgen_opnsense_api_url }}
OPNSENSE_API_KEY={{ vpgen_opnsense_api_key }}
OPNSENSE_API_SECRET={{ vpgen_opnsense_api_secret }}
OPNSENSE_WG_IFNAME={{ vpgen_opnsense_wg_ifname }}
IPV4_STARTING_ADDR={{ vpgen_ipv4_starting_addr }}
IPV6_STARTING_ADDR={{ vpgen_ipv6_starting_addr }}
IPV6_CLIENT_PREFIX_SIZE={{ vpgen_ipv6_client_prefix_size }}
IP_MAX_INDEX={{ vpgen_ip_max_index }}
VPN_ENDPOINT={{ vpgen_vpn_endpoint }}
VPN_DNS={{ vpgen_vpn_dns }}
MAX_CLIENTS_PER_USER={{ vpgen_max_clients_per_user }}
ORIGIN=https://vpgen.{{ domain }}

View File

@@ -0,0 +1,16 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(196) | indent(2) }}
services:
vpgen:
image: gitea.cazzzer.com/cazzzer/vpgen:develop
container_name: vpgen
labels:
- {{ helpers.traefik_labels('vpgen', port='3000') | indent(6) }}
restart: unless-stopped
env_file:
- .env.vpgen
volumes:
- {{ base_volume_path }}/vpgen:/data

View File

@@ -0,0 +1,35 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(195) | indent(2) }}
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
container_name: woodpecker_server
labels:
- {{ helpers.traefik_labels('woodpecker', port='8000') | indent(6) }}
restart: unless-stopped
volumes:
- {{ base_volume_path }}/woodpecker/data:/var/lib/woodpecker
environment:
- WOODPECKER_OPEN=true
- WOODPECKER_HOST=https://woodpecker.{{ domain }}
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://gitea.{{ domain }}
- WOODPECKER_GITEA_CLIENT={{ woodpecker_gitea_client_id }}
- WOODPECKER_GITEA_SECRET={{ woodpecker_gitea_client_secret }}
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
container_name: woodpecker_agent
restart: unless-stopped
depends_on:
- woodpecker-server
volumes:
- {{ base_volume_path }}/woodpecker/agent_config:/etc/woodpecker
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}

View File

@@ -4,14 +4,14 @@ AUTHENTIK_REDIS__HOST=redis
AUTHENTIK_POSTGRESQL__HOST=postgres
AUTHENTIK_POSTGRESQL__USER=authentik
AUTHENTIK_POSTGRESQL__NAME=authentik
AUTHENTIK_POSTGRESQL__PASSWORD={{ db_password }}
AUTHENTIK_POSTGRESQL__PASSWORD={{ authentik_db_password }}
AUTHENTIK_SECRET_KEY={{ authentik_secret_key }}
AUTHENTIK_EMAIL__HOST=smtp.sendgrid.net
AUTHENTIK_EMAIL__PORT=587
AUTHENTIK_EMAIL__USERNAME=apikey
AUTHENTIK_EMAIL__PASSWORD={{ sengrid_api_key }}
AUTHENTIK_EMAIL__PASSWORD={{ authentik_sendgrid_api_key }}
AUTHENTIK_EMAIL__USE_TLS=true
AUTHENTIK_EMAIL__TIMEOUT=10

View File

@@ -1,3 +1,3 @@
POSTGRES_USER=authentik
POSTGRES_DB=authentik
POSTGRES_PASSWORD={{ db_password }}
POSTGRES_PASSWORD={{ authentik_db_password }}

View File

@@ -0,0 +1,225 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Enrollment by Invitation (Internal)
entries:
# Flow for internal enrollment by invitation
- identifiers:
slug: enrollment-internal-invitation-flow
model: authentik_flows.flow
id: flow
attrs:
name: Alpina Enrollment Flow
title: Sign Up
designation: enrollment
authentication: require_unauthenticated
# Prompt fields
- identifiers:
name: alpina-enrollment-field-name
model: authentik_stages_prompt.prompt
id: prompt-field-name
attrs:
field_key: name
label: Name
type: text
required: true
placeholder: Name
placeholder_expression: false
order: 0
- identifiers:
name: alpina-enrollment-field-password
model: authentik_stages_prompt.prompt
id: prompt-field-password
attrs:
field_key: password
label: Password
type: password
required: true
placeholder: Password
placeholder_expression: false
order: 1
- identifiers:
name: alpina-enrollment-field-password-repeat
model: authentik_stages_prompt.prompt
id: prompt-field-password-repeat
attrs:
field_key: password_repeat
label: Password (repeat)
type: password
required: true
placeholder: Password (repeat)
placeholder_expression: false
order: 2
# Flow stages
- identifiers:
name: alpina-enrollment-invitation
model: authentik_stages_invitation.invitationstage
id: enrollment-invitation
- identifiers:
name: alpina-enrollment-identification-oauth
model: authentik_stages_identification.identificationstage
id: enrollment-identification-oauth
attrs:
user_fields:
- email
pretend_user_exists: true
show_matched_user: false
sources:
- !Find [authentik_sources_oauth.oauthsource, [slug, github-enrollment]]
- !Find [authentik_sources_oauth.oauthsource, [slug, google-enrollment]]
- identifiers:
name: alpina-enrollment-deny-existing-email
model: authentik_stages_deny.denystage
id: enrollment-deny-existing-email
attrs:
deny_message: "An account with this email already exists"
- identifiers:
name: alpina-enrollment-prompt-name-password
model: authentik_stages_prompt.promptstage
id: enrollment-prompt-name-password
attrs:
fields:
- !KeyOf prompt-field-name
- !KeyOf prompt-field-password
- !KeyOf prompt-field-password-repeat
validation_policies:
- !Find [authentik_policies_password.passwordpolicy, [name, default-password-change-password-policy]]
- identifiers:
name: alpina-enrollment-user-write
model: authentik_stages_user_write.userwritestage
id: enrollment-user-write
attrs:
user_type: internal
create_users_group: !Find [authentik_core.group, [name, {{ auth_default_enrollment_group }}]]
- identifiers:
name: alpina-enrollment-email-verify
model: authentik_stages_email.emailstage
id: enrollment-email-verify
attrs:
use_global_settings: true
template: email/account_confirmation.html
activate_user_on_success: true
- identifiers:
name: alpina-enrollment-user-login
model: authentik_stages_user_login.userloginstage
id: enrollment-user-login
# Policies
- identifiers:
name: alpina-enrollment-invited-used-policy
model: authentik_policies_event_matcher.eventmatcherpolicy
id: enrollment-invited-used-policy
attrs:
action: invitation_used
- identifiers:
name: alpina-enrollment-unique-email-policy
model: authentik_policies_expression.expressionpolicy
id: enrollment-unique-email-policy
attrs:
expression: |
# https://docs.goauthentik.io/docs/customize/policies/expression/unique_email
from authentik.core.models import User
email = request.context["flow_plan"].context["pending_user"].email
if User.objects.filter(email=email).exists():
ak_message("Email address in use")
return False
if request.context["flow_plan"].context.get("prompt_data") is None:
request.context["flow_plan"].context["prompt_data"] = {}
request.context["flow_plan"].context["prompt_data"]["email"] = email
request.context["flow_plan"].context["prompt_data"]["username"] = email
return True
- identifiers:
name: alpina-enrollment-user-write-add-groups-policy
model: authentik_policies_expression.expressionpolicy
id: enrollment-user-write-add-groups-policy
attrs:
expression: |
# https://docs.goauthentik.io/docs/add-secure-apps/flows-stages/stages/user_write
from authentik.core.models import Group
ak_logger.info("Adding groups", request=request, prompt_data=request.context["prompt_data"], invitation=request.context.get("invitation"))
requested_groups = request.context["prompt_data"].get("alpina_add_groups")
if requested_groups is None:
return True
groups = []
for group_name in requested_groups:
group, _ = Group.objects.get_or_create(name=group_name)
groups.append(group)
# ["groups"] *must* be set to an array of Group objects, names alone are not enough.
request.context["flow_plan"].context["groups"] = groups
return True
# Flow stage bindings
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-invitation
order: 0
model: authentik_flows.flowstagebinding
id: enrollment-invitation-binding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-identification-oauth
order: 1
model: authentik_flows.flowstagebinding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-deny-existing-email
order: 2
model: authentik_flows.flowstagebinding
id: enrollment-deny-existing-email-binding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-prompt-name-password
order: 10
model: authentik_flows.flowstagebinding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-user-write
order: 20
model: authentik_flows.flowstagebinding
id: enrollment-user-write-binding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-email-verify
order: 30
model: authentik_flows.flowstagebinding
- identifiers:
target: !KeyOf flow
stage: !KeyOf enrollment-user-login
order: 100
model: authentik_flows.flowstagebinding
# Stage policy bindings
# Log used invitations
- identifiers:
target: !KeyOf enrollment-invitation-binding
policy: !KeyOf enrollment-invited-used-policy
order: 0
model: authentik_policies.policybinding
attrs:
negate: true
# Deny existing email addresses
- identifiers:
target: !KeyOf enrollment-deny-existing-email-binding
policy: !KeyOf enrollment-unique-email-policy
order: 0
model: authentik_policies.policybinding
attrs:
negate: true
# Add groups to user from invitation "alpina_add_groups" field
# This only work for email sign up, as the invitation flow context isn't
# preserved for the default-source-enrollment flow
- identifiers:
target: !KeyOf enrollment-user-write-binding
policy: !KeyOf enrollment-user-write-add-groups-policy
order: 0
model: authentik_policies.policybinding

View File

@@ -0,0 +1,45 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Default Groups
entries:
- identifiers:
name: "admins"
model: authentik_core.group
id: "admins"
attrs:
is_superuser: true
- identifiers:
name: "users"
model: authentik_core.group
id: "users"
- identifiers:
name: "arrstack"
model: authentik_core.group
id: "arrstack"
attrs:
arrstack_username: "arr"
arrstack_password: "{{ arrstack_password }}"
- identifiers:
scope_name: "minio"
model: authentik_providers_oauth2.scopemapping
id: "scope-minio"
attrs:
name: "Minio Policy"
expression: |
policy = "default"
if ak_is_group_member(request.user, name="admins"):
policy = "consoleAdmin"
return {
"policy": policy,
}
- identifiers:
name: "vpgen"
model: authentik_core.group
id: "vpgen"

View File

@@ -0,0 +1,79 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - External OAuth
entries:
{% set sources = {
"GitHub": {
"provider_type": "github",
"consumer_key": github_consumer_key,
"consumer_secret": github_consumer_secret,
},
"Google": {
"provider_type": "google",
"consumer_key": google_consumer_key,
"consumer_secret": google_consumer_secret,
},
} -%}
{% for source in sources.keys() -%}
- identifiers:
slug: {{ source | lower }}-auth
model: authentik_sources_oauth.oauthsource
attrs:
provider_type: {{ sources[source]["provider_type"] }}
name: {{ source }} (Auth Only)
consumer_key: {{ sources[source]["consumer_key"] }}
consumer_secret: {{ sources[source]["consumer_secret"] }}
user_matching_mode: email_link
user_path_template: goauthentik.io/sources/%(slug)s
authentication_flow: !Find [authentik_flows.flow, [slug, default-source-authentication]]
- identifiers:
slug: {{ source | lower }}-enrollment
model: authentik_sources_oauth.oauthsource
attrs:
provider_type: {{ sources[source]["provider_type"] }}
name: {{ source }} (Auth and Enrollment)
consumer_key: {{ sources[source]["consumer_key"] }}
consumer_secret: {{ sources[source]["consumer_secret"] }}
user_matching_mode: email_link
user_path_template: goauthentik.io/sources/%(slug)s
authentication_flow: !Find [authentik_flows.flow, [slug, default-source-authentication]]
enrollment_flow: !Find [authentik_flows.flow, [slug, default-source-enrollment]]
{% endfor %}
# Modify default source enrollment to use email as username
- identifiers:
slug: default-source-enrollment
model: authentik_flows.flow
id: source-enrollment-flow
attrs:
policy_engine_mode: all
- identifiers:
name: alpina-email-as-username-policy
model: authentik_policies_expression.expressionpolicy
id: email-as-username-policy
attrs:
expression: |
# https://docs.goauthentik.io/docs/users-sources/sources/social-logins/google/#username-mapping
email = request.context["prompt_data"].get("email")
# Direct set username to email
request.context["prompt_data"]["username"] = email
# Set username to email without domain
# request.context["prompt_data"]["username"] = email.split("@")[0]
return True
- identifiers:
policy: !KeyOf email-as-username-policy
target: !KeyOf source-enrollment-flow
model: authentik_policies.policybinding
attrs:
order: 0
# Modify default source enrollment to create internal users
# with the internal user type and the users group
- identifiers:
name: default-source-enrollment-write
model: authentik_stages_user_write.userwritestage
attrs:
user_type: internal
create_users_group: !Find [authentik_core.group, [name, {{ auth_default_enrollment_group }}]]

View File

@@ -0,0 +1,98 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - OAuth2 Apps
entries:
{% set apps = {
"Grafana": {
"redirect_uri": "https://grafana."~ domain ~"/login/generic_oauth",
"icon": "https://grafana."~ domain ~"/public/img/grafana_icon.svg",
"client_secret": auth_grafana_client_secret,
"ui_group": "Services",
"allowed_for_groups": ["admins"],
},
"Minio": {
"redirect_uri": "https://minio."~ domain ~"/oauth_callback",
"icon": "https://minio."~ domain ~"/logo192.png",
"client_secret": auth_minio_client_secret,
"ui_group": "Services",
"allowed_for_groups": ["admins"],
},
"Gitea": {
"redirect_uri": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
"icon": "https://gitea."~ domain ~"/assets/img/logo.svg",
"client_secret": auth_gitea_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
},
"Nextcloud": {
"redirect_uri": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
"icon": "https://nc."~ domain ~"/apps/theming/favicon",
"client_secret": auth_nextcloud_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
},
"VPGen": {
"redirect_uri": "https://vpgen."~ domain ~"/auth/authentik/callback",
"icon": "https://vpgen."~ domain ~"/favicon.png",
"client_secret": auth_vpgen_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users", "vpgen"],
},
"Pgrok": {
"redirect_uri": "https://pgrok."~ domain ~"/-/oidc/callback",
"icon": "https://pgrok."~ domain ~"/pgrok.svg",
"client_secret": auth_pgrok_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
},
} -%}
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
model: authentik_providers_oauth2.oauth2provider
id: {{ app }}
attrs:
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: confidential
client_id: {{ app | lower }}
client_secret: {{ apps[app]["client_secret"] }}
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
{% if app == "Minio" -%}
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, minio]]
{%- endif %}
redirect_uris:
- matching_mode: strict
url: {{ apps[app]["redirect_uri"] }}
# Necessary for JWKS to be generated correctly
signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
- identifiers:
slug: {{ app | lower }}
model: authentik_core.application
id: app-{{ app }}
attrs:
name: {{ app }}
group: "{{ apps[app]["ui_group"] }}"
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app }}
{% for group in apps[app]["allowed_for_groups"] -%}
- identifiers:
group: !Find [authentik_core.group, [name, {{ group }}]]
target: !KeyOf app-{{ app }}
model: authentik_policies.policybinding
attrs:
order: 10
{% endfor %}
{% endfor %}

View File

@@ -4,61 +4,47 @@ metadata:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Proxied Apps
entries:
- identifiers:
name: arrstack
model: authentik_core.group
id: arrstack
attrs:
arrstack_username: "arr"
arrstack_password: "{{ arrstack_password }}"
# TODO: Probably refactor this into a jinja macro
# TODO: Possibly refactor this into a jinja macro (?)
{% set apps = {
"uptime-kuma": {
"Uptime Kuma": {
"host": "uptime",
"name": "Uptime Kuma",
"icon": "https://uptime."~ domain ~"/icon.svg",
"unauthenticated_paths": "^/icon.svg$",
"group": "Services",
"create_admin_group": true,
"ui_group": "Services",
"allowed_for_groups": ["admins"],
},
"qbit": {
"qBit": {
"host": "qbit",
"name": "qBit",
"icon": "https://qbit."~ domain ~"/images/qbittorrent-tray.svg",
"unauthenticated_paths": "^/images/qbittorrent-tray.svg$",
"group": "Arrstack",
"create_admin_group": false,
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
},
"prowlarr": {
"Prowlarr": {
"host": "prowlarr",
"name": "Prowlarr",
"icon": "https://prowlarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"group": "Arrstack",
"create_admin_group": false,
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
},
"sonarr": {
"Sonarr": {
"host": "sonarr",
"name": "Sonarr",
"icon": "https://sonarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"group": "Arrstack",
"create_admin_group": false,
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
},
"radarr": {
"Radarr": {
"host": "radarr",
"name": "Radarr",
"icon": "https://radarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"group": "Arrstack",
"create_admin_group": false,
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
},
} -%}
{% for app in apps.keys() -%}
- identifiers:
name: {{ apps[app]["name"] }}
name: {{ app }}
model: authentik_providers_proxy.proxyprovider
id: {{ app }}
attrs:
@@ -68,39 +54,26 @@ entries:
skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}"
- identifiers:
slug: {{ app }}
slug: {{ app | lower | replace(" ", "-") }}
model: authentik_core.application
id: app-{{ app }}
attrs:
name: {{ apps[app]["name"] }}
group: {{ apps[app]["group"] }}
meta_description: "Hello, I'm {{ apps[app]["name"] }}!"
name: {{ app }}
group: {{ apps[app]["ui_group"] }}
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app }}
{% if apps[app]["create_admin_group"] -%}
{% for group in apps[app]["allowed_for_groups"] -%}
- identifiers:
name: "{{ apps[app]["name"] }} Admins"
model: authentik_core.group
id: "{{ app }} Admins"
- identifiers:
group: !KeyOf "{{ app }} Admins"
target: !Find [authentik_core.application, [ slug, {{ app }}] ]
group: !Find [authentik_core.group, [name, {{ group }}]]
target: !KeyOf app-{{ app }}
model: authentik_policies.policybinding
attrs:
order: 0
{% endif %}
{% if apps[app]["group"] == "Arrstack" -%}
- identifiers:
group: !KeyOf arrstack
target: !Find [authentik_core.application, [slug, {{ app }}]]
model: authentik_policies.policybinding
attrs:
order: 0
{% endif %}
order: 10
{% endfor %}
{% endfor %}

View File

@@ -48,7 +48,8 @@ entries:
passwordless_flow: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]]
sources:
- !Find [authentik_core.source, [slug, authentik-built-in]]
- !Find [authentik_sources_oauth.oauthsource, [slug, github]]
- !Find [authentik_sources_oauth.oauthsource, [slug, github-auth]]
- !Find [authentik_sources_oauth.oauthsource, [slug, google-auth]]
# Enable compatibility mode for the default authentication flow for better autofill support
- identifiers:

View File

@@ -2,8 +2,6 @@
networks:
{{ helpers.default_network(253) | indent(2) }}
traefik_traefik:
external: true
services:
server:
@@ -17,13 +15,11 @@ services:
restart: unless-stopped
# Port forward is needed because traefik can't resolve the container name from the host network
ports:
- "9000:9000"
- "127.0.0.1:9000:9000"
- "[::1]:9000:9000"
command: server
env_file:
- .env.authentik
networks:
- default
- traefik_traefik
worker:
image: ghcr.io/goauthentik/server:latest
@@ -37,7 +33,7 @@ services:
- {{ base_volume_path }}/authentik/certs:/certs
postgres:
image: postgres:12-alpine
image: postgres:16-alpine
container_name: authentik_postgres
restart: unless-stopped
env_file:

View File

@@ -0,0 +1,20 @@
MINIO_ROOT_USER=minio
MINIO_ROOT_PASSWORD={{ minio_password }}
MINIO_DOMAIN=s3.{{ domain }}
MINIO_SERVER_URL=https://s3.{{ domain }}
MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }}
# https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html
MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
MINIO_IDENTITY_OPENID_CLIENT_ID=minio
MINIO_IDENTITY_OPENID_CLIENT_SECRET={{ auth_minio_client_secret }}
# defaults to "policy"
#MINIO_IDENTITY_OPENID_CLAIM_NAME=policy
MINIO_IDENTITY_OPENID_DISPLAY_NAME=Authentik
# no need to specify scopes,
# as it defaults to the ones advertised at the discovery url
#MINIO_IDENTITY_OPENID_SCOPES=openid,profile,email,minio
#MINIO_IDENTITY_OPENID_REDIRECT_URI_DYNAMIC=off
#MINIO_IDENTITY_OPENID_CLAIM_USERINFO=on
#MINIO_IDENTITY_OPENID_COMMENT=

View File

@@ -0,0 +1,19 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(252) | indent(2) }}
services:
minio:
image: minio/minio:latest
container_name: minio
labels:
- {{ helpers.traefik_labels('minio', port='9090') | indent(6) }}
- {{ helpers.traefik_labels('s3', port='9000') | indent(6) }}
- {{ helpers.traefik_labels('s3', port='9000', wildcard=true) | indent(6) }}
restart: unless-stopped
command: server --console-address ":9090" /data
env_file:
- .env.minio
volumes:
- {{ base_volume_path }}/minio/data:/data

View File

@@ -0,0 +1,17 @@
FROM python:3-alpine AS builder
RUN pip install grafanalib
COPY ./grafana_config/dashboards /dashboards
# Required for grafanalib to find the shared python files like common.py
# https://github.com/weaveworks/grafanalib/issues/58
ENV PYTHONPATH=/dashboards
RUN generate-dashboards /dashboards/*.dashboard.py
FROM grafana/grafana:latest
#COPY ./grafana_config /etc/grafana
COPY ./grafana_config/dashboards/*.yaml /etc/grafana/provisioning/dashboards
COPY --from=builder /dashboards/*.json /etc/grafana/provisioning/dashboards

View File

@@ -2,36 +2,37 @@
networks:
{{ helpers.default_network(251) | indent(2) }}
traefik_traefik:
external: true
services:
grafana:
image: grafana/grafana:latest
{# image: grafana/grafana:latest#}
build:
context: .
dockerfile: Dockerfile
container_name: grafana
labels:
- {{ helpers.traefik_labels('grafana', port='3000') | indent(6) }}
restart: unless-stopped
# Needed to make config files readable
# Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}"
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/monitoring/grafana:/var/lib/grafana
- ./grafana_config:/etc/grafana:ro
- ./grafana_config/grafana.ini:/etc/grafana/grafana.ini:ro
- ./grafana_config/datasources:/etc/grafana/provisioning/datasources:ro
{# - ./grafana_config:/etc/grafana:ro#}
loki:
image: grafana/loki:latest
container_name: loki
restart: unless-stopped
# Needed to make config files readable
# Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}"
command:
- -config.file=/etc/loki/loki-config.yaml
# Port forward is needed because not possible to resolve the container name from the host network
ports:
- 3100:3100
- "127.0.0.1:3100:3100"
- "[::1]:3100:3100"
volumes:
- {{ base_volume_path }}/monitoring/loki:/loki
- ./loki_config:/etc/loki:ro
@@ -56,7 +57,7 @@ services:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
# Needed to make config files readable
# Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}"
command:
- --config.file=/etc/prometheus/prometheus.yml
@@ -79,6 +80,11 @@ services:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
command:
- --docker_only=true
- --store_container_labels=false
- --whitelisted_container_labels=com.docker.compose.project,com.docker.compose.service
- --enable_metrics=cpu,cpuLoad,diskIO,memory,network,oom_event,process
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
@@ -93,22 +99,9 @@ services:
restart: unless-stopped
env_file:
- .env.influxdb
networks:
- default
- traefik_traefik
volumes:
- {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2
jaeger:
image: jaegertracing/all-in-one:1
container_name: jaeger
restart: unless-stopped
ports:
- 5778:5778
- 6831:6831/udp
volumes:
- {{ base_volume_path }}/monitoring/jaeger:/jaeger
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma

View File

@@ -0,0 +1,9 @@
apiVersion: 1
providers:
- name: "Grafana"
org_id: 1
folder: "Alpina"
type: "file"
options:
path: "/etc/grafana/provisioning/dashboards"

View File

@@ -0,0 +1,81 @@
from attrs import define
from grafanalib.core import Template, TimeSeries, Dashboard, HIDE_VARIABLE, Target
CONF_SUPPORT_LOKI = True
CONF_SUPPORT_ZFS = True
CONF_DATASOURCE_VAR_PROM = 'prom_datasource'
CONF_DATASOURCE_VAR_LOKI = 'loki_datasource'
prom_datasource = f'${{{CONF_DATASOURCE_VAR_PROM}}}'
loki_datasource = f'${{{CONF_DATASOURCE_VAR_LOKI}}}'
prom_template = Template(
name=CONF_DATASOURCE_VAR_PROM,
type='datasource',
label='Prometheus',
query='prometheus',
hide=HIDE_VARIABLE,
)
loki_template = Template(
name=CONF_DATASOURCE_VAR_LOKI,
type='datasource',
label='Loki',
query='loki',
hide=HIDE_VARIABLE,
)
@define
class MyDashboard(Dashboard):
"""Wrapper class for Dashboard with some default values"""
timezone: str = 'browser'
sharedCrosshair: bool = True
@define
class MyTimeSeries(TimeSeries):
"""Wrapper class for TimeSeries with some default values and custom fields"""
fillOpacity: int = 10
lineWidth: int = 1
showPoints: str = 'never'
tooltipMode: str = 'multi'
maxDataPoints: int = None
# new fields
axisCenteredZero: bool = False
def to_json_data(self):
data = super().to_json_data()
data['fieldConfig']['defaults']['custom']['axisCenteredZero'] = self.axisCenteredZero
return data
@define
class PromTarget(Target):
"""Wrapper class for Target with default prometheus datasource"""
datasource: str = prom_datasource
@define
class LokiTarget(object):
"""Custom class for Loki Target, because normal Target gave errors in grafana"""
expr: str
legendFormat: str
datasource: str = loki_datasource
refId: str = None
queryType: str = 'range'
def to_json_data(self):
return {
'datasource': self.datasource,
'expr': self.expr,
'legendFormat': self.legendFormat,
'refId': self.refId,
'queryType': self.queryType,
}
def filter_none(l: list):
return [i for i in l if i is not None]

View File

@@ -0,0 +1,101 @@
from grafanalib.core import GridPos, Templating, Template, Logs
from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC
from common import LokiTarget, prom_template, loki_template, MyTimeSeries, MyDashboard, CONF_SUPPORT_LOKI, filter_none, \
prom_datasource, PromTarget
dashboard = MyDashboard(
title='Containers',
uid='containers',
description='Data for compose projects from default Prometheus datasource collected by Cadvisor',
tags=[
'linux',
'docker',
],
templating=Templating(list=filter_none([
prom_template,
loki_template if CONF_SUPPORT_LOKI else None,
Template(
name='compose_project',
label='Compose Project',
dataSource=prom_datasource,
query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)',
includeAll=True,
multi=True,
),
Template(
name='container_name',
label='Container',
dataSource=prom_datasource,
query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)',
includeAll=True,
multi=True,
),
Template(
name='logs_query',
label='Log Search',
query='',
type='textbox',
),
])),
panels=filter_none([
MyTimeSeries(
title='Container Memory Usage',
unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=0),
tooltipSort='desc',
stacking={'mode': 'normal'},
targets=[
PromTarget(
expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})',
legendFormat='{{ name }}',
),
],
),
MyTimeSeries(
title='Container CPU Usage',
unit=SECONDS,
gridPos=GridPos(h=8, w=12, x=12, y=0),
tooltipSort='desc',
stacking={'mode': 'normal'},
targets=[
PromTarget(
expr='max by (name) (irate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat='{{ name }}',
),
],
),
MyTimeSeries(
title='Container Network Traffic',
unit=BYTES_SEC_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=8),
tooltipSort='desc',
axisCenteredZero=True,
targets=[
PromTarget(
expr='max by (name) (irate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="rx {{ name }}",
),
PromTarget(
expr='-max by (name) (irate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="tx {{ name }}",
),
],
),
Logs(
title='',
gridPos=GridPos(h=8, w=12, x=12, y=8),
showLabels=True,
showCommonLabels=True,
wrapLogMessages=True,
prettifyLogMessage=True,
dedupStrategy='numbers',
targets=[
LokiTarget(
expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
legendFormat='{{ container_name }}',
),
],
) if CONF_SUPPORT_LOKI else None,
]),
).auto_panel_ids()

View File

@@ -0,0 +1,159 @@
from grafanalib.core import Templating, Template, GridPos
from grafanalib.formatunits import BYTES_IEC, BITS_SEC, PERCENT_UNIT
from common import prom_template, MyTimeSeries, MyDashboard, CONF_SUPPORT_ZFS, PromTarget, prom_datasource
dashboard = MyDashboard(
title='Node Exporter',
uid='node',
description='Node Exporter (not quite full)',
tags=[
'linux',
],
templating=Templating(list=[
# Datasource
prom_template,
# Job
Template(
name='job',
label='Job',
dataSource=prom_datasource,
query='label_values(node_uname_info, job)',
),
# Instance
Template(
name='instance',
label='Instance',
dataSource=prom_datasource,
query='label_values(node_uname_info{job="$job"}, instance)',
),
]),
panels=[
# CPU Basic
MyTimeSeries(
title='CPU Basic',
description='Basic CPU usage info',
unit=PERCENT_UNIT,
gridPos=GridPos(h=8, w=12, x=0, y=0),
stacking={'mode': 'percent'},
targets=[
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="system"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy System',
),
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="user"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy User',
),
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="iowait"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Iowait',
),
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode=~".*irq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy IRQs',
),
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode!="idle",mode!="user",mode!="system",mode!="iowait",mode!="irq",mode!="softirq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Other',
),
PromTarget(
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="idle"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Idle',
),
],
),
# Memory Basic
MyTimeSeries(
title='Memory Basic',
description='Basic memory usage',
unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=12, y=0),
stacking={'mode': 'normal'},
valueMin=0,
targets=[
PromTarget(
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"}',
format='time_series',
legendFormat='RAM Total',
),
PromTarget(
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"})',
format='time_series',
legendFormat='RAM Used',
hide=CONF_SUPPORT_ZFS,
),
PromTarget(
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}) - node_zfs_arc_size{instance="$instance",job="$job"}',
format='time_series',
legendFormat='RAM Used',
hide=not CONF_SUPPORT_ZFS,
),
PromTarget(
expr='node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Cache + Buffer',
),
PromTarget(
expr='node_zfs_arc_size{instance="$instance",job="$job"}',
legendFormat='ZFS Arc',
hide=not CONF_SUPPORT_ZFS,
),
PromTarget(
expr='node_memory_MemFree_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Free',
),
PromTarget(
expr='(node_memory_SwapTotal_bytes{instance="$instance",job="$job"} - node_memory_SwapFree_bytes{instance="$instance",job="$job"})',
legendFormat='SWAP Used',
),
],
overrides=[
# Prevent total memory from being stacked
{
'matcher': {
'id': 'byName',
'options': 'RAM Total'
},
'properties': [
{
'id': 'custom.stacking',
'value': {'mode': 'none'}
}
]
},
],
),
# Network Traffic Basic
MyTimeSeries(
title='Network Traffic Basic',
description='Basic network usage info per interface',
unit=BITS_SEC,
gridPos=GridPos(h=8, w=12, x=0, y=8),
tooltipSort='desc',
axisCenteredZero=True,
targets=[
PromTarget(
expr='irate(node_network_receive_bytes_total{instance="$instance",job="$job"}[$__rate_interval]) * 8',
legendFormat='rx {{ device }}',
),
PromTarget(
expr='-irate(node_network_transmit_bytes_total{instance="$instance",job="$job"}[$__rate_interval]) * 8',
legendFormat='tx {{ device }}',
),
],
),
# Disk Space Basic
MyTimeSeries(
title='Disk Space Used Basic',
description='Disk space used of all filesystems mounted',
unit=PERCENT_UNIT,
gridPos=GridPos(h=8, w=12, x=12, y=8),
targets=[
PromTarget(
expr='1 - (node_filesystem_avail_bytes{instance="$instance",job="$job",device!~"rootfs"} / node_filesystem_size_bytes{instance="$instance",job="$job",device!~"rootfs"})',
legendFormat='{{ mountpoint }}',
),
],
),
],
).auto_panel_ids()

View File

@@ -27,20 +27,3 @@ datasources:
secureJsonData:
token: {{ influxdb_admin_token }}
editable: false
- name: Jaeger
type: jaeger
access: proxy
uid: jaeger
url: http://jaeger:16686
editable: false
jsonData:
tracesToLogsV2:
datasourceUid: loki
spanStartTimeShift: 1h
spanEndTimeShift: -1h
tags: []
filterByTraceID: false
filterBySpanID: false
customQuery: true
query: '{container_name=~".*$${__span.tags["traefik.service.name"]}.*"}'

View File

@@ -31,4 +31,4 @@ name_attribute_path = name
# Optionally map user groups to Grafana roles
allow_assign_grafana_admin = true
role_attribute_path = contains(groups[*], 'Grafana Admins') && 'GrafanaAdmin' || 'Viewer'
role_attribute_path = contains(groups[*], 'admins') && 'GrafanaAdmin' || 'Viewer'

View File

@@ -17,14 +17,14 @@ common:
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
- from: 2024-10-18
index:
prefix: index_
period: 24h
prefix: index_
object_store: filesystem
schema: v13
store: tsdb
# TODO: Figure this out
ruler:
alertmanager_url: http://localhost:9093
# ruler:
# alertmanager_url: http://localhost:9093

View File

@@ -1,18 +1,11 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
traefik:
internal: true
enable_ipv6: true
ipam:
config:
# TODO: Consider removing traefik network, it shouldn't be needed with host networking
- subnet: {{ traefik_subnet }}/24
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, 255) }}
{{ helpers.default_network(254) | indent(2) }}
services:
traefik:
image: traefik:v2.10
image: traefik:v3.2
container_name: traefik
restart: unless-stopped
env_file:
@@ -23,14 +16,10 @@ services:
- ./rules:/rules:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- {{ base_volume_path }}/traefik/rules:/rules/extra:ro
- {{ base_volume_path }}/traefik/logs:/logs
- {{ base_volume_path }}/traefik/acme:/acme
# This is mostly just so that the traefik network gets created
whoami:
image: containous/whoami
container_name: whoami
labels:
- {{ helpers.traefik_labels('whoami', port=80) | indent(6) }}
networks:
- traefik
- {{ helpers.traefik_labels('whoami', port='80') | indent(6) }}

View File

@@ -2,14 +2,8 @@ api:
insecure: true
log:
filePath: /logs/traefik.log
level: INFO
accessLog:
filePath: /logs/access.log
bufferingSize: 100
experimental:
http3: true
entryPoints:
web:
@@ -25,10 +19,6 @@ metrics:
prometheus:
entryPoint: metrics
tracing:
jaeger:
samplingServerURL: http://localhost:5778/sampling
certificatesResolvers:
letsencrypt:
acme:
@@ -46,7 +36,6 @@ certificatesResolvers:
providers:
docker:
exposedByDefault: false
network: traefik_traefik
file:
directory: /rules
watch: true

View File

@@ -0,0 +1,22 @@
- name: Get list of running Docker containers
docker_host_info:
containers: yes
register: docker_container_list
- name: Stop all running Docker containers
docker_container:
name: "{{ item }}"
state: stopped
loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}"
async: 300
poll: 0
- name: Prune all Docker containers and networks
docker_prune:
containers: yes
networks: yes
- name: Clean alpina directory
file:
path: "{{ alpina_svc_path }}"
state: absent

View File

@@ -64,6 +64,14 @@
state: enabled
immediate: yes
- name: Allow 2222 tcp for pgrok ssh tunnel
become: yes
firewalld:
port: 2222/tcp
permanent: yes
state: enabled
immediate: yes
- name: Reboot if needed
become: yes
ansible.builtin.reboot:

View File

@@ -1,12 +1,5 @@
- name: Get IPv6 subnet for Docker
set_fact:
docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
- debug:
- name: IPv6 subnet for Docker
debug:
var: docker_ipv6_subnet
- name: Configure Docker daemon
@@ -35,33 +28,6 @@
state: disabled
register: docker0_firewalld
- name: Get list of running Docker containers
docker_host_info:
containers: yes
register: docker_container_list
when: clean_desired is true
- name: Stop all running Docker containers
docker_container:
name: "{{ item }}"
state: stopped
loop: "{{ docker_container_list.containers | map(attribute='Id') | list }}"
async: 300
poll: 0
when: clean_desired is true and docker_container_list.containers | length > 0
- name: Prune all Docker containers and networks
docker_prune:
containers: yes
networks: yes
when: clean_desired is true
- name: Clean alpina directory
file:
path: "{{ my_svc_path }}"
state: absent
when: clean_desired is true
- name: Restart Docker daemon
become: yes
service:

View File

@@ -1,14 +1,14 @@
- hosts: docker_hosts
- hosts: alpina
roles:
- docker_host
- alpina
post_tasks:
- name: Docker prune objects
docker_prune:
containers: yes
images: yes
containers: true
# Keep images for building grafana
images: true
images_filters:
dangling: false
until: "720h"
networks: true
volumes: true
builder_cache: true
builder_cache: false

View File

@@ -1,12 +1,4 @@
- hosts: all
- hosts: alpina
roles:
- common
pre_tasks:
- name: Set fact for clean desired of docker objects and compose files
set_fact:
# clean_desired_arg is an extra variable passed to the playbook
clean_desired: "{{ clean_desired_arg | bool }}"
- name: Install services
import_playbook: services.yml
- docker_host