mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-06-24 19:25:32 +02:00
Compare commits
7 Commits
1ed26ab706
...
cfc052c129
Author | SHA1 | Date | |
---|---|---|---|
cfc052c129 | |||
20c3fdd455 | |||
68287c3c66 | |||
716c1c40e9 | |||
aa4d54c0c2 | |||
0ca33139b8 | |||
0114b30824 |
@ -2,7 +2,7 @@
|
||||
defaults_service_provider:
|
||||
type: "legal" # Accepted Values: natural, legal
|
||||
company:
|
||||
titel: "CyMaIS GbR"
|
||||
titel: "CyMaIS by Kevin Veen-Birkenbach"
|
||||
slogan: "CyMaIS — Empowering a Sovereign Digital Future."
|
||||
address:
|
||||
street: "Binary Avenue 01"
|
||||
|
15
main.py
15
main.py
@ -162,12 +162,17 @@ if __name__ == "__main__":
|
||||
text=True
|
||||
)
|
||||
os.close(slave_fd)
|
||||
import errno
|
||||
with os.fdopen(master_fd) as master:
|
||||
for line in master:
|
||||
ts = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
||||
log_file.write(f"{ts} {line}")
|
||||
log_file.flush()
|
||||
print(line, end='')
|
||||
try:
|
||||
for line in master:
|
||||
ts = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
|
||||
log_file.write(f"{ts} {line}")
|
||||
log_file.flush()
|
||||
print(line, end='')
|
||||
except OSError as e:
|
||||
if e.errno != errno.EIO:
|
||||
raise
|
||||
proc.wait()
|
||||
rc = proc.returncode
|
||||
else:
|
||||
|
@ -1,16 +1,27 @@
|
||||
- name: Check if docker is installed
|
||||
ansible.builtin.stat:
|
||||
path: /usr/bin/docker
|
||||
register: docker_bin
|
||||
|
||||
- name: "pkgmgr install"
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
vars:
|
||||
package_name: dockreap
|
||||
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
when:
|
||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
- docker_bin.stat.exists
|
||||
|
||||
- name: run dockreap with --no-confirmation
|
||||
command:
|
||||
cmd: "dockreap --no-confirmation"
|
||||
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
when:
|
||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
- docker_bin.stat.exists
|
||||
|
||||
- name: mark dockreap as run
|
||||
set_fact:
|
||||
run_once_cleanup_docker_anonymous_volumes: true
|
||||
when: run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
when:
|
||||
- run_once_cleanup_docker_anonymous_volumes is not defined
|
||||
- docker_bin.stat.exists
|
||||
|
5
roles/docker-nextcloud/Administration.md
Normal file
5
roles/docker-nextcloud/Administration.md
Normal file
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
# 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;
|
||||
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always;
|
||||
|
||||
# set max upload size
|
||||
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
|
||||
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:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -2,6 +2,11 @@ version: "13" # Update when available. Sadly no rolling release
|
||||
oauth2_proxy:
|
||||
application: "proxy"
|
||||
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:
|
||||
filters:
|
||||
administrators: True # Set true to filter administrators
|
||||
|
@ -114,5 +114,8 @@ class LookupModule(LookupBase):
|
||||
|
||||
cards.append(card)
|
||||
|
||||
# Sort A-Z
|
||||
cards.sort(key=lambda c: c['title'].lower())
|
||||
|
||||
# Return the list of cards
|
||||
return [cards]
|
||||
|
@ -43,9 +43,10 @@
|
||||
- name: Debug portfolio data
|
||||
debug:
|
||||
msg:
|
||||
portfolio_cards: "{{ portfolio_cards }}"
|
||||
portfolio_menu_categories: "{{ portfolio_menu_categories}}"
|
||||
portfolio_menu_data: "{{ portfolio_menu_data }}"
|
||||
portfolio_cards: "{{ portfolio_cards }}"
|
||||
portfolio_menu_categories: "{{ portfolio_menu_categories}}"
|
||||
portfolio_menu_data: "{{ portfolio_menu_data }}"
|
||||
service_provider: "{{ service_provider }}"
|
||||
when:
|
||||
- enable_debug | bool
|
||||
- run_once_docker_portfolio is not defined
|
||||
|
@ -93,7 +93,7 @@ platform:
|
||||
source: {{service_provider.platform.favicon}}
|
||||
company:
|
||||
titel: {{service_provider.company.titel}}
|
||||
subtitel: {{service_provider.company.subtitel}}
|
||||
subtitel: {{service_provider.company.slogan}}
|
||||
logo:
|
||||
source: {{service_provider.company.logo}}
|
||||
address:
|
||||
|
@ -5,7 +5,9 @@ version: "latest"
|
||||
oauth2_proxy:
|
||||
application: "application"
|
||||
port: "80"
|
||||
location: "/admin/" # Protects the admin area
|
||||
acl:
|
||||
blacklist:
|
||||
- "/admin/" # Protects the admin area
|
||||
features:
|
||||
matomo: true
|
||||
css: true
|
||||
|
@ -1,5 +1,5 @@
|
||||
- name: reload health-msmtp.cymais.service
|
||||
- name: "reload health-journalctl.cymais.service"
|
||||
systemd:
|
||||
name: health-msmtp.cymais.service
|
||||
name: health-journalctl.cymais.service
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
@ -1,5 +1,5 @@
|
||||
- name: "reload health-journalctl.cymais.service"
|
||||
- name: reload health-msmtp.cymais.service
|
||||
systemd:
|
||||
name: health-journalctl.cymais.service
|
||||
name: health-msmtp.cymais.service
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
daemon_reload: yes
|
@ -15,21 +15,47 @@ server
|
||||
|
||||
{% include 'roles/letsencrypt/templates/ssl_header.j2' %}
|
||||
|
||||
{% if applications | is_feature_enabled('oauth2',application_id) %}
|
||||
{% if applications[application_id].oauth2_proxy.location is defined %}
|
||||
{# Exposed and Unprotected Location #}
|
||||
{% if applications | is_feature_enabled('oauth2', application_id) %}
|
||||
{% set acl = applications[application_id].oauth2_proxy.acl | default({}) %}
|
||||
|
||||
{% 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' %}
|
||||
|
||||
{% 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 location = applications[application_id].oauth2_proxy.location %}
|
||||
{# Gated Location by OAuth2 Proxy #}
|
||||
{% set location = "/" %}
|
||||
{% 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 %}
|
||||
{# 3. OAuth2 enabled but no (or empty) ACL — protect all #}
|
||||
{% set oauth2_proxy_enabled = true %}
|
||||
{# Protected Domain by OAuth2 Proxy #}
|
||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2'%}
|
||||
{% set location = "/" %}
|
||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
{# Exposed Domain - Not protected by OAuth2 Proxy #}
|
||||
{# 4. OAuth2 completely disabled — expose all #}
|
||||
{% set oauth2_proxy_enabled = false %}
|
||||
{% set location = "/" %}
|
||||
{% include 'roles/nginx-docker-reverse-proxy/templates/location/proxy_basic.conf.j2' %}
|
||||
{% endif %}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1198,4 +1198,9 @@ input.ng-empty::placeholder,.ng-empty::placeholder {
|
||||
.navbar-toggler {
|
||||
background-color: rgba(var(--color-rgb-01-75), 0.9);
|
||||
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 /
|
||||
{
|
||||
alias {{nginx.directories.data.files}}; {# Path to your file directory #}
|
||||
autoindex on; {# Enable directory listing #}
|
||||
autoindex_exact_size off; {# Display sizes in a human-readable format #}
|
||||
autoindex_localtime on; {# Show local time #}
|
||||
autoindex on; {# Enable directory listing #}
|
||||
autoindex_exact_size off; {# Display sizes in a human-readable format #}
|
||||
autoindex_localtime on; {# Show local time #}
|
||||
}
|
||||
|
||||
location /.well-known/ {
|
||||
|
@ -11,7 +11,7 @@
|
||||
<h2>Information in accordance with § 5 TMG</h2>
|
||||
<p>
|
||||
<strong>{{ service_provider.company.titel }}</strong><br>
|
||||
{{ service_provider.company.subtitel }}<br>
|
||||
{{ service_provider.company.slogan }}<br>
|
||||
<br>
|
||||
<strong>Address:</strong><br>
|
||||
{{ service_provider.company.address.street }}<br>
|
||||
|
@ -35,3 +35,4 @@ galaxy_info:
|
||||
dependencies:
|
||||
- git
|
||||
- make
|
||||
- python-yaml
|
||||
|
20
roles/python-yaml/README.md
Normal file
20
roles/python-yaml/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# 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.
|
24
roles/python-yaml/meta/main.yml
Normal file
24
roles/python-yaml/meta/main.yml
Normal file
@ -0,0 +1,24 @@
|
||||
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"
|
11
roles/python-yaml/tasks/main.yml
Normal file
11
roles/python-yaml/tasks/main.yml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
- 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 |
|
||||
canonical_domains_map(primary_domain) |
|
||||
combine(domains | default({}, true), recursive=True)
|
||||
combine(current_play_domains, recursive=True)
|
||||
}}
|
||||
|
||||
- name: Merge redirect_domain_mappings
|
||||
@ -44,7 +44,7 @@
|
||||
redirect_domain_mappings: "{{
|
||||
[] |
|
||||
add_redirect_if_group('assets-server', domains | get_domain('assets-server'), domains | get_domain('file-server'), group_names) |
|
||||
merge_mapping(redirect_domain_mappings, 'source')
|
||||
merge_mapping(redirect_domain_mappings| default([]), 'source')
|
||||
}}"
|
||||
|
||||
- name: Set current play redirect domain mappings
|
||||
|
45
tests/integration/test_oauth2_acl_mutual_exclusive.py
Normal file
45
tests/integration/test_oauth2_acl_mutual_exclusive.py
Normal file
@ -0,0 +1,45 @@
|
||||
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