Compare commits

...

32 Commits

Author SHA1 Message Date
3b08d1a615
monitoring: revert loki version to 3.5 2025-06-08 14:55:25 -07:00
825c2b78a5
monitoring: downgrade loki because of issues in 3.5 2025-05-14 01:55:45 -07:00
renovate[bot]
1c5cd1afcc
chore(deps): update traefik docker tag to v3.4 2025-05-05 19:13:00 +00:00
68a6635c5e
apps: vpgen: add google oauth provider config 2025-05-02 17:05:43 -07:00
renovate[bot]
23b5cd5bc1 fix(deps): update dependency ansible to v11.5.0 2025-05-02 17:05:17 -07:00
a9fdce52dc renovate: add compose.yml.j2 file support to config 2025-05-01 19:13:24 -07:00
renovate[bot]
09961d2bdb Add renovate.json 2025-05-01 19:13:24 -07:00
a551f86e37
updates: woodpecker 2025-04-21 23:59:58 -07:00
e2c9e783e6
update inventory hosts 2025-03-25 21:35:46 -07:00
cafdc07631
traefik: add cloudflare ips as trusted for forwarded headers 2025-03-25 20:47:04 -07:00
963ba3d785
apps: add syncthing 2025-02-25 23:00:11 -08:00
88133daf7e
updates: poetry, traefik, gitea, nextcloud 2025-02-25 18:24:18 -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
63 changed files with 1810 additions and 739 deletions

2
.idea/alpina.iml generated
View File

@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
</content> </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" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PyDocumentationSettings"> <component name="PyDocumentationSettings">

31
.idea/jsonSchemas.xml generated
View File

@ -31,7 +31,7 @@
<list> <list>
<Item> <Item>
<option name="directory" value="true" /> <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" /> <option name="mappingKind" value="Directory" />
</Item> </Item>
</list> </list>
@ -39,6 +39,22 @@
</SchemaInfo> </SchemaInfo>
</value> </value>
</entry> </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"> <entry key="Traefik v2">
<value> <value>
<SchemaInfo> <SchemaInfo>
@ -90,6 +106,16 @@
<option name="applicationDefined" value="true" /> <option name="applicationDefined" value="true" />
<option name="patterns"> <option name="patterns">
<list> <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> <Item>
<option name="pattern" value="true" /> <option name="pattern" value="true" />
<option name="path" value="*/docker-compose.yml" /> <option name="path" value="*/docker-compose.yml" />
@ -116,6 +142,9 @@
<Item> <Item>
<option name="path" value="roles/alpina/collections/services/monitoring/templates/prometheus_config/prometheus.yml.j2" /> <option name="path" value="roles/alpina/collections/services/monitoring/templates/prometheus_config/prometheus.yml.j2" />
</Item> </Item>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/prometheus.yml.j2" />
</Item>
</list> </list>
</option> </option>
</SchemaInfo> </SchemaInfo>

2
.idea/misc.xml generated
View File

@ -3,5 +3,5 @@
<component name="Black"> <component name="Black">
<option name="sdkName" value="Poetry (alpina) (2)" /> <option name="sdkName" value="Poetry (alpina) (2)" />
</component> </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> </project>

View File

@ -1,19 +1,23 @@
.POSIX: .POSIX:
.PHONY: * .PHONY: *
.EXPORT_ALL_VARIABLES: .EXPORT_ALL_VARIABLES:
MAKEFLAGS += -r # no use of built-in rules
env ?= staging env ?= staging
vault_id ?= alpina@contrib/rbw-client.sh 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: setup:
poetry install --quiet poetry install --quiet
site: setup 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 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

@ -8,6 +8,22 @@ running on top of TrueNAS SCALE, separating all the docker stuff from the applia
# Notes # 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 ## IPv6
The current configuration is designed to work with IPv6. The current configuration is designed to work with IPv6.
However, because of how (not properly) I'm doing the subnetting However, because of how (not properly) I'm doing the subnetting

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) }} - subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, subnet_index) }}
{% endmacro %} {% 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.enable=true
- traefik.http.routers.{{ host }}.rule=Host(`{{ host }}.{{ domain }}`) - traefik.http.routers.r-{{ name }}.rule={{ host_rule(host, path_prefix, wildcard) }}
- traefik.http.routers.{{ host }}.entrypoints=web - traefik.http.routers.r-{{ name }}.entrypoints=websecure
- traefik.http.routers.{{ host }}-tls.rule=Host(`{{ host }}.{{ domain }}`) - traefik.http.routers.r-{{ name }}.tls=true
- traefik.http.routers.{{ host }}-tls.entrypoints=websecure - traefik.http.routers.r-{{ name }}.tls.certresolver=letsencrypt
- traefik.http.routers.{{ host }}-tls.tls=true - traefik.http.routers.r-{{ name }}.tls.domains.0.main={{ tls_base }}
- traefik.http.routers.{{ host }}-tls.tls.certresolver=letsencrypt - traefik.http.routers.r-{{ name }}.tls.domains.0.sans=*.{{ tls_base }}
- 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 %}
{% if port -%} {% 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 %} {% endif %}
{% if auth -%} {% if auth -%}
- traefik.http.routers.{{ host }}-tls.middlewares=authentik@docker - traefik.http.routers.r-{{ name }}.middlewares=authentik@docker
{% endif %} {% endif %}
{% endmacro %} {% 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

@ -5,22 +5,31 @@ alpina_svc_path: ~/alpina
base_volume_path: /mnt/dock base_volume_path: /mnt/dock
media_volume_path: /mnt/media media_volume_path: /mnt/media
traefik_subnet: 172.16.122.0 docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
# Authentik # Authentik
authentik_db_password: "{{ vault_authentik_db_password }}" authentik_db_password: "{{ vault_authentik_db_password }}"
authentik_secret_key: "{{ vault_authentik_secret_key }}" authentik_secret_key: "{{ vault_authentik_secret_key }}"
authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}" authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}"
auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}" 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 }}" 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
minio_password: "{{ vault_minio_password }}" minio_password: "{{ vault_minio_password }}"
# Monitoring # Monitoring
## auth_grafana_client_secret:
influxdb_admin_password: "{{ vault_influxdb_admin_password }}" influxdb_admin_password: "{{ vault_influxdb_admin_password }}"
influxdb_admin_token: "{{ vault_influxdb_admin_token }}" influxdb_admin_token: "{{ vault_influxdb_admin_token }}"
@ -46,3 +55,23 @@ jwt_secret: "{{ vault_jwt_secret }}"
nextcloud_db_password: "{{ vault_nextcloud_db_password }}" nextcloud_db_password: "{{ vault_nextcloud_db_password }}"
redis_password: "{{ vault_redis_password }}" redis_password: "{{ vault_redis_password }}"
nextcloud_sendgrid_api_key: "{{ vault_nextcloud_sendgrid_api_key }}" nextcloud_sendgrid_api_key: "{{ vault_nextcloud_sendgrid_api_key }}"
# VPGen
vpgen_auth_invite_token: "{{ vault_vpgen_auth_invite_token }}"
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 }}"

View File

@ -1,88 +1,158 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
36636236366435333738633465323539336231393239656538643863643233346563333836623335 39313964356339363432393662666162343133633033316465636433323339323931303866646635
3136393936656261396434316232356338313838373666660a653464613833306133343232623864 3630663865626431396563346365363636383637626263620a633332623365643765386566356336
61666561336462376664363463313533353238623031613664353063396236343663643936303730 65356439386565306461313863633835623031656136393039326366623137333536363836316563
6235646336306636360a653238633038306532613436633132363231613862383636313838623461 3062356431346539330a366534646239353934363137373662343862393365373835653530336166
32633366326136346435613232396632396365656138643361643139353430663637353565383664 34613763626630316431326133366461363030663137366536393764356437323235343438326237
36623961663030653639316131376535363138343965636437653139646233613765323439393030 36656234653363623836303863346233616661623135383130663930333365373733663134323234
31666137346339663162393836636638636431326232323461353661613062623032306130393965 39666233643733653336386234613563656134396638373561323432313631633166386266323865
38313931313935666633343835303232333961633232623538383138366262663335323764323939 66313630333332316662643434646465343861643461373631396538663763633263323738616330
32373333663834626633363265373632356439633862316562323565646530383534653338353165 37316561663231366336383539306130396631643839383563643363623362376266356565363434
38396434353332623164346137383238343536303130616666643065306431656137303263323135 31306634356162383839613464386664633237343461646132366439613563623732346362363534
34316662353031653932396239623733313037383935383762623136346636323434363231623161 39636635396133336330373938366236646237393866316136663537363138636239636638386363
30393864353466643637316566663366363231373335663331323932663837626239663633663965 37623131636133343062306139666666393566333665356566313530383033636534383132373765
66333531323861663130353531323339386566303630366236636135393439356634393732623033 31303362303237623337323632373161306138353666633462386165633935626536396135363330
31336231363935633436363962316666666336303338313636386163313666636336343464336133 62633233316664656166306438653039306564633336616661306366306634333734353866313765
33313730303961663632323435323963663530623265663664343735643061323332343265343431 30386236643033303537336562643431306232656162663066643238353662303533616130303335
61363039333730623562363233373537633138663239313132336666313237373137353663326538 61643436333063313164353366346564336366663431663636653334326262626635326264653938
32366130326635366433393434653735616132366264386461363063393265623765666461626366 37393136336336656538366533626566366365313837383236653762653464666336353862313434
38636239376534653230663932393930343162333262643130633835343363613061623932363761 64646431363462643839643937646537306433616565303466626530386366373934376665303638
64643164323335376565646137643763316562343565366462376162333633313737303465373362 63653164623231636539643332356162353134646130626365393166373932386530313030336136
63343734633536353661353165346632666230616138396461336332623365366432313734343837 30303138373432306665376432646664336461303564333535636463373232303661323336633536
30613736313961663334326335333834336634373338326631313739363765303036303132346166 63366363393161613832356362356437666365333062303635363961343739373739343364646331
37313030373264383564383936396339623061616134356663333733653838393537306336313135 63383131363430393331666331613965666239393865346234646632353962333531346239333333
32336261356437653863653839373130323035346538343938646265653239376236373932646433 39643832386363353461366332366138366134333638666664383434353262376263386531346262
35373932326535643763396563373138626239393661373231393066323335336264373835336635 36383365613764363135343765313863306135373062613362313761353165613166613966366363
38393732643630336364363834303534663334396363623261383339313939663461303236646237 37616163643230343062336462666233666438643332343963666161333631663532653733376239
36393330373534383836373065373239353836653137306338336638396662363434303839363466 37383335623337343761643936333264383766373137393964636138663362643064363666643130
37303332343464663733653632363239366337656364333532313237633935616637333361383763 39636639646264303333623036373439636566346437643539656531303534376139613832396638
62363063323362323565363837333264346161353032643039323839336666656333336433376231 37373736343538663062633132376164386635333038656338373037633033623238633035333130
36363335626137366135373230613436653232663138343862623562306331336330356630316166 65316330393261326139373331386239636230376237386664386134663131343836393464646362
30613264353165343634663461373630653632366333313837373237613339336638396338376465 39366434313034383561623664343530633165316438333830346330653730613264656661303061
64633638373263376330343561303664666139663237326637663964386133623164626339346635 34393863306465373639306531643534366464393365373264316136653334356530376366303330
66636365366562343636653362656133306164353761346661343430356633613063656466316262 31383137306439616362313861396633333430626463326531336533323038333336313337396338
31633932313532663930303837353863333664393563646566396164666236633832633235653362 64636161333839366536643662653563613138633331316166333766666537386666616161313531
63663931353436623034653733313766393465363466363831643130643939356335643166356436 62363666646635656233363962346333393861303165643130333435613436366131393463663162
38386530333264313263636438376134666235646636316233653330613735323234313036356639 34623536316363643539663261373830316638383439326431373866646436616635303466343830
61316164376434616239646235326661323363333835393430646462323234356138653163616530 33303362356166333338333265633366353538353135353933383939343562633433333337363564
65623233636435396462343437626130353735643530376538633762346332653162353563386366 37366536343066326338313262313830623263356464323565373362356631303538646366373635
32656633633935626238323431643631633434633032303435383037353834653964326336616530 31343861626636313530343964656133333031326634333434643037393436313833306133396563
30363765663133313239373664383830393238303439653531316664636532363135636563356666 61333636646437623963666265666565623965386364376430666662336365363762316639343939
34376636373033353665373261363536393562653638306661663832326139383565613862333831 66303164303161396463363265393966306636616231633838366437626162323465356430643333
38616238616332326532656430393331383161376237393365666639363732363164306332343336 66663633353462646334663034373465343432626638383237383330313932663930663962656665
37366638326464373261386431623731306663616262633837313965633530616265326536323136 62363133306632613062393830316135333965623963643337336638366236343533323832633564
62366365666461383535663637633332626464643062653139623333663038316536353930653266 66643331623263393966343930613430646438386563646235363837376230373365346462633937
37343830613062346533613762663738343138383537396435643765323237623130363564396462 37333431346363303630313265626533373662613332383236313736663534306132653635333464
61663063643135303539313062396338353061346336303938626361343238366366393533363638 30643761613762353536613531326334336138323934393832393765613533666432616631396337
31313437623631626437393761366537636664393863306164373431653133316639623630353336 36373261313236666365656563316330313061336664646230393931616264643864623263333132
65313037636533393362363266366231393334613264343331623531393666336336626265366163 33336263663164343962383366333264633735383731613939383333343265366166346534326538
34663161396633666162326564313735373137303337386538633866653331646635633532336465 31636136643466623037333334396162333435303062313861626435623134386432333065383865
34386166373436386566656135313438363733353139663630613430363332656239356139393532 62343435396233376366656365303966633533633232303763616234396365306338326562363234
35626337666639376664346631323938316538333066353363646562323266353165366632656137 65313437396534346661643365363533363133663133613733316331663364326131613464653133
66366162376165626564363230353062666364646363366637666433636333316536623435623836 63386535366138636436616666613664663632376430623063343030393631386233346133373466
62346566363362363939353038396566653238666138666531396338323262323965383031336362 39386436313566636662306438373932386232353865363736383962353864373132363564393133
34613332363334653531383231363539343133333531666564386133346562323338366139663438 38343439313766323035363238336335333063323730396161303634313738663931316262613164
31613466366438643566333632326239653662636464373337326537313234393038306132343730 61623939666263323563313131383064386632663132336234373132316430306431636535393663
36633136366162643966396362643165313336383862653435343630646431306366656636353230 66653835396431626633616236666365333264306662333865663739623430656563393133393938
64326633346561613662383863356531306563623439363566643733336535303335303164633535 37633665633961326162666232386338316432633139386233393834376533326333343435643562
36356463616162313039386434323637383937613133623131373033373462363365643730666166 32353664383436633832356662326265613636636534346432356534303061633337313139323138
65383166346638313533326366346433656461346439343838306564393336383536633732343965 66303064366636316537333735336232303964333139626161373138373765303464633835623333
39306231386130303433616361366363366163646534316138623362393063663438313165643762 66623862343636343134363266666164666432393835316165333465363736643735643134636364
39393332653564333762663762366633386135353865366338396138666265653662373535666366 65383037646633613564363436663235616530643631356462383337396437653437613933653739
35613937613366323064316561643435353830316239396464393737613835373964626437316464 64396434343839393638363866386234393132396262363637643466333439656464326364393231
39643664656565633966393832643033323130636562383233323636363361353430353062323439 39333635643165666331636230333931663561663532326338366136343832613862616466623132
39396464633336623963633963326461316562333162333766613064336462613235336531623437 37653139343235656335336566356631663938646631626562363130393031346133326562656366
30383063653666633839646533386239366637346230363033306161386537303039376465303535 38623633346632393263663536623131316662646130633533333431666162353834363537633631
34643162323065326264343662303138313063303834353832393663616239383739313133393532 36643439313734396365633533303930626431376132656439393838306662363934663764373939
62393766343037666564326132386139346661383564366366646530346434373366326531356138 65623136363239636161343162363265313036346332333864366363663933356264663935653762
31323531653338653130303733363764636430336563336439666132626434363463306631363334 61306135366562613162616538303334626433633731613530613837323433306235393338613532
39623332376334383338633132653262653735346563626365613336623435396539383630366332 35626366613535326363643864663863303734373435636664653931613462336332353334323365
31316638393562376131363166633163333332633332393062393962613132366538653865663264 37616539343335386636306138656233396238636137636130663035336365653230666436663030
38313237393436353333323431336361653938343034346164353335366535396265633961333138 63653136636162386630656538636338646531336335363737333062383138646538356137353837
65386137356161643732636531613166633464326163303336303439383435376331373935333563 61306235303564653065653034633762653466376530653338383362613766313563636232613934
64633961623761393131333234656530653737346563643963643833383262383434653266343362 63373466613136663035646134623335383037653231333035323036653264636161623766643332
35623832643032346133346363646136646438663761363330666231316434306232623339656535 35323530386333333563373565356130393836343137656361316437343235343235623539333963
34393337666237656262313439386336336466373466663663616139353463316265396135626366 36396565336233373433643466643330623434363261643933666332386536323332643466363135
62313562306334343831616364633933343463386233323637313832316635346235623830333461 64353464386365313862323032363932656662376464323830326432313737336166373764303034
33663530343966383739643261653736363865323438363430653661653964643339633833386438 66343664613839323731643463323239303138303234316564626438663031613763393532376531
36333331366334366461346636636462343335313234663864613864366134356161396662383632 30333037386138306466313332346139363238323736656463633038323261363862666433663865
36663538373761353937313666363262626435623537646665646364353934373638366261333234 34333464363637313362303863356236376531643161646632303265646337616532323039373562
36353439303663656531666637376364313838386130343966316138356338643135316139363630 31316262643764353937336433343630396534653831376231626338643033353939363562636535
30386635376565363931333331336431303562346431323534643238333337386264616161356163 62326634396538393564353531343461353137613932386531353362313262653363623633373131
35663766306635626235373663643064393233346364666663393236353561653362373361666164 33353861373136663162383439616131303639313931616633333538363436353934636530303461
65653566666234626464356338613834323332383939643935323337376162316163333034643062 30346237373331356335656632633632353735386433313934323031646339386631373838366331
63646237646234636561313038383636373936656164333735323461626233633337623764383830 35303736373432343361643439316333386233633634393464343164633161643436306637336234
66383161346336633962643032376662656566396666343662656337306333313836613335643961 62373136303263323133303839333438633038356161653839333139383633366333616363303766
64323961663032373239636430306430383639306333363938303837386139643230353061623937 34313236306462366261336331306634373538316435623963313335383130653732323032663234
36373733636337616264313432643230303935626666633533666135666538626266626266643864 65626131353839373137346166633164303462336234666230383664383139323036393732373531
376430653461346366626432636336653437 32653034326134626133313363613432663366373739653332376364636139666261353536303437
33626332376361653930356261316162623134303135346235616165323632353538653661393261
37373561616237353133646466313262633632383533656632633431643131333366306662653361
39653066326564383461623035636136613035613962623131633734663262313532653366306530
38366132323030346262366262363231303737646131633931363162383461333262316564383861
32313537323637363163646335333566333463366265323438386230333765396334646436623234
62653233306433643261373262376535616365363065346431333331653164306463643033333930
34383533336536613233663630656561653034333134326563613538613134633038356265343839
36303266303363666335323831613430373536346336333934643338373064646365386365316633
37303565653565653334643463323137366137346538613632343131383235326339333235373562
36326230333734373365376239306664616433373664343462383961366636383263333764646362
32383463343130313931656436613235336561383165613737643835396264616262356431333564
36313965323164393633653330366666393337363831653763343938653464383235623236343332
30653034386136643961323034346262613566373534333464653235636164393931393131316662
65656462623431613239336431313239343762643731663438323333613661343462633038333264
31303435313431373461623564396336386131383565376162386439383562653036373262643662
37326634646233326461633236336364356133383135326638623063313332616539353538663432
31396135396430646635323335323666646265646339333838326261393963383331356334303630
63313465356233363636336136356336366333636261613663663433343535323563663062626361
35323161376466383966343963306237396362323736666331633235383832376364343037656433
33326638396232396666393939303735636337313730363137663839393662613333393061386536
35353132366432623336333331386234326139653435376261366631356538303562383034623338
66353834633161313462663531623762356561393535656535613663393137663436313466633364
33313533343633376638333339653834313231393131363866333961393639393665373638353930
39653831613563313537333137323633613536363536613335363836336339613135346330626335
63323038626462656435343431326663643332363962393863393461336334616637316462363538
33333762393164396435646266376534363861633430643265646662626630643035396466363537
63386233663130373335376334353630386662306563323736623265333230623136356664666639
32316139386165623264616466353765613239313635653635343439666337656335393334323939
66393331653266316330633535636534663436316235373231626664393565303161643730323537
36373063326339326339653232323331663532653337343638653236306263313264323734303465
33363239653634623630393961346139343230363135393830336139386130356239346430306238
61616433343566393962656532333833363036373235386530303237653537363139373962386364
32336231613362353131623263313539623330663632646135313038346161346135353233303965
39356331626465613036376266376264396563373239333834336337383332646536346636623666
31386536343964643433616638386161383935386165363230643131336439623835326136646161
39343035383039396235653364396638656334396231323263636534633932386161616233343063
61373462366235383564313762366334313137363636333732313663356233653133323537663331
64636336663862303335316432393663653436313834323231663730623562373333346634303138
31353662333139626133623564333863363565616466353266343737616163386432636631613136
34313530383934336138336535373562636366653663383238376136376561306532383933336236
62613361613539663030323832666430356138376236383335393538306131333061313339323163
32313131383134663838393462343963623962613638656462356664303132386233363063316266
35656635333861366435396638653934663935306230373962346633613431353461373933316435
35373134643562616662656130396266613365326565666536653732333635346338643435376264
65323237386565363431653930373137633330363764663063393335633638653036623732316464
66373863303364333534316464636130633665383439626531383466313330393233663933666438
36333535636562396361643564343534626436373961636261666135386635316331326164316565
34386565636538633361613235303862303231343664363465373363306461356333363764356163
65396533626238356331346434383435343135326135366235393862663861636361363032613266
34633631653261653230396338363762376563613138303533653530636666313864303334626261
34346436316564663632303634343837303065306530306662343062633738653635653164656465
36393239373763666131343739303132616366353365636338333263326539343862623462653639
64616430663033663162306335303230643131633763633635306464346431393237666536343130
35366231386237666331383132373835616365316665353235623735363530626266366437326537
32326230306562343830666135326464383834623461643465336131356332376235623735633232
62663535303661376465303533306530636366356632626137353135336264356266366335396539
31616661363065366136323061303764366332326362653036353562336561336166316664346661
63303835626463303731376337366265653931343238316631333032656535376439313335326265
62383761623437323862643035333832653065396439303738343336653961623563383964326338
38613464653530373938333737316133353064356362323933383765363566343638303233616233
63333039363063616464616465313166626262363030326565346461313034633432643232356336
65306534366234333562333764653539333935613166313065646430343834653833386434613436
62613033313632623236663731343533643864373139613739336135353833386438353461626336
64336334646139633633656266633034373461656539633238383531356537396439363233633466
64663639383166303261303864383137623236643934356665623537363839396565633863376639
64376131356637333562663731393437653236393366303830323239643736386464326539636234
61353939356465656465666263336232373733326331623831376539336438373265666135306134
64303736346431633332633635633839663235373864323664343830393336376336633235373164
64326335326664376530313838386266613632633764373430643663306434303263613234616438
6230

View File

@ -1 +0,0 @@
domain: cazzzer.com

View File

@ -1,6 +1,8 @@
# Environment specific variables (prod) # Environment specific variables (prod)
--- ---
domain: cazzzer.com
docker_ipv6_index: 255 docker_ipv6_index: 255
# Arrstack VPN # Arrstack VPN
@ -9,6 +11,16 @@ wg_psk: "{{ vault_wg_psk }}"
wg_addresses: "{{ vault_wg_addresses }}" wg_addresses: "{{ vault_wg_addresses }}"
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}" fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik GitHub OAuth # Authentik External OAuth
github_consumer_key: 32d5cae58d744c56fcc9 github_consumer_key: 32d5cae58d744c56fcc9
github_consumer_secret: "{{ vault_github_consumer_secret }}" 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

@ -1,21 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
61656162363565633436373135333536623561663136303736393865623830633539376362363363 36313835643238353932323631323439626432316436346533376365633332313963666433313333
3938333137343336626634346262363964316563643261310a366538363037343965363766646535 6134633133636133623130376237373462383164396338380a316463396139653161366536636336
61636239326464373039333462653562373933396665393039633266326234663335363337666439 64346664356538366538363239306631326464633635316161663963326635656430326637333963
6137323332303533640a383062383135633762323561313666636566306531306636633466316536 6462633236353132300a323062353639646238663737353461633733636530613036316364353864
66623731626266333731303336323733343336626366343833633365616330343565363035323039 34326534376639643734303137613866393464306334336566653134333765356361386436323939
35313961383131616133386663376331336639633137383137346164353632653939363266613562 35393535303635376162386266396431313739663961643061623037343463303637623130623131
36316631366661353632386230306532633862393963663465383862653964646462666334396666 31653761616639613964386432643561376637316435333064343837636463303033333432636234
66626636353539316266343937623662613336616331626439306538363764636366656635356639 39323735373161616133396566316266383165343033666530376333626264643531613334363634
30663535393366383261333832356237373230663037373638303161303534636230616464636265 35393766623361346461333764666139366632306362613362376133363239656562346263643066
37623938303638646233346338616239393838396433313063343065386666323264646461373032 65616538366532346537383432663766366161633234373562623531356339666661346164306563
63376661646139316430303533643063336634333364643231336130613638626431623732646434 35343339386631383462656466303563376237386137346437323634626163353464356462346364
63643833353164313465633333646232653761356333323933396666323837656334343866363762 35373061636237383335396231326563366230663566333665326338303564326263316630666233
39646263653137356632323534356631366531636530613736343438393136363835373435636230 65303930663862313137333630353837363265333532303133306466643462626662613166326132
30313163386335353935663432323033326235653963653930396235373863373232666334326661 66346439333739653965346236313766346532356233333164633538326135643662623533646561
34336632666365666563326366376461386130343965363832343430396537323734363533353065 65626530386333303362343830653430653866336261623566616362313739303939656364656363
64313837623366356261383437306465633730353332636561333462356363326132313933653234 37336331353766633534653936626139303061623531323362346564363665663438646533646166
66363634333664333433613466396639306436353035346134373430663532373934343861323262 62376534653562373138656465666133353235313935626534383537643436376665613865303363
30666664336336393835346234316238613839326436363162626439376530306133343530303365 62326562396361306131616363363866316232623635353663323537366563333239383636643763
65393030633237333166336637363435646435323736353461333932366638333264333239373733 35623366663463303831323730363036306363643364303532326339353633393739306366396331
30623062643336643431 33313230656431623462376135623438633164323064653866646165643263383832353138633931
66306463346361646561376334613837383762366365666638643434383034376339643239646463
66343461363233626635323535336462666339323032616136396239396534346434623238396330
37653665643366323362313136386231396532323035363963623738346564356435303263303832
37346532366432363638363330316464366361313461626535616165333433343835393565633766
32663162386562373035333335303332323136613233613431386265626337653939326435396262
61303631633838613962346663326232636438393563396230306361333335383462653432383766
35376662353262303635316635363130383032366530396439613861653037383234363831333562
37343332646534353838626366623361636261393865363633303631613837323733626264643835
63376430613234386463336234623062656534643863656434386134616265333666613939393331
39333166393538306135313431303831623063363533326330633062653333313733653831383736
613864303461323739336563356161353234

View File

@ -1,2 +1,2 @@
[alpina] [alpina]
debbi.lab.home debbi.sys.cazzzer.com

View File

@ -1 +0,0 @@
domain: lab.cazzzer.com

View File

@ -1,6 +1,8 @@
# Environment specific variables (staging) # Environment specific variables (staging)
--- ---
domain: lab.cazzzer.com
docker_ipv6_index: 254 docker_ipv6_index: 254
# Arrstack VPN # Arrstack VPN
@ -9,6 +11,16 @@ wg_psk: "{{ vault_wg_psk }}"
wg_addresses: "{{ vault_wg_addresses }}" wg_addresses: "{{ vault_wg_addresses }}"
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}" fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik GitHub OAuth # Authentik External OAuth
github_consumer_key: dbacb8621c37320eb745 github_consumer_key: dbacb8621c37320eb745
github_consumer_secret: "{{ vault_github_consumer_secret }}" 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

@ -1,21 +1,32 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
63633535633462326534626562373461373363643166383961303861623531663263323534366537 36343339366166383430383235626463376339653331333635623936653135633633353064613634
3263633238646439306430356365623233313838326639350a386633363434623737313565316535 3263306161376232356634363532653266366665333364650a636365393465383165306563346132
33393734633937333637373432366132323366343836393538366339626235613937323066613666 37653564633630653635353464333939353266396562316663653933373065353536333130383065
3737393262646333390a623331333461373563313166323232343234616538623433376166313532 3864353332303164320a316439313164663736636465366539643131303663343861333164613561
32323834346336336164343938303062336438643566343866316164643535663039326331646465 37383965373964313535313335643164376164323263613539643933333035323837373662303030
36666162393365323633646635333666613030386265306238633434303234336439646663356363 66636465303566313334386435326433653032383962353739643861346161323738636366396239
63323638373035326465633934326363316364616539613462653232393465633233366666373664 39623336336234376339343562656362323932383265313161396435346530663330353266323433
66616361646564303530356331323864343966633736643434653237316236363063613634646438 66396538313365653963323164306464663565303364386466666636346533633661333634313236
35303238646632616465643264316164363139393834626362326538613033656464323435396638 33623936616239613264613730363039366561646535633239633564656166343162303633373366
31346631653764303332386331663361623766333332366537313634636333346538653537346631 37656163333838656533363735383332626632353237613666396633363531666366336630613064
62363438303036386530633236376633326162336434343861346261373835653735323161323965 66626561663766376531313666663963643766393965653564333062653139336230356330383464
62353965373164616537346134303232363033323134323130316439386339613966646330666533 38343562383430303132663964303736623238386562323033623861303432363363373934643332
65346239383230646565346133663530613462363532663562326136376233303638323332326630 63363239323664333131306237336134613137653136633932356238343733393632616464366134
35656432363563653663616236393932663637323139666664636237336136366438656666633865 33623038363032653134626337663863366663383433633134326239616136656139366535613565
66353162656364356638313236643131613830393838636264663833343461373963613431656364 61646330356330396236303566363834613236653733643162666536303435643133346633353632
32303331623033303433333631313038316336653638656638373031653234356164333363336532 62386135303262353332643135636164303963616234626132356161663463366434323864626261
37316334353463376562643138346633613633353536653939376564333166323931353634333736 33356536626263626261343937386666396561306334346435316262333431353234303836356563
63616133663266383339323562343265613461623865623263623139396163343065623264366230 31343566373935396633636133616265346235396333396664333534336162323039623937656336
32633362336335396562366563363830636133376238646433386236666461333731353337386333 36656133383966613333646336613039626563353862646238376461373264633233313836333062
61323931643766326338 30343134363862626630393035643762376435346532306462363437646238333463396230666465
64386365393063613139313164366562643066323461313364393265393638643137386561633530
65643861386531323836306339386462656530383533363831323461303131396666626464303136
64343865616235616366633136393662623862383961323338366435396334653538303830616166
39636164613466313033643639366635323666666235653633333436613133343962353664313838
64356466393239666131363964643461346633313030643061643938643232343334313731636463
37396637643232353539626239306463623237623534366666396164613135356136313534663231
36613662653237343061316463386231656136383636393034333666633063613731316162333464
64313866633062623530326233633166343434636639346565346337396461393637383333366435
62393030383963396638653230613431623837353461313630343333376131616239313164336234
62323739316536353835613032303438623230626563303934626466303934613566656232323663
643265386333313065333737613438316532

View File

@ -1,2 +1,2 @@
[alpina] [alpina]
etappi.lab.home etappi.sys.cazzzer.com

543
poetry.lock generated
View File

@ -1,28 +1,30 @@
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
[[package]] [[package]]
name = "ansible" name = "ansible"
version = "10.1.0" version = "11.5.0"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.11"
groups = ["main"]
files = [ files = [
{file = "ansible-10.1.0-py3-none-any.whl", hash = "sha256:05b761c4628a0fc216478a5e3c111613c61fd13280846fa84843a63c36c7b1b6"}, {file = "ansible-11.5.0-py3-none-any.whl", hash = "sha256:d20bc30f44a35678ca5f05868084f2f52a8bb6f024e85dc80639f6ac4364cc61"},
{file = "ansible-10.1.0.tar.gz", hash = "sha256:7d8c44557f570687306e19d0e3296ad230593cb12bda35dcfc9274a6063af22a"}, {file = "ansible-11.5.0.tar.gz", hash = "sha256:18a3fc73120a49ade9a9a67eb8f9d4f5009d2106c34ffeb9663ad928b76ed59b"},
] ]
[package.dependencies] [package.dependencies]
ansible-core = ">=2.17.1,<2.18.0" ansible-core = ">=2.18.5,<2.19.0"
[[package]] [[package]]
name = "ansible-core" name = "ansible-core"
version = "2.17.1" version = "2.18.5"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.10" python-versions = ">=3.11"
groups = ["main"]
files = [ files = [
{file = "ansible_core-2.17.1-py3-none-any.whl", hash = "sha256:aaaccf6a9fe05968821a02079c5ec4c33a7fe5f02d9f5d94f7c3a69f71eab675"}, {file = "ansible_core-2.18.5-py3-none-any.whl", hash = "sha256:4a1e75a24969d0a650d399bffbaf5a76d7c9b96a21a199a939fe836c3452718d"},
{file = "ansible_core-2.17.1.tar.gz", hash = "sha256:46449d71bbd17c3ce85fe379721d88d333fd23637b5c3798e83fae5fa38def00"}, {file = "ansible_core-2.18.5.tar.gz", hash = "sha256:319304d161770a8a891c07dec8a22c528548a948a7097eaf1a79939395105535"},
] ]
[package.dependencies] [package.dependencies]
@ -38,6 +40,7 @@ version = "2.1.0"
description = "R/W an ansible-vault yaml file" description = "R/W an ansible-vault yaml file"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["main"]
files = [ files = [
{file = "ansible-vault-2.1.0.tar.gz", hash = "sha256:5ce8fdb5470f1449b76bf07ae2abc56480dad48356ae405c85b686efb64dbd5e"}, {file = "ansible-vault-2.1.0.tar.gz", hash = "sha256:5ce8fdb5470f1449b76bf07ae2abc56480dad48356ae405c85b686efb64dbd5e"},
] ]
@ -47,68 +50,105 @@ ansible = "*"
setuptools = "*" setuptools = "*"
[package.extras] [package.extras]
dev = ["black", "flake8", "isort[pyproject]", "pytest"] dev = ["black ; python_version >= \"3.6\"", "flake8 ; python_version >= \"3.6\"", "isort[pyproject] ; python_version >= \"3.6\"", "pytest"]
release = ["twine"] release = ["twine"]
[[package]]
name = "attrs"
version = "25.1.0"
description = "Classes Without Boilerplate"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"},
{file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"},
]
[package.extras]
benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"]
tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""]
[[package]] [[package]]
name = "cffi" name = "cffi"
version = "1.16.0" version = "1.17.1"
description = "Foreign Function Interface for Python calling C code." description = "Foreign Function Interface for Python calling C code."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
markers = "platform_python_implementation != \"PyPy\""
files = [ files = [
{file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"},
{file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"},
{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.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"},
{file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"},
{file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"},
{file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"},
{file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"},
{file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"},
{file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"},
{file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"},
{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.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, {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.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"},
{file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"},
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"},
{file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"},
{file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"},
{file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"},
{file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"},
{file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"},
{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.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, {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.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"},
{file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"},
{file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"},
{file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"},
{file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"},
{file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"},
{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.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"},
{file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, {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.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"},
{file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"},
{file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"},
{file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"},
{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.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"},
{file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"},
{file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, {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.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"},
{file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"},
{file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"},
{file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, {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] [package.dependencies]
@ -116,67 +156,86 @@ pycparser = "*"
[[package]] [[package]]
name = "cryptography" name = "cryptography"
version = "42.0.8" version = "44.0.1"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false optional = false
python-versions = ">=3.7" python-versions = "!=3.9.0,!=3.9.1,>=3.7"
groups = ["main"]
files = [ files = [
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, {file = "cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009"},
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864"},
{file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, {file = "cryptography-44.0.1-cp37-abi3-win32.whl", hash = "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a"},
{file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, {file = "cryptography-44.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00"},
{file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, {file = "cryptography-44.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b"},
{file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7"},
{file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, {file = "cryptography-44.0.1-cp39-abi3-win32.whl", hash = "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, {file = "cryptography-44.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, {file = "cryptography-44.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, {file = "cryptography-44.0.1.tar.gz", hash = "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14"},
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
] ]
[package.dependencies] [package.dependencies]
cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""}
[package.extras] [package.extras]
docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""]
docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"]
nox = ["nox"] nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""]
pep8test = ["check-sdist", "click", "mypy", "ruff"] pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
sdist = ["build"] sdist = ["build (>=1.0.0)"]
ssh = ["bcrypt (>=3.1.5)"] 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.1)", "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"] test-randomorder = ["pytest-randomly"]
[[package]]
name = "grafanalib"
version = "0.7.1"
description = "Library for building Grafana dashboards"
optional = false
python-versions = "*"
groups = ["dev"]
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]] [[package]]
name = "jinja2" name = "jinja2"
version = "3.1.4" version = "3.1.5"
description = "A very fast and expressive template engine." description = "A very fast and expressive template engine."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["main"]
files = [ files = [
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"},
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"},
] ]
[package.dependencies] [package.dependencies]
@ -187,71 +246,73 @@ i18n = ["Babel (>=2.7)"]
[[package]] [[package]]
name = "markupsafe" name = "markupsafe"
version = "2.1.5" version = "3.0.2"
description = "Safely add untrusted strings to HTML/XML markup." description = "Safely add untrusted strings to HTML/XML markup."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.9"
groups = ["main"]
files = [ files = [
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
{file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
{file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
{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-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
{file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
{file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
{file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
{file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
{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-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
{file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
{file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
{file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
{file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
{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-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
{file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
{file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
{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-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, {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-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
{file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
{file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
{file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
{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-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, {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-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
{file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
{file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
{file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
{file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
{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-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, {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-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
{file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
{file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
{file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
] ]
[[package]] [[package]]
@ -260,6 +321,7 @@ version = "1.3.0"
description = "A network address manipulation library for Python" description = "A network address manipulation library for Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
groups = ["main"]
files = [ files = [
{file = "netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe"}, {file = "netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe"},
{file = "netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a"}, {file = "netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a"},
@ -270,13 +332,14 @@ nicer-shell = ["ipython"]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "24.1" version = "24.2"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
files = [ files = [
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
] ]
[[package]] [[package]]
@ -285,6 +348,8 @@ version = "2.22"
description = "C parser in Python" description = "C parser in Python"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
groups = ["main"]
markers = "platform_python_implementation != \"PyPy\""
files = [ files = [
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
@ -292,62 +357,65 @@ files = [
[[package]] [[package]]
name = "pyyaml" name = "pyyaml"
version = "6.0.1" version = "6.0.2"
description = "YAML parser and emitter for Python" description = "YAML parser and emitter for Python"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.8"
groups = ["main"]
files = [ files = [
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, {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]] [[package]]
@ -356,6 +424,7 @@ version = "1.0.1"
description = "Resolve abstract dependencies into concrete ones" description = "Resolve abstract dependencies into concrete ones"
optional = false optional = false
python-versions = "*" python-versions = "*"
groups = ["main"]
files = [ files = [
{file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"}, {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"},
{file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"}, {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"},
@ -369,20 +438,26 @@ test = ["commentjson", "packaging", "pytest"]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "70.1.1" version = "75.8.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.9"
groups = ["main"]
files = [ files = [
{file = "setuptools-70.1.1-py3-none-any.whl", hash = "sha256:a58a8fde0541dab0419750bcc521fbdf8585f6e5cb41909df3a472ef7b81ca95"}, {file = "setuptools-75.8.1-py3-none-any.whl", hash = "sha256:3bc32c0b84c643299ca94e77f834730f126efd621de0cc1de64119e0e17dab1f"},
{file = "setuptools-70.1.1.tar.gz", hash = "sha256:937a48c7cdb7a21eb53cd7f9b59e525503aa8abaf3584c730dc5f7a5bec3a650"}, {file = "setuptools-75.8.1.tar.gz", hash = "sha256:65fb779a8f28895242923582eadca2337285f0891c2c9e160754df917c3d2530"},
] ]
[package.extras] [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"] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
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"] core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "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) ; python_version < \"3.11\"", "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) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "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 ; sys_platform != \"cygwin\"", "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) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.1"
python-versions = "^3.10" python-versions = "^3.11"
content-hash = "2b6819adc72a58e8d504a1ba77064b09a47ec69d1cd39542ee6e068091927cb3" content-hash = "aee53e668f5f3a99526ea72999ad57256351453f5331f71c0abf94b5bd74a0c3"

View File

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

11
renovate.json Normal file
View File

@ -0,0 +1,11 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"docker-compose": {
"fileMatch": [
"(^|/)(?:docker-)?compose[^/]*\\.ya?ml(\\.j2)?$"
]
}
}

View File

@ -10,17 +10,25 @@
file: file:
path: "{{ current_stack_dest }}/{{ item.path }}" path: "{{ current_stack_dest }}/{{ item.path }}"
state: directory state: directory
mode: "700" mode: "755"
loop: "{{ lookup('community.general.filetree', current_stack_source) }}" loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "directory" when: item.state == "directory"
- name: Generate {{ current_stack_name }} deployment from templates - name: Generate {{ current_stack_name }} deployment from templates
template: template:
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}" dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}"
mode: "600" mode: "644"
loop: "{{ lookup('community.general.filetree', current_stack_source) }}" loop: "{{ query('community.general.filetree', current_stack_source) }}"
when: item.state == "file" 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 }} - name: Deploy docker-compose for {{ current_stack_name }}
community.docker.docker_compose_v2: community.docker.docker_compose_v2:
@ -30,5 +38,5 @@
remove_orphans: yes remove_orphans: yes
register: docker_compose_output register: docker_compose_output
- debug: # - debug:
var: docker_compose_output # var: docker_compose_output

View File

@ -28,7 +28,11 @@
collection: apps collection: apps
stacks: stacks:
- gitea - gitea
- woodpecker
- syncthing
- nextcloud - nextcloud
- jellyfin - jellyfin
- arrstack - arrstack
- vpgen
- pgrok
import_tasks: deploy_collection.yml import_tasks: deploy_collection.yml

View File

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

View File

@ -25,5 +25,7 @@ GITEA__security__INTERNAL_TOKEN={{ internal_token }}
GITEA__oauth2__JWT_SECRET={{ jwt_secret }} GITEA__oauth2__JWT_SECRET={{ jwt_secret }}
GITEA__webhook__ALLOWED_HOST_LIST="external,woodpecker.{{ domain }}"
# Indexer # Indexer
GITEA__indexer__REPO_INDEXER_ENABLED=true GITEA__indexer__REPO_INDEXER_ENABLED=true

View File

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

View File

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

View File

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

View File

@ -2,13 +2,10 @@
networks: networks:
{{ helpers.default_network(198) | indent(2) }} {{ helpers.default_network(198) | indent(2) }}
traefik_traefik:
external: true
services: services:
app: app:
image: nextcloud:${NEXTCLOUD_VERSION} image: &nextcloud_image nextcloud:stable-apache
container_name: nextcloud_app container_name: nextcloud_app
labels: labels:
- {{ helpers.traefik_labels('nc', port='80') | indent(6) }} - {{ helpers.traefik_labels('nc', port='80') | indent(6) }}
@ -18,40 +15,28 @@ services:
- redis - redis
env_file: env_file:
- .env.nextcloud - .env.nextcloud
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html - {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config - {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data - {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data
cron: cron:
image: nextcloud:${NEXTCLOUD_VERSION} image: *nextcloud_image
container_name: nextcloud_cron container_name: nextcloud_cron
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:
- app - app
entrypoint: /cron.sh entrypoint: /cron.sh
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html - {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config - {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data - {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data
notify_push: notify_push:
image: nextcloud:${NEXTCLOUD_VERSION} image: *nextcloud_image
container_name: nextcloud_notify_push container_name: nextcloud_notify_push
{# TODO: Refactor this and minio -#}
labels: labels:
- traefik.enable=true - {{ helpers.traefik_labels('nc', port='7867', path_prefix='/push') | indent(6) }}
- traefik.http.routers.nc-notify.rule=Host(`nc.{{ domain }}`) && PathPrefix(`/push`)
- traefik.http.routers.nc-notify.entrypoints=websecure
- traefik.http.routers.nc-notify.tls=true
- traefik.http.routers.nc-notify.tls.certresolver=letsencrypt
- traefik.http.routers.nc-notify.tls.domains.0.main={{ domain }}
- traefik.http.routers.nc-notify.tls.domains.0.sans=*.{{ domain }}
- traefik.http.services.nc-notify.loadbalancer.server.port=7867
restart: unless-stopped restart: unless-stopped
user: www-data user: www-data
env_file: env_file:
@ -68,8 +53,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.db - .env.db
networks:
- default
volumes: volumes:
- {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data - {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data
@ -79,8 +62,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.redis - .env.redis
networks:
- default
command: command:
- sh - sh
- -c - -c

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,16 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(193) | indent(2) }}
services:
syncthing:
image: linuxserver/syncthing
container_name: syncthing
labels:
- {{ helpers.traefik_labels('sync', port='8384', auth=true) | indent(6) }}
restart: unless-stopped
network_mode: host
volumes:
- {{ base_volume_path }}/syncthing/config:/config
- {{ base_volume_path }}/syncthing/data:/data

View File

@ -0,0 +1,29 @@
DATABASE_URL=file:/data/vpgen.db
PUBLIC_AUTH_AUTHENTIK_ENABLE=1
AUTH_AUTHENTIK_REQUIRE_INVITE=0
AUTH_AUTHENTIK_DOMAIN="auth.{{ domain }}"
AUTH_AUTHENTIK_CLIENT_ID=vpgen
AUTH_AUTHENTIK_CLIENT_SECRET="{{ auth_vpgen_client_secret }}"
PUBLIC_AUTH_GOOGLE_ENABLE=1
AUTH_GOOGLE_REQUIRE_INVITE=1
AUTH_GOOGLE_CLIENT_ID="{{ google_consumer_key }}"
AUTH_GOOGLE_CLIENT_SECRET="{{ google_consumer_secret }}"
AUTH_INVITE_TOKEN="{{ vpgen_auth_invite_token }}"
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:v3
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:v3
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

@ -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

@ -5,46 +5,94 @@ metadata:
name: Alpina - OAuth2 Apps name: Alpina - OAuth2 Apps
entries: entries:
{% set apps = { {% 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": { "Gitea": {
"redirect_uris": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback", "redirect_uri": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
"icon": "https://gitea."~ domain ~"/assets/img/logo.svg", "icon": "https://gitea."~ domain ~"/assets/img/logo.svg",
"client_secret": auth_gitea_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
}, },
"Nextcloud": { "Nextcloud": {
"redirect_uris": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik", "redirect_uri": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
"icon": "https://nc."~ domain ~"/apps/theming/favicon", "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() -%} {% for app in apps.keys() -%}
- identifiers: - identifiers:
name: {{ app }} name: {{ app }}
model: authentik_providers_oauth2.oauth2provider model: authentik_providers_oauth2.oauth2provider
id: {{ app | lower }} id: {{ app }}
attrs: attrs:
access_code_validity: minutes=1
access_token_validity: minutes=5
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] 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_type: confidential
issuer_mode: per_provider client_id: {{ app | lower }}
sub_mode: hashed_user_id client_secret: {{ apps[app]["client_secret"] }}
property_mappings: property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
redirect_uris: {{ apps[app]["redirect_uris"] }} {% if app == "Minio" -%}
refresh_token_validity: days=30 - !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"]] signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
- identifiers: - identifiers:
slug: {{ app | lower }} slug: {{ app | lower }}
model: authentik_core.application model: authentik_core.application
id: {{ app | lower }} id: app-{{ app }}
attrs: attrs:
name: {{ app }} name: {{ app }}
group: "Apps" group: "{{ apps[app]["ui_group"] }}"
meta_description: "Hello, I'm {{ app }}!" meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}" icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true open_in_new_tab: true
policy_engine_mode: any provider: !KeyOf {{ app }}
provider: !KeyOf {{ app | lower }}
{% 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 %} {% endfor %}

View File

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

View File

@ -48,7 +48,8 @@ entries:
passwordless_flow: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]] passwordless_flow: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]]
sources: sources:
- !Find [authentik_core.source, [slug, authentik-built-in]] - !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 # Enable compatibility mode for the default authentication flow for better autofill support
- identifiers: - identifiers:

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

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

View File

@ -5,11 +5,16 @@ MINIO_DOMAIN=s3.{{ domain }}
MINIO_SERVER_URL=https://s3.{{ domain }} MINIO_SERVER_URL=https://s3.{{ domain }}
MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }} MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }}
#MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration # https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html
#MINIO_IDENTITY_OPENID_CLIENT_ID= MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
#MINIO_IDENTITY_OPENID_CLIENT_SECRET= MINIO_IDENTITY_OPENID_CLIENT_ID=minio
#MINIO_IDENTITY_OPENID_CLAIM_NAME= MINIO_IDENTITY_OPENID_CLIENT_SECRET={{ auth_minio_client_secret }}
#MINIO_IDENTITY_OPENID_CLAIM_PREFIX= # defaults to "policy"
#MINIO_IDENTITY_OPENID_SCOPES= #MINIO_IDENTITY_OPENID_CLAIM_NAME=policy
#MINIO_IDENTITY_OPENID_REDIRECT_URI= 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= #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

@ -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=Host(`s3.{{ domain }}`) || HostRegexp(`^.+[.]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

@ -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: networks:
{{ helpers.default_network(251) | indent(2) }} {{ helpers.default_network(251) | indent(2) }}
traefik_traefik:
external: true
services: services:
grafana: grafana:
image: grafana/grafana:latest {# image: grafana/grafana:latest#}
build:
context: .
dockerfile: Dockerfile
container_name: grafana container_name: grafana
labels: labels:
- {{ helpers.traefik_labels('grafana', port='3000') | indent(6) }} - {{ helpers.traefik_labels('grafana', port='3000') | indent(6) }}
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable # Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}" user: "{{ remote_uid }}"
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/monitoring/grafana:/var/lib/grafana - {{ 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: loki:
image: grafana/loki:latest image: grafana/loki:3.5
container_name: loki container_name: loki
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable # Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}" user: "{{ remote_uid }}"
command: command:
- -config.file=/etc/loki/loki-config.yaml - -config.file=/etc/loki/loki-config.yaml
# Port forward is needed because not possible to resolve the container name from the host network # Port forward is needed because not possible to resolve the container name from the host network
ports: ports:
- 3100:3100 - "127.0.0.1:3100:3100"
- "[::1]:3100:3100"
volumes: volumes:
- {{ base_volume_path }}/monitoring/loki:/loki - {{ base_volume_path }}/monitoring/loki:/loki
- ./loki_config:/etc/loki:ro - ./loki_config:/etc/loki:ro
@ -39,7 +40,7 @@ services:
- /tmp/loki - /tmp/loki
promtail: promtail:
image: grafana/promtail:latest image: grafana/promtail:3.5
container_name: promtail container_name: promtail
restart: unless-stopped restart: unless-stopped
command: command:
@ -56,7 +57,7 @@ services:
image: prom/prometheus:latest image: prom/prometheus:latest
container_name: prometheus container_name: prometheus
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable # Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}" user: "{{ remote_uid }}"
command: command:
- --config.file=/etc/prometheus/prometheus.yml - --config.file=/etc/prometheus/prometheus.yml
@ -79,6 +80,11 @@ services:
image: gcr.io/cadvisor/cadvisor:latest image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor container_name: cadvisor
restart: unless-stopped 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: volumes:
- /:/rootfs:ro - /:/rootfs:ro
- /var/run:/var/run:rw - /var/run:/var/run:rw
@ -93,9 +99,6 @@ services:
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env.influxdb - .env.influxdb
networks:
- default
- traefik_traefik
volumes: volumes:
- {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2 - {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2

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

@ -31,4 +31,4 @@ name_attribute_path = name
# Optionally map user groups to Grafana roles # Optionally map user groups to Grafana roles
allow_assign_grafana_admin = true 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: schema_config:
configs: configs:
- from: 2020-10-24 - from: 2024-10-18
store: boltdb-shipper
object_store: filesystem
schema: v11
index: index:
prefix: index_
period: 24h period: 24h
prefix: index_
object_store: filesystem
schema: v13
store: tsdb
# TODO: Figure this out # TODO: Figure this out
ruler: # ruler:
alertmanager_url: http://localhost:9093 # alertmanager_url: http://localhost:9093

View File

@ -1,18 +1,11 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %} {% import 'contrib/compose_helpers.j2' as helpers with context %}
networks: networks:
traefik: {{ helpers.default_network(254) | indent(2) }}
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) }}
services: services:
traefik: traefik:
image: traefik:v3.0 image: traefik:v3.4
container_name: traefik container_name: traefik
restart: unless-stopped restart: unless-stopped
env_file: env_file:
@ -23,14 +16,10 @@ services:
- ./rules:/rules:ro - ./rules:/rules:ro
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- {{ base_volume_path }}/traefik/rules:/rules/extra:ro - {{ base_volume_path }}/traefik/rules:/rules/extra:ro
- {{ base_volume_path }}/traefik/logs:/logs
- {{ base_volume_path }}/traefik/acme:/acme - {{ base_volume_path }}/traefik/acme:/acme
# This is mostly just so that the traefik network gets created
whoami: whoami:
image: containous/whoami image: containous/whoami
container_name: whoami container_name: whoami
labels: labels:
- {{ helpers.traefik_labels('whoami', port=80) | indent(6) }} - {{ helpers.traefik_labels('whoami', port='80') | indent(6) }}
networks:
- traefik

View File

@ -2,11 +2,8 @@ api:
insecure: true insecure: true
log: log:
filePath: /logs/traefik.log
level: INFO level: INFO
accessLog: accessLog:
filePath: /logs/access.log
bufferingSize: 100
entryPoints: entryPoints:
web: web:
@ -15,6 +12,16 @@ entryPoints:
address: ":443" address: ":443"
http3: http3:
advertisedPort: 443 advertisedPort: 443
forwardedHeaders:
trustedIPs:
# https://www.cloudflare.com/ips-v6
- 2400:cb00::/32
- 2606:4700::/32
- 2803:f800::/32
- 2405:b500::/32
- 2405:8100::/32
- 2a06:98c0::/29
- 2c0f:f248::/32
metrics: metrics:
address: ":8082" address: ":8082"
@ -39,7 +46,6 @@ certificatesResolvers:
providers: providers:
docker: docker:
exposedByDefault: false exposedByDefault: false
network: traefik_traefik
file: file:
directory: /rules directory: /rules
watch: true 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

@ -32,7 +32,7 @@
state: enabled state: enabled
immediate: yes immediate: yes
- name: Allow Web - name: Disallow Web
become: yes become: yes
firewalld: firewalld:
service: http service: http
@ -64,6 +64,22 @@
state: enabled state: enabled
immediate: yes immediate: yes
- name: Allow 2222 tcp for pgrok ssh tunnel
become: yes
firewalld:
port: 2222/tcp
permanent: yes
state: enabled
immediate: yes
- name: Allow Syncthing
become: yes
firewalld:
service: syncthing
permanent: yes
state: enabled
immediate: yes
- name: Reboot if needed - name: Reboot if needed
become: yes become: yes
ansible.builtin.reboot: ansible.builtin.reboot:

View File

@ -1,12 +1,5 @@
- name: Get IPv6 subnet for Docker - name: IPv6 subnet for Docker
set_fact: debug:
docker_ipv6_subnet: "{{ \
ansible_default_ipv6.address \
| ansible.utils.ipsubnet(64) \
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
}}"
- debug:
var: docker_ipv6_subnet var: docker_ipv6_subnet
- name: Configure Docker daemon - name: Configure Docker daemon
@ -35,33 +28,6 @@
state: disabled state: disabled
register: docker0_firewalld 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: "{{ alpina_svc_path }}"
state: absent
when: clean_desired is true
- name: Restart Docker daemon - name: Restart Docker daemon
become: yes become: yes
service: service:

View File

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

View File

@ -1,12 +1,4 @@
- hosts: all - hosts: alpina
roles: roles:
- common - common
pre_tasks: - docker_host
- 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