Compare commits
1 Commits
master
...
feature/zf
| Author | SHA1 | Date | |
|---|---|---|---|
|
9c9bec28a4
|
7
.idea/alpina.iml
generated
7
.idea/alpina.iml
generated
@@ -4,7 +4,7 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Poetry (alpina)" jdkType="Python SDK" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
@@ -23,8 +23,9 @@
|
||||
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||
<option name="TEMPLATE_FOLDERS">
|
||||
<list>
|
||||
<option value="$MODULE_DIR$/roles/docker_host/templates" />
|
||||
<option value="$MODULE_DIR$/roles/alpina/templates" />
|
||||
<option value="$MODULE_DIR$/roles/traefik/templates" />
|
||||
<option value="$MODULE_DIR$/roles/gitea/templates" />
|
||||
<option value="$MODULE_DIR$/roles/nextcloud/templates" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
133
.idea/jsonSchemas.xml
generated
133
.idea/jsonSchemas.xml
generated
@@ -3,58 +3,6 @@
|
||||
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||
<state>
|
||||
<map>
|
||||
<entry key="Ansible Tasks File">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="Ansible Tasks File" />
|
||||
<option name="relativePathToSchema" value="https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/ansible.json#/$defs/tasks" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/tasks/*.yml" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="Authentik Blueprint">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="generatedName" value="New Schema" />
|
||||
<option name="name" value="Authentik Blueprint" />
|
||||
<option name="relativePathToSchema" value="https://goauthentik.io/blueprints/schema.json" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="directory" value="true" />
|
||||
<option name="path" value="roles/alpina/templates/services/authentik/blueprints" />
|
||||
<option name="mappingKind" value="Directory" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="Loki">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="Loki" />
|
||||
<option name="relativePathToSchema" value="https://json.schemastore.org/loki.json" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="path" value="roles/alpina/templates/services/monitoring/loki_config/loki-config.yaml.j2" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="Traefik v2">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
@@ -64,86 +12,7 @@
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/traefik.yml.j2" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="Traefik v2 File Provider">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="generatedName" value="New Schema" />
|
||||
<option name="name" value="Traefik v2 File Provider" />
|
||||
<option name="relativePathToSchema" value="https://json.schemastore.org/traefik-v2-file-provider.json" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="path" value="file://$APPLICATION_CONFIG_DIR$/scratches/scratch.yml" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="path" value="file://$APPLICATION_CONFIG_DIR$/scratches/scratch_1.yml" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="path" value="file:///run/user/1000/kio-fuse-kipURF/sftp/root@debbi.lab.home/mnt/dock/traefik/rules/hello-world.yml" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="path" value="roles/alpina/templates/services/traefik/rules/traefik-dash.yml.j2" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="docker-compose.yml">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="docker-compose.yml" />
|
||||
<option name="relativePathToSchema" value="https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/compose.yml" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/compose.yml.j2" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/docker-compose.yml" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="pattern" value="true" />
|
||||
<option name="path" value="*/docker-compose.yml.j2" />
|
||||
<option name="mappingKind" value="Pattern" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
</SchemaInfo>
|
||||
</value>
|
||||
</entry>
|
||||
<entry key="prometheus.json">
|
||||
<value>
|
||||
<SchemaInfo>
|
||||
<option name="name" value="prometheus.json" />
|
||||
<option name="relativePathToSchema" value="https://json.schemastore.org/prometheus.json" />
|
||||
<option name="applicationDefined" value="true" />
|
||||
<option name="patterns">
|
||||
<list>
|
||||
<Item>
|
||||
<option name="path" value="roles/alpina/collections/services/monitoring/templates/prometheus_config/prometheus.yml.j2" />
|
||||
</Item>
|
||||
<Item>
|
||||
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/prometheus.yml.j2" />
|
||||
<option name="path" value="roles/traefik/templates/traefik.yml.j2" />
|
||||
</Item>
|
||||
</list>
|
||||
</option>
|
||||
|
||||
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Poetry (alpina) (2)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (alpina)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
23
Makefile
23
Makefile
@@ -1,23 +0,0 @@
|
||||
.POSIX:
|
||||
.PHONY: *
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
MAKEFLAGS += -r # no use of built-in rules
|
||||
|
||||
env ?= staging
|
||||
vault_id ?= alpina@contrib/rbw-client.sh
|
||||
|
||||
playbook_cmd := poetry run ansible-playbook --vault-id ${vault_id} -i inventories/${env}
|
||||
|
||||
all: site services
|
||||
|
||||
setup:
|
||||
poetry install --quiet
|
||||
|
||||
site: setup
|
||||
$(playbook_cmd) site.yml
|
||||
|
||||
services: setup
|
||||
$(playbook_cmd) services.yml
|
||||
|
||||
clean: setup
|
||||
$(playbook_cmd) clean.yml
|
||||
75
README.md
75
README.md
@@ -1,75 +0,0 @@
|
||||
# Alpina
|
||||
|
||||
A home for configuring all of my homelab containers on a Debian Linux machine.
|
||||
This assumes a Debian Linux machine with Docker and Docker Compose installed.
|
||||
|
||||
My particular setup is based on a [jailmaker](https://github.com/Jip-Hop/jailmaker) container
|
||||
running on top of TrueNAS SCALE, separating all the docker stuff from the appliance.
|
||||
|
||||
# Notes
|
||||
|
||||
## Monitoring
|
||||
The monitoring stack is set up to monitor all the containers and the host.
|
||||
|
||||
This is a work in progress, Grafana is set up with grafanalib, a Python library that generates Grafana dashboards.
|
||||
The dashboards are generated from Python scripts in
|
||||
[grafana_config/dashboards](roles/alpina/templates/services/monitoring/grafana_config/dashboards).
|
||||
|
||||
This requires a custom grafana image, which is built from the
|
||||
[Dockerfile](roles/alpina/templates/services/monitoring/Dockerfile).
|
||||
|
||||
This also means it has to be manually rebuilt whenever the dashboards are updated.
|
||||
From the services/monitoring directory, run:
|
||||
```bash
|
||||
docker compose up -d --build --force-recreate grafana
|
||||
```
|
||||
|
||||
## IPv6
|
||||
The current configuration is designed to work with IPv6.
|
||||
However, because of how (not properly) I'm doing the subnetting
|
||||
from the host's network, NDP doesn't work.
|
||||
This means that container IPs are not accessible from other hosts on the local network.
|
||||
I simply have a static route on my router to the container subnet,
|
||||
that uses the IP of this host as the gateway.
|
||||
|
||||
This is a limitation of my current ISP, I only have a single /64 subnet for my lab network.
|
||||
I'd like to get a /56 or /48, perhaps using Hurricane Electric's tunnel broker.
|
||||
*Sigh* ISPs being stingy with the 2^48 prefixes they're afraid of running out of.
|
||||
|
||||
## Upgrading Postgres
|
||||
Upgrading the postgres container for a given stack requires a dump and restore.
|
||||
|
||||
After making a snapshot or backup of postgres data directory,
|
||||
in the compose directory for a given stack, run the following commands:
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose up -d <db_service>
|
||||
docker compose exec -it <db_service> pg_dumpall -U <db_user> | tee /tmp/dump.sql
|
||||
docker compose down
|
||||
|
||||
rm -r <postgres_data_dir>/* # as root
|
||||
# Edit the docker-compose.yml file to use the new postgres image
|
||||
docker compose up -d <db_service>
|
||||
# For some reason, compose exec doesn't like the input redirection
|
||||
docker exec -i <db_container_name> psql -U <db_user> < /tmp/dump.sql
|
||||
docker compose up -d
|
||||
rm /tmp/dump.sql
|
||||
```
|
||||
|
||||
Additionally, if upgrading from postgres <= 13, it is necessary to upgrade the
|
||||
password hashes. This can be done by running the following command:
|
||||
```bash
|
||||
docker compose exec -it <db_service> psql -U <db_user> -c "\password"
|
||||
```
|
||||
|
||||
## Nextcloud
|
||||
Nextcloud requires some additional work to set up notify_push.
|
||||
|
||||
- Initially, comment out the notify_push service in the docker compose.
|
||||
- Set up nextcloud and install the Client Push (notify_push) app.
|
||||
- Uncomment the notify_push service in the docker compose and `up -d` the stack.
|
||||
- ```bash
|
||||
docker compose exec app ./occ notify_push:setup https://nc.<domain>/push
|
||||
```
|
||||
|
||||
I should probably get around to automating this at some point.
|
||||
@@ -1,43 +0,0 @@
|
||||
{% macro default_network(subnet_index) %}
|
||||
default:
|
||||
enable_ipv6: true
|
||||
ipam:
|
||||
config:
|
||||
- subnet: {{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, subnet_index) }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro traefik_labels(host, port='', path_prefix='', auth=false, wildcard=false) %}
|
||||
{% set name = host ~ (wildcard * '-*') ~ path_prefix -%}
|
||||
{% set tls_base = domain %}
|
||||
{% if wildcard -%}
|
||||
{% set tls_base = host ~ '.' ~ domain %}
|
||||
{%- endif -%}
|
||||
|
||||
traefik.enable=true
|
||||
- traefik.http.routers.r-{{ name }}.rule={{ host_rule(host, path_prefix, wildcard) }}
|
||||
- traefik.http.routers.r-{{ name }}.entrypoints=websecure
|
||||
- traefik.http.routers.r-{{ name }}.tls=true
|
||||
- traefik.http.routers.r-{{ name }}.tls.certresolver=letsencrypt
|
||||
- traefik.http.routers.r-{{ name }}.tls.domains.0.main={{ tls_base }}
|
||||
- traefik.http.routers.r-{{ name }}.tls.domains.0.sans=*.{{ tls_base }}
|
||||
{% if port -%}
|
||||
- traefik.http.routers.r-{{ name }}.service=svc-{{ name }}
|
||||
- traefik.http.services.svc-{{ name }}.loadbalancer.server.port={{ port }}
|
||||
{% endif %}
|
||||
{% if auth -%}
|
||||
- traefik.http.routers.r-{{ name }}.middlewares=authentik@docker
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro host_rule(host, path_prefix="", wildcard=false) %}
|
||||
{% if wildcard %}
|
||||
{# regular a.host prevents warnings from 'No domain found in rule HostRegexp' #}
|
||||
{# TODO: figure out this stupidity properly #}
|
||||
Host(`a.{{ host }}.{{ domain }}`) || HostRegexp(`^.+\.{{ host }}\.{{ domain | replace('.', '\.') }}$`)
|
||||
{%- else %}
|
||||
Host(`{{ host }}.{{ domain }}`)
|
||||
{%- endif %}
|
||||
{% if path_prefix -%}
|
||||
&& PathPrefix(`{{ path_prefix }}`)
|
||||
{%- endif %}
|
||||
{% endmacro %}
|
||||
@@ -1,81 +0,0 @@
|
||||
# Shared variables between environments
|
||||
|
||||
---
|
||||
alpina_svc_path: ~/alpina
|
||||
base_volume_path: /mnt/dock
|
||||
media_volume_path: /mnt/media
|
||||
|
||||
docker_ipv6_subnet: "{{ \
|
||||
ansible_facts['default_ipv6'].address \
|
||||
| ansible.utils.ipsubnet(64) \
|
||||
| ansible.utils.ipsubnet(72, docker_ipv6_index) \
|
||||
}}"
|
||||
|
||||
# Authentik
|
||||
authentik_db_password: "{{ vault_authentik_db_password }}"
|
||||
authentik_secret_key: "{{ vault_authentik_secret_key }}"
|
||||
authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}"
|
||||
|
||||
auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}"
|
||||
auth_minio_client_secret: "{{ vault_auth_minio_client_secret }}"
|
||||
auth_gitea_client_secret: "{{ vault_auth_gitea_client_secret }}"
|
||||
auth_nextcloud_client_secret: "{{ vault_auth_nextcloud_client_secret }}"
|
||||
arrstack_password: "{{ vault_arrstack_password }}"
|
||||
auth_vpgen_client_secret: "{{ vault_auth_vpgen_client_secret }}"
|
||||
auth_pgrok_client_secret: "{{ vault_auth_pgrok_client_secret }}"
|
||||
|
||||
auth_default_enrollment_group: vpgen
|
||||
|
||||
# Minio
|
||||
minio_password: "{{ vault_minio_password }}"
|
||||
|
||||
# Monitoring
|
||||
influxdb_admin_password: "{{ vault_influxdb_admin_password }}"
|
||||
influxdb_admin_token: "{{ vault_influxdb_admin_token }}"
|
||||
|
||||
# Traefik
|
||||
acme_email: "{{ vault_acme_email }}"
|
||||
cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
|
||||
|
||||
# Arrstack
|
||||
wg_peer_pubkey: "{{ vault_wg_peer_pubkey }}"
|
||||
vpn_server_names: "{{ vault_vpn_server_names }}"
|
||||
|
||||
# Gitea
|
||||
gitea_db_password: "{{ vault_gitea_db_password }}"
|
||||
gitea_sendgrid_api_key: "{{ vault_gitea_sendgrid_api_key }}"
|
||||
## Security
|
||||
secret_key: "{{ vault_secret_key }}"
|
||||
internal_token: "{{ vault_internal_token }}"
|
||||
jwt_secret: "{{ vault_jwt_secret }}"
|
||||
|
||||
# Jellyfin
|
||||
|
||||
# Nextcloud
|
||||
nextcloud_db_password: "{{ vault_nextcloud_db_password }}"
|
||||
redis_password: "{{ vault_redis_password }}"
|
||||
nextcloud_sendgrid_api_key: "{{ vault_nextcloud_sendgrid_api_key }}"
|
||||
|
||||
# VPGen
|
||||
vpgen_auth_invite_token: "{{ vault_vpgen_auth_invite_token }}"
|
||||
|
||||
vpgen_opnsense_api_url: https://opnsense.cazzzer.com
|
||||
vpgen_opnsense_api_key: "{{ vault_vpgen_opnsense_api_key }}"
|
||||
vpgen_opnsense_api_secret: "{{ vault_vpgen_opnsense_api_secret }}"
|
||||
vpgen_opnsense_wg_ifname: wg2
|
||||
|
||||
vpgen_ipv6_client_prefix_size: 112
|
||||
vpgen_ip_max_index: 100
|
||||
vpgen_vpn_endpoint: "{{ vault_vpgen_vpn_endpoint }}"
|
||||
vpgen_vpn_dns: "{{ vault_vpgen_vpn_dns }}"
|
||||
vpgen_max_clients_per_user: 20
|
||||
|
||||
# Woodpecker
|
||||
woodpecker_agent_secret: "{{ vault_woopecker_agent_secret }}"
|
||||
|
||||
# Pgrok
|
||||
pgrok_db_password: "{{ vault_pgrok_db_password }}"
|
||||
|
||||
# Minecruft
|
||||
|
||||
minecruft_cf_api_key: "{{ vault_minecruft_cf_api_key }}"
|
||||
@@ -1,165 +0,0 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
31623438643264373065653633306538336133623864643438653630353265376138613361393466
|
||||
3464643166633332666230353734333363623030646564310a313134336539343436626234626364
|
||||
62336366323433346165373666656466616434613565323632353033323161363533356133613732
|
||||
3464353362333362350a633937313036336438393462396538613764636337386166613861613439
|
||||
39656466383833646236383062396130306563633861396234383462306331663136396331333433
|
||||
37303737626533666530393632616130313734653331353364616135633664343035303631343266
|
||||
65356133376438393639643931636561616434333637393264343832613035653034363863653233
|
||||
35313035303731316431313634643638666339396139333565663464633131393266333036316437
|
||||
32363661303534306535326130313139366466393634373762393165393735613563396230636538
|
||||
37623665373538633237373235396430333539343232363931656463363866363539326464613337
|
||||
65303932396666383235616162333564626231656361353133326333663039303331613433613030
|
||||
38353366393466343334656130306131626330613934313865343039616462363137336238303262
|
||||
64393931353466643466373331396536386231363233396339326637643662613438376666386661
|
||||
34346530346533643364636665313633633635656564333436346531623564646534646566623135
|
||||
30613036616662643461623561623837386538633231383736376462363836313538393036356164
|
||||
61323664666663313838313033336664363062646562336561663138393635626134613036623332
|
||||
39396137306531366464643862376238643238336230626533653033376361653839323962373162
|
||||
65373463643235626463316362356161323737623335633832353663613661636436626632313634
|
||||
39333033393861306333356335623439653432626336376133646432633332393639323230306435
|
||||
66376631313033643336373430616638393366313538316239386430393064613430666330363233
|
||||
39343234663635623764646332666634346437333264636339616431666330313138623734326364
|
||||
34336335353763396238353633333837616534303537303565323264383963616362643761363332
|
||||
61326566656337373437353236363865376661376462346430626639623561326435613131626330
|
||||
64643361323533633462313330333536343739393461616264653737626432343362393232613166
|
||||
35376631666537373765343035616333323663376363613563336366623235643536356134353434
|
||||
63363337366461623762653964396534336530373134333364633037343739393134616230363033
|
||||
66666231346362313561323432376164316439646263333131306335333533353939363763653964
|
||||
36656164623838323638663363336666343766383865393461653435666539663339656239303861
|
||||
65353032623966653239393234646664633132306163323438343436343365353361653638376637
|
||||
34393734316166393234313536656533326337616564663732353735343130646265386635363439
|
||||
33393331656538346563623031623861396437613437663437326134656535633362323039396232
|
||||
35346135633235623933393239373361376535376332666338626538353333303038666239643837
|
||||
30356265313235626330613931323538303362626330333162323062326139353661326536633239
|
||||
38386336613362646465313635613432666436663938353733313365353137333830333362393365
|
||||
66623961336335633365386339643437303933346432376466643562623232336461306231623038
|
||||
63646566636434616364613230316238363563623364643138316135326166613939343464633462
|
||||
36326338343234643338333737313434366461306435643165353030323939333635666435353639
|
||||
32346563353037653231373836656261623162356138393861313463616532653039396138383436
|
||||
38646462636464336564663633333631323731623663383138613231643861323932613466326439
|
||||
31666535313136613632383833323134613639623836653635326336363531363832303633323731
|
||||
61646630353462363932396661613639353538343136653433656132323637313434306136306366
|
||||
66336164643431333564623965623064326139646664383965656636393564366535343365616634
|
||||
31366665396330663864323666386431633439323933306538316231663066323565386132326563
|
||||
64376434333636373362613937323632356261326439653736336331323233653063613661633539
|
||||
39323261363333666461393166353362656630633262373661636535363863323664666438306633
|
||||
61643865323634643063636631366165373230303533323338333832643364663066333131383436
|
||||
32623662373439636164633939623164396666613138623632333532636634303633356638393537
|
||||
31343933313965326238643331653635373430636236656433363039383263366363626565326462
|
||||
30336631656431643262613663376331353631333563623361373231643439646465333261303862
|
||||
36343766323033356536623931306365313363343232343538396561636133643365663933306231
|
||||
31666362313935346336333662643237326137336263633934663663656636663836626364643966
|
||||
34653830356163616636306536303030393634343062623538383239636365373663343463306262
|
||||
62666536393332316365646630636232376165313266353138346536663435313063663466343533
|
||||
35323238323466323663396563636361353833663636383234383533356362626232353632633665
|
||||
31323865303935643765323663383730643462376464626566663562323339613037373761326632
|
||||
33623636353832323735383866366534663561623136633639653232313564383639653833623532
|
||||
32326535306661383433656436633031626235373466383633366663376537306530616438383361
|
||||
65363838663965333831636166316464383964656431383161313838303736656130363132623664
|
||||
32656232363933616532643461353565366438323166323237393434333630633830366562396531
|
||||
35626564306634376364333332326539613839346639336561303038653937306339376161393763
|
||||
30356464646435653237643065643264326630656366656138376566636161323261663366343462
|
||||
62643837336133316262306261363238316533326436343631643031623731353563323836336533
|
||||
66613737306232366339653962613136326430353732373034623130306539366431363864626535
|
||||
38346166613864396434616663393837613466666436613730373466653532663561386533343635
|
||||
37336233383337343266663037333133373036373435303432313265663539343961653665363762
|
||||
64323761376632393638356235316362366630323039323336316262343663343563383839363165
|
||||
38346161303931613832316333353130303637373638636561366134636137376537393538306532
|
||||
66343133616333353664353062613862656439636161653864343734663537663762626539636138
|
||||
32643361623135363539663865643935666263373432656138383966393162656164363734626332
|
||||
61626634643135323262616465393332366235333637393937646531386562313338363431336135
|
||||
30316632326637393431323538376663336136323438636463656639623238353533633336376534
|
||||
32303566643264373861323030303033393939326161613037333162363864653839643966393939
|
||||
34353765653765393336393338663761626663366136303136353932386231346331363961363930
|
||||
39383131366466633365376635636231363639656238613737356630363734646166336432303535
|
||||
34313938663864303730373331643437613636356139363934343261306666326437353737336466
|
||||
30653139656335356133376239386666393166613062303233396330386462633666336532663765
|
||||
36343230663035353638633662343035656639633433363165346539396661646635653562653161
|
||||
31363161346565356164343530363731353935663563643532363535343266623935646663336333
|
||||
35313065663439313535623430333533303964663263643064393331363035376635663964646138
|
||||
63366361393531326132623236636333626334333433383531653161663961636430663964636561
|
||||
36333463636334323834336435663636623133306434646530336332386265613962663132663737
|
||||
31393537336162336532613239666332646436363266313632653538366561643137393332643065
|
||||
32643264396135653439613632613332393937336230303131343465346232353261646536633130
|
||||
35626363363763623839343566376633323765353934356431313537323332323736656635613039
|
||||
39383039366437356535396133396336666330396566373961653762633965373761393633336165
|
||||
39613261306465353634336666363138343830653939666637353330303234393632306166626633
|
||||
62336531373636656130363731363334313731376561636466643638363530353363323730643232
|
||||
31643636623363646233613733326630646235383539393834303864383039313934383633613232
|
||||
33376433656561356337666638353038353362363936366561323966653862303837663264623039
|
||||
36353966626362373531333939633934373266313831663337383464616237386361303166383634
|
||||
61643434633964373634646436623861646266366530313535663361626438323530343361313430
|
||||
31663066323232353130333732616663373361666661333561343133353837353766623230623963
|
||||
32323936373336646131653166633365323963616339643630623962663866373038393034623632
|
||||
35656130383562353734666162666264626138363265626263666661346465333130373764653262
|
||||
65623939623831633265346638626134386131303339386434343466656565373538613934653035
|
||||
31663265646266656432333739653439356134366663346366373139353562303964333537396361
|
||||
35353132636266613965313232326439366231653535653861653131373936303439303662643261
|
||||
32623662636565396632376437633064663032393538323432393764383062643835616563656535
|
||||
31386366393839643931656334633930343535326462623761353762396264323362326231643336
|
||||
32633534323661666239366563633837666161643438643033303732623237356139333739663135
|
||||
36343732656263313536383136663832323130393031313265326439383061666264333461373134
|
||||
34616163643839373663306630343861613663643030643437373833643239633539616565636233
|
||||
66303234303036616438356563663636633833396137323462316363613864663536343137303064
|
||||
32623030616562313131343536373435353636353161346337303337633135343262336164336632
|
||||
39343736313165626562353665613061626461393130373735303533636239376533636137396331
|
||||
37346234396364333537623034333430616133396363656164393337396338613766336433396464
|
||||
36346664383838386366366537306333306436383235316535623631343438633232313234613036
|
||||
36396564353833626566316130343439653562313863653761383564643162386362383138356530
|
||||
63376336616266623133323031353966623830633135316636383863333266333136303839373333
|
||||
35366130306431636362636162333661343939386463373936313866646162396138626663353765
|
||||
61666463653939373363393463656537653965313735653863323965666237353230316135346138
|
||||
34373637326366363033393830386164643530313937663031363932343637323836363932303832
|
||||
30316163393431663436643638313233643664333461623932356231383636633536393133666463
|
||||
38303030633866383866356262386235623034666161326632633735396162653437643533313034
|
||||
35306134343731376563383662353463386164323633643231386339356263663534613061306632
|
||||
37646338653633366530323837386333393335323664306265643235346366613164303962643433
|
||||
66303964346339663364633631656434626361396564666366333165396436666632663364336431
|
||||
31376435396134646665353135636138663733363565393833336464653465303961373262393932
|
||||
63396461653133396633376130326463313465363161633861653964313639666534633434393032
|
||||
38383334386432353630316336313839363362643533356433636665623235366664326139346430
|
||||
35646435356131666230383966383230336336623935336431653562363863643739373962366230
|
||||
32373661313832313963373263613764336635616239393063346232666364623631373839303632
|
||||
66386462666166616465336538313335323461316162346461613163643363313732366331313166
|
||||
39646535393235383633323663333865383462623162393665336132303334326138303431616665
|
||||
35633864373530613762396632303737653535663538316237663538646465313038373961616361
|
||||
39643866363563643133346437643038393361373938633935363332346236353362363238353365
|
||||
38393632336139313937616536633839383830376131633561383237313264373739626661646139
|
||||
32613465613933623062653362646439343035376261613361356233363631636539653062613138
|
||||
65633235656534633135633434336233303031333135363838666361306238323530643838386264
|
||||
33666639613931313239306539313131313530353836306361643665666231663966316237613134
|
||||
30303437376132373034366534383435626139623162653335636434373665623034376163633239
|
||||
39326332396631333965373337653239356237656235393765303236366565326536313732353137
|
||||
32623036343831383335336539303439303864666561323463393162353536303235626631373363
|
||||
37346338393336363038643430313037373164336264633838656231343331356266386266376563
|
||||
31633561376166343939326534383363393738613837653135663765366464306336326663333566
|
||||
61613339373234303838633639396562313930643339633733663030323761343737323862343232
|
||||
64343233326330306662653535633539393566626565306530363161343731613439383362393738
|
||||
61303339373565643036396563376230376464636632316265326165333761656164626632303235
|
||||
61353962613731633238643937343166343261363337303731633134373238643062643133633434
|
||||
37306265373666613131316332663066363834663864396364373637613632376539616363623963
|
||||
31356264393335366266613339343233383830643364356435316432613566316365326130333531
|
||||
64366536383937306437386538643338306662633739363231616438633465613563336564616363
|
||||
64363130326337383734666435336333656136326663336637336231623637633738323863636437
|
||||
39373766646333363433383130336336626163616564376336633833633835653231333239656462
|
||||
63316263313931626333663832653939616436643964613061343866303035653830633734643631
|
||||
35316533383333616332313938653762623435353161653061633732386365303138656466313238
|
||||
30616666666433333237313835623764373361633938396361393930393832323763373533356565
|
||||
65393261393363623435346463343537386531643439383764626239356530346666346633313332
|
||||
61656639616361396562633137666631613062303031343734313738313735346237613233363833
|
||||
39663036653865346336653734306631303563343563663438643533626638363463353731386132
|
||||
62326538613237616264623936393530613366303632643939336539333138626464383964663838
|
||||
34363763663732336536656162393635306563633662636664323563363161386261313230393766
|
||||
66373037343135616531653938633931643539386433633037623138613639653238303936383930
|
||||
62333564663537653764653638663465326462323838613838643034363238343339396663333835
|
||||
62396161373531646132663931356638643331626135376432633531383564393335316534313266
|
||||
62613935313661303636303762336166323064633837396435363937623238333461396235636534
|
||||
31616461303334363361376334306366633133633965646138623663623137393634613465376663
|
||||
33613836316365393136333639643035333238373535643932353330316161363733333439356532
|
||||
31343935376564333938613630616437343864336632356435326265363761643339653638666139
|
||||
30613035393830616263353338393334353635333534336165396266326462373036653663393863
|
||||
61323838363831663434636236636463633362633136653662623863323737626163613863643566
|
||||
63363933336533386666636632656661303033326535613234336264376337376139353831386364
|
||||
64643331353934323761623264353030653265336462356233313864343233323866333262363536
|
||||
36346630396536663565
|
||||
2
group_vars/docker_hosts.yml
Normal file
2
group_vars/docker_hosts.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
my_svc_path: ~/services
|
||||
1
inventories/prod/group_vars/all.yml
Normal file
1
inventories/prod/group_vars/all.yml
Normal file
@@ -0,0 +1 @@
|
||||
domain: cazzzer.com
|
||||
@@ -1,26 +0,0 @@
|
||||
# Environment specific variables (prod)
|
||||
|
||||
---
|
||||
domain: cazzzer.com
|
||||
|
||||
docker_ipv6_index: 255
|
||||
|
||||
# Arrstack VPN
|
||||
wg_privkey: "{{ vault_wg_privkey }}"
|
||||
wg_psk: "{{ vault_wg_psk }}"
|
||||
wg_addresses: "{{ vault_wg_addresses }}"
|
||||
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
|
||||
|
||||
# Authentik External OAuth
|
||||
github_consumer_key: 32d5cae58d744c56fcc9
|
||||
github_consumer_secret: "{{ vault_github_consumer_secret }}"
|
||||
google_consumer_key: 606830535764-9vc8mjta87g9974pb7qasp82cpoc1d3a.apps.googleusercontent.com
|
||||
google_consumer_secret: "{{ vault_google_consumer_secret }}"
|
||||
|
||||
# VPGen
|
||||
vpgen_ipv4_starting_addr: 10.18.11.100
|
||||
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
|
||||
|
||||
# Woodpecker
|
||||
woodpecker_gitea_client_id: 3b7515f3-6005-4512-a2ee-5464dba315f8
|
||||
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"
|
||||
@@ -1,32 +0,0 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
36313835643238353932323631323439626432316436346533376365633332313963666433313333
|
||||
6134633133636133623130376237373462383164396338380a316463396139653161366536636336
|
||||
64346664356538366538363239306631326464633635316161663963326635656430326637333963
|
||||
6462633236353132300a323062353639646238663737353461633733636530613036316364353864
|
||||
34326534376639643734303137613866393464306334336566653134333765356361386436323939
|
||||
35393535303635376162386266396431313739663961643061623037343463303637623130623131
|
||||
31653761616639613964386432643561376637316435333064343837636463303033333432636234
|
||||
39323735373161616133396566316266383165343033666530376333626264643531613334363634
|
||||
35393766623361346461333764666139366632306362613362376133363239656562346263643066
|
||||
65616538366532346537383432663766366161633234373562623531356339666661346164306563
|
||||
35343339386631383462656466303563376237386137346437323634626163353464356462346364
|
||||
35373061636237383335396231326563366230663566333665326338303564326263316630666233
|
||||
65303930663862313137333630353837363265333532303133306466643462626662613166326132
|
||||
66346439333739653965346236313766346532356233333164633538326135643662623533646561
|
||||
65626530386333303362343830653430653866336261623566616362313739303939656364656363
|
||||
37336331353766633534653936626139303061623531323362346564363665663438646533646166
|
||||
62376534653562373138656465666133353235313935626534383537643436376665613865303363
|
||||
62326562396361306131616363363866316232623635353663323537366563333239383636643763
|
||||
35623366663463303831323730363036306363643364303532326339353633393739306366396331
|
||||
33313230656431623462376135623438633164323064653866646165643263383832353138633931
|
||||
66306463346361646561376334613837383762366365666638643434383034376339643239646463
|
||||
66343461363233626635323535336462666339323032616136396239396534346434623238396330
|
||||
37653665643366323362313136386231396532323035363963623738346564356435303263303832
|
||||
37346532366432363638363330316464366361313461626535616165333433343835393565633766
|
||||
32663162386562373035333335303332323136613233613431386265626337653939326435396262
|
||||
61303631633838613962346663326232636438393563396230306361333335383462653432383766
|
||||
35376662353262303635316635363130383032366530396439613861653037383234363831333562
|
||||
37343332646534353838626366623361636261393865363633303631613837323733626264643835
|
||||
63376430613234386463336234623062656534643863656434386134616265333666613939393331
|
||||
39333166393538306135313431303831623063363533326330633062653333313733653831383736
|
||||
613864303461323739336563356161353234
|
||||
@@ -1,2 +1,2 @@
|
||||
[alpina]
|
||||
debbi.sys.cazzzer.com
|
||||
[docker_hosts]
|
||||
root@alpina.lab.home
|
||||
|
||||
1
inventories/staging/group_vars/all.yml
Normal file
1
inventories/staging/group_vars/all.yml
Normal file
@@ -0,0 +1 @@
|
||||
domain: lab.cazzzer.com
|
||||
@@ -1,26 +0,0 @@
|
||||
# Environment specific variables (staging)
|
||||
|
||||
---
|
||||
domain: lab.cazzzer.com
|
||||
|
||||
docker_ipv6_index: 254
|
||||
|
||||
# Arrstack VPN
|
||||
wg_privkey: "{{ vault_wg_privkey }}"
|
||||
wg_psk: "{{ vault_wg_psk }}"
|
||||
wg_addresses: "{{ vault_wg_addresses }}"
|
||||
fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
|
||||
|
||||
# Authentik External OAuth
|
||||
github_consumer_key: dbacb8621c37320eb745
|
||||
github_consumer_secret: "{{ vault_github_consumer_secret }}"
|
||||
google_consumer_key: 606830535764-pec4b3sa2tohim3u9jl2jmnl1see46q1.apps.googleusercontent.com
|
||||
google_consumer_secret: "{{ vault_google_consumer_secret }}"
|
||||
|
||||
# VPGen
|
||||
vpgen_ipv4_starting_addr: 10.18.11.50
|
||||
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"
|
||||
|
||||
# Woodpecker
|
||||
woodpecker_gitea_client_id: c7122416-b160-498b-8021-8f2837552588
|
||||
woodpecker_gitea_client_secret: "{{ vault_woodpecker_gitea_client_secret }}"
|
||||
@@ -1,32 +0,0 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
36343339366166383430383235626463376339653331333635623936653135633633353064613634
|
||||
3263306161376232356634363532653266366665333364650a636365393465383165306563346132
|
||||
37653564633630653635353464333939353266396562316663653933373065353536333130383065
|
||||
3864353332303164320a316439313164663736636465366539643131303663343861333164613561
|
||||
37383965373964313535313335643164376164323263613539643933333035323837373662303030
|
||||
66636465303566313334386435326433653032383962353739643861346161323738636366396239
|
||||
39623336336234376339343562656362323932383265313161396435346530663330353266323433
|
||||
66396538313365653963323164306464663565303364386466666636346533633661333634313236
|
||||
33623936616239613264613730363039366561646535633239633564656166343162303633373366
|
||||
37656163333838656533363735383332626632353237613666396633363531666366336630613064
|
||||
66626561663766376531313666663963643766393965653564333062653139336230356330383464
|
||||
38343562383430303132663964303736623238386562323033623861303432363363373934643332
|
||||
63363239323664333131306237336134613137653136633932356238343733393632616464366134
|
||||
33623038363032653134626337663863366663383433633134326239616136656139366535613565
|
||||
61646330356330396236303566363834613236653733643162666536303435643133346633353632
|
||||
62386135303262353332643135636164303963616234626132356161663463366434323864626261
|
||||
33356536626263626261343937386666396561306334346435316262333431353234303836356563
|
||||
31343566373935396633636133616265346235396333396664333534336162323039623937656336
|
||||
36656133383966613333646336613039626563353862646238376461373264633233313836333062
|
||||
30343134363862626630393035643762376435346532306462363437646238333463396230666465
|
||||
64386365393063613139313164366562643066323461313364393265393638643137386561633530
|
||||
65643861386531323836306339386462656530383533363831323461303131396666626464303136
|
||||
64343865616235616366633136393662623862383961323338366435396334653538303830616166
|
||||
39636164613466313033643639366635323666666235653633333436613133343962353664313838
|
||||
64356466393239666131363964643461346633313030643061643938643232343334313731636463
|
||||
37396637643232353539626239306463623237623534366666396164613135356136313534663231
|
||||
36613662653237343061316463386231656136383636393034333666633063613731316162333464
|
||||
64313866633062623530326233633166343434636639346565346337396461393637383333366435
|
||||
62393030383963396638653230613431623837353461313630343333376131616239313164336234
|
||||
62323739316536353835613032303438623230626563303934626466303934613566656232323663
|
||||
643265386333313065333737613438316532
|
||||
@@ -1,2 +1,2 @@
|
||||
[alpina]
|
||||
etappi.sys.cazzzer.com
|
||||
[docker_hosts]
|
||||
root@etapp.lab.home
|
||||
|
||||
522
poetry.lock
generated
522
poetry.lock
generated
@@ -1,522 +0,0 @@
|
||||
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "ansible"
|
||||
version = "13.0.0"
|
||||
description = "Radically simple IT automation"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "ansible-13.0.0-py3-none-any.whl", hash = "sha256:c5efd095be1e4d15aa39691e3ce8233727269da4a17043f16f67c6899b98a239"},
|
||||
{file = "ansible-13.0.0.tar.gz", hash = "sha256:fd0f4a29c3e77617011b98d80e4579c31e1d58f40928d3e8fd5e434696676797"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
ansible-core = ">=2.20.0,<2.21.0"
|
||||
|
||||
[[package]]
|
||||
name = "ansible-core"
|
||||
version = "2.20.0"
|
||||
description = "Radically simple IT automation"
|
||||
optional = false
|
||||
python-versions = ">=3.12"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "ansible_core-2.20.0-py3-none-any.whl", hash = "sha256:665f9e46401509f1f799b0fc624ce162127765885d61607c5e31a0f77652d7b6"},
|
||||
{file = "ansible_core-2.20.0.tar.gz", hash = "sha256:cd73faf28a056c933bc1eee8f66ab597e7ec7309d42c8a6e5d6e4294c4a78b54"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cryptography = "*"
|
||||
jinja2 = ">=3.1.0"
|
||||
packaging = "*"
|
||||
PyYAML = ">=5.1"
|
||||
resolvelib = ">=0.8.0,<2.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "ansible-vault"
|
||||
version = "4.1.0"
|
||||
description = "R/W an ansible-vault yaml file"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "ansible_vault-4.1.0-py3-none-any.whl", hash = "sha256:ae2e194bb68cc94471d0cdba0705cea9390d9c3dfe6299eeb1d4ee36af602bd9"},
|
||||
{file = "ansible_vault-4.1.0.tar.gz", hash = "sha256:7e985a9329e4728961d7a00f62412fa8ec246a4d832ad6e6d158165e0026529b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
ansible-core = ">=2.16"
|
||||
PyYAML = ">=5.1"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black", "coveralls", "flake8", "isort", "pylint", "pylint-pytest", "pytest", "pytest-cov", "setuptools"]
|
||||
release = ["build", "twine"]
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "25.4.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["dev"]
|
||||
files = [
|
||||
{file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"},
|
||||
{file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "2.0.0"
|
||||
description = "Foreign Function Interface for Python calling C code."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
markers = "platform_python_implementation != \"PyPy\""
|
||||
files = [
|
||||
{file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"},
|
||||
{file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"},
|
||||
{file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"},
|
||||
{file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"},
|
||||
{file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"},
|
||||
{file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"},
|
||||
{file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"},
|
||||
{file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"},
|
||||
{file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pycparser = {version = "*", markers = "implementation_name != \"PyPy\""}
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "46.0.3"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
optional = false
|
||||
python-versions = "!=3.9.0,!=3.9.1,>=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "cryptography-46.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win32.whl", hash = "sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb"},
|
||||
{file = "cryptography-46.0.3-cp311-abi3-win_arm64.whl", hash = "sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win32.whl", hash = "sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db"},
|
||||
{file = "cryptography-46.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win32.whl", hash = "sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win_amd64.whl", hash = "sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f"},
|
||||
{file = "cryptography-46.0.3-cp38-abi3-win_arm64.whl", hash = "sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372"},
|
||||
{file = "cryptography-46.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32"},
|
||||
{file = "cryptography-46.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9"},
|
||||
{file = "cryptography-46.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c"},
|
||||
{file = "cryptography-46.0.3.tar.gz", hash = "sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""}
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"]
|
||||
docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"]
|
||||
nox = ["nox[uv] (>=2024.4.15)"]
|
||||
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"]
|
||||
sdist = ["build (>=1.0.0)"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["certifi (>=2024)", "cryptography-vectors (==46.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
|
||||
test-randomorder = ["pytest-randomly"]
|
||||
|
||||
[[package]]
|
||||
name = "grafanalib"
|
||||
version = "0.7.1"
|
||||
description = "Library for building Grafana dashboards"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["dev"]
|
||||
files = [
|
||||
{file = "grafanalib-0.7.1-py3-none-any.whl", hash = "sha256:6fab5d7b837a1f2d1322ef762cd52e565ec0422707a7512765c59f668bdceb58"},
|
||||
{file = "grafanalib-0.7.1.tar.gz", hash = "sha256:3d92bb4e92ae78fe4e21c5b252ab51f4fdcacd8523ba5a44545b897b2a375b83"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
attrs = ">=15.2.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["flake8", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.6"
|
||||
description = "A very fast and expressive template engine."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
|
||||
{file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.0"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.3"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"},
|
||||
{file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"},
|
||||
{file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"},
|
||||
{file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"},
|
||||
{file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"},
|
||||
{file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"},
|
||||
{file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"},
|
||||
{file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netaddr"
|
||||
version = "1.3.0"
|
||||
description = "A network address manipulation library for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe"},
|
||||
{file = "netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
nicer-shell = ["ipython"]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"},
|
||||
{file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.23"
|
||||
description = "C parser in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
markers = "platform_python_implementation != \"PyPy\" and implementation_name != \"PyPy\""
|
||||
files = [
|
||||
{file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"},
|
||||
{file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.3"
|
||||
description = "YAML parser and emitter for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"},
|
||||
{file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"},
|
||||
{file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"},
|
||||
{file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"},
|
||||
{file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"},
|
||||
{file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"},
|
||||
{file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"},
|
||||
{file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"},
|
||||
{file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resolvelib"
|
||||
version = "1.2.1"
|
||||
description = "Resolve abstract dependencies into concrete ones"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "resolvelib-1.2.1-py3-none-any.whl", hash = "sha256:fb06b66c8da04172d9e72a21d7d06186d8919e32ae5ab5cdf5b9d920be805ac2"},
|
||||
{file = "resolvelib-1.2.1.tar.gz", hash = "sha256:7d08a2022f6e16ce405d60b68c390f054efcfd0477d4b9bd019cc941c28fad1c"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
lint = ["mypy", "ruff", "types-requests"]
|
||||
release = ["build", "towncrier", "twine"]
|
||||
test = ["packaging", "pytest"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "5d542bdeae079233a36951fb69e4883f0c34c7aea13df7ba6cc6765f938bf300"
|
||||
@@ -1,2 +0,0 @@
|
||||
[virtualenvs]
|
||||
in-project = true
|
||||
@@ -1,20 +0,0 @@
|
||||
[tool.poetry]
|
||||
name = "alpina"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Iurii Tatishchev <itatishch@gmail.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
ansible = "^13.0.0"
|
||||
ansible-vault = "^4.1.0"
|
||||
netaddr = "^1.3.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
grafanalib = "^0.7.1"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
],
|
||||
"docker-compose": {
|
||||
"fileMatch": [
|
||||
"(^|/)(?:docker-)?compose[^/]*\\.ya?ml(\\.j2)?$"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
ansible==6.0.0
|
||||
@@ -1,15 +0,0 @@
|
||||
- name: Ensure {{ collection }} collection directory exists
|
||||
file:
|
||||
path: "{{ alpina_svc_path }}/{{ collection }}"
|
||||
state: directory
|
||||
mode: "700"
|
||||
|
||||
- name: Deploy docker compose stacks for {{ collection }}
|
||||
vars:
|
||||
current_stack_name: "{{ stack }}"
|
||||
current_stack_dest: "{{ alpina_svc_path }}/{{ collection }}/{{ stack }}"
|
||||
current_stack_source: "{{ role_path }}/templates/{{ collection }}/{{ stack }}"
|
||||
include_tasks: deploy_compose_stack.yml
|
||||
loop: "{{ stacks }}"
|
||||
loop_control:
|
||||
loop_var: stack
|
||||
@@ -1,42 +0,0 @@
|
||||
# https://stackoverflow.com/questions/41667864/can-the-templates-module-handle-multiple-templates-directories
|
||||
|
||||
- name: Ensure {{ stack }} stack directory exists
|
||||
file:
|
||||
path: "{{ current_stack_dest }}"
|
||||
state: directory
|
||||
mode: "700"
|
||||
|
||||
- name: Ensure directory structure exists
|
||||
file:
|
||||
path: "{{ current_stack_dest }}/{{ item.path }}"
|
||||
state: directory
|
||||
mode: "755"
|
||||
loop: "{{ query('community.general.filetree', current_stack_source) }}"
|
||||
when: item.state == "directory"
|
||||
|
||||
- name: Generate {{ current_stack_name }} deployment from templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ current_stack_dest }}/{{ item.path | regex_replace('\\.j2$', '') }}"
|
||||
mode: "644"
|
||||
loop: "{{ query('community.general.filetree', current_stack_source) }}"
|
||||
when: item.state == "file" and (item.path | regex_search('\\.j2$')) is not none
|
||||
|
||||
- name: Generate {{ current_stack_name }} deployment from static files
|
||||
copy:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ current_stack_dest }}/{{ item.path }}"
|
||||
mode: "644"
|
||||
loop: "{{ query('community.general.filetree', current_stack_source) }}"
|
||||
when: item.state == "file" and (item.path | regex_search('\\.j2$')) is none
|
||||
|
||||
- name: Deploy docker-compose for {{ current_stack_name }}
|
||||
community.docker.docker_compose_v2:
|
||||
project_src: "{{ current_stack_dest }}"
|
||||
state: present
|
||||
pull: always
|
||||
remove_orphans: yes
|
||||
register: docker_compose_output
|
||||
|
||||
# - debug:
|
||||
# var: docker_compose_output
|
||||
@@ -1,40 +0,0 @@
|
||||
- name: Register uid of remote user
|
||||
command: id -u
|
||||
register: remote_uid_command
|
||||
changed_when: false
|
||||
|
||||
- name: Set fact for uid
|
||||
set_fact:
|
||||
remote_uid: "{{ remote_uid_command.stdout }}"
|
||||
|
||||
- name: Ensure alpina directory exists
|
||||
file:
|
||||
state: directory
|
||||
path: "{{ alpina_svc_path }}"
|
||||
mode: "700"
|
||||
|
||||
- name: Deploy collection services
|
||||
vars:
|
||||
collection: services
|
||||
stacks:
|
||||
- traefik
|
||||
- monitoring
|
||||
- authentik
|
||||
- minio
|
||||
import_tasks: deploy_collection.yml
|
||||
|
||||
- name: Deploy collection apps
|
||||
vars:
|
||||
collection: apps
|
||||
stacks:
|
||||
- gitea
|
||||
- woodpecker
|
||||
- syncthing
|
||||
- nextcloud
|
||||
- jellyfin
|
||||
- arrstack
|
||||
- vpgen
|
||||
- pgrok
|
||||
- n8n
|
||||
- minecruft
|
||||
import_tasks: deploy_collection.yml
|
||||
@@ -1,33 +0,0 @@
|
||||
## ProtonVPN OpenVPN
|
||||
#VPN_SERVICE_PROVIDER=protonvpn
|
||||
#OPENVPN_USER=+pmp
|
||||
#OPENVPN_PASSWORD=
|
||||
#SERVER_HOSTNAMES=node-us-160.protonvpn.net,node-us-161.protonvpn.net
|
||||
#VPN_PORT_FORWARDING=on
|
||||
|
||||
## ProtonVPN WireGuard
|
||||
#VPN_SERVICE_PROVIDER=custom
|
||||
#VPN_TYPE=wireguard
|
||||
#VPN_ENDPOINT_IP=
|
||||
#VPN_ENDPOINT_PORT=
|
||||
#WIREGUARD_PUBLIC_KEY=
|
||||
#WIREGUARD_PRIVATE_KEY=
|
||||
#WIREGUARD_PRESHARED_KEY=
|
||||
#WIREGUARD_ADDRESSES=
|
||||
#VPN_DNS_ADDRESS=
|
||||
#VPN_PORT_FORWARDING=on
|
||||
#VPN_PORT_FORWARDING_PROVIDER=protonvpn
|
||||
|
||||
## AirVPN
|
||||
VPN_SERVICE_PROVIDER=airvpn
|
||||
VPN_TYPE=wireguard
|
||||
SERVER_NAMES={{ vpn_server_names }}
|
||||
WIREGUARD_PUBLIC_KEY={{ wg_peer_pubkey }}
|
||||
WIREGUARD_PRIVATE_KEY={{ wg_privkey }}
|
||||
WIREGUARD_PRESHARED_KEY={{ wg_psk }}
|
||||
WIREGUARD_ADDRESSES={{ wg_addresses }}
|
||||
FIREWALL_VPN_INPUT_PORTS={{ fw_vpn_input_ports }}
|
||||
|
||||
UPDATER_PERIOD=24h
|
||||
|
||||
#FIREWALL_OUTBOUND_SUBNETS=10.0.0.0/8,{{ docker_ipv6_subnet }}
|
||||
@@ -1,76 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(249) | indent(2) }}
|
||||
|
||||
services:
|
||||
gluetun:
|
||||
image: qmcgaw/gluetun:latest
|
||||
container_name: gluetun
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
sysctls:
|
||||
- net.ipv6.conf.all.disable_ipv6=0
|
||||
env_file:
|
||||
- .env.gluetun
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- {{ base_volume_path }}/arrstack/gluetun:/gluetun
|
||||
|
||||
qbittorrent:
|
||||
image: linuxserver/qbittorrent:latest
|
||||
container_name: qbittorrent
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('qbit', port='8080', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
{# Keeping this for debugging purposes -#}
|
||||
- DOCKER_MODS=linuxserver/mods:universal-package-install
|
||||
network_mode: service:gluetun
|
||||
volumes:
|
||||
- {{ base_volume_path }}/arrstack/config/qbittorrent:/config
|
||||
- {{ base_volume_path }}/arrstack/downloads:/downloads
|
||||
- {{ media_volume_path }}/Plex:/media/Plex
|
||||
- {{ media_volume_path }}/iso-img:/media/iso-img
|
||||
depends_on:
|
||||
gluetun:
|
||||
condition: service_healthy
|
||||
|
||||
prowlarr:
|
||||
image: linuxserver/prowlarr:latest
|
||||
container_name: prowlarr
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('prowlarr', port='9696', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- qbittorrent
|
||||
volumes:
|
||||
- {{ base_volume_path }}/arrstack/config/prowlarr:/config
|
||||
|
||||
sonarr:
|
||||
image: linuxserver/sonarr:latest
|
||||
container_name: sonarr
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('sonarr', port='8989', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- qbittorrent
|
||||
volumes:
|
||||
- {{ base_volume_path }}/arrstack/config/sonarr:/config
|
||||
- {{ base_volume_path }}/arrstack/downloads:/downloads
|
||||
- {{ media_volume_path }}/Plex:/media/Plex
|
||||
|
||||
radarr:
|
||||
image: linuxserver/radarr:latest
|
||||
container_name: radarr
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('radarr', port='7878', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- qbittorrent
|
||||
volumes:
|
||||
- {{ base_volume_path }}/arrstack/config/radarr:/config
|
||||
- {{ base_volume_path }}/arrstack/downloads:/downloads
|
||||
- {{ media_volume_path }}/Plex:/media/Plex
|
||||
@@ -1,3 +0,0 @@
|
||||
POSTGRES_USER=gitea
|
||||
POSTGRES_DB=gitea
|
||||
POSTGRES_PASSWORD={{ gitea_db_password }}
|
||||
@@ -1,31 +0,0 @@
|
||||
GITEA____APP_NAME=CazGitea
|
||||
|
||||
# Database
|
||||
GITEA__database__DB_TYPE=postgres
|
||||
GITEA__database__HOST=db:5432
|
||||
GITEA__database__NAME=gitea
|
||||
GITEA__database__USER=gitea
|
||||
GITEA__database__PASSWD={{ gitea_db_password }}
|
||||
|
||||
# Server
|
||||
GITEA__server__ROOT_URL=https://gitea.{{ domain }}/
|
||||
GITEA__server__DISABLE_SSH=true
|
||||
|
||||
# Mail
|
||||
GITEA__mailer__ENABLED=true
|
||||
GITEA__mailer__SMTP_ADDR=smtp.sendgrid.net
|
||||
GITEA__mailer__SMTP_PORT=587
|
||||
GITEA__mailer__FROM=gitea@cazzzer.com
|
||||
GITEA__mailer__USER=apikey
|
||||
GITEA__mailer__PASSWD={{ gitea_sendgrid_api_key }}
|
||||
|
||||
# Security
|
||||
GITEA__security__SECRET_KEY={{ secret_key }}
|
||||
GITEA__security__INTERNAL_TOKEN={{ internal_token }}
|
||||
|
||||
GITEA__oauth2__JWT_SECRET={{ jwt_secret }}
|
||||
|
||||
GITEA__webhook__ALLOWED_HOST_LIST="external,woodpecker.{{ domain }}"
|
||||
|
||||
# Indexer
|
||||
GITEA__indexer__REPO_INDEXER_ENABLED=true
|
||||
@@ -1,26 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(199) | indent(2) }}
|
||||
|
||||
services:
|
||||
server:
|
||||
image: gitea/gitea
|
||||
container_name: gitea_server
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('gitea', port='3000') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.gitea
|
||||
volumes:
|
||||
- {{ base_volume_path }}/gitea/gitea:/data
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: gitea_db
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.db
|
||||
volumes:
|
||||
- {{ base_volume_path }}/gitea/postgres:/var/lib/postgresql/data
|
||||
@@ -1 +0,0 @@
|
||||
JELLYFIN_PublishedServerUrl=https://jellyfin.{{ domain }}
|
||||
@@ -1,23 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(197) | indent(2) }}
|
||||
|
||||
services:
|
||||
jellyfin:
|
||||
image: jellyfin/jellyfin:latest
|
||||
container_name: jellyfin_jellyfin
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('jellyfin', port='8096') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.jellyfin
|
||||
volumes:
|
||||
- {{ base_volume_path }}/jellyfin/config:/config
|
||||
- {{ base_volume_path }}/jellyfin/cache:/cache
|
||||
- {{ media_volume_path }}/Plex/media:/data/media:ro
|
||||
- {{ media_volume_path }}/other_videos:/data/other_videos:ro
|
||||
tmpfs:
|
||||
- /tmp/transcodes
|
||||
devices:
|
||||
- /dev/dri:/dev/dri
|
||||
@@ -1,27 +0,0 @@
|
||||
EULA=true
|
||||
|
||||
CF_API_KEY="{{ minecruft_cf_api_key }}"
|
||||
TYPE=AUTO_CURSEFORGE
|
||||
CF_PAGE_URL=https://www.curseforge.com/minecraft/modpacks/create-arcane-engineering/files/4852034
|
||||
CF_EXCLUDE_MODS=591711
|
||||
CURSEFORGE_FILES="https://www.curseforge.com/minecraft/mc-mods/simple-voice-chat/files/7011546
|
||||
https://www.curseforge.com/minecraft/mc-mods/bluemap/files/5555751"
|
||||
|
||||
|
||||
MEMORY=16G
|
||||
ENABLE_ROLLING_LOGS=true
|
||||
#TZ=America/New_York
|
||||
|
||||
OVERRIDE_SERVER_PROPERTIES=true
|
||||
DIFFICULTY=normal
|
||||
MAX_TICK_TIME=-1
|
||||
ALLOW_FLIGHT=true
|
||||
OPS=Litoprobka,CaZzzer
|
||||
VIEW_DISTANCE=12
|
||||
MAX_PLAYERS=16
|
||||
PVP=false
|
||||
LEVEL_TYPE=normal
|
||||
LEVEL_SEED=133769
|
||||
MOTD="Remember the Cavendish"
|
||||
ONLINE_MODE=false
|
||||
SPAWN_PROTECTION=0
|
||||
@@ -1,18 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
services:
|
||||
minecruft:
|
||||
image: itzg/minecraft-server:java17-alpine
|
||||
container_name: minecruft
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('minecruft', port='8100') | indent(6) }}
|
||||
ports:
|
||||
- 25565:25565
|
||||
- 25565:25565/udp
|
||||
- 24454:24454/udp
|
||||
restart: unless-stopped
|
||||
env_file: .env.minecruft
|
||||
volumes:
|
||||
- {{ base_volume_path }}/minecruft/data:/data
|
||||
- {{ base_volume_path }}/minecruft/downloads:/downloads
|
||||
- ./config:/config
|
||||
@@ -1,42 +0,0 @@
|
||||
# By changing the setting (accept-download) below to TRUE you are indicating that you have accepted mojang's EULA (https://account.mojang.com/documents/minecraft_eula),
|
||||
# you confirm that you own a license to Minecraft (Java Edition)
|
||||
# and you agree that BlueMap will download and use a minecraft-client file (depending on the minecraft-version) from mojangs servers (https://piston-meta.mojang.com/) for you.
|
||||
# This file contains resources that belong to mojang and you must not redistribute it or do anything else that is not compliant with mojang's EULA.
|
||||
# BlueMap uses resources in this file to generate the 3D-Models used for the map and texture them. (BlueMap will not work without those resources.)
|
||||
accept-download: true
|
||||
|
||||
# The folder where bluemap saves data-files it needs during runtime or to save e.g. the render-progress to resume it later.
|
||||
# Default is "bluemap"
|
||||
data: "bluemap"
|
||||
|
||||
# This changes the amount of threads that BlueMap will use to render the maps.
|
||||
# A higher value can improve render-speed but could impact performance on the host machine.
|
||||
# This should be always below or equal to the number of available processor-cores.
|
||||
# Zero or a negative value means the amount of available processor-cores subtracted by the value.
|
||||
# (So a value of -2 with 6 cores results in 4 render-processes)
|
||||
# Default is 1
|
||||
render-thread-count: 3
|
||||
|
||||
# Controls whether BlueMap should try to find and load mod-resources and datapacks from the server/world-directories.
|
||||
# Default is true
|
||||
scan-for-mod-resources: true
|
||||
|
||||
# If this is true, BlueMap might send really basic metrics reports containing only the implementation-type and the version that is being used to https://metrics.bluecolored.de/bluemap/
|
||||
# This allows me to track the basic usage of BlueMap and helps me stay motivated to further develop this tool! Please leave it on :)
|
||||
# An example report looks like this: {"implementation":"bukkit","version":"5.3","mcVersion":"?"}
|
||||
# Default is true
|
||||
metrics: true
|
||||
|
||||
# Config-section for debug-logging
|
||||
log: {
|
||||
# The file where the debug-log will be written to.
|
||||
# Comment out to disable debug-logging completely.
|
||||
# Java String formatting syntax can be used to add time, see: https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html
|
||||
# Default is no logging
|
||||
file: "bluemap/logs/debug.log"
|
||||
#file: "bluemap/logs/debug_%1$tF_%1$tT.log"
|
||||
|
||||
# Whether the logger should append to an existing file, or overwrite it
|
||||
# Default is false
|
||||
append: false
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(192) | indent(2) }}
|
||||
|
||||
services:
|
||||
n8n:
|
||||
image: n8nio/n8n
|
||||
container_name: n8n
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('n8n', port='5678') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- {{ base_volume_path }}/n8n/data:/home/node/.n8n
|
||||
- {{ base_volume_path }}/n8n/local-files:/files
|
||||
environment:
|
||||
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
|
||||
- N8N_HOST=n8n.{{ domain }}
|
||||
- N8N_PORT=5678
|
||||
- N8N_PROTOCOL=https
|
||||
- N8N_RUNNERS_ENABLED=true
|
||||
- NODE_ENV=production
|
||||
- WEBHOOK_URL=https://n8n.{{ domain }}/
|
||||
- N8N_PROXY_HOPS=1
|
||||
@@ -1,24 +0,0 @@
|
||||
POSTGRES_DB=nextcloud
|
||||
POSTGRES_USER=nextcloud
|
||||
POSTGRES_PASSWORD={{ nextcloud_db_password }}
|
||||
POSTGRES_HOST=db
|
||||
|
||||
NEXTCLOUD_TRUSTED_DOMAINS=nc.{{ domain }}
|
||||
|
||||
REDIS_HOST=redis
|
||||
REDIS_HOST_PASSWORD={{ redis_password }}
|
||||
|
||||
SMTP_HOST=smtp.sendgrid.net
|
||||
SMTP_SECURE=tls
|
||||
SMTP_PORT=587
|
||||
SMTP_AUTHTYPE=LOGIN
|
||||
SMTP_NAME=apikey
|
||||
SMTP_PASSWORD={{ nextcloud_sendgrid_api_key }}
|
||||
MAIL_FROM_ADDRESS=nc
|
||||
MAIL_DOMAIN=cazzzer.com
|
||||
|
||||
# host IPv4 and IPv6 addresses, loopback for notify_push
|
||||
TRUSTED_PROXIES={{ ansible_facts['default_ipv4'].address }} {{ ansible_facts['default_ipv6'].address }} 127.0.0.1 ::1
|
||||
OVERWRITEHOST=nc.{{ domain }}
|
||||
OVERWRITEPROTOCOL=https
|
||||
OVERWRITECLIURL=https://nc.{{ domain }}
|
||||
@@ -1,4 +0,0 @@
|
||||
DATABASE_URL=postgres://nextcloud:{{ nextcloud_db_password }}@db/nextcloud
|
||||
DATABASE_PREFIX=oc_
|
||||
REDIS_URL=redis://:{{ redis_password }}@redis
|
||||
NEXTCLOUD_URL=http://localhost
|
||||
@@ -1 +0,0 @@
|
||||
REDIS_PASSWORD={{ redis_password }}
|
||||
@@ -1,68 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(198) | indent(2) }}
|
||||
|
||||
services:
|
||||
app:
|
||||
image: &nextcloud_image nextcloud:stable-apache
|
||||
container_name: nextcloud_app
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('nc', port='80') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
env_file:
|
||||
- .env.nextcloud
|
||||
volumes:
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data
|
||||
|
||||
cron:
|
||||
image: *nextcloud_image
|
||||
container_name: nextcloud_cron
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- app
|
||||
entrypoint: /cron.sh
|
||||
volumes:
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud_config:/var/www/html/config
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud_data:/var/www/html/data
|
||||
|
||||
notify_push:
|
||||
image: *nextcloud_image
|
||||
container_name: nextcloud_notify_push
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('nc', port='7867', path_prefix='/push') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
user: www-data
|
||||
env_file:
|
||||
- .env.notify_push
|
||||
network_mode: service:app
|
||||
entrypoint:
|
||||
- /var/www/html/custom_apps/notify_push/bin/x86_64/notify_push
|
||||
volumes:
|
||||
- {{ base_volume_path }}/nextcloud/nextcloud:/var/www/html
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
container_name: nextcloud_db
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.db
|
||||
volumes:
|
||||
- {{ base_volume_path }}/nextcloud/db:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
container_name: nextcloud_redis
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.redis
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- redis-server --requirepass $$REDIS_PASSWORD
|
||||
@@ -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 }}"
|
||||
@@ -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"
|
||||
@@ -1,16 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(193) | indent(2) }}
|
||||
|
||||
services:
|
||||
syncthing:
|
||||
image: linuxserver/syncthing
|
||||
container_name: syncthing
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('sync', port='8384', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
volumes:
|
||||
- {{ base_volume_path }}/syncthing/config:/config
|
||||
- {{ base_volume_path }}/syncthing/data:/data
|
||||
@@ -1,29 +0,0 @@
|
||||
DATABASE_URL=file:/data/vpgen.db
|
||||
|
||||
PUBLIC_AUTH_AUTHENTIK_ENABLE=1
|
||||
AUTH_AUTHENTIK_REQUIRE_INVITE=0
|
||||
AUTH_AUTHENTIK_DOMAIN="auth.{{ domain }}"
|
||||
AUTH_AUTHENTIK_CLIENT_ID=vpgen
|
||||
AUTH_AUTHENTIK_CLIENT_SECRET="{{ auth_vpgen_client_secret }}"
|
||||
|
||||
PUBLIC_AUTH_GOOGLE_ENABLE=1
|
||||
AUTH_GOOGLE_REQUIRE_INVITE=1
|
||||
AUTH_GOOGLE_CLIENT_ID="{{ google_consumer_key }}"
|
||||
AUTH_GOOGLE_CLIENT_SECRET="{{ google_consumer_secret }}"
|
||||
|
||||
AUTH_INVITE_TOKEN="{{ vpgen_auth_invite_token }}"
|
||||
|
||||
OPNSENSE_API_URL={{ vpgen_opnsense_api_url }}
|
||||
OPNSENSE_API_KEY={{ vpgen_opnsense_api_key }}
|
||||
OPNSENSE_API_SECRET={{ vpgen_opnsense_api_secret }}
|
||||
OPNSENSE_WG_IFNAME={{ vpgen_opnsense_wg_ifname }}
|
||||
|
||||
IPV4_STARTING_ADDR={{ vpgen_ipv4_starting_addr }}
|
||||
IPV6_STARTING_ADDR={{ vpgen_ipv6_starting_addr }}
|
||||
IPV6_CLIENT_PREFIX_SIZE={{ vpgen_ipv6_client_prefix_size }}
|
||||
IP_MAX_INDEX={{ vpgen_ip_max_index }}
|
||||
VPN_ENDPOINT={{ vpgen_vpn_endpoint }}
|
||||
VPN_DNS={{ vpgen_vpn_dns }}
|
||||
MAX_CLIENTS_PER_USER={{ vpgen_max_clients_per_user }}
|
||||
|
||||
ORIGIN=https://vpgen.{{ domain }}
|
||||
@@ -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
|
||||
@@ -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:v3
|
||||
container_name: woodpecker_server
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('woodpecker', port='8000') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- {{ base_volume_path }}/woodpecker/data:/var/lib/woodpecker
|
||||
environment:
|
||||
- WOODPECKER_OPEN=true
|
||||
- WOODPECKER_HOST=https://woodpecker.{{ domain }}
|
||||
- WOODPECKER_GITEA=true
|
||||
- WOODPECKER_GITEA_URL=https://gitea.{{ domain }}
|
||||
- WOODPECKER_GITEA_CLIENT={{ woodpecker_gitea_client_id }}
|
||||
- WOODPECKER_GITEA_SECRET={{ woodpecker_gitea_client_secret }}
|
||||
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}
|
||||
|
||||
woodpecker-agent:
|
||||
image: woodpeckerci/woodpecker-agent:v3
|
||||
container_name: woodpecker_agent
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- woodpecker-server
|
||||
volumes:
|
||||
- {{ base_volume_path }}/woodpecker/agent_config:/etc/woodpecker
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
environment:
|
||||
- WOODPECKER_SERVER=woodpecker-server:9000
|
||||
- WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}
|
||||
@@ -1,21 +0,0 @@
|
||||
AUTHENTIK_ERROR_REPORTING__ENABLED=true
|
||||
|
||||
AUTHENTIK_REDIS__HOST=redis
|
||||
AUTHENTIK_POSTGRESQL__HOST=postgres
|
||||
AUTHENTIK_POSTGRESQL__USER=authentik
|
||||
AUTHENTIK_POSTGRESQL__NAME=authentik
|
||||
AUTHENTIK_POSTGRESQL__PASSWORD={{ authentik_db_password }}
|
||||
|
||||
AUTHENTIK_SECRET_KEY={{ authentik_secret_key }}
|
||||
|
||||
AUTHENTIK_EMAIL__HOST=smtp.sendgrid.net
|
||||
AUTHENTIK_EMAIL__PORT=587
|
||||
AUTHENTIK_EMAIL__USERNAME=apikey
|
||||
AUTHENTIK_EMAIL__PASSWORD={{ authentik_sendgrid_api_key }}
|
||||
|
||||
AUTHENTIK_EMAIL__USE_TLS=true
|
||||
AUTHENTIK_EMAIL__TIMEOUT=10
|
||||
AUTHENTIK_EMAIL__FROM=auth@cazzzer.com
|
||||
|
||||
AUTHENTIK_DEFAULT_USER_CHANGE_EMAIL=false
|
||||
AUTHENTIK_DEFAULT_USER_CHANGE_USERNAME=false
|
||||
@@ -1,3 +0,0 @@
|
||||
POSTGRES_USER=authentik
|
||||
POSTGRES_DB=authentik
|
||||
POSTGRES_PASSWORD={{ authentik_db_password }}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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 }}]]
|
||||
@@ -1,98 +0,0 @@
|
||||
version: 1
|
||||
metadata:
|
||||
labels:
|
||||
blueprints.goauthentik.io/instantiate: "true"
|
||||
name: Alpina - OAuth2 Apps
|
||||
entries:
|
||||
{% set apps = {
|
||||
"Grafana": {
|
||||
"redirect_uri": "https://grafana."~ domain ~"/login/generic_oauth",
|
||||
"icon": "https://grafana."~ domain ~"/public/img/grafana_icon.svg",
|
||||
"client_secret": auth_grafana_client_secret,
|
||||
"ui_group": "Services",
|
||||
"allowed_for_groups": ["admins"],
|
||||
},
|
||||
"Minio": {
|
||||
"redirect_uri": "https://minio."~ domain ~"/oauth_callback",
|
||||
"icon": "https://minio."~ domain ~"/logo192.png",
|
||||
"client_secret": auth_minio_client_secret,
|
||||
"ui_group": "Services",
|
||||
"allowed_for_groups": ["admins"],
|
||||
},
|
||||
"Gitea": {
|
||||
"redirect_uri": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
|
||||
"icon": "https://gitea."~ domain ~"/assets/img/logo.svg",
|
||||
"client_secret": auth_gitea_client_secret,
|
||||
"ui_group": "Apps",
|
||||
"allowed_for_groups": ["admins", "users"],
|
||||
},
|
||||
"Nextcloud": {
|
||||
"redirect_uri": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
|
||||
"icon": "https://nc."~ domain ~"/apps/theming/favicon",
|
||||
"client_secret": auth_nextcloud_client_secret,
|
||||
"ui_group": "Apps",
|
||||
"allowed_for_groups": ["admins", "users"],
|
||||
},
|
||||
"VPGen": {
|
||||
"redirect_uri": "https://vpgen."~ domain ~"/auth/authentik/callback",
|
||||
"icon": "https://vpgen."~ domain ~"/favicon.png",
|
||||
"client_secret": auth_vpgen_client_secret,
|
||||
"ui_group": "Apps",
|
||||
"allowed_for_groups": ["admins", "users", "vpgen"],
|
||||
},
|
||||
"Pgrok": {
|
||||
"redirect_uri": "https://pgrok."~ domain ~"/-/oidc/callback",
|
||||
"icon": "https://pgrok."~ domain ~"/pgrok.svg",
|
||||
"client_secret": auth_pgrok_client_secret,
|
||||
"ui_group": "Apps",
|
||||
"allowed_for_groups": ["admins", "users"],
|
||||
},
|
||||
} -%}
|
||||
{% for app in apps.keys() -%}
|
||||
- identifiers:
|
||||
name: {{ app }}
|
||||
model: authentik_providers_oauth2.oauth2provider
|
||||
id: {{ app }}
|
||||
attrs:
|
||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||
client_type: confidential
|
||||
client_id: {{ app | lower }}
|
||||
client_secret: {{ apps[app]["client_secret"] }}
|
||||
property_mappings:
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
|
||||
{% if app == "Minio" -%}
|
||||
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, minio]]
|
||||
{%- endif %}
|
||||
|
||||
redirect_uris:
|
||||
- matching_mode: strict
|
||||
url: {{ apps[app]["redirect_uri"] }}
|
||||
# Necessary for JWKS to be generated correctly
|
||||
signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
|
||||
|
||||
- identifiers:
|
||||
slug: {{ app | lower }}
|
||||
model: authentik_core.application
|
||||
id: app-{{ app }}
|
||||
attrs:
|
||||
name: {{ app }}
|
||||
group: "{{ apps[app]["ui_group"] }}"
|
||||
meta_description: "Hello, I'm {{ app }}!"
|
||||
meta_publisher: Alpina
|
||||
icon: "{{ apps[app]["icon"] }}"
|
||||
open_in_new_tab: true
|
||||
provider: !KeyOf {{ app }}
|
||||
|
||||
{% for group in apps[app]["allowed_for_groups"] -%}
|
||||
- identifiers:
|
||||
group: !Find [authentik_core.group, [name, {{ group }}]]
|
||||
target: !KeyOf app-{{ app }}
|
||||
model: authentik_policies.policybinding
|
||||
attrs:
|
||||
order: 10
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
@@ -1,95 +0,0 @@
|
||||
version: 1
|
||||
metadata:
|
||||
labels:
|
||||
blueprints.goauthentik.io/instantiate: "true"
|
||||
name: Alpina - Proxied Apps
|
||||
entries:
|
||||
# TODO: Possibly refactor this into a jinja macro (?)
|
||||
{% set apps = {
|
||||
"Uptime Kuma": {
|
||||
"host": "uptime",
|
||||
"icon": "https://uptime."~ domain ~"/icon.svg",
|
||||
"unauthenticated_paths": "^/icon.svg$",
|
||||
"ui_group": "Services",
|
||||
"allowed_for_groups": ["admins"],
|
||||
},
|
||||
"Syncthing": {
|
||||
"host": "sync",
|
||||
"icon": "https://sync."~ domain ~"/assets/img/favicon-default.png",
|
||||
"unauthenticated_paths": "^/assets/img/favicon-default.png$",
|
||||
"ui_group": "Apps",
|
||||
"allowed_for_groups": ["admins"],
|
||||
},
|
||||
"qBit": {
|
||||
"host": "qbit",
|
||||
"icon": "https://qbit."~ domain ~"/images/qbittorrent-tray.svg",
|
||||
"unauthenticated_paths": "^/images/qbittorrent-tray.svg$",
|
||||
"ui_group": "Arrstack",
|
||||
"allowed_for_groups": ["arrstack"],
|
||||
},
|
||||
"Prowlarr": {
|
||||
"host": "prowlarr",
|
||||
"icon": "https://prowlarr."~ domain ~"/Content/Images/logo.svg",
|
||||
"unauthenticated_paths": "^/Content/Images/logo.svg$",
|
||||
"ui_group": "Arrstack",
|
||||
"allowed_for_groups": ["arrstack"],
|
||||
},
|
||||
"Sonarr": {
|
||||
"host": "sonarr",
|
||||
"icon": "https://sonarr."~ domain ~"/Content/Images/logo.svg",
|
||||
"unauthenticated_paths": "^/Content/Images/logo.svg$",
|
||||
"ui_group": "Arrstack",
|
||||
"allowed_for_groups": ["arrstack"],
|
||||
},
|
||||
"Radarr": {
|
||||
"host": "radarr",
|
||||
"icon": "https://radarr."~ domain ~"/Content/Images/logo.svg",
|
||||
"unauthenticated_paths": "^/Content/Images/logo.svg$",
|
||||
"ui_group": "Arrstack",
|
||||
"allowed_for_groups": ["arrstack"],
|
||||
},
|
||||
} -%}
|
||||
{% for app in apps.keys() -%}
|
||||
- identifiers:
|
||||
name: {{ app }}
|
||||
model: authentik_providers_proxy.proxyprovider
|
||||
id: {{ app }}
|
||||
attrs:
|
||||
authorization_flow: !Find [authentik_flows.flow, [ slug, default-provider-authorization-implicit-consent ] ]
|
||||
mode: forward_single
|
||||
external_host: "https://{{ apps[app]["host"] }}.{{ domain }}/"
|
||||
skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}"
|
||||
|
||||
- identifiers:
|
||||
slug: {{ app | lower | replace(" ", "-") }}
|
||||
model: authentik_core.application
|
||||
id: app-{{ app }}
|
||||
attrs:
|
||||
name: {{ app }}
|
||||
group: {{ apps[app]["ui_group"] }}
|
||||
meta_description: "Hello, I'm {{ app }}!"
|
||||
meta_publisher: Alpina
|
||||
icon: "{{ apps[app]["icon"] }}"
|
||||
open_in_new_tab: true
|
||||
provider: !KeyOf {{ app }}
|
||||
|
||||
{% for group in apps[app]["allowed_for_groups"] -%}
|
||||
- identifiers:
|
||||
group: !Find [authentik_core.group, [name, {{ group }}]]
|
||||
target: !KeyOf app-{{ app }}
|
||||
model: authentik_policies.policybinding
|
||||
attrs:
|
||||
order: 10
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
- identifiers:
|
||||
managed: goauthentik.io/outposts/embedded
|
||||
name: authentik Embedded Outpost
|
||||
model: authentik_outposts.outpost
|
||||
attrs:
|
||||
providers:
|
||||
{% for app in apps.keys() -%}
|
||||
- !KeyOf {{ app }}
|
||||
{% endfor %}
|
||||
@@ -1,59 +0,0 @@
|
||||
version: 1
|
||||
metadata:
|
||||
labels:
|
||||
blueprints.goauthentik.io/instantiate: "true"
|
||||
name: Alpina - Default Authentication Modifications
|
||||
entries:
|
||||
# Add a new flow for passwordless WebAuthn authentication
|
||||
- identifiers:
|
||||
slug: authentication-passwordless-flow
|
||||
model: authentik_flows.flow
|
||||
attrs:
|
||||
designation: authentication
|
||||
name: WebAuthn Authentication Flow
|
||||
title: Sign in with a passkey
|
||||
|
||||
# Add a new stage to the flow to validate just WebAuthn devices
|
||||
- identifiers:
|
||||
name: webauthn-validation
|
||||
model: authentik_stages_authenticator_validate.authenticatorvalidatestage
|
||||
attrs:
|
||||
device_classes:
|
||||
- webauthn
|
||||
not_configured_action: deny
|
||||
webauthn_user_verification: required
|
||||
|
||||
# Stage bindings for passwordless flow,
|
||||
# 1. Validate WebAuthn key
|
||||
- identifiers:
|
||||
order: 10
|
||||
stage: !Find [authentik_stages_authenticator_validate.authenticatorvalidatestage, [name, webauthn-validation]]
|
||||
target: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]]
|
||||
model: authentik_flows.flowstagebinding
|
||||
# 2. Finish authenticating user
|
||||
- identifiers:
|
||||
order: 100
|
||||
stage: !Find [authentik_stages_user_login.userloginstage, [name, default-authentication-login]]
|
||||
target: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]]
|
||||
model: authentik_flows.flowstagebinding
|
||||
|
||||
# Some modifications to the default identification stage
|
||||
- identifiers:
|
||||
name: default-authentication-identification
|
||||
model: authentik_stages_identification.identificationstage
|
||||
attrs:
|
||||
# Allow username and password fields to be on the same page
|
||||
password_stage: !Find [authentik_stages_password.passwordstage, [name, default-authentication-password]]
|
||||
# Add a button to use the passwordless WebAuthn flow
|
||||
passwordless_flow: !Find [authentik_flows.flow, [slug, authentication-passwordless-flow]]
|
||||
sources:
|
||||
- !Find [authentik_core.source, [slug, authentik-built-in]]
|
||||
- !Find [authentik_sources_oauth.oauthsource, [slug, github-auth]]
|
||||
- !Find [authentik_sources_oauth.oauthsource, [slug, google-auth]]
|
||||
|
||||
# Enable compatibility mode for the default authentication flow for better autofill support
|
||||
- identifiers:
|
||||
slug: default-authentication-flow
|
||||
model: authentik_flows.flow
|
||||
attrs:
|
||||
compatibility_mode: true
|
||||
@@ -1,62 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(253) | indent(2) }}
|
||||
|
||||
services:
|
||||
server:
|
||||
image: ghcr.io/goauthentik/server:latest
|
||||
container_name: authentik_server
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('auth', port='9000') | indent(6) }}
|
||||
- traefik.http.middlewares.authentik.forwardauth.address=http://localhost:9000/outpost.goauthentik.io/auth/traefik
|
||||
- traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true
|
||||
- traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=Authorization,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
|
||||
restart: unless-stopped
|
||||
# Port forward is needed because traefik can't resolve the container name from the host network
|
||||
ports:
|
||||
- "127.0.0.1:9000:9000"
|
||||
- "[::1]:9000:9000"
|
||||
command: server
|
||||
env_file:
|
||||
- .env.authentik
|
||||
|
||||
worker:
|
||||
image: ghcr.io/goauthentik/server:latest
|
||||
container_name: authentik_worker
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
env_file:
|
||||
- .env.authentik
|
||||
volumes:
|
||||
- ./blueprints:/blueprints/alpina
|
||||
- {{ base_volume_path }}/authentik/certs:/certs
|
||||
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: authentik_postgres
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.db
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||
start_period: 20s
|
||||
interval: 30s
|
||||
retries: 5
|
||||
timeout: 5s
|
||||
volumes:
|
||||
- {{ base_volume_path }}/authentik/postgres:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:alpine
|
||||
container_name: authentik_redis
|
||||
restart: unless-stopped
|
||||
command: --save 60 1 --loglevel warning
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
|
||||
start_period: 20s
|
||||
interval: 30s
|
||||
retries: 5
|
||||
timeout: 3s
|
||||
volumes:
|
||||
- {{ base_volume_path }}/authentik/redis:/data
|
||||
@@ -1,20 +0,0 @@
|
||||
MINIO_ROOT_USER=minio
|
||||
MINIO_ROOT_PASSWORD={{ minio_password }}
|
||||
|
||||
MINIO_DOMAIN=s3.{{ domain }}
|
||||
MINIO_SERVER_URL=https://s3.{{ domain }}
|
||||
MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }}
|
||||
|
||||
# https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html
|
||||
MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
|
||||
MINIO_IDENTITY_OPENID_CLIENT_ID=minio
|
||||
MINIO_IDENTITY_OPENID_CLIENT_SECRET={{ auth_minio_client_secret }}
|
||||
# defaults to "policy"
|
||||
#MINIO_IDENTITY_OPENID_CLAIM_NAME=policy
|
||||
MINIO_IDENTITY_OPENID_DISPLAY_NAME=Authentik
|
||||
# no need to specify scopes,
|
||||
# as it defaults to the ones advertised at the discovery url
|
||||
#MINIO_IDENTITY_OPENID_SCOPES=openid,profile,email,minio
|
||||
#MINIO_IDENTITY_OPENID_REDIRECT_URI_DYNAMIC=off
|
||||
#MINIO_IDENTITY_OPENID_CLAIM_USERINFO=on
|
||||
#MINIO_IDENTITY_OPENID_COMMENT=
|
||||
@@ -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
|
||||
@@ -1,7 +0,0 @@
|
||||
DOCKER_INFLUXDB_INIT_MODE=setup
|
||||
DOCKER_INFLUXDB_INIT_ORG=home
|
||||
DOCKER_INFLUXDB_INIT_BUCKET=influx
|
||||
DOCKER_INFLUXDB_INIT_USERNAME=CaZzzer
|
||||
DOCKER_INFLUXDB_INIT_PASSWORD={{ influxdb_admin_password }}
|
||||
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN={{ influxdb_admin_token }}
|
||||
DOCKER_INFLUXDB_INIT_RETENTION=1w
|
||||
@@ -1,17 +0,0 @@
|
||||
FROM python:3-alpine AS builder
|
||||
|
||||
RUN pip install grafanalib
|
||||
|
||||
COPY ./grafana_config/dashboards /dashboards
|
||||
|
||||
# Required for grafanalib to find the shared python files like common.py
|
||||
# https://github.com/weaveworks/grafanalib/issues/58
|
||||
ENV PYTHONPATH=/dashboards
|
||||
|
||||
RUN generate-dashboards /dashboards/*.dashboard.py
|
||||
|
||||
FROM grafana/grafana:latest
|
||||
|
||||
#COPY ./grafana_config /etc/grafana
|
||||
COPY ./grafana_config/dashboards/*.yaml /etc/grafana/provisioning/dashboards
|
||||
COPY --from=builder /dashboards/*.json /etc/grafana/provisioning/dashboards
|
||||
@@ -1,112 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(251) | indent(2) }}
|
||||
|
||||
services:
|
||||
grafana:
|
||||
{# image: grafana/grafana:latest#}
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: grafana
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('grafana', port='3000') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
# Needed to make config files readable (not anymore, TODO: remove)
|
||||
user: "{{ remote_uid }}"
|
||||
volumes:
|
||||
- {{ base_volume_path }}/monitoring/grafana:/var/lib/grafana
|
||||
- ./grafana_config/grafana.ini:/etc/grafana/grafana.ini:ro
|
||||
- ./grafana_config/datasources:/etc/grafana/provisioning/datasources:ro
|
||||
{# - ./grafana_config:/etc/grafana:ro#}
|
||||
|
||||
loki:
|
||||
image: grafana/loki:3.6
|
||||
container_name: loki
|
||||
restart: unless-stopped
|
||||
# Needed to make config files readable (not anymore, TODO: remove)
|
||||
user: "{{ remote_uid }}"
|
||||
command:
|
||||
- -config.file=/etc/loki/loki-config.yaml
|
||||
# Port forward is needed because not possible to resolve the container name from the host network
|
||||
ports:
|
||||
- "127.0.0.1:3100:3100"
|
||||
- "[::1]:3100:3100"
|
||||
volumes:
|
||||
- {{ base_volume_path }}/monitoring/loki:/loki
|
||||
- ./loki_config:/etc/loki:ro
|
||||
tmpfs:
|
||||
- /tmp/loki
|
||||
|
||||
promtail:
|
||||
image: grafana/promtail:3.6
|
||||
container_name: promtail
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- -config.file=/etc/promtail/promtail-config.yaml
|
||||
ports:
|
||||
- 514:514
|
||||
volumes:
|
||||
- ./promtail_config:/etc/promtail:ro
|
||||
- /var/log:/var/log:ro
|
||||
tmpfs:
|
||||
- /tmp
|
||||
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: prometheus
|
||||
restart: unless-stopped
|
||||
# Needed to make config files readable (not anymore, TODO: remove)
|
||||
user: "{{ remote_uid }}"
|
||||
command:
|
||||
- --config.file=/etc/prometheus/prometheus.yml
|
||||
- --storage.tsdb.retention.time=30d
|
||||
volumes:
|
||||
- ./prometheus_config:/etc/prometheus:ro
|
||||
- {{ base_volume_path }}/monitoring/prometheus_configs:/etc/prometheus/extra:ro
|
||||
- {{ base_volume_path }}/monitoring/prometheus:/prometheus
|
||||
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
pid: host
|
||||
volumes:
|
||||
- /:/host:ro,rslave
|
||||
|
||||
cadvisor:
|
||||
image: ghcr.io/google/cadvisor:v0.53.0
|
||||
container_name: cadvisor
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- --docker_only=true
|
||||
- --store_container_labels=false
|
||||
- --whitelisted_container_labels=com.docker.compose.project,com.docker.compose.service
|
||||
- --enable_metrics=cpu,cpuLoad,diskIO,memory,network,oom_event,process
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:rw
|
||||
- /sys:/sys:ro
|
||||
- /var/lib/docker/:/var/lib/docker:ro
|
||||
|
||||
influxdb:
|
||||
image: influxdb:2.7-alpine
|
||||
container_name: influxdb
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('influxdb', port='8086') | indent(6) }}
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.influxdb
|
||||
volumes:
|
||||
- {{ base_volume_path }}/monitoring/influxdb:/var/lib/influxdb2
|
||||
|
||||
uptime-kuma:
|
||||
image: louislam/uptime-kuma:2
|
||||
container_name: uptime-kuma
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('uptime', port='3001', auth=true) | indent(6) }}
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- {{ base_volume_path }}/monitoring/uptime-kuma:/app/data
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: "Grafana"
|
||||
org_id: 1
|
||||
folder: "Alpina"
|
||||
type: "file"
|
||||
options:
|
||||
path: "/etc/grafana/provisioning/dashboards"
|
||||
@@ -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]
|
||||
@@ -1,101 +0,0 @@
|
||||
from grafanalib.core import GridPos, Templating, Template, Logs
|
||||
from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC
|
||||
|
||||
from common import LokiTarget, prom_template, loki_template, MyTimeSeries, MyDashboard, CONF_SUPPORT_LOKI, filter_none, \
|
||||
prom_datasource, PromTarget
|
||||
|
||||
dashboard = MyDashboard(
|
||||
title='Containers',
|
||||
uid='containers',
|
||||
description='Data for compose projects from default Prometheus datasource collected by Cadvisor',
|
||||
tags=[
|
||||
'linux',
|
||||
'docker',
|
||||
],
|
||||
templating=Templating(list=filter_none([
|
||||
prom_template,
|
||||
loki_template if CONF_SUPPORT_LOKI else None,
|
||||
Template(
|
||||
name='compose_project',
|
||||
label='Compose Project',
|
||||
dataSource=prom_datasource,
|
||||
query='label_values({__name__=~"container.*"}, container_label_com_docker_compose_project)',
|
||||
includeAll=True,
|
||||
multi=True,
|
||||
),
|
||||
Template(
|
||||
name='container_name',
|
||||
label='Container',
|
||||
dataSource=prom_datasource,
|
||||
query='label_values({__name__=~"container.*", container_label_com_docker_compose_project=~"$compose_project"}, name)',
|
||||
includeAll=True,
|
||||
multi=True,
|
||||
),
|
||||
Template(
|
||||
name='logs_query',
|
||||
label='Log Search',
|
||||
query='',
|
||||
type='textbox',
|
||||
),
|
||||
])),
|
||||
panels=filter_none([
|
||||
MyTimeSeries(
|
||||
title='Container Memory Usage',
|
||||
unit=BYTES_IEC,
|
||||
gridPos=GridPos(h=8, w=12, x=0, y=0),
|
||||
tooltipSort='desc',
|
||||
stacking={'mode': 'normal'},
|
||||
targets=[
|
||||
PromTarget(
|
||||
expr='max by (name) (container_memory_usage_bytes{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"})',
|
||||
legendFormat='{{ name }}',
|
||||
),
|
||||
],
|
||||
),
|
||||
MyTimeSeries(
|
||||
title='Container CPU Usage',
|
||||
unit=SECONDS,
|
||||
gridPos=GridPos(h=8, w=12, x=12, y=0),
|
||||
tooltipSort='desc',
|
||||
stacking={'mode': 'normal'},
|
||||
targets=[
|
||||
PromTarget(
|
||||
expr='max by (name) (irate(container_cpu_usage_seconds_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
|
||||
legendFormat='{{ name }}',
|
||||
),
|
||||
],
|
||||
),
|
||||
MyTimeSeries(
|
||||
title='Container Network Traffic',
|
||||
unit=BYTES_SEC_IEC,
|
||||
gridPos=GridPos(h=8, w=12, x=0, y=8),
|
||||
tooltipSort='desc',
|
||||
axisCenteredZero=True,
|
||||
targets=[
|
||||
PromTarget(
|
||||
expr='max by (name) (irate(container_network_receive_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
|
||||
legendFormat="rx {{ name }}",
|
||||
),
|
||||
PromTarget(
|
||||
expr='-max by (name) (irate(container_network_transmit_bytes_total{name=~"$container_name", container_label_com_docker_compose_project=~"$compose_project"}[$__rate_interval]))',
|
||||
legendFormat="tx {{ name }}",
|
||||
),
|
||||
],
|
||||
),
|
||||
Logs(
|
||||
title='',
|
||||
gridPos=GridPos(h=8, w=12, x=12, y=8),
|
||||
showLabels=True,
|
||||
showCommonLabels=True,
|
||||
wrapLogMessages=True,
|
||||
prettifyLogMessage=True,
|
||||
dedupStrategy='numbers',
|
||||
targets=[
|
||||
LokiTarget(
|
||||
expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
|
||||
legendFormat='{{ container_name }}',
|
||||
),
|
||||
],
|
||||
) if CONF_SUPPORT_LOKI else None,
|
||||
]),
|
||||
).auto_panel_ids()
|
||||
@@ -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()
|
||||
@@ -1,29 +0,0 @@
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Loki
|
||||
type: loki
|
||||
access: proxy
|
||||
uid: loki
|
||||
url: http://loki:3100
|
||||
editable: false
|
||||
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
uid: prometheus
|
||||
url: http://prometheus:9090
|
||||
editable: false
|
||||
|
||||
- name: InfluxDB
|
||||
type: influxdb
|
||||
access: proxy
|
||||
uid: influxdb
|
||||
url: http://influxdb:8086
|
||||
jsonData:
|
||||
version: Flux
|
||||
organization: home
|
||||
defaultBucket: influx
|
||||
secureJsonData:
|
||||
token: {{ influxdb_admin_token }}
|
||||
editable: false
|
||||
@@ -1,34 +0,0 @@
|
||||
[server]
|
||||
domain = grafana.{{ domain }}
|
||||
root_url = https://%(domain)s/
|
||||
|
||||
;[security]
|
||||
;admin_user =
|
||||
;admin_email =
|
||||
;admin_password =
|
||||
|
||||
; https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/
|
||||
[auth]
|
||||
disable_login_form = true
|
||||
signout_redirect_url = https://auth.{{ domain }}/application/o/grafana/end-session/
|
||||
|
||||
[auth.generic_oauth]
|
||||
name = Authentik
|
||||
enabled = true
|
||||
allow_sign_up = true
|
||||
|
||||
client_id = grafana
|
||||
client_secret = {{ auth_grafana_client_secret }}
|
||||
|
||||
scopes = openid profile email
|
||||
auth_url = https://auth.{{ domain }}/application/o/authorize/
|
||||
token_url = https://auth.{{ domain }}/application/o/token/
|
||||
api_url = https://auth.{{ domain }}/application/o/userinfo/
|
||||
|
||||
email_attribute_path = email
|
||||
login_attribute_path = preferred_username
|
||||
name_attribute_path = name
|
||||
|
||||
# Optionally map user groups to Grafana roles
|
||||
allow_assign_grafana_admin = true
|
||||
role_attribute_path = contains(groups[*], 'admins') && 'GrafanaAdmin' || 'Viewer'
|
||||
@@ -1,30 +0,0 @@
|
||||
auth_enabled: false
|
||||
|
||||
server:
|
||||
http_listen_port: 3100
|
||||
|
||||
common:
|
||||
path_prefix: /loki
|
||||
# TODO: Consider setting up S3 for storage
|
||||
storage:
|
||||
filesystem:
|
||||
chunks_directory: /loki/chunks
|
||||
rules_directory: /loki/rules
|
||||
replication_factor: 1
|
||||
ring:
|
||||
kvstore:
|
||||
store: inmemory
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2024-10-18
|
||||
index:
|
||||
period: 24h
|
||||
prefix: index_
|
||||
object_store: filesystem
|
||||
schema: v13
|
||||
store: tsdb
|
||||
|
||||
# TODO: Figure this out
|
||||
# ruler:
|
||||
# alertmanager_url: http://localhost:9093
|
||||
@@ -1,39 +0,0 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
external_labels:
|
||||
monitor: "{{ ansible_host }}"
|
||||
|
||||
scrape_configs:
|
||||
- job_name: "prometheus"
|
||||
static_configs:
|
||||
- targets: ["localhost:9090"]
|
||||
|
||||
- job_name: "node"
|
||||
static_configs:
|
||||
- targets: ["{{ ansible_host }}:9100"]
|
||||
|
||||
- job_name: "cadvisor"
|
||||
static_configs:
|
||||
- targets: ["cadvisor:8080"]
|
||||
|
||||
- job_name: "traefik"
|
||||
static_configs:
|
||||
- targets: ["{{ ansible_host }}:8082"]
|
||||
|
||||
- job_name: "loki"
|
||||
static_configs:
|
||||
- targets: ["loki:3100"]
|
||||
|
||||
- job_name: "promtail"
|
||||
static_configs:
|
||||
- targets: ["promtail:9080"]
|
||||
|
||||
rule_files:
|
||||
- "/etc/prometheus/extra/rules/*.yml"
|
||||
- "/etc/prometheus/extra/rules/*.json"
|
||||
|
||||
scrape_config_files:
|
||||
- "/etc/prometheus/extra/scrape_configs/*.yml"
|
||||
- "/etc/prometheus/extra/scrape_configs/*.json"
|
||||
@@ -1,48 +0,0 @@
|
||||
server:
|
||||
http_listen_port: 9080
|
||||
grpc_listen_port: 0
|
||||
|
||||
positions:
|
||||
filename: /tmp/positions.yaml
|
||||
|
||||
clients:
|
||||
- url: http://loki:3100/loki/api/v1/push
|
||||
|
||||
scrape_configs:
|
||||
|
||||
# local machine logs
|
||||
- job_name: local
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost
|
||||
labels:
|
||||
job: varlogs
|
||||
__path__: /var/log/*log
|
||||
|
||||
# syslog target
|
||||
- job_name: syslog
|
||||
syslog:
|
||||
listen_address: "0.0.0.0:514" # make sure you also expose this port on the container
|
||||
idle_timeout: 60s
|
||||
label_structured_data: yes
|
||||
labels:
|
||||
job: "syslog"
|
||||
relabel_configs:
|
||||
- source_labels: ['__syslog_message_hostname']
|
||||
target_label: 'host'
|
||||
- source_labels: ['__syslog_message_facility']
|
||||
target_label: 'facility'
|
||||
- source_labels: ['__syslog_message_severity']
|
||||
target_label: 'severity'
|
||||
- source_labels: ['__syslog_message_app_name']
|
||||
target_label: 'app_name'
|
||||
|
||||
## docker logs
|
||||
|
||||
#- job_name: docker
|
||||
# pipeline_stages:
|
||||
# - docker: {}
|
||||
# static_configs:
|
||||
# - labels:
|
||||
# job: docker
|
||||
# __path__: /var/lib/docker/containers/*/*-json.log
|
||||
@@ -1 +0,0 @@
|
||||
CF_DNS_API_TOKEN={{ cloudflare_api_token }}
|
||||
@@ -1,25 +0,0 @@
|
||||
{% import 'contrib/compose_helpers.j2' as helpers with context %}
|
||||
|
||||
networks:
|
||||
{{ helpers.default_network(254) | indent(2) }}
|
||||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v3.6
|
||||
container_name: traefik
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.traefik
|
||||
network_mode: host
|
||||
volumes:
|
||||
- ./traefik.yml:/etc/traefik/traefik.yml:ro
|
||||
- ./rules:/rules:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- {{ base_volume_path }}/traefik/rules:/rules/extra:ro
|
||||
- {{ base_volume_path }}/traefik/acme:/acme
|
||||
|
||||
whoami:
|
||||
image: containous/whoami
|
||||
container_name: whoami
|
||||
labels:
|
||||
- {{ helpers.traefik_labels('whoami', port='80') | indent(6) }}
|
||||
@@ -1,25 +0,0 @@
|
||||
http:
|
||||
routers:
|
||||
traefik-dash:
|
||||
rule: "Host(`traefik.{{ domain }}`)"
|
||||
entryPoints:
|
||||
- web
|
||||
service: traefik-dash
|
||||
|
||||
traefik-dash-tls:
|
||||
rule: "Host(`traefik.{{ domain }}`)"
|
||||
entryPoints:
|
||||
- websecure
|
||||
service: traefik-dash
|
||||
tls:
|
||||
certResolver: letsencrypt
|
||||
domains:
|
||||
- main: "{{ domain }}"
|
||||
sans:
|
||||
- "*.{{ domain }}"
|
||||
|
||||
services:
|
||||
traefik-dash:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://localhost:8080"
|
||||
@@ -1,51 +0,0 @@
|
||||
api:
|
||||
insecure: true
|
||||
|
||||
log:
|
||||
level: INFO
|
||||
accessLog:
|
||||
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
websecure:
|
||||
address: ":443"
|
||||
http3:
|
||||
advertisedPort: 443
|
||||
forwardedHeaders:
|
||||
trustedIPs:
|
||||
# https://www.cloudflare.com/ips-v6
|
||||
- 2400:cb00::/32
|
||||
- 2606:4700::/32
|
||||
- 2803:f800::/32
|
||||
- 2405:b500::/32
|
||||
- 2405:8100::/32
|
||||
- 2a06:98c0::/29
|
||||
- 2c0f:f248::/32
|
||||
metrics:
|
||||
address: ":8082"
|
||||
|
||||
metrics:
|
||||
prometheus:
|
||||
entryPoint: metrics
|
||||
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: {{ acme_email }}
|
||||
storage: "/acme/acme.json"
|
||||
keyType: "EC384"
|
||||
dnsChallenge:
|
||||
provider: "cloudflare"
|
||||
delayBeforeCheck: 10
|
||||
resolvers:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
- 9.9.9.9
|
||||
|
||||
providers:
|
||||
docker:
|
||||
exposedByDefault: false
|
||||
file:
|
||||
directory: /rules
|
||||
watch: true
|
||||
@@ -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
|
||||
@@ -1,110 +1,44 @@
|
||||
- name: Install Debian packages
|
||||
become: yes
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- docker-ce
|
||||
- docker-compose-plugin
|
||||
- firewalld
|
||||
state: latest
|
||||
|
||||
- name: Upgrade Debian packages
|
||||
become: yes
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
- name: Upgrade alpine packages
|
||||
community.general.apk:
|
||||
upgrade: yes
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
autoremove: yes
|
||||
state: latest
|
||||
register: apt_upgrades
|
||||
register: apk_upgrades
|
||||
|
||||
- name: Ensure firewalld is running
|
||||
become: yes
|
||||
- name: Install alpine packages
|
||||
community.general.apk:
|
||||
name:
|
||||
- qemu-guest-agent
|
||||
- dhcpcd
|
||||
- python3
|
||||
- fish
|
||||
- docker
|
||||
- docker-compose
|
||||
- docker-fish-completion
|
||||
- docker-compose-fish-completion
|
||||
- zfs
|
||||
- zfs-auto-snapshot
|
||||
state: latest
|
||||
update_cache: yes
|
||||
register: apk_installs
|
||||
|
||||
- name: Enable qemu-guest-agent service
|
||||
service:
|
||||
name: firewalld
|
||||
state: started
|
||||
name: qemu-guest-agent
|
||||
runlevel: boot
|
||||
enabled: yes
|
||||
|
||||
- name: Allow SSH
|
||||
become: yes
|
||||
firewalld:
|
||||
service: ssh
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
- name: Enable zfs-import service
|
||||
service:
|
||||
name: zfs-import
|
||||
runlevel: sysinit
|
||||
enabled: yes
|
||||
|
||||
- name: Disallow Web
|
||||
become: yes
|
||||
firewalld:
|
||||
service: http
|
||||
permanent: yes
|
||||
state: disabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow Web Secure
|
||||
become: yes
|
||||
firewalld:
|
||||
service: https
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 443 udp for http3
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 443/udp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 514 tcp for syslog
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 514/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 2222 tcp for pgrok ssh tunnel
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 2222/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow Syncthing
|
||||
become: yes
|
||||
firewalld:
|
||||
service: syncthing
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 25565 tcp for minecruft
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 25565/tcp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 25565 udp for minecruft
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 25565/udp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
|
||||
- name: Allow 24454 udp for minecruft voice chat
|
||||
become: yes
|
||||
firewalld:
|
||||
port: 24454/udp
|
||||
permanent: yes
|
||||
state: enabled
|
||||
immediate: yes
|
||||
- name: Enable zfs-mount service
|
||||
service:
|
||||
name: zfs-mount
|
||||
runlevel: sysinit
|
||||
enabled: yes
|
||||
|
||||
- name: Reboot if needed
|
||||
become: yes
|
||||
ansible.builtin.reboot:
|
||||
when: apt_upgrades.changed
|
||||
reboot:
|
||||
when: apk_upgrades.changed or apk_installs.changed
|
||||
|
||||
13
roles/common/templates/zfs-send-daily
Normal file
13
roles/common/templates/zfs-send-daily
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
destination_connection=ssh root@truenas.lab.home
|
||||
destination_dataset=Mass-Storage-New/Backup
|
||||
|
||||
# Wait for zfs-auto-snapshot
|
||||
sleep 1
|
||||
|
||||
dataset="dock/volumes"
|
||||
|
||||
latest_snap=$(zfs list -t snap -Hp -o name -S creation $dataset | head -1 | tr -d '\n')
|
||||
|
||||
zfs send $latest_snap | $destination_connection zfs recv -o encry
|
||||
7
roles/common/templates/zfsbackup/Dockerfile
Normal file
7
roles/common/templates/zfsbackup/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.10-alpine
|
||||
RUN \
|
||||
apk add openssh && \
|
||||
pip install zfs-autobackup && \
|
||||
ln -s /run-backup.sh /etc/periodic/daily/
|
||||
COPY ["cron.sh", "run-backup.sh", "/"]
|
||||
CMD ["/cron.sh"]
|
||||
4
roles/common/templates/zfsbackup/cron.sh
Executable file
4
roles/common/templates/zfsbackup/cron.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
exec busybox crond -f -l 0 -L /dev/stdout
|
||||
29
roles/common/templates/zfsbackup/run-backup.sh
Executable file
29
roles/common/templates/zfsbackup/run-backup.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
echo "running backup job"
|
||||
date -Iminutes
|
||||
|
||||
if [ ! -d ~/.ssh ]; then echo "error: $(realpath ~/.ssh) directory does not exist"; exit 1; fi
|
||||
|
||||
host_ip=$(ip r | head -1 | cut -d' ' -f3 | tr -d '\n')
|
||||
host=root@"$host_ip"
|
||||
remote=root@truenas.lab.home
|
||||
|
||||
if ! ssh -q "$host" exit; then echo "error: not able to ssh into host of container $host"; exit 1; fi
|
||||
if ! ssh -q "$remote" exit; then echo "error: not able to ssh into backup remote $remote"; exit 1; fi
|
||||
|
||||
hostname=$(ssh "$host" hostname | tr -d '\n')
|
||||
remote_dataset=Mass-Storage-New/Backup/$hostname
|
||||
zfs_prop_name="nas" # autobackup:nas = true
|
||||
|
||||
zfs-autobackup \
|
||||
--snapshot-format "{}_%Y-%m-%d_%H-%M_%S" \
|
||||
--encrypt \
|
||||
--ssh-source "$host" \
|
||||
--ssh-target "$remote" \
|
||||
"$zfs_prop_name" \
|
||||
"$remote_dataset"
|
||||
|
||||
echo "ran backup job"
|
||||
date -Iminutes
|
||||
@@ -1,36 +1,5 @@
|
||||
- name: IPv6 subnet for Docker
|
||||
debug:
|
||||
var: docker_ipv6_subnet
|
||||
|
||||
- name: Configure Docker daemon
|
||||
become: yes
|
||||
template:
|
||||
src: "daemon.json.j2"
|
||||
dest: "/etc/docker/daemon.json"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
register: docker_daemon_config
|
||||
|
||||
- name: Install Docker loki plugin for logs
|
||||
community.docker.docker_plugin:
|
||||
plugin_name: grafana/loki-docker-driver:latest
|
||||
alias: loki
|
||||
state: enable
|
||||
|
||||
- name: Remove docker0 from firewalld trusted zone
|
||||
become: yes
|
||||
firewalld:
|
||||
zone: trusted
|
||||
interface: docker0
|
||||
permanent: yes
|
||||
immediate: yes
|
||||
state: disabled
|
||||
register: docker0_firewalld
|
||||
|
||||
- name: Restart Docker daemon
|
||||
become: yes
|
||||
service:
|
||||
name: docker
|
||||
state: restarted
|
||||
when: docker_daemon_config.changed or docker0_firewalld.changed
|
||||
- name: Create my service directory
|
||||
file:
|
||||
state: directory
|
||||
path: "{{ my_svc_path }}"
|
||||
mode: "700"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"ipv6": true,
|
||||
"fixed-cidr-v6": "{{ docker_ipv6_subnet | ansible.utils.ipsubnet(80, 0) }}",
|
||||
"log-driver": "loki",
|
||||
"log-opts": {
|
||||
"loki-url": "http://localhost:3100/loki/api/v1/push",
|
||||
"loki-batch-size": "400",
|
||||
"loki-retries": "5"
|
||||
}
|
||||
}
|
||||
33
roles/gitea/tasks/main.yml
Normal file
33
roles/gitea/tasks/main.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
# https://stackoverflow.com/questions/41667864/can-the-templates-module-handle-multiple-templates-directories
|
||||
|
||||
- name: Ensure service directory exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
|
||||
- name: Ensure directory structure exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}/{{ item.path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "directory"
|
||||
|
||||
|
||||
- name: Include app config variables
|
||||
include_vars:
|
||||
file: "{{ role_path }}/vars/app_config.yml"
|
||||
|
||||
- name: Generate {{ current_svc_name }} deployment from templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ current_svc_path }}/{{ item.path | regex_replace('\\.j2$', '') }}"
|
||||
mode: "400"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "file"
|
||||
|
||||
- name: Deploy docker-compose for {{ current_svc_name }}
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ current_svc_path }}"
|
||||
state: present
|
||||
3
roles/gitea/templates/.env.db.j2
Normal file
3
roles/gitea/templates/.env.db.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
POSTGRES_USER=gitea
|
||||
POSTGRES_DB=gitea
|
||||
POSTGRES_PASSWORD="{{ db_password }}"
|
||||
25
roles/gitea/templates/.env.gitea.j2
Normal file
25
roles/gitea/templates/.env.gitea.j2
Normal file
@@ -0,0 +1,25 @@
|
||||
GITEA____APP_NAME=CazGitea
|
||||
|
||||
# Database
|
||||
GITEA__database__DB_TYPE=postgres
|
||||
GITEA__database__HOST=db:5432
|
||||
GITEA__database__NAME="{{ db_user }}"
|
||||
GITEA__database__USER="{{ db_name }}"
|
||||
GITEA__database__PASSWD="{{ db_password }}"
|
||||
|
||||
# Server
|
||||
GITEA__server__ROOT_URL=https://gitea.cazzzer.com/
|
||||
GITEA__server__DISABLE_SSH=true
|
||||
|
||||
# Mail
|
||||
GITEA__mailer__ENABLED=true
|
||||
GITEA__mailer__HOST=smtp.sendgrid.net:587
|
||||
GITEA__mailer__FROM=gitea@cazzzer.com
|
||||
GITEA__mailer__USER=apikey
|
||||
GITEA__mailer__PASSWD="{{ sendgrid_api_key }}"
|
||||
|
||||
# Security
|
||||
GITEA__security__SECRET_KEY="{{ secret_key }}"
|
||||
GITEA__security__INTERNAL_TOKEN="{{ internal_token }}"
|
||||
|
||||
GITEA__oauth2__JWT_SECRET="{{ jwt_secret }}"
|
||||
39
roles/gitea/templates/docker-compose.yml.j2
Normal file
39
roles/gitea/templates/docker-compose.yml.j2
Normal file
@@ -0,0 +1,39 @@
|
||||
version: "3.9"
|
||||
|
||||
networks:
|
||||
default:
|
||||
traefik_traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
gitea:
|
||||
postgres:
|
||||
|
||||
services:
|
||||
server:
|
||||
image: gitea/gitea:1.17.2
|
||||
container_name: gitea_server
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.gitea.rule=Host(`gitea.{{ domain }}`)
|
||||
- traefik.http.services.gitea.loadbalancer.server.port=3000
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.gitea
|
||||
networks:
|
||||
- default
|
||||
- traefik_traefik
|
||||
volumes:
|
||||
- gitea:/data
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
image: postgres:14-alpine
|
||||
container_name: gitea_db
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.db
|
||||
networks:
|
||||
- default
|
||||
volumes:
|
||||
- postgres:/var/lib/postgresql/data
|
||||
27
roles/gitea/vars/app_config.yml
Normal file
27
roles/gitea/vars/app_config.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
$ANSIBLE_VAULT;1.2;AES256;alpina
|
||||
35303032386566343430633238343936366234333434343763666231666232633539303232383534
|
||||
3035346233346162373939333531613535353232626531640a646537616163353736653161326265
|
||||
31336530316335623335353661373834613264326436303933326135396166346562343136353931
|
||||
6439383039346465300a366266393130356630316630333336616565366562613038393239623738
|
||||
65626664643630353236333932373337333363626337386163613464306638633964663264363964
|
||||
30373661393531306662323134626664656233323762393037356434353066343830333033316365
|
||||
65616636613437663737306263373066306361376630616331663031346434336663393862316464
|
||||
62343339663461353934323063653566303932656264363562333136353665336263646230323832
|
||||
35376666303531383961646234663230663634393135326664386665633538616233613866373965
|
||||
64363361313232316336376631646662376565353536316438306361306261663532386564616566
|
||||
61663534393035343233326562303863646165346538393761326335376165623964396130393831
|
||||
64333665313461666335383134613831376138393061343238643661366439636534626265323865
|
||||
35393035336632653038623438626366373733626331633866373935616531623664303063376562
|
||||
31356332346164663364636235333461383437623161343338643839323765336237633266633864
|
||||
64363234646533616439313638363865373364623637636537623666383664656630333533303233
|
||||
64383734366666633832393230663739333435666138636462336332373061346239306136336263
|
||||
39643666303863303035313738343664636536663939616335303834333834363739303938646665
|
||||
66303637633239373461393434313036316563313132356432633337666537616363373830313034
|
||||
61313538633663653230643262613333306361666131663036643162343966313365653566393235
|
||||
36623832663034373734653664613038363137366437326565373761663963636336393536386435
|
||||
30393831326134376639366661653439616138643438646363343632346131306532663439396534
|
||||
32383661306539306635336262383563376561303862396532633362666266313562623336383235
|
||||
36366565633734633639653239306331333237353233326563653930653739316230666362323931
|
||||
39663931376562653530323434656436353166393836643238643632396430353034333034333665
|
||||
62323338373839383132323537353431636537616366393965643463316164323034316536383961
|
||||
6164333537633631646663333463306236613038326339643439
|
||||
5
roles/gitea/vars/main.yml
Normal file
5
roles/gitea/vars/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
current_svc_name: gitea
|
||||
current_svc_path: "{{ my_svc_path }}/{{ current_svc_name }}"
|
||||
|
||||
templates_source: "{{ role_path }}/templates"
|
||||
33
roles/jellyfin/tasks/main.yml
Normal file
33
roles/jellyfin/tasks/main.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
# https://stackoverflow.com/questions/41667864/can-the-templates-module-handle-multiple-templates-directories
|
||||
|
||||
- name: Ensure service directory exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
|
||||
- name: Ensure directory structure exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}/{{ item.path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "directory"
|
||||
|
||||
|
||||
- name: Include app config variables
|
||||
include_vars:
|
||||
file: "{{ role_path }}/vars/app_config.yml"
|
||||
|
||||
- name: Generate {{ current_svc_name }} deployment from templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ current_svc_path }}/{{ item.path | regex_replace('\\.j2$', '') }}"
|
||||
mode: "400"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "file"
|
||||
|
||||
- name: Deploy docker-compose for {{ current_svc_name }}
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ current_svc_path }}"
|
||||
state: present
|
||||
1
roles/jellyfin/templates/.env.jellyfin.j2
Normal file
1
roles/jellyfin/templates/.env.jellyfin.j2
Normal file
@@ -0,0 +1 @@
|
||||
JELLYFIN_PublishedServerUrl="https://jellyfin.{{ domain }}"
|
||||
35
roles/jellyfin/templates/docker-compose.yml.j2
Normal file
35
roles/jellyfin/templates/docker-compose.yml.j2
Normal file
@@ -0,0 +1,35 @@
|
||||
version: "3.9"
|
||||
|
||||
networks:
|
||||
default:
|
||||
traefik_traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
config:
|
||||
cache:
|
||||
media:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: nfs
|
||||
o: "addr=truenas.lab.home,nfsvers=4,ro,noatime"
|
||||
device: ":/mnt/Mass-Storage-New/JailStorage/Plex"
|
||||
|
||||
services:
|
||||
jellyfin:
|
||||
image: jellyfin/jellyfin:10.8.5
|
||||
container_name: jellyfin_jellyfin
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.jellyfin.rule=Host(`jellyfin.{{ domain }}`)
|
||||
- traefik.http.services.jellyfin.loadbalancer.server.port=8096
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.jellyfin
|
||||
networks:
|
||||
- default
|
||||
- traefik_traefik
|
||||
volumes:
|
||||
- config:/config
|
||||
- cache:/cache
|
||||
- media:/data/media
|
||||
6
roles/jellyfin/vars/app_config.yml
Normal file
6
roles/jellyfin/vars/app_config.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
$ANSIBLE_VAULT;1.2;AES256;alpina
|
||||
61626665353536663033663661393434616339396434383530306265363837313839303939623465
|
||||
3634333839333530383464613966326238363738663637360a343837623832343232316565346131
|
||||
66663831356162653363383131396665326531363430656539333866313031306537343864343262
|
||||
3730643765633232620a643734623336646565663266656262343162613239306166386665333139
|
||||
6366
|
||||
5
roles/jellyfin/vars/main.yml
Normal file
5
roles/jellyfin/vars/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
current_svc_name: jellyfin
|
||||
current_svc_path: "{{ my_svc_path }}/{{ current_svc_name }}"
|
||||
|
||||
templates_source: "{{ role_path }}/templates"
|
||||
33
roles/nextcloud/tasks/main.yml
Normal file
33
roles/nextcloud/tasks/main.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
# https://stackoverflow.com/questions/41667864/can-the-templates-module-handle-multiple-templates-directories
|
||||
|
||||
- name: Ensure service directory exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
|
||||
- name: Ensure directory structure exists
|
||||
file:
|
||||
path: "{{ current_svc_path }}/{{ item.path }}"
|
||||
state: directory
|
||||
mode: "500"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "directory"
|
||||
|
||||
|
||||
- name: Include app config variables
|
||||
include_vars:
|
||||
file: "{{ role_path }}/vars/app_config.yml"
|
||||
|
||||
- name: Generate {{ current_svc_name }} deployment from templates
|
||||
template:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ current_svc_path }}/{{ item.path | regex_replace('\\.j2$', '') }}"
|
||||
mode: "400"
|
||||
with_community.general.filetree: "{{ templates_source }}"
|
||||
when: item.state == "file"
|
||||
|
||||
- name: Deploy docker-compose for {{ current_svc_name }}
|
||||
community.docker.docker_compose:
|
||||
project_src: "{{ current_svc_path }}"
|
||||
state: present
|
||||
@@ -1,3 +1,3 @@
|
||||
POSTGRES_USER=nextcloud
|
||||
POSTGRES_DB=nextcloud
|
||||
POSTGRES_PASSWORD={{ nextcloud_db_password }}
|
||||
POSTGRES_PASSWORD="{{ db_password }}"
|
||||
18
roles/nextcloud/templates/.env.nextcloud.j2
Normal file
18
roles/nextcloud/templates/.env.nextcloud.j2
Normal file
@@ -0,0 +1,18 @@
|
||||
POSTGRES_DB=nextcloud
|
||||
POSTGRES_USER=nextcloud
|
||||
POSTGRES_PASSWORD="{{ db_password }}"
|
||||
POSTGRES_HOST=db
|
||||
|
||||
NEXTCLOUD_TRUSTED_DOMAINS=nc.cazzzer.com
|
||||
|
||||
REDIS_HOST=redis
|
||||
REDIS_HOST_PASSWORD="{{ redis_password }}"
|
||||
|
||||
SMTP_HOST=smtp.sendgrid.net
|
||||
SMTP_SECURE=tls
|
||||
SMTP_PORT=587
|
||||
SMTP_AUTHTYPE=LOGIN
|
||||
SMTP_NAME=apikey
|
||||
SMTP_PASSWORD="{{ sendgrid_api_key }}"
|
||||
MAIL_FROM_ADDRESS=nc
|
||||
MAIL_DOMAIN=cazzzer.com
|
||||
1
roles/nextcloud/templates/.env.redis.j2
Normal file
1
roles/nextcloud/templates/.env.redis.j2
Normal file
@@ -0,0 +1 @@
|
||||
REDIS_PASSWORD="{{ redis_password }}"
|
||||
96
roles/nextcloud/templates/docker-compose.yml.j2
Normal file
96
roles/nextcloud/templates/docker-compose.yml.j2
Normal file
@@ -0,0 +1,96 @@
|
||||
version: "3.9"
|
||||
|
||||
networks:
|
||||
default:
|
||||
traefik_traefik:
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
nextcloud:
|
||||
nextcloud_config:
|
||||
nextcloud_data:
|
||||
db:
|
||||
|
||||
services:
|
||||
app:
|
||||
image: nextcloud:24-fpm-alpine
|
||||
container_name: nextcloud_app
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
env_file:
|
||||
- .env.nextcloud
|
||||
networks:
|
||||
- default
|
||||
volumes:
|
||||
- nextcloud:/var/www/html
|
||||
- nextcloud_config:/var/www/html/config
|
||||
- nextcloud_data:/var/www/html/data
|
||||
|
||||
cron:
|
||||
image: nextcloud:24-fpm-alpine
|
||||
container_name: nextcloud_cron
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- app
|
||||
entrypoint: /cron.sh
|
||||
networks:
|
||||
- default
|
||||
volumes_from:
|
||||
- app
|
||||
|
||||
notify_push:
|
||||
image: nextcloud:24-fpm-alpine
|
||||
container_name: nextcloud_notify_push
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- app
|
||||
entrypoint:
|
||||
- /var/www/html/custom_apps/notify_push/bin/x86_64/notify_push
|
||||
- /var/www/html/config/config.php
|
||||
networks:
|
||||
- default
|
||||
volumes_from:
|
||||
- app
|
||||
|
||||
db:
|
||||
image: postgres:13-alpine
|
||||
container_name: nextcloud_db
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.db
|
||||
networks:
|
||||
- default
|
||||
volumes:
|
||||
- db:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: nextcloud_redis
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env.redis
|
||||
networks:
|
||||
- default
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- redis-server --requirepass $$REDIS_PASSWORD
|
||||
|
||||
web:
|
||||
image: nginx:1.23-alpine
|
||||
container_name: nextcloud_web
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.nextcloud.rule=Host(`nc.{{ domain }}`)
|
||||
restart: unless-stopped
|
||||
links:
|
||||
- app
|
||||
networks:
|
||||
- traefik_traefik
|
||||
- default
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf
|
||||
volumes_from:
|
||||
- app
|
||||
182
roles/nextcloud/templates/nginx.conf.j2
Normal file
182
roles/nextcloud/templates/nginx.conf.j2
Normal file
@@ -0,0 +1,182 @@
|
||||
# https://github.com/nextcloud/docker/blob/master/.examples/docker-compose/with-nginx-proxy/postgres/fpm/web/nginx.conf
|
||||
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
|
||||
# Prevent nginx HTTP Server Detection
|
||||
server_tokens off;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
upstream php-handler {
|
||||
server app:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
# HSTS settings
|
||||
# WARNING: Only add the preload option once you read about
|
||||
# the consequences in https://hstspreload.org/. This option
|
||||
# will add the domain to a hardcoded list that is shipped
|
||||
# in all major browsers and getting removed from this list
|
||||
# could take several months.
|
||||
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
|
||||
|
||||
# set max upload size
|
||||
client_max_body_size 512M;
|
||||
fastcgi_buffers 64 4K;
|
||||
|
||||
# Enable gzip but do not remove ETag headers
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
|
||||
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
|
||||
|
||||
# Pagespeed is not supported by Nextcloud, so if your server is built
|
||||
# with the `ngx_pagespeed` module, uncomment this line to disable it.
|
||||
#pagespeed off;
|
||||
|
||||
# HTTP response headers borrowed from Nextcloud `.htaccess`
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Download-Options "noopen" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Permitted-Cross-Domain-Policies "none" always;
|
||||
add_header X-Robots-Tag "none" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
# Remove X-Powered-By, which is an information leak
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
|
||||
# Path to the root of your installation
|
||||
root /var/www/html;
|
||||
|
||||
# Specify how to handle directories -- specifying `/index.php$request_uri`
|
||||
# here as the fallback means that Nginx always exhibits the desired behaviour
|
||||
# when a client requests a path that corresponds to a directory that exists
|
||||
# on the server. In particular, if that directory contains an index.php file,
|
||||
# that file is correctly served; if it doesn't, then the request is passed to
|
||||
# the front-end controller. This consistent behaviour means that we don't need
|
||||
# to specify custom rules for certain paths (e.g. images and other assets,
|
||||
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
|
||||
# `try_files $uri $uri/ /index.php$request_uri`
|
||||
# always provides the desired behaviour.
|
||||
index index.php index.html /index.php$request_uri;
|
||||
|
||||
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
|
||||
location = / {
|
||||
if ( $http_user_agent ~ ^DavClnt ) {
|
||||
return 302 /remote.php/webdav/$is_args$args;
|
||||
}
|
||||
}
|
||||
|
||||
location = /robots.txt {
|
||||
allow all;
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# Make a regex exception for `/.well-known` so that clients can still
|
||||
# access it despite the existence of the regex rule
|
||||
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
|
||||
# for `/.well-known`.
|
||||
location ^~ /.well-known {
|
||||
# The rules in this block are an adaptation of the rules
|
||||
# in `.htaccess` that concern `/.well-known`.
|
||||
|
||||
location = /.well-known/carddav { return 301 /remote.php/dav/; }
|
||||
location = /.well-known/caldav { return 301 /remote.php/dav/; }
|
||||
|
||||
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
|
||||
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
|
||||
|
||||
# Let Nextcloud's API for `/.well-known` URIs handle all other
|
||||
# requests by passing them to the front-end controller.
|
||||
return 301 /index.php$request_uri;
|
||||
}
|
||||
|
||||
# Rules borrowed from `.htaccess` to hide certain paths from clients
|
||||
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
|
||||
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
|
||||
|
||||
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
|
||||
# which handle static assets (as seen below). If this block is not declared first,
|
||||
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
|
||||
# to the URI, resulting in a HTTP 500 error response.
|
||||
location ~ \.php(?:$|/) {
|
||||
# Required for legacy support
|
||||
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
|
||||
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
set $path_info $fastcgi_path_info;
|
||||
|
||||
try_files $fastcgi_script_name =404;
|
||||
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PATH_INFO $path_info;
|
||||
#fastcgi_param HTTPS on;
|
||||
|
||||
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
|
||||
fastcgi_param front_controller_active true; # Enable pretty urls
|
||||
fastcgi_pass php-handler;
|
||||
|
||||
fastcgi_intercept_errors on;
|
||||
fastcgi_request_buffering off;
|
||||
}
|
||||
|
||||
location ~ \.(?:css|js|svg|gif)$ {
|
||||
try_files $uri /index.php$request_uri;
|
||||
expires 6M; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
}
|
||||
|
||||
location ~ \.woff2?$ {
|
||||
try_files $uri /index.php$request_uri;
|
||||
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
||||
access_log off; # Optional: Don't log access to assets
|
||||
}
|
||||
|
||||
# Rule borrowed from `.htaccess`
|
||||
location /remote {
|
||||
return 301 /remote.php$request_uri;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$request_uri;
|
||||
}
|
||||
|
||||
location ^~ /push/ {
|
||||
proxy_pass http://notify_push:7867/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
roles/nextcloud/vars/app_config.yml
Normal file
14
roles/nextcloud/vars/app_config.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
$ANSIBLE_VAULT;1.2;AES256;alpina
|
||||
65313636646233613364363933616361346639653939346337303832646339316632383966666237
|
||||
3766396134383434613534373937663162393134306536300a626139373732393037346630333838
|
||||
63663439353238643532316231623866396434303034313130386635623363353263626362376334
|
||||
3933346434633662320a386432373465646432343338666561366161646335636232353133393933
|
||||
65313364666564353039626238383033343765323730316633356139326666623135326131353864
|
||||
32386237643538636538356261393164633137636235346564393930346539623731386633336339
|
||||
31303466653936343166366164383134306232613236663735623834393963306331376435616365
|
||||
31313866383730393063353335626164303632636331303830636530656131636139376633623439
|
||||
63663639323964623231343066373538633336353561646230363363643762393634643435306164
|
||||
31366364326237636365336363343264343562353337303235633034383635373934376334353336
|
||||
61373065386639643064303431623162373665363937353832313561386134613834613935653964
|
||||
64656339316165313936333736643030356366663162316462636662326134396539356262666536
|
||||
64336133393937396330353234316563356337623733326264363333373536633833
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user