5 Commits

65 changed files with 921 additions and 1458 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)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Poetry (alpina) (4)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PyDocumentationSettings"> <component name="PyDocumentationSettings">

47
.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/templates/services/authentik/blueprints" /> <option name="path" value="roles/alpina/collections/services/authentik/templates/blueprints" />
<option name="mappingKind" value="Directory" /> <option name="mappingKind" value="Directory" />
</Item> </Item>
</list> </list>
@@ -39,22 +39,6 @@
</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>
@@ -106,16 +90,6 @@
<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" />
@@ -150,6 +124,25 @@
</SchemaInfo> </SchemaInfo>
</value> </value>
</entry> </entry>
<entry key="prometheus.rules.json">
<value>
<SchemaInfo>
<option name="name" value="prometheus.rules.json" />
<option name="relativePathToSchema" value="https://json.schemastore.org/prometheus.rules.json" />
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/container-alerts.yml" />
</Item>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/container.alerts.yml" />
</Item>
</list>
</option>
</SchemaInfo>
</value>
</entry>
</map> </map>
</state> </state>
</component> </component>

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)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina) (4)" project-jdk-type="Python SDK" />
</project> </project>

View File

@@ -1,23 +1,19 @@
.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
playbook_cmd := poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} clean_desired ?= false
all: site services all: site
setup: setup:
poetry install --quiet poetry install --quiet
site: setup site: setup
$(playbook_cmd) site.yml poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} --extra-vars "clean_desired_arg=${clean_desired}" site.yml
services: setup services: setup
$(playbook_cmd) services.yml poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env} services.yml
clean: setup
$(playbook_cmd) clean.yml

View File

@@ -8,22 +8,6 @@ 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

View File

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

View File

@@ -6,38 +6,23 @@ 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, port='', path_prefix='', auth=false, wildcard=false) %} {% macro traefik_labels(host, service="", port="", auth=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.r-{{ name }}.rule={{ host_rule(host, path_prefix, wildcard) }} - traefik.http.routers.{{ host }}.rule=Host(`{{ host }}.{{ domain }}`)
- traefik.http.routers.r-{{ name }}.entrypoints=websecure - traefik.http.routers.{{ host }}.entrypoints=web
- traefik.http.routers.r-{{ name }}.tls=true - traefik.http.routers.{{ host }}-tls.rule=Host(`{{ host }}.{{ domain }}`)
- traefik.http.routers.r-{{ name }}.tls.certresolver=letsencrypt - traefik.http.routers.{{ host }}-tls.entrypoints=websecure
- traefik.http.routers.r-{{ name }}.tls.domains.0.main={{ tls_base }} - traefik.http.routers.{{ host }}-tls.tls=true
- traefik.http.routers.r-{{ name }}.tls.domains.0.sans=*.{{ tls_base }} - traefik.http.routers.{{ host }}-tls.tls.certresolver=letsencrypt
- traefik.http.routers.{{ host }}-tls.tls.domains.0.main={{ domain }}
- traefik.http.routers.{{ host }}-tls.tls.domains.0.sans=*.{{ domain }}
{% if service -%}
- traefik.http.routers.{{ host }}.service={{ service }}
{% endif %}
{% if port -%} {% if port -%}
- traefik.http.routers.r-{{ name }}.service=svc-{{ name }} - traefik.http.services.{{ host }}.loadbalancer.server.port={{ port }}
- traefik.http.services.svc-{{ name }}.loadbalancer.server.port={{ port }}
{% endif %} {% endif %}
{% if auth -%} {% if auth -%}
- traefik.http.routers.r-{{ name }}.middlewares=authentik@docker - traefik.http.routers.{{ host }}-tls.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,34 +5,27 @@ alpina_svc_path: ~/alpina
base_volume_path: /mnt/dock base_volume_path: /mnt/dock
media_volume_path: /mnt/media media_volume_path: /mnt/media
docker_ipv6_subnet: "{{ \ traefik_subnet: 172.16.122.0
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 }}"
alertmanager_discord_webhook: "{{ vault_alertmanager_discord_webhook }}"
# Traefik # Traefik
acme_email: "{{ vault_acme_email }}" acme_email: "{{ vault_acme_email }}"
cloudflare_api_token: "{{ vault_cloudflare_api_token }}" cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
@@ -55,21 +48,3 @@ 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_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,154 +1,96 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
64326366396663613133333430356565636565363066383339646533623964613638613932633865 32653863663065353431636364373163613536643238613961666561653663633530646165643766
3435613234306336376565623861303864323735323533360a656533303734646630343964666666 3833323937353331313136633965393061616135366534660a333037383066303431623830313464
65396638373733353833333736626465336663323934373461303564376531623066303062646630 65346431633238666534373033663138353438313762326361666233353866663534363536643034
6362633163653936390a626138656361663635336533376563373139663538663037306336333865 3636323439316261630a623262336331663431633266336235653034323234383566323963623365
63393263646665663664333162656532373064336361346133383064383035333831653563393337 32626363626164373536663464643632393761346137623866633237643038306265636362626561
39306138623764366131303332653839653061393530353235613563376430666337656336386262 61313634353634373530383061393364613461303132326335316566326436633635633131643433
64363731656230323832616437633735343662376637303334343161343165636137623434613636 31376539396639326464333233643933373737313064363262323639363964643862633035396161
35666439383036633761353062613464363264633231306138636362643434333338303238616364 35643037636535623966626131393538643432396536643365383736636262356135373434376433
35636430626536633264616233303462363839653436323138613836633336383438393364373338 32316361343330303431376234323632323932376635343964383733633761326639393966383039
37623539306635636462363239396231663264613034646165393031343763643265363235623736 35646131343034663962363335373661323065663764396631343461383661663738386163323633
37383439313066386139373736396465323962663131383664393939373862336231306266653832 36303464646532633235663662666663343238633465663334326463383133643239666634653739
61663037613535663138333565613066663938616432356434323531383837363931393837323634 35396130393961303230396236303766336666643930626161333338326137663235323066663032
66353436303065323266386264353436393266363136326531646438326130613865663132353164 33376564373563323635356233616264313663373534333636643236393866613062656338353864
30366434373164623037613931393634613065383737643863343939373063376530633938346434 66386132663362363832366661646462316139353132626662663934336530386534376538633235
62633432636430366361616636313337366238303566303566616363653336643736333636663737 62653131653835323261373435373631396466353738306362616266616532313435323633613933
38316330646266636633323162346231353337626133663939306131653434326533326162663963 61646132346536323632643865326234356535346566346532383162393265613931343962303463
34666262313232663564356633393162653639653739323639396562613362313663383736393438 31636334343736666434353835633734396465653862613234386431306463326134613931646232
31373930393465356535303236343934663238373764303333663634666338643666646665326563 32353535663133623434643866336165616232613662336533383432633338373763643337616637
34376164303538336133613630623466656466663266326432343439613235376463326661663131 38323237646461376433316164646366383438316639633162303739383263656265633364303565
38373533313661333431343638346334303736306237653336633366313831626466633430373865 36643339356136653332666230633939636264306431636562323864373037623138363739616561
32646536643862646135653434343337373563666532333561316232393063306365363631623262 37613364653737353638646564323439646138646536636564303866636233616264383466656439
31313538306264623030353230326330666234303138646237613435633637373837656565623538 33646232653061616437656162353036313834616162313936353533393833313432656534343363
33616233623366346237376563613430663835653432653834353835376338643236663266646462 35636638326236646163323463356634326534623165306461316530353936646162323435633862
62316438356233383965616434393737306132306538396564396431376661323135353137316534 64396464303363323837316162353734626663643962303534336637336632333463393734383532
63353663343338353339373163343737333835363363316563393538353266653033383136646437 66616534666466393333386337363238383432643764373864613461363766333932333862363332
37626661383531363233656663616630316361373438616232313131316234386665653262313937 61313364613031376334326635636432346532613462613265643462636436663963323862353733
61366536613731663231616663393735303535326636383066333330386233306534656237653561 38396261613332396633666130653262313234633132353264363266336231373535306532383661
33336639356331313636363865313836306137333439613365636132356631653437316161346230 65323530653531646339626537653433303332656535346639393466353133363833326236656231
64643736323437396663653937633634633230386164333239616261616332323137643764383335 33336265373463396135653730616266346331376461346433343464326238323034653330393732
64613966653764623031323961386530383731316464386131393264346261356331666165623738 36643432316662333633333036633761653031393433333338663633386264656535623534653463
62643564323134393630336566343834356265316264393530356633356466313831623262363730 36363565303333356361616539376532353066336137336134656465383364636361656664356439
66373232353439616539643433653435643931623430633338623737643039306532343234646333 65326334643631663665376530646433323439653864623964323363396561313663636538356536
34393536333730626136313039646364626235616233323137386137383565326461393635353838 63626336303862333364363166353437353163656238303765636662636137383337623563666264
35616530383765373431626130386165663538663861653064646363633465326364353533646137 66326633343230386638616438393436633431343264343231386563613935626430306337343533
62326435353239363164383236333236643430396561396231323130376264646139666264356138 66656366333332326131343661356236396430303832303834653530623639353036663436373862
35353466396335336532363566323738373932643634363763633832353462663836636465626434 61336437386338343965653563646664643438353232306231316564616462643236646239333062
38656332626236626335386166333835306666643438376330373936656639313933373635333436 38643461346639623964626438396631396139383332666130316635656530653136333662353566
30633731376166376232363834346632633261353361323563376162343063343065643439306231 36313261646330373963663032316662383137366436636534383366636362366435393036373264
30666131373361633862363833373366313733626161643932306332613230393636636138363337 34646537666462363531343335336638343038333633663862666163306662643634326533316561
61666565633931376639613262666332363037373337663430343939333431303732636434633934 61613235366233636530663462353066646530386265623534663336376364323237343936646134
35386130386363333431636363336130336430633839653231363935313930393037306536336563 31616563653864383565306439613932396562613835613562326264326535636630646666366335
36653462383432366337646266313139346536666230386565333364383330653333353765326136 36653631353961353933386236636534393636356334633336313333383238353838336335646630
33626236333765333863363265346561643835373235393361643234386336656134353731393033 63633365666530623562323634303935326362643762616532303531303139333565643835396163
34316430383933626434343839333065333166386233316132373138666534653434653033356135 36353130656365326435343130613234336637346461313639653133623933376163393935366266
31366539346538336639626363396636646135386266386138356362616464316630313437386265 66653337353732363038663164363663623266356366663637343466393836353965343730666362
30353361626338633961366633333631383366316331333635613738366139633863376331333435 38663636336265383331666666616535366334616431306164303738306436333364653765356662
39376239336532343937346563646331366136666130646336366537366534323961363930663438 37316433323563323431623164386337343563663538333435616333343433396236356363333262
65333663613030336131663665343234616231306130663761643163646233353265333030396333 61396664326234343136666331356465333233663135613839616334623033316362336162613731
30326436396163343732313430373135323332326161623566633932303537666564633834623863 38646530326538643337323838326563303130643934623939346635343331356531373235663937
66353039626565646539313763373864623638323765313065646133646430666162616533323036 62396530383365666439373632613633633233376139616138323033613135383330333132643839
64313238633264623465313961656563643536313435313162376339353532363232613637343463 65363833616337656662653462323436303531653635663739633366616532333761323238353764
33343066303465643930613364356635333234363563653731663137306337346630653637656566 39373836303735393165393435323139346661346135636138613731373165386533386333393364
30323537356264356137643637646265643537303263373964346165656266623263636331323130 32336265386334386338653734353565343733393931373436336233333031356531313739636666
31396433346561666331616639306131623261353763343638663931623161343133616639633561 61376234393631343236643137616631373564376132623534333939346162353662306661393438
36646266643636613564346663666633313665386137323266633330333862313637386330643937 32326566373934653463653737383131386431363664333535626361646637613632383132623533
33393561376331316235323961636462363661383466663635323464366238386531393466316361 32343465366562363765353366333330633631353936613930376631336538306230626632303966
30396434666335346232643738396638633239323935636637343838353364656662663666303366 31343936386535663165663066663862656439306363326337313561396132316338363930323632
37663666373839613837313335366635363634623133653463626466316435303538303632633762 33313061623534373338623931663934396339633564353533626639373837323832366132343538
66366538303630336630663365663831313562383334666435383831376564333438633364343861 63373862663137306665383732303863343564343830636233613139666631626532373938386663
35343462653233636265336266386637636261666331316666663966313666383965303163656238 35646331646462356639383964373732393866653963643832633661323430323430613330633364
66343932323939363339323664366334386166373139363866353161396235366466306466636439 35343262366362646165383032333236623863656264353964623136643631326135623538306261
36313039313263643739353230313362353263626236393239656164656334653363623965653936 37393839343331653665356131343063316232303963636462653238333466636334616435666463
65386165663361313066646532393939383165316239653335623965346363613335396639653134 65636662383930353238623130363834616137643830633261646338363435343839633565303562
36346164383439636237306233333166383233376462633136383933666161643734303032313530 37623231396163346464303464333962336261353634396236613132306464643764356265656137
62343866316162393766626261393635643564366431383164626236653062336466343634323432 32373263613964396430646332666235303634373431643939623963633334326135626565656662
38343663623261343535616536613961636564376563303064623537303233373366326136353665 30646166303732643562653166633232666635343665616665653566316632303861613861313333
33336532633161623638303761383034306265613230323433326133653035303661626234353931 38393636663137333231613239353661656338333536656563616237343234623031363535666637
31646530383637626231313965343138303565303030316132613930306137313465616664646230 61343662663965663161666436366630366432363733663537613064386130326466343366383232
30353163626562396566653261643336653832663635333963343539396366346132353465386463 32363662343561666665323565356163383932336361656132373263363239636666613461366339
33666365363639343066653330326233373035313433316264373236366565643931616335643762 31323264393866386239353333386161643330343262366666323533303737373163313262313766
63306165393166396437646366303837316235643562366464326530373230633664653235363136 61303638366263346232353134333431613730386431623235323537323962666133613939353762
31333938616139653261656132663439323066636135303430383662333639306265633436326666 63326361633630323937353163383930626336663365626532613031623532393932316138353335
62353936663463343864383432636465373737666239613033383538396338303533636663393339 32363262393764663135393466616639373965313238323935383531633434633038663437646662
63633561343135343339393063636163373936323461303734613766626539343363363365643632 31633265373937316533373332316132363061386133356231623230393739326464333761336338
66306630303634353230393933353333346166303436333038303637313162626464373334373063 38626234646164616265633061346239363164376532383834356435346232653065326362343363
38313438633365316562363564316138393531633661323139343938633636373534386465643631 39613532356166633133626563643238373661323937353635343464666339323561326136623366
35396261643865393531366432343265663363336562643366623062343331306431663461393066 62633637656462376136633963653263346565366563646533373431613761616231653739613537
32633732333634383462383061623334306332326466306666626131363461343436393966633233 32343332356435393635363837396463613165626337346235303363613764306132343539333836
31656538633733303264663239643639326235316561386564613563383930383336386664363135 63386633626332396339383165303166653334663239313066666632356165643161356262346230
39616263313036646630373233636534376361386230386235363636643835636538663930633630 32636365636364663466343939663538386439343336303537636230306263643534653339313538
38656664383138373138626639666230623635613137666533353233333636323062666432313434 31373165363962373337636138336561336638633762373363646139366339323031313664306534
37666132303233353438346439653965626434663136386631313337633636653464396566323532 30623130663037323839666166323162393065643535663866383062356330633137343239316436
39366434373830343764346138613665373536656164363637663037663534633963336230663439 32303132393739653363376138633430313832383165663366626436653033663637616664346632
38373138336666633934643537383131333034316135343738623435643630653661633432363161 63633439663734393236343265323533633639316133323336373064633138363266316135363335
37373837303838343566626662656231306438613538333733323632616132343563376533663539 31336637666331333139306537333565333064666433653730633430336261656665613263663937
64653262646463613739313737356139666666623963636261336433396363636632333933393463 64313230656333373838346439623061393164393239393934306336373063303934663334353532
63653366666536323536666264343931373961356361646434623461316630626133376639613362 31313637623466313835313566616161376230343532653561343364383133653736646338303631
38333836653332346134616134313164313965613531343630383764636161653730656332616238 36356164303630303433356332343630616465383831623036383833393330663566616333653161
31393132363064663431316165346135343861653462383162353063653837393566356161333535 63393361643266323336393962663263323338633634633033393762656139393665353630633637
35343133646632343164336364623337393138343630643737643531346566636633646438396162 39386462303731396261613961613238616237373332656361303139633763303837653765623464
31393632303661323363346164636331626638326437383035363930656635316236366434623236 64333565666532653864383861333433353731343161613231383836353966353636373762306132
33633136303533636239666434323962333134366461363037343463623437363961353962346236 35333536373939656638356333383135313231306433656536383933623634653263353434393238
66313838643238323136356135346564363732656666363431653061663863616537663035373631 32323037666135316337633465666335376332326633346665643333656139386465353134356636
34613262363065333162353039613762386130353930316161613061633164383539623263323865 36333434303538326135346539313734393939353163316666366438613133333464623732666438
30313566613365656563353236386334636335366663643034316435376532333438643166663536 663934323030303937623038343662646163
38363363373330326132336363363039396563396435366131353933393434373336363033343265
30613539366436643631303933376137386635366166663930303331623238633034326631656366
31356337303834356334633636333832363837343735396632356365613439383061366232383462
62613934373535626639363230366266343762643232623933613265356436656364363835323062
32393062386432323562313734346133393465316135316135366331653161636261316364643632
36326161653937336562643034636638666265386264623133626335616633353239333965656632
31323134393230303733623732313836373465383535626434383638666135313237633731613763
64343066336662643264663130363962626435626332626464396137386538333731373238616636
66313931666466306133643666363862626438343634353336376566333533393936363866626233
63616633373536633138393563323636343035343564626236383064376135656638616534353431
31643063346631636666333065386339663363623431653532643065363636303764666333393761
36313439303765356532393832633637636336643036306333663935393734663662346435396466
37376537323262653033356336363835666231363661653133666361383065343063643061376164
32333530376530326662373738333363373631663536373961373965373263346635643762396666
61396632343464343735623531653831393735666331316162353430353134383430393865383662
66656264376564343636386263333934313364373564616134623863613439636537613764376434
65313964303539376131396339356238363735363766616365306133393464613131643166646437
39353961393036646164663865633633373465653766386230333762643735363734633633363461
62613332346336633833663862333230363161663636646232343761356338393639613035646438
32663465303138613731303961633565616239633033333361613861623161353032353661363062
39316262363738383163366332373438636539623365353232316536363130333438613031653665
62366334653036353566333663353862303335656266613134633731633535313730303539306334
63393431306265373234313939373133363961626265626633343631613931636132653635376634
61366262336239656638343438646231653030666638383239313834363334663661316235366162
34346438386461633366353838346664663832323436333737306566333164323066313931643630
33363733356231326636646133366136663431343038643265633136626363343131656463373264
65363833353831656638303439623636373062383235363966356332343163616336643735306466
65663366643030626437326439633665333564623065633431636232393465623365636565363230
38393664653432383539376363366462386438663137363562323231663661353635383866373761
66303165323861626538353236366533336533333939376232313038343331663833303864356235
64383664376237346465626339336536393537323665653766363464393133323637646264643830
32376435623666383633383636323862376166623938346239363339336333373531376433383032
39656466363761376565653936366430363638623332636532383431373334386436373737323163
61616230396135353831343139346464623261303231633035353264626232393933393732393634
35353531626532626334613836623633636265613963613064626334363436336664363633653636
64366262336134653932386236663161623639626562303135386532366261396134613664653037
63656665393835653831366464386236303239363338623338653833653430323135333063616266
61383539613066623563616139666261373066316662636633613561366466623032386434366137
63643030653538623039353934373531633034386665303866623835356433353666653831326464
32323134323333386563316230656362396635656461643061393562393766633736613361373637
65663763373139343162643431353039613565333639336530666164343239653461623734303538
30613432363233353335373539653439313333353537343733616432316338343836336539613832
63353363373536333731636431336433333061336537353231656430343434613836383264663634
38346165373533663330373964303161373331316666633865333538656136656637346266313237
30376135656230353464643262633837336465376434323166663731346130626338613138656161
34623765316239363863626139333536376534396563623631643231616266656238383763386137
30313162373338653131623464396362666163656638656164656131616631373833373936373539
37633861306362383762363733333233623134616565383037336539343937633663356262376133
38656630343136613337663164643338323261613033383564353330306465663932653566376465
63613933626164303466366539303863366263366638663830333861663734616439316463373537
66396433663764336630643038323964656131393731623733393133653432663763326662643137
38323130336137356263303961363562623235343765356366353964396636306235616435663932
39663732313066663834616664336631376639336536323230333462386636333234373063336535
66633238666639643632383666666136383834313162396265386466643130313736653239653231
64613637646539626432613532633231343634363263363331346434613833376532323366643063
61386565316132386162663539623164626234383665336234653534336461623632636461323934
66653966656230366166363535656261363534636136376566333566313564363361316563653638
61643361383263643833636639643362613134623464346537386237616464626265

View File

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

View File

@@ -1,8 +1,6 @@
# Environment specific variables (prod) # Environment specific variables (prod)
--- ---
domain: cazzzer.com
docker_ipv6_index: 255 docker_ipv6_index: 255
# Arrstack VPN # Arrstack VPN
@@ -11,16 +9,6 @@ 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 External OAuth # Authentik GitHub 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,32 +1,21 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
36313835643238353932323631323439626432316436346533376365633332313963666433313333 61656162363565633436373135333536623561663136303736393865623830633539376362363363
6134633133636133623130376237373462383164396338380a316463396139653161366536636336 3938333137343336626634346262363964316563643261310a366538363037343965363766646535
64346664356538366538363239306631326464633635316161663963326635656430326637333963 61636239326464373039333462653562373933396665393039633266326234663335363337666439
6462633236353132300a323062353639646238663737353461633733636530613036316364353864 6137323332303533640a383062383135633762323561313666636566306531306636633466316536
34326534376639643734303137613866393464306334336566653134333765356361386436323939 66623731626266333731303336323733343336626366343833633365616330343565363035323039
35393535303635376162386266396431313739663961643061623037343463303637623130623131 35313961383131616133386663376331336639633137383137346164353632653939363266613562
31653761616639613964386432643561376637316435333064343837636463303033333432636234 36316631366661353632386230306532633862393963663465383862653964646462666334396666
39323735373161616133396566316266383165343033666530376333626264643531613334363634 66626636353539316266343937623662613336616331626439306538363764636366656635356639
35393766623361346461333764666139366632306362613362376133363239656562346263643066 30663535393366383261333832356237373230663037373638303161303534636230616464636265
65616538366532346537383432663766366161633234373562623531356339666661346164306563 37623938303638646233346338616239393838396433313063343065386666323264646461373032
35343339386631383462656466303563376237386137346437323634626163353464356462346364 63376661646139316430303533643063336634333364643231336130613638626431623732646434
35373061636237383335396231326563366230663566333665326338303564326263316630666233 63643833353164313465633333646232653761356333323933396666323837656334343866363762
65303930663862313137333630353837363265333532303133306466643462626662613166326132 39646263653137356632323534356631366531636530613736343438393136363835373435636230
66346439333739653965346236313766346532356233333164633538326135643662623533646561 30313163386335353935663432323033326235653963653930396235373863373232666334326661
65626530386333303362343830653430653866336261623566616362313739303939656364656363 34336632666365666563326366376461386130343965363832343430396537323734363533353065
37336331353766633534653936626139303061623531323362346564363665663438646533646166 64313837623366356261383437306465633730353332636561333462356363326132313933653234
62376534653562373138656465666133353235313935626534383537643436376665613865303363 66363634333664333433613466396639306436353035346134373430663532373934343861323262
62326562396361306131616363363866316232623635353663323537366563333239383636643763 30666664336336393835346234316238613839326436363162626439376530306133343530303365
35623366663463303831323730363036306363643364303532326339353633393739306366396331 65393030633237333166336637363435646435323736353461333932366638333264333239373733
33313230656431623462376135623438633164323064653866646165643263383832353138633931 30623062643336643431
66306463346361646561376334613837383762366365666638643434383034376339643239646463
66343461363233626635323535336462666339323032616136396239396534346434623238396330
37653665643366323362313136386231396532323035363963623738346564356435303263303832
37346532366432363638363330316464366361313461626535616165333433343835393565633766
32663162386562373035333335303332323136613233613431386265626337653939326435396262
61303631633838613962346663326232636438393563396230306361333335383462653432383766
35376662353262303635316635363130383032366530396439613861653037383234363831333562
37343332646534353838626366623361636261393865363633303631613837323733626264643835
63376430613234386463336234623062656534643863656434386134616265333666613939393331
39333166393538306135313431303831623063363533326330633062653333313733653831383736
613864303461323739336563356161353234

View File

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

View File

@@ -1,8 +1,6 @@
# Environment specific variables (staging) # Environment specific variables (staging)
--- ---
domain: lab.cazzzer.com
docker_ipv6_index: 254 docker_ipv6_index: 254
# Arrstack VPN # Arrstack VPN
@@ -11,16 +9,6 @@ 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 External OAuth # Authentik GitHub 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,32 +1,21 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
36343339366166383430383235626463376339653331333635623936653135633633353064613634 63633535633462326534626562373461373363643166383961303861623531663263323534366537
3263306161376232356634363532653266366665333364650a636365393465383165306563346132 3263633238646439306430356365623233313838326639350a386633363434623737313565316535
37653564633630653635353464333939353266396562316663653933373065353536333130383065 33393734633937333637373432366132323366343836393538366339626235613937323066613666
3864353332303164320a316439313164663736636465366539643131303663343861333164613561 3737393262646333390a623331333461373563313166323232343234616538623433376166313532
37383965373964313535313335643164376164323263613539643933333035323837373662303030 32323834346336336164343938303062336438643566343866316164643535663039326331646465
66636465303566313334386435326433653032383962353739643861346161323738636366396239 36666162393365323633646635333666613030386265306238633434303234336439646663356363
39623336336234376339343562656362323932383265313161396435346530663330353266323433 63323638373035326465633934326363316364616539613462653232393465633233366666373664
66396538313365653963323164306464663565303364386466666636346533633661333634313236 66616361646564303530356331323864343966633736643434653237316236363063613634646438
33623936616239613264613730363039366561646535633239633564656166343162303633373366 35303238646632616465643264316164363139393834626362326538613033656464323435396638
37656163333838656533363735383332626632353237613666396633363531666366336630613064 31346631653764303332386331663361623766333332366537313634636333346538653537346631
66626561663766376531313666663963643766393965653564333062653139336230356330383464 62363438303036386530633236376633326162336434343861346261373835653735323161323965
38343562383430303132663964303736623238386562323033623861303432363363373934643332 62353965373164616537346134303232363033323134323130316439386339613966646330666533
63363239323664333131306237336134613137653136633932356238343733393632616464366134 65346239383230646565346133663530613462363532663562326136376233303638323332326630
33623038363032653134626337663863366663383433633134326239616136656139366535613565 35656432363563653663616236393932663637323139666664636237336136366438656666633865
61646330356330396236303566363834613236653733643162666536303435643133346633353632 66353162656364356638313236643131613830393838636264663833343461373963613431656364
62386135303262353332643135636164303963616234626132356161663463366434323864626261 32303331623033303433333631313038316336653638656638373031653234356164333363336532
33356536626263626261343937386666396561306334346435316262333431353234303836356563 37316334353463376562643138346633613633353536653939376564333166323931353634333736
31343566373935396633636133616265346235396333396664333534336162323039623937656336 63616133663266383339323562343265613461623865623263623139396163343065623264366230
36656133383966613333646336613039626563353862646238376461373264633233313836333062 32633362336335396562366563363830636133376238646433386236666461333731353337386333
30343134363862626630393035643762376435346532306462363437646238333463396230666465 61323931643766326338
64386365393063613139313164366562643066323461313364393265393638643137386561633530
65643861386531323836306339386462656530383533363831323461303131396666626464303136
64343865616235616366633136393662623862383961323338366435396334653538303830616166
39636164613466313033643639366635323666666235653633333436613133343962353664313838
64356466393239666131363964643461346633313030643061643938643232343334313731636463
37396637643232353539626239306463623237623534366666396164613135356136313534663231
36613662653237343061316463386231656136383636393034333666633063613731316162333464
64313866633062623530326233633166343434636639346565346337396461393637383333366435
62393030383963396638653230613431623837353461313630343333376131616239313164336234
62323739316536353835613032303438623230626563303934626466303934613566656232323663
643265386333313065333737613438316532

256
poetry.lock generated
View File

@@ -1,28 +1,28 @@
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]] [[package]]
name = "ansible" name = "ansible"
version = "11.1.0" version = "10.5.0"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.11" python-versions = ">=3.10"
files = [ files = [
{file = "ansible-11.1.0-py3-none-any.whl", hash = "sha256:bbaf7073993f019fc0293fc8b76c7b215081831957c28eb020f12c270a16e8f0"}, {file = "ansible-10.5.0-py3-none-any.whl", hash = "sha256:1d10bddba58f1edd0fe0b8e0387e0fafc519535066bb3c919c33b6ea3ec32a0f"},
{file = "ansible-11.1.0.tar.gz", hash = "sha256:d01b425990d960d2a33fc378e1b73dbca1c0e28bc22f4056ab6b3c8e9ae74fba"}, {file = "ansible-10.5.0.tar.gz", hash = "sha256:ba2045031a7d60c203b6e5fe1f8eaddd53ae076f7ada910e636494384135face"},
] ]
[package.dependencies] [package.dependencies]
ansible-core = ">=2.18.1,<2.19.0" ansible-core = ">=2.17.5,<2.18.0"
[[package]] [[package]]
name = "ansible-core" name = "ansible-core"
version = "2.18.1" version = "2.17.5"
description = "Radically simple IT automation" description = "Radically simple IT automation"
optional = false optional = false
python-versions = ">=3.11" python-versions = ">=3.10"
files = [ files = [
{file = "ansible_core-2.18.1-py3-none-any.whl", hash = "sha256:4a312e416e09c7271188d6b8e2b1062fc6834fefd6a1814d0e02fb8aadb3e1ba"}, {file = "ansible_core-2.17.5-py3-none-any.whl", hash = "sha256:10f165b475cf2bc8d886e532cadb32c52ee6a533649793101d3166bca9bd3ea3"},
{file = "ansible_core-2.18.1.tar.gz", hash = "sha256:14cac1f92bbdae881cb0616eddeb17925e8cb507e486087975e724533d9de74f"}, {file = "ansible_core-2.17.5.tar.gz", hash = "sha256:ae7f51fd13dc9d57c9bcd43ef23f9c255ca8f18f4b5c0011a4f9b724d92c5a8e"},
] ]
[package.dependencies] [package.dependencies]
@@ -52,19 +52,19 @@ release = ["twine"]
[[package]] [[package]]
name = "attrs" name = "attrs"
version = "24.3.0" version = "24.2.0"
description = "Classes Without Boilerplate" description = "Classes Without Boilerplate"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.7"
files = [ files = [
{file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
{file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
] ]
[package.extras] [package.extras]
benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
@@ -150,51 +150,51 @@ pycparser = "*"
[[package]] [[package]]
name = "cryptography" name = "cryptography"
version = "44.0.0" version = "43.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.9.0,!=3.9.1,>=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"},
{file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"},
{file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"},
{file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"},
{file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"},
{file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"},
{file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"},
{file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"},
{file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"},
{file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"},
{file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"},
{file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"},
{file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"},
{file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"},
] ]
[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 (>=3.0.0)"] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"]
nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] nox = ["nox"]
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] pep8test = ["check-sdist", "click", "mypy", "ruff"]
sdist = ["build (>=1.0.0)"] sdist = ["build"]
ssh = ["bcrypt (>=3.1.5)"] ssh = ["bcrypt (>=3.1.5)"]
test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
test-randomorder = ["pytest-randomly"] test-randomorder = ["pytest-randomly"]
[[package]] [[package]]
@@ -216,13 +216,13 @@ dev = ["flake8", "pytest"]
[[package]] [[package]]
name = "jinja2" name = "jinja2"
version = "3.1.5" version = "3.1.4"
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"
files = [ files = [
{file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
{file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
] ]
[package.dependencies] [package.dependencies]
@@ -233,72 +233,72 @@ i18n = ["Babel (>=2.7)"]
[[package]] [[package]]
name = "markupsafe" name = "markupsafe"
version = "3.0.2" version = "3.0.1"
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.9" python-versions = ">=3.9"
files = [ files = [
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"},
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"},
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"},
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"},
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"},
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"},
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"},
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"},
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"},
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"},
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"},
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"},
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"},
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"},
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"},
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"},
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"},
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"},
] ]
[[package]] [[package]]
@@ -317,13 +317,13 @@ nicer-shell = ["ipython"]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "24.2" version = "24.1"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
] ]
[[package]] [[package]]
@@ -418,25 +418,25 @@ test = ["commentjson", "packaging", "pytest"]
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "75.7.0" version = "75.1.0"
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.9" python-versions = ">=3.8"
files = [ files = [
{file = "setuptools-75.7.0-py3-none-any.whl", hash = "sha256:84fb203f278ebcf5cd08f97d3fb96d3fbed4b629d500b29ad60d11e00769b183"}, {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"},
{file = "setuptools-75.7.0.tar.gz", hash = "sha256:886ff7b16cd342f1d1defc16fc98c9ce3fde69e087a4e1983d7ab634e5f41f4f"}, {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"},
] ]
[package.extras] [package.extras]
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.5.2)"]
core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] core = ["importlib-metadata (>=6)", "importlib-resources (>=5.10.2)", "jaraco.collections", "jaraco.functools", "jaraco.text (>=3.7)", "more-itertools", "more-itertools (>=8.8)", "packaging", "packaging (>=24)", "platformdirs (>=2.6.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"]
cover = ["pytest-cov"] 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)"] 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)"] enabler = ["pytest-enabler (>=2.2)"]
test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.11.*)", "pytest-mypy"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.11" python-versions = "^3.10"
content-hash = "7c5b28e1b7fc5cf1c55fedf89a01f26e9246b9d1baa1441d51a8693697b6767a" content-hash = "334448cb0c7d192f0e10987a995ecefca5e136733cce4dd15dcc2238f1c371c8"

View File

@@ -6,8 +6,8 @@ authors = ["Iurii Tatishchev <itatishch@gmail.com>"]
readme = "README.md" readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.11" python = "^3.10"
ansible = "^11.1.0" ansible = "^10.1.0"
ansible-vault = "^2.1.0" ansible-vault = "^2.1.0"
netaddr = "^1.3.0" netaddr = "^1.3.0"

View File

@@ -11,7 +11,7 @@
path: "{{ current_stack_dest }}/{{ item.path }}" path: "{{ current_stack_dest }}/{{ item.path }}"
state: directory state: directory
mode: "755" mode: "755"
loop: "{{ query('community.general.filetree', current_stack_source) }}" loop: "{{ lookup('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
@@ -19,7 +19,7 @@
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: "644" mode: "644"
loop: "{{ query('community.general.filetree', current_stack_source) }}" loop: "{{ lookup('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and item.path | regex_search('\\.j2$') when: item.state == "file" and item.path | regex_search('\\.j2$')
- name: Generate {{ current_stack_name }} deployment from static files - name: Generate {{ current_stack_name }} deployment from static files
@@ -27,7 +27,7 @@
src: "{{ item.src }}" src: "{{ item.src }}"
dest: "{{ current_stack_dest }}/{{ item.path }}" dest: "{{ current_stack_dest }}/{{ item.path }}"
mode: "644" mode: "644"
loop: "{{ query('community.general.filetree', current_stack_source) }}" loop: "{{ lookup('community.general.filetree', current_stack_source) }}"
when: item.state == "file" and not item.path | regex_search('\\.j2$') 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 }}

View File

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

View File

@@ -2,6 +2,8 @@
networks: networks:
{{ helpers.default_network(249) | indent(2) }} {{ helpers.default_network(249) | indent(2) }}
traefik_traefik:
external: true
services: services:
gluetun: gluetun:
@@ -9,13 +11,14 @@ 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
@@ -46,6 +49,9 @@ 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
@@ -57,6 +63,9 @@ 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
@@ -70,6 +79,9 @@ 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

@@ -2,6 +2,8 @@
networks: networks:
{{ helpers.default_network(199) | indent(2) }} {{ helpers.default_network(199) | indent(2) }}
traefik_traefik:
external: true
services: services:
server: server:
@@ -12,6 +14,9 @@ services:
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:
@@ -22,5 +27,7 @@ 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,6 +2,8 @@
networks: networks:
{{ helpers.default_network(197) | indent(2) }} {{ helpers.default_network(197) | indent(2) }}
traefik_traefik:
external: true
services: services:
jellyfin: jellyfin:
@@ -12,6 +14,9 @@ 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 +1 @@
NEXTCLOUD_VERSION=30-apache NEXTCLOUD_VERSION=29-apache

View File

@@ -2,6 +2,9 @@
networks: networks:
{{ helpers.default_network(198) | indent(2) }} {{ helpers.default_network(198) | indent(2) }}
traefik_traefik:
external: true
services: services:
app: app:
@@ -15,6 +18,8 @@ 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
@@ -27,6 +32,8 @@ services:
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
@@ -35,8 +42,16 @@ services:
notify_push: notify_push:
image: nextcloud:${NEXTCLOUD_VERSION} image: nextcloud:${NEXTCLOUD_VERSION}
container_name: nextcloud_notify_push container_name: nextcloud_notify_push
{# TODO: Refactor this and minio -#}
labels: labels:
- {{ helpers.traefik_labels('nc', port='7867', path_prefix='/push') | indent(6) }} - traefik.enable=true
- 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:
@@ -53,6 +68,8 @@ 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
@@ -62,6 +79,8 @@ 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

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

View File

@@ -1,31 +0,0 @@
{% 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

@@ -1,29 +0,0 @@
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

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

View File

@@ -1,16 +0,0 @@
{% 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

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

View File

@@ -1,225 +0,0 @@
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

@@ -1,45 +0,0 @@
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

@@ -1,79 +0,0 @@
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,94 +5,46 @@ 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_uri": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback", "redirect_uris": "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_uri": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik", "redirect_uris": "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 }} id: {{ app | lower }}
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
client_id: {{ app | lower }} issuer_mode: per_provider
client_secret: {{ apps[app]["client_secret"] }} sub_mode: hashed_user_id
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]]
{% if app == "Minio" -%} redirect_uris: {{ apps[app]["redirect_uris"] }}
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, minio]] refresh_token_validity: days=30
{%- 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-{{ app }} id: {{ app | lower }}
attrs: attrs:
name: {{ app }} name: {{ app }}
group: "{{ apps[app]["ui_group"] }}" group: "Apps"
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
provider: !KeyOf {{ app }} policy_engine_mode: any
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,47 +4,61 @@ metadata:
blueprints.goauthentik.io/instantiate: "true" blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Proxied Apps name: Alpina - Proxied Apps
entries: entries:
# TODO: Possibly refactor this into a jinja macro (?) - identifiers:
name: arrstack
model: authentik_core.group
id: arrstack
attrs:
arrstack_username: "arr"
arrstack_password: "{{ arrstack_password }}"
# TODO: Probably refactor this into a jinja macro
{% 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$",
"ui_group": "Services", "group": "Services",
"allowed_for_groups": ["admins"], "create_admin_group": true,
}, },
"qBit": { "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$",
"ui_group": "Arrstack", "group": "Arrstack",
"allowed_for_groups": ["arrstack"], "create_admin_group": false,
}, },
"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$",
"ui_group": "Arrstack", "group": "Arrstack",
"allowed_for_groups": ["arrstack"], "create_admin_group": false,
}, },
"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$",
"ui_group": "Arrstack", "group": "Arrstack",
"allowed_for_groups": ["arrstack"], "create_admin_group": false,
}, },
"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$",
"ui_group": "Arrstack", "group": "Arrstack",
"allowed_for_groups": ["arrstack"], "create_admin_group": false,
}, },
} -%} } -%}
{% for app in apps.keys() -%} {% for app in apps.keys() -%}
- identifiers: - identifiers:
name: {{ app }} name: {{ apps[app]["name"] }}
model: authentik_providers_proxy.proxyprovider model: authentik_providers_proxy.proxyprovider
id: {{ app }} id: {{ app }}
attrs: attrs:
@@ -54,26 +68,39 @@ entries:
skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}" skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}"
- identifiers: - identifiers:
slug: {{ app | lower | replace(" ", "-") }} slug: {{ app }}
model: authentik_core.application model: authentik_core.application
id: app-{{ app }}
attrs: attrs:
name: {{ app }} name: {{ apps[app]["name"] }}
group: {{ apps[app]["ui_group"] }} group: {{ apps[app]["group"] }}
meta_description: "Hello, I'm {{ app }}!" meta_description: "Hello, I'm {{ apps[app]["name"] }}!"
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 }}
{% for group in apps[app]["allowed_for_groups"] -%} {% if apps[app]["create_admin_group"] -%}
- identifiers: - identifiers:
group: !Find [authentik_core.group, [name, {{ group }}]] name: "{{ apps[app]["name"] }} Admins"
target: !KeyOf app-{{ app }} model: authentik_core.group
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: 10 order: 0
{% endfor %} {% endif %}
{% if apps[app]["group"] == "Arrstack" -%}
- identifiers:
group: !KeyOf arrstack
target: !Find [authentik_core.application, [slug, {{ app }}]]
model: authentik_policies.policybinding
attrs:
order: 0
{% endif %}
{% endfor %} {% endfor %}

View File

@@ -48,8 +48,7 @@ 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-auth]] - !Find [authentik_sources_oauth.oauthsource, [slug, github]]
- !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

@@ -0,0 +1,25 @@
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

@@ -0,0 +1,56 @@
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,6 +2,8 @@
networks: networks:
{{ helpers.default_network(253) | indent(2) }} {{ helpers.default_network(253) | indent(2) }}
traefik_traefik:
external: true
services: services:
server: server:
@@ -15,11 +17,13 @@ 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:
- "127.0.0.1:9000:9000" - "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,16 +5,11 @@ 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 }}
# https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html #MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration #MINIO_IDENTITY_OPENID_CLIENT_ID=
MINIO_IDENTITY_OPENID_CLIENT_ID=minio #MINIO_IDENTITY_OPENID_CLIENT_SECRET=
MINIO_IDENTITY_OPENID_CLIENT_SECRET={{ auth_minio_client_secret }} #MINIO_IDENTITY_OPENID_CLAIM_NAME=
# defaults to "policy" #MINIO_IDENTITY_OPENID_CLAIM_PREFIX=
#MINIO_IDENTITY_OPENID_CLAIM_NAME=policy #MINIO_IDENTITY_OPENID_SCOPES=
MINIO_IDENTITY_OPENID_DISPLAY_NAME=Authentik #MINIO_IDENTITY_OPENID_REDIRECT_URI=
# 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

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

View File

@@ -0,0 +1,32 @@
{% 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 @@
DISCORD_WEBHOOK={{ alertmanager_discord_webhook }}

View File

@@ -4,10 +4,6 @@ RUN pip install grafanalib
COPY ./grafana_config/dashboards /dashboards 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 RUN generate-dashboards /dashboards/*.dashboard.py
FROM grafana/grafana:latest FROM grafana/grafana:latest

View File

@@ -0,0 +1,68 @@
# The root route on which each incoming alert enters.
route:
group_by: ["alertname", "job"]
group_wait: 20s
group_interval: 5m
repeat_interval: 3h
receiver: discord_webhook
receivers:
- name: "discord_webhook"
discord_configs:
- webhook_url: "{{ alertmanager_discord_webhook }}"
{# - send_resolved: true#}
{# username: 'Alertmanager'#}
{# webhook_configs:#}
{# - send_resolved: true#}
{# url: '{{ alertmanager_discord_webhook }}'#}
{# username: 'Alertmanager'#}
{# icon_url: 'https://prometheus.io/assets/icon.png'#}
{# icon_emoji: ':alert:'#}
{# send_resolved: true#}
{# text: "{{ .CommonAnnotations.summary }}"#}
{# title: "{{ .CommonLabels.alertname }}"#}
{# color: '{{ if eq .Status "firing" }}#FF0000{{ else }}#00FF00{{ end }}'#}
{# footer: '{{ .CommonLabels.monitor }}'#}
{# footer_icon: 'https://prometheus.io/assets/icon.png'#}
{# actions:#}
{# - type: 'button'#}
{# text: 'Open in Grafana'#}
{# url: '{{ .ExternalURL }}'#}
{# style: 'primary'#}
{# send_resolved: true#}
{# confirm:#}
{# title: 'Are you sure?'#}
{# text: 'This will open Grafana in a new tab.'#}
{# ok_text: 'Yes'#}
{# dismiss_text: 'No'#}
{# fields:#}
{# - title: 'Description'#}
{# value: "{{ .CommonAnnotations.description }}"#}
{# short: false#}
{# - title: 'Details'#}
{# value: "{{ .CommonAnnotations.details }}"#}
{# short: false#}
{# - title: 'Severity'#}
{# value: '{{ if eq .Labels.severity "critical" }}Critical{{ else if eq .Labels.severity "warning" }}Warning{{ else }}Info{{ end }}'#}
{# short: true#}
{# - title: 'Host'#}
{# value: '{{ .CommonLabels.monitor }}'#}
{# short: true#}
{# - title: 'Starts At'#}
{# value: '{{ .StartsAt.Format "2006-01-02 15:04:05" }}'#}
{# short: true#}
{# - title: 'Ends At'#}
{# value: '{{ .EndsAt.Format "2006-01-02 15:04:05" }}'#}
{# short: true#}
{# - title: 'Runbook'#}
{# value: '{{ .CommonAnnotations.runbook_url }}'#}
{# short: true#}
{# - title: 'Dashboard'#}
{# value: '{{ .CommonAnnotations.dashboard_url }}'#}
{# short: true#}
{# - title: 'Alerting Rule'#}
{# value: '{{ .CommonLabels.alertname }}'#}
{# short: true#}
{# - title: 'Alerting Rule Description'#}
{# value: '{{ .CommonLabels.alertname }}'#}
{# short: true#}

View File

@@ -2,6 +2,8 @@
networks: networks:
{{ helpers.default_network(251) | indent(2) }} {{ helpers.default_network(251) | indent(2) }}
traefik_traefik:
external: true
services: services:
grafana: grafana:
@@ -15,6 +17,9 @@ services:
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable (not anymore, TODO: remove) # 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/grafana.ini:/etc/grafana/grafana.ini:ro - ./grafana_config/grafana.ini:/etc/grafana/grafana.ini:ro
@@ -31,8 +36,7 @@ services:
- -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:
- "127.0.0.1:3100:3100" - 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
@@ -56,17 +60,33 @@ services:
prometheus: prometheus:
image: prom/prometheus:latest image: prom/prometheus:latest
container_name: prometheus container_name: prometheus
labels:
- {{ helpers.traefik_labels('prom', port='9090') | indent(6) }}
restart: unless-stopped restart: unless-stopped
# Needed to make config files readable (not anymore, TODO: remove) # 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
- --storage.tsdb.retention.time=30d - --storage.tsdb.retention.time=30d
- --web.external-url=https://prom.{{ domain }}/
volumes: volumes:
- ./prometheus_config:/etc/prometheus:ro - ./prometheus_config:/etc/prometheus:ro
- {{ base_volume_path }}/monitoring/prometheus_configs:/etc/prometheus/extra:ro - {{ base_volume_path }}/monitoring/prometheus_configs:/etc/prometheus/extra:ro
- {{ base_volume_path }}/monitoring/prometheus:/prometheus - {{ base_volume_path }}/monitoring/prometheus:/prometheus
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
labels:
- {{ helpers.traefik_labels('alert', port='9093') | indent(6) }}
restart: unless-stopped
command:
- --config.file=/etc/alertmanager/alertmanager.yml
- --web.external-url=https://alert.{{ domain }}/
volumes:
- ./alertmanager_config:/etc/alertmanager:ro
- {{ base_volume_path }}/monitoring/alertmanager:/alertmanager
node-exporter: node-exporter:
image: prom/node-exporter:latest image: prom/node-exporter:latest
container_name: node-exporter container_name: node-exporter
@@ -80,11 +100,6 @@ 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
@@ -99,6 +114,9 @@ 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

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

View File

@@ -1,81 +0,0 @@
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

@@ -1,20 +1,32 @@
from grafanalib.core import GridPos, Templating, Template, Logs from grafanalib.core import (
Dashboard, TimeSeries,
Target, GridPos,
Templating, Template, REFRESH_ON_TIME_RANGE_CHANGE, Logs
)
from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC 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='prometheus'
prom_datasource, PromTarget loki_datasource='loki'
dashboard = MyDashboard( # TODO: this is (clown emoji), normal Target gave me errors in grafana
class LokiTarget(object):
def to_json_data(self):
return {
'datasource': loki_datasource,
'expr': '{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
'legendFormat': '{{ container_name }}',
'refId': 'A',
'queryType': 'range',
}
dashboard = Dashboard(
title='Containers', title='Containers',
uid='containers', uid='containers',
description='Data for compose projects from default Prometheus datasource collected by Cadvisor', description='Data for compose projects from default Prometheus datasource collected by Cadvisor',
tags=[ tags=[
'linux', 'example'
'docker',
], ],
templating=Templating(list=filter_none([ templating=Templating(list=[
prom_template,
loki_template if CONF_SUPPORT_LOKI else None,
Template( Template(
name='compose_project', name='compose_project',
label='Compose Project', label='Compose Project',
@@ -22,6 +34,7 @@ dashboard = MyDashboard(
query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)', query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)',
includeAll=True, includeAll=True,
multi=True, multi=True,
refresh=REFRESH_ON_TIME_RANGE_CHANGE,
), ),
Template( Template(
name='container_name', name='container_name',
@@ -30,6 +43,8 @@ dashboard = MyDashboard(
query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)', query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)',
includeAll=True, includeAll=True,
multi=True, multi=True,
refresh=REFRESH_ON_TIME_RANGE_CHANGE,
), ),
Template( Template(
name='logs_query', name='logs_query',
@@ -37,52 +52,73 @@ dashboard = MyDashboard(
query='', query='',
type='textbox', type='textbox',
), ),
])), ]),
panels=filter_none([ timezone='browser',
MyTimeSeries( panels=[
TimeSeries(
id=1,
title='Container Memory Usage', title='Container Memory Usage',
unit=BYTES_IEC, unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=0), gridPos=GridPos(h=8, w=12, x=0, y=0),
tooltipSort='desc', lineWidth=2,
fillOpacity=10,
showPoints='never',
stacking={'mode': 'normal'}, stacking={'mode': 'normal'},
tooltipMode='all',
tooltipSort='desc',
targets=[ targets=[
PromTarget( Target(
datasource=prom_datasource,
expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})', expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})',
legendFormat='{{ name }}', legendFormat='{{ name }}',
refId='A',
), ),
], ],
), ),
MyTimeSeries( TimeSeries(
id=2,
title='Container CPU Usage', title='Container CPU Usage',
unit=SECONDS, unit=SECONDS,
gridPos=GridPos(h=8, w=12, x=12, y=0), gridPos=GridPos(h=8, w=12, x=12, y=0),
tooltipSort='desc', lineWidth=2,
stacking={'mode': 'normal'}, fillOpacity=10,
showPoints='never',
targets=[ targets=[
PromTarget( Target(
expr='max by (name) (irate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))', datasource=prom_datasource,
expr='max by (name) (rate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat='{{ name }}', legendFormat='{{ name }}',
refId='A',
), ),
], ],
), ),
MyTimeSeries( TimeSeries(
id=3,
title='Container Network Traffic', title='Container Network Traffic',
unit=BYTES_SEC_IEC, unit=BYTES_SEC_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=8), gridPos=GridPos(h=8, w=12, x=0, y=8),
lineWidth=2,
fillOpacity=10,
showPoints='never',
tooltipMode='all',
tooltipSort='desc', tooltipSort='desc',
axisCenteredZero=True,
targets=[ targets=[
PromTarget( Target(
expr='max by (name) (irate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))', datasource=prom_datasource,
expr='max by (name) (rate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="rx {{ name }}", legendFormat="rx {{ name }}",
refId='A',
), ),
PromTarget( Target(
expr='-max by (name) (irate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))', datasource=prom_datasource,
expr='-max by (name) (rate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
legendFormat="tx {{ name }}", legendFormat="tx {{ name }}",
refId='B',
), ),
], ],
), ),
Logs( Logs(
id=4,
title='', title='',
gridPos=GridPos(h=8, w=12, x=12, y=8), gridPos=GridPos(h=8, w=12, x=12, y=8),
showLabels=True, showLabels=True,
@@ -91,11 +127,14 @@ dashboard = MyDashboard(
prettifyLogMessage=True, prettifyLogMessage=True,
dedupStrategy='numbers', dedupStrategy='numbers',
targets=[ targets=[
LokiTarget( LokiTarget(),
expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`', # Target(
legendFormat='{{ container_name }}', # datasource=loki_datasource,
), # expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
# legendFormat='{{ container_name }}',
# refId='A',
# ),
], ],
) if CONF_SUPPORT_LOKI else None, ),
]), ],
).auto_panel_ids() ).auto_panel_ids()

View File

@@ -0,0 +1,51 @@
from grafanalib.core import (
Dashboard, TimeSeries, GaugePanel,
Target, GridPos,
OPS_FORMAT
)
dashboard = Dashboard(
title="Python generated example dashboard",
description="Example dashboard using the Random Walk and default Prometheus datasource",
tags=[
'example'
],
timezone="browser",
panels=[
TimeSeries(
title="Random Walk",
dataSource='default',
targets=[
Target(
datasource='grafana',
expr='example',
),
],
gridPos=GridPos(h=8, w=16, x=0, y=0),
),
GaugePanel(
title="Random Walk",
dataSource='default',
targets=[
Target(
datasource='grafana',
expr='example',
),
],
gridPos=GridPos(h=4, w=4, x=17, y=0),
),
TimeSeries(
title="Prometheus http requests",
dataSource='prometheus',
targets=[
Target(
expr='rate(prometheus_http_requests_total[5m])',
legendFormat="{{ handler }}",
refId='A',
),
],
unit=OPS_FORMAT,
gridPos=GridPos(h=8, w=16, x=0, y=10),
),
],
).auto_panel_ids()

View File

@@ -1,159 +0,0 @@
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

@@ -15,6 +15,18 @@ datasources:
url: http://prometheus:9090 url: http://prometheus:9090
editable: false editable: false
- name: Alertmanager
type: alertmanager
access: proxy
uid: alertmanager
url: http://alertmanager:9093
jsonData:
# Valid options for implementation include mimir, cortex and prometheus
implementation: prometheus
# Whether Grafana should send alert instances to this Alertmanager
handleGrafanaManagedAlerts: true
editable: false
- name: InfluxDB - name: InfluxDB
type: influxdb type: influxdb
access: proxy access: proxy

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[*], 'admins') && 'GrafanaAdmin' || 'Viewer' role_attribute_path = contains(groups[*], 'Grafana Admins') && 'GrafanaAdmin' || 'Viewer'

View File

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

View File

@@ -0,0 +1,23 @@
groups:
- name: qbit-low-traffic
interval: 1m
rules:
- alert: QbitLowTraffic
expr: |
rate(container_network_transmit_bytes_total{name=~"gluetun"}[1m]) < 1024
for: 2m
labels:
severity: warning
annotations:
title: 'Low traffic on qBit'
description: |
The traffic on qBittorrent is lower than 1KiB/s for 2 minutes.
Last value was x bytes/s.
[Grafana Dashboard](https://grafana.{{ domain }}/d/containers?orgId=1)
[View in Grafana](https://grafana.{{ domain }}/d/containers?orgId=1&viewPanel=3)
__dashboard__uid: 'containers'
__orgId__: 1
__panelId__: 3

View File

@@ -0,0 +1,20 @@
groups:
- name: demo-service-alerts
rules:
- alert: DemoServiceHighErrorRate
expr: |
(
sum without(status, instance) (
rate(demo_api_request_duration_seconds_count{status=~"5..",job="demo"}[1m])
)
/
sum without(status, instance) (
rate(demo_api_request_duration_seconds_count{job="demo"}[1m])
) * 100 > 0.5
)
for: 1m
labels:
severity: critical
annotations:
title: 'High 5xx rate for {{'{{ $labels.method }}'}} on {{'{{ $labels.path }}'}}'
description: 'The 5xx error rate for path {{'{{ $labels.path }}'}} with method {{'{{ $labels.method }}'}} in {{'{{ $labels.job }}'}} is {{'{{ printf "%.2f" $value }}'}}%.'

View File

@@ -5,6 +5,11 @@ global:
external_labels: external_labels:
monitor: "{{ ansible_host }}" monitor: "{{ ansible_host }}"
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs: scrape_configs:
- job_name: "prometheus" - job_name: "prometheus"
static_configs: static_configs:
@@ -30,7 +35,15 @@ scrape_configs:
static_configs: static_configs:
- targets: ["promtail:9080"] - targets: ["promtail:9080"]
- job_name: 'demo'
static_configs:
- targets:
- 'demo.promlabs.com:10000'
- 'demo.promlabs.com:10001'
- 'demo.promlabs.com:10002'
rule_files: rule_files:
- "/etc/prometheus/container.alerts.yml"
- "/etc/prometheus/extra/rules/*.yml" - "/etc/prometheus/extra/rules/*.yml"
- "/etc/prometheus/extra/rules/*.json" - "/etc/prometheus/extra/rules/*.json"

View File

@@ -1,11 +1,18 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %} {% import 'contrib/compose_helpers.j2' as helpers with context %}
networks: networks:
{{ helpers.default_network(254) | indent(2) }} traefik:
internal: true
enable_ipv6: true
ipam:
config:
# TODO: Consider removing traefik network, it shouldn't be needed with host networking
- subnet: {{ traefik_subnet }}/24
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, 255) }}
services: services:
traefik: traefik:
image: traefik:v3.2 image: traefik:v3.0
container_name: traefik container_name: traefik
restart: unless-stopped restart: unless-stopped
env_file: env_file:
@@ -16,10 +23,14 @@ 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,8 +2,11 @@ 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:
@@ -36,6 +39,7 @@ certificatesResolvers:
providers: providers:
docker: docker:
exposedByDefault: false exposedByDefault: false
network: traefik_traefik
file: file:
directory: /rules directory: /rules
watch: true watch: true

View File

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

View File

@@ -64,14 +64,6 @@
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: Reboot if needed - name: Reboot if needed
become: yes become: yes
ansible.builtin.reboot: ansible.builtin.reboot:

View File

@@ -1,5 +1,12 @@
- name: IPv6 subnet for Docker - name: Get IPv6 subnet for Docker
debug: set_fact:
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
@@ -28,6 +35,33 @@
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: true containers: yes
# Keep images for building grafana images: yes
images: true
images_filters: images_filters:
until: "720h" dangling: false
networks: true networks: true
volumes: true volumes: true
builder_cache: false builder_cache: true

View File

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