mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-25 11:45:32 +02:00
Compare commits
No commits in common. "cfc052c1293365b92af9a5a6291ffa7f0e4960e5" and "1ed26ab706ac6ea37822d9c7de4043ee075e0fdb" have entirely different histories.
cfc052c129
...
1ed26ab706
@ -2,7 +2,7 @@
|
|||||||
defaults_service_provider:
|
defaults_service_provider:
|
||||||
type: "legal" # Accepted Values: natural, legal
|
type: "legal" # Accepted Values: natural, legal
|
||||||
company:
|
company:
|
||||||
titel: "CyMaIS by Kevin Veen-Birkenbach"
|
titel: "CyMaIS GbR"
|
||||||
slogan: "CyMaIS — Empowering a Sovereign Digital Future."
|
slogan: "CyMaIS — Empowering a Sovereign Digital Future."
|
||||||
address:
|
address:
|
||||||
street: "Binary Avenue 01"
|
street: "Binary Avenue 01"
|
||||||
|
15
main.py
15
main.py
@ -162,17 +162,12 @@ if __name__ == "__main__":
|
|||||||
text=True
|
text=True
|
||||||
)
|
)
|
||||||
os.close(slave_fd)
|
os.close(slave_fd)
|
||||||
import errno
|
|
||||||
with os.fdopen(master_fd) as master:
|
with os.fdopen(master_fd) as master:
|
||||||
try:
|
for line in master:
|
||||||
for line in master:
|
ts = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
ts = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
log_file.write(f"{ts} {line}")
|
||||||
log_file.write(f"{ts} {line}")
|
log_file.flush()
|
||||||
log_file.flush()
|
print(line, end='')
|
||||||
print(line, end='')
|
|
||||||
except OSError as e:
|
|
||||||
if e.errno != errno.EIO:
|
|
||||||
raise
|
|
||||||
proc.wait()
|
proc.wait()
|
||||||
rc = proc.returncode
|
rc = proc.returncode
|
||||||
else:
|
else:
|
||||||
|
@ -1,27 +1,16 @@
|
|||||||
- name: Check if docker is installed
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /usr/bin/docker
|
|
||||||
register: docker_bin
|
|
||||||
|
|
||||||
- name: "pkgmgr install"
|
- name: "pkgmgr install"
|
||||||
include_role:
|
include_role:
|
||||||
name: pkgmgr-install
|
name: pkgmgr-install
|
||||||
vars:
|
vars:
|
||||||
package_name: dockreap
|
package_name: dockreap
|
||||||
when:
|
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
|
||||||
- docker_bin.stat.exists
|
|
||||||
|
|
||||||
- name: run dockreap with --no-confirmation
|
- name: run dockreap with --no-confirmation
|
||||||
command:
|
command:
|
||||||
cmd: "dockreap --no-confirmation"
|
cmd: "dockreap --no-confirmation"
|
||||||
when:
|
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
|
||||||
- docker_bin.stat.exists
|
|
||||||
|
|
||||||
- name: mark dockreap as run
|
- name: mark dockreap as run
|
||||||
set_fact:
|
set_fact:
|
||||||
run_once_cleanup_docker_anonymous_volumes: true
|
run_once_cleanup_docker_anonymous_volumes: true
|
||||||
when:
|
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
|
||||||
- docker_bin.stat.exists
|
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
# Administration
|
|
||||||
|
|
||||||
## Logs
|
|
||||||
|
|
||||||
The logs you will find here on the host: **/var/lib/docker/volumes/nextcloud_data/_data/data/nextcloud.log**
|
|
@ -49,7 +49,7 @@ http {
|
|||||||
# will add the domain to a hardcoded list that is shipped
|
# will add the domain to a hardcoded list that is shipped
|
||||||
# in all major browsers and getting removed from this list
|
# in all major browsers and getting removed from this list
|
||||||
# could take several months.
|
# could take several months.
|
||||||
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
|
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
|
||||||
|
|
||||||
# set max upload size
|
# set max upload size
|
||||||
client_max_body_size 512M;
|
client_max_body_size 512M;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it
|
configuration_file: "oauth2-proxy-keycloak.cfg" # Needs to be set true in the roles which use it
|
||||||
version: "latest" # Docker Image version
|
version: "latest" # Docker Image version
|
||||||
allowed_roles: "admin" # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups
|
allowed_roles: admin # Restrict it default to admin role. Use the vars/main.yml to open the specific role for other groups
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -2,11 +2,6 @@ version: "13" # Update when available. Sadly no rolling release
|
|||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
application: "proxy"
|
application: "proxy"
|
||||||
port: "80"
|
port: "80"
|
||||||
acl:
|
|
||||||
whitelist:
|
|
||||||
- "/users/me" # Necessary for Nextcloud Plugin to work
|
|
||||||
- "/api/" # Necessary for Nextcloud Plugin to work
|
|
||||||
- "/oauth/token" # Necessary for Nextcloud Plugin to work
|
|
||||||
ldap:
|
ldap:
|
||||||
filters:
|
filters:
|
||||||
administrators: True # Set true to filter administrators
|
administrators: True # Set true to filter administrators
|
||||||
|
@ -114,8 +114,5 @@ class LookupModule(LookupBase):
|
|||||||
|
|
||||||
cards.append(card)
|
cards.append(card)
|
||||||
|
|
||||||
# Sort A-Z
|
|
||||||
cards.sort(key=lambda c: c['title'].lower())
|
|
||||||
|
|
||||||
# Return the list of cards
|
# Return the list of cards
|
||||||
return [cards]
|
return [cards]
|
||||||
|
@ -43,10 +43,9 @@
|
|||||||
- name: Debug portfolio data
|
- name: Debug portfolio data
|
||||||
debug:
|
debug:
|
||||||
msg:
|
msg:
|
||||||
portfolio_cards: "{{ portfolio_cards }}"
|
portfolio_cards: "{{ portfolio_cards }}"
|
||||||
portfolio_menu_categories: "{{ portfolio_menu_categories}}"
|
portfolio_menu_categories: "{{ portfolio_menu_categories}}"
|
||||||
portfolio_menu_data: "{{ portfolio_menu_data }}"
|
portfolio_menu_data: "{{ portfolio_menu_data }}"
|
||||||
service_provider: "{{ service_provider }}"
|
|
||||||
when:
|
when:
|
||||||
- enable_debug | bool
|
- enable_debug | bool
|
||||||
- run_once_docker_portfolio is not defined
|
- run_once_docker_portfolio is not defined
|
||||||
|
@ -93,7 +93,7 @@ platform:
|
|||||||
source: {{service_provider.platform.favicon}}
|
source: {{service_provider.platform.favicon}}
|
||||||
company:
|
company:
|
||||||
titel: {{service_provider.company.titel}}
|
titel: {{service_provider.company.titel}}
|
||||||
subtitel: {{service_provider.company.slogan}}
|
subtitel: {{service_provider.company.subtitel}}
|
||||||
logo:
|
logo:
|
||||||
source: {{service_provider.company.logo}}
|
source: {{service_provider.company.logo}}
|
||||||
address:
|
address:
|
||||||
|
@ -5,9 +5,7 @@ version: "latest"
|
|||||||
oauth2_proxy:
|
oauth2_proxy:
|
||||||
application: "application"
|
application: "application"
|
||||||
port: "80"
|
port: "80"
|
||||||
acl:
|
location: "/admin/" # Protects the admin area
|
||||||
blacklist:
|
|
||||||
- "/admin/" # Protects the admin area
|
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
- name: "reload health-journalctl.cymais.service"
|
- name: reload health-msmtp.cymais.service
|
||||||
systemd:
|
systemd:
|
||||||
name: health-journalctl.cymais.service
|
name: health-msmtp.cymais.service
|
||||||
enabled: yes
|
enabled: yes
|
||||||
daemon_reload: yes
|
daemon_reload: yes
|
@ -1,5 +1,5 @@
|
|||||||
- name: reload health-msmtp.cymais.service
|
- name: "reload health-journalctl.cymais.service"
|
||||||
systemd:
|
systemd:
|
||||||
name: health-msmtp.cymais.service
|
name: health-journalctl.cymais.service
|
||||||
enabled: yes
|
enabled: yes
|
||||||
daemon_reload: yes
|
daemon_reload: yes
|
||||||
|
@ -15,47 +15,21 @@ server
|
|||||||
|
|
||||||
{% include 'roles/letsencrypt/templates/ssl_header.j2' %}
|
{% include 'roles/letsencrypt/templates/ssl_header.j2' %}
|
||||||
|
|
||||||
{% if applications | is_feature_enabled('oauth2', application_id) %}
|
{% if applications | is_feature_enabled('oauth2',application_id) %}
|
||||||
{% set acl = applications[application_id].oauth2_proxy.acl | default({}) %}
|
{% if applications[application_id].oauth2_proxy.location is defined %}
|
||||||
|
{# Exposed and Unprotected Location #}
|
||||||
{% if acl.blacklist is defined %}
|
|
||||||
{# 1. Expose everything by default, then protect blacklisted paths #}
|
|
||||||
{% set oauth2_proxy_enabled = false %}
|
|
||||||
{% set location = "/" %}
|
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
||||||
|
|
||||||
{% for loc in acl.blacklist %}
|
|
||||||
{% set oauth2_proxy_enabled = true %}
|
|
||||||
{% set location = loc %}
|
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% elif acl.whitelist is defined %}
|
|
||||||
{# 2. Protect everything by default, then expose whitelisted paths #}
|
|
||||||
{% set oauth2_proxy_enabled = true %}
|
{% set oauth2_proxy_enabled = true %}
|
||||||
{% set location = "/" %}
|
{% set location = applications[application_id].oauth2_proxy.location %}
|
||||||
|
{# Gated Location by OAuth2 Proxy #}
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
||||||
|
|
||||||
{% for loc in acl.whitelist %}
|
|
||||||
{% set oauth2_proxy_enabled = false %}
|
|
||||||
{% set location = loc %}
|
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{# 3. OAuth2 enabled but no (or empty) ACL — protect all #}
|
|
||||||
{% set oauth2_proxy_enabled = true %}
|
{% set oauth2_proxy_enabled = true %}
|
||||||
{% set location = "/" %}
|
{# Protected Domain by OAuth2 Proxy #}
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2'%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{# 4. OAuth2 completely disabled — expose all #}
|
{# Exposed Domain - Not protected by OAuth2 Proxy #}
|
||||||
{% set oauth2_proxy_enabled = false %}
|
|
||||||
{% set location = "/" %}
|
|
||||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1198,9 +1198,4 @@ input.ng-empty::placeholder,.ng-empty::placeholder {
|
|||||||
.navbar-toggler {
|
.navbar-toggler {
|
||||||
background-color: rgba(var(--color-rgb-01-75), 0.9);
|
background-color: rgba(var(--color-rgb-01-75), 0.9);
|
||||||
border-color: var(--color-01-67)
|
border-color: var(--color-01-67)
|
||||||
}
|
|
||||||
|
|
||||||
.alert-info {
|
|
||||||
--bs-alert-color: var(--color-03-14);
|
|
||||||
--bs-alert-bg: var(--color-01-86);
|
|
||||||
}
|
}
|
@ -12,9 +12,9 @@ server
|
|||||||
location /
|
location /
|
||||||
{
|
{
|
||||||
alias {{nginx.directories.data.files}}; {# Path to your file directory #}
|
alias {{nginx.directories.data.files}}; {# Path to your file directory #}
|
||||||
autoindex on; {# Enable directory listing #}
|
autoindex on; {# Enable directory listing #}
|
||||||
autoindex_exact_size off; {# Display sizes in a human-readable format #}
|
autoindex_exact_size off; {# Display sizes in a human-readable format #}
|
||||||
autoindex_localtime on; {# Show local time #}
|
autoindex_localtime on; {# Show local time #}
|
||||||
}
|
}
|
||||||
|
|
||||||
location /.well-known/ {
|
location /.well-known/ {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<h2>Information in accordance with § 5 TMG</h2>
|
<h2>Information in accordance with § 5 TMG</h2>
|
||||||
<p>
|
<p>
|
||||||
<strong>{{ service_provider.company.titel }}</strong><br>
|
<strong>{{ service_provider.company.titel }}</strong><br>
|
||||||
{{ service_provider.company.slogan }}<br>
|
{{ service_provider.company.subtitel }}<br>
|
||||||
<br>
|
<br>
|
||||||
<strong>Address:</strong><br>
|
<strong>Address:</strong><br>
|
||||||
{{ service_provider.company.address.street }}<br>
|
{{ service_provider.company.address.street }}<br>
|
||||||
|
@ -35,4 +35,3 @@ galaxy_info:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- git
|
- git
|
||||||
- make
|
- make
|
||||||
- python-yaml
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
# Python-Yaml
|
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
This Ansible role installs the **python-yaml** package on the target system. It ensures that the Python `yaml` library is available for loading and processing YAML files.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Optimized for simplicity and idempotency, this role provides:
|
|
||||||
- Installation of the `python-yaml` package via the Pacman package manager.
|
|
||||||
- A mechanism to run the installation only once.
|
|
||||||
|
|
||||||
## Purpose
|
|
||||||
|
|
||||||
The purpose of this role is to reliably provide the Python-YAML package so that Python scripts can work with YAML files.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **YAML Support:** Installs the `python-yaml` package, which supplies the `yaml` library for Python.
|
|
||||||
- **Idempotency:** Uses a fact to ensure that the installation runs only on the first execution.
|
|
@ -1,24 +0,0 @@
|
|||||||
galaxy_info:
|
|
||||||
author: "Kevin Veen-Birkenbach"
|
|
||||||
description: >
|
|
||||||
Installs the `python-yaml` package to enable YAML support in Python.
|
|
||||||
license: "CyMaIS NonCommercial License (CNCL)"
|
|
||||||
license_url: "https://s.veen.world/cncl"
|
|
||||||
company: |
|
|
||||||
Kevin Veen-Birkenbach
|
|
||||||
Consulting & Coaching Solutions
|
|
||||||
https://www.veen.world
|
|
||||||
min_ansible_version: "2.9"
|
|
||||||
platforms:
|
|
||||||
- name: Archlinux
|
|
||||||
versions:
|
|
||||||
- rolling
|
|
||||||
galaxy_tags:
|
|
||||||
- python
|
|
||||||
- yaml
|
|
||||||
- package
|
|
||||||
- installation
|
|
||||||
- automation
|
|
||||||
repository: "https://s.veen.world/cymais"
|
|
||||||
issue_tracker_url: "https://s.veen.world/cymaisissues"
|
|
||||||
documentation: "https://s.veen.world/cymais"
|
|
@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: python-yaml install
|
|
||||||
pacman:
|
|
||||||
name: python-yaml
|
|
||||||
state: present
|
|
||||||
when: run_once_python_yaml is not defined
|
|
||||||
|
|
||||||
- name: run the python_yaml tasks once
|
|
||||||
set_fact:
|
|
||||||
run_once_python_yaml: true
|
|
||||||
when: run_once_python_yaml is not defined
|
|
@ -35,7 +35,7 @@
|
|||||||
{{
|
{{
|
||||||
defaults_applications |
|
defaults_applications |
|
||||||
canonical_domains_map(primary_domain) |
|
canonical_domains_map(primary_domain) |
|
||||||
combine(current_play_domains, recursive=True)
|
combine(domains | default({}, true), recursive=True)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
- name: Merge redirect_domain_mappings
|
- name: Merge redirect_domain_mappings
|
||||||
@ -44,7 +44,7 @@
|
|||||||
redirect_domain_mappings: "{{
|
redirect_domain_mappings: "{{
|
||||||
[] |
|
[] |
|
||||||
add_redirect_if_group('assets-server', domains | get_domain('assets-server'), domains | get_domain('file-server'), group_names) |
|
add_redirect_if_group('assets-server', domains | get_domain('assets-server'), domains | get_domain('file-server'), group_names) |
|
||||||
merge_mapping(redirect_domain_mappings| default([]), 'source')
|
merge_mapping(redirect_domain_mappings, 'source')
|
||||||
}}"
|
}}"
|
||||||
|
|
||||||
- name: Set current play redirect domain mappings
|
- name: Set current play redirect domain mappings
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
import os
|
|
||||||
import yaml
|
|
||||||
import unittest
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
ROLES_DIR = Path(__file__).resolve().parent.parent.parent / "roles"
|
|
||||||
|
|
||||||
class TestOauth2AclMutualExclusion(unittest.TestCase):
|
|
||||||
def test_acl_has_either_whitelist_or_blacklist(self):
|
|
||||||
failures = []
|
|
||||||
|
|
||||||
for role_path in ROLES_DIR.iterdir():
|
|
||||||
vars_file = role_path / "vars" / "configuration.yml"
|
|
||||||
if not vars_file.exists():
|
|
||||||
continue
|
|
||||||
|
|
||||||
# open the YAML file instead of passing the Path object
|
|
||||||
try:
|
|
||||||
with open(vars_file) as f:
|
|
||||||
data = yaml.safe_load(f) or {}
|
|
||||||
except yaml.YAMLError as e:
|
|
||||||
failures.append(f"{role_path.name}: failed to parse YAML ({e})")
|
|
||||||
continue
|
|
||||||
|
|
||||||
oauth2 = data.get("oauth2_proxy", {})
|
|
||||||
acl = oauth2.get("acl", None)
|
|
||||||
if acl is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
has_wl = "whitelist" in acl
|
|
||||||
has_bl = "blacklist" in acl
|
|
||||||
|
|
||||||
if has_wl and has_bl:
|
|
||||||
failures.append(
|
|
||||||
f"{role_path.name}: both 'whitelist' and 'blacklist' are defined"
|
|
||||||
)
|
|
||||||
|
|
||||||
if failures:
|
|
||||||
self.fail(
|
|
||||||
"The following roles define both whitelist and blacklist under oauth2_proxy.acl:\n"
|
|
||||||
+ "\n".join(failures)
|
|
||||||
)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
Loading…
x
Reference in New Issue
Block a user