Huge role refactoring/cleanup. Other commits will propably follow. Because some bugs will exist. Still important for longrun and also for auto docs/help/slideshow generation

This commit is contained in:
2025-07-08 23:43:13 +02:00
parent 6b87a049d4
commit 563d5fd528
1242 changed files with 2301 additions and 1355 deletions

View File

@@ -0,0 +1,7 @@
# Administration 🛠️
Clear and restart the application:
```bash
docker-compose exec application php artisan config:clear
docker-compose exec application php artisan cache:clear
docker-compose restart application
```

View File

@@ -0,0 +1,40 @@
# SnipeIT
## Description
SnipeIT is an opensource asset management system designed to streamline hardware and software inventory tracking. This deployment provides an automated, containerized solution using Docker Compose, centralized MariaDB database integration, and secure, configurable environment settings—including robust SMTP email support and pending SAML authentication enhancements.
## Overview
This Docker deployment uses Ansible automation to set up SnipeIT along with necessary services such as a MariaDB database, an optional OAuth2 proxy for additional security, and a reverse proxy configuration. The system is built for reliable asset management in various environments.
## Features
- **Automated Deployment:**
Launch SnipeIT quickly with Docker Compose and Ansible automation for a productionready platform.
- **Centralized Database Support:**
Leverage MariaDB for secure and reliable data storage.
- **Configurable SMTP Settings:**
Manage email notifications and alerts with customizable SMTP configurations.
- **Optional SAML Authentication:**
Prepare for enhanced, standardsbased authentication (integration pending).
- **Redis Caching:**
Improve application performance with builtin Redis caching support.
## Other Resources
- [SnipeIT Official Documentation](https://snipe-it.readme.io/docs/ldap-sync-login)
- [SAML Setup Instructions](https://snipe-it.readme.io/docs/saml)
- [Mattermost SSO Integration Guide](https://docs.mattermost.com/onboard/sso-saml-keycloak.html)
- [Additional GitHub Issues and Discussions](https://github.com/snipe/snipe-it/issues)
## Credits
Developed and maintained by **Kevin Veen-Birkenbach**.
Learn more at [veen.world](https://veen.world)
Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais)
License: [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl)

View File

@@ -0,0 +1,34 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "SnipeIT is an opensource asset management system providing a containerized deployment with centralized MariaDB integration, configurable SMTP settings, and pending SAML authentication enhancements for secure asset tracking and management."
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: Linux
versions:
- all
galaxy_tags:
- snipe-it
- asset-management
- docker
- mariadb
- smtp
- saml
- automation
repository: "https://s.veen.world/cymais"
issue_tracker_url: "https://s.veen.world/cymaisissues"
documentation: "https://s.veen.world/cymais"
logo:
class: "fa-solid fa-box"
run_after:
- web-app-matomo
- web-app-keycloak
- web-app-mailu
dependencies: []

View File

@@ -0,0 +1,5 @@
credentials:
app_key:
description: "Generic 32-byte base64 key with base64: prefix"
algorithm: base64_prefixed_32
validation: '^base64:[A-Za-z0-9+/]{43}=$'

View File

@@ -0,0 +1,106 @@
# @See https://raw.githubusercontent.com/snipe/snipe-it/master/app/Models/Setting.php
---
- name: "Wait until the Snipe-IT Login is available"
uri:
url: "{{ snipe_it_url }}/login"
method: GET
return_content: no
status_code: 200
register: snipeit_admin_check
retries: 30
delay: 5
until: snipeit_admin_check.status == 200
when: not ( applications | is_feature_enabled('oauth2', application_id))
- name: "Debug: show APP_KEY in container shell"
shell: |
docker-compose exec -T \
-u www-data \
-e XDG_CONFIG_HOME=/tmp \
-e APP_KEY='{{ applications[application_id].credentials.app_key }}' \
application \
sh -c 'echo "SHELL sees APP_KEY=$APP_KEY"'
args:
chdir: "/opt/docker/snipe-it/"
- name: "Debug: show APP_KEY in container shell"
shell: |
docker-compose exec -T -u www-data \
-e XDG_CONFIG_HOME=/tmp \
-e APP_KEY="{{ applications[application_id].credentials.app_key }}" \
application \
php artisan tinker --execute="echo 'CONFIG app.key: ' . config('app.key') . PHP_EOL;"
args:
chdir: "/opt/docker/snipe-it/"
- name: "Set all LDAP settings via Laravel Setting model (inside container as www-data)"
shell: |
docker-compose exec -T \
-e APP_KEY='{{ applications[application_id].credentials.app_key }}' \
-e XDG_CONFIG_HOME=/tmp \
-u www-data application \
sh -c 'php artisan tinker << "EOF"
$s = \App\Models\Setting::getSettings();
$s->ldap_enabled = 1;
$s->ldap_server = "{{ ldap.server.uri }}";
$s->ldap_port = {{ ldap.server.port }};
$s->ldap_uname = "{{ ldap.dn.administrator.data }}";
$s->ldap_basedn = "{{ ldap.dn.ou.users }}";
$s->ldap_filter = "&(objectClass=inetOrgPerson)";
$s->ldap_username_field = "{{ ldap.user.attributes.id }}";
$s->ldap_fname_field = "{{ ldap.user.attributes.firstname }}";
$s->ldap_lname_field = "{{ ldap.user.attributes.surname }}";
$s->ldap_auth_filter_query = "uid=";
$s->ldap_version = 3;
$s->ldap_pw_sync = 0;
$s->is_ad = 0;
$s->ad_domain = "";
$s->ldap_default_group = "";
$s->ldap_email = "{{ ldap.user.attributes.mail }}";
$s->custom_forgot_pass_url = "{{ oidc.client.reset_credentials }}";
$s->save();
EOF'
args:
chdir: "{{ docker_compose.directories.instance }}"
register: ldap_tinker
failed_when: >
ldap_tinker.stdout_lines is not defined
or ldap_tinker.stdout_lines[0] != '= true'
changed_when: >
ldap_tinker.stdout_lines is defined
and ldap_tinker.stdout_lines[0] == '= true'
notify: docker compose up
- name: Encrypt & save LDAP bind password via Crypt + DB façade
shell: |
docker-compose exec -T \
-u www-data \
-e APP_KEY="{{ applications[application_id].credentials.app_key }}" \
-e XDG_CONFIG_HOME=/tmp \
application \
php artisan tinker --execute="
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
/* encrypt the clear-text password */
\$encrypted = Crypt::encrypt('{{ ldap.bind_credential }}');
/* write it straight into settings.ldap_pword */
/* update the one and only row in `settings` */
DB::table('settings')->update([
'ldap_pword' => \$encrypted
]);
echo 'Stored: ' . \$encrypted . PHP_EOL;
"
args:
chdir: "/opt/docker/snipe-it/"
register: ldap_encrypt
failed_when: ldap_encrypt.rc != 0
- name: "Clear Laravel config & cache (inside container as www-data)"
shell: |
docker-compose exec -T -u www-data application php artisan config:clear
docker-compose exec -T -u www-data application php artisan cache:clear
args:
chdir: "{{ docker_compose.directories.instance }}"
notify: docker compose up

View File

@@ -0,0 +1,16 @@
---
- name: "include service-rdbms-central"
include_role:
name: service-rdbms-central
- name: "include role webserver-proxy-domain for {{application_id}}"
include_role:
name: webserver-proxy-domain
vars:
domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}"
- name: "Configure Snipe-IT LDAP settings"
import_tasks: ldap.yml
when: applications | is_feature_enabled('ldap',application_id)

View File

@@ -0,0 +1,18 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
{% set container_port = 80 %}
image: grokability/snipe-it:{{applications[application_id].version}}
{% include 'roles/docker-container/templates/base.yml.j2' %}
volumes:
- data:/var/lib/snipeit
ports:
- "127.0.0.1:{{ports.localhost.http[application_id]}}:{{ container_port }}"
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-compose/templates/volumes.yml.j2' %}
redis:
data:
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -0,0 +1,167 @@
# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
APP_ENV={{ CYMAIS_ENVIRONMENT | lower }}
APP_DEBUG={{enable_debug | string | lower }}
APP_KEY={{ applications[application_id].credentials.app_key}}
APP_URL={{ snipe_it_url }}
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones - TZ identifier
APP_TIMEZONE='{{ HOST_TIMEZONE }}'
APP_LOCALE={{ HOST_LL }}
MAX_RESULTS=500
# --------------------------------------------
# REQUIRED: UPLOADED FILE STORAGE SETTINGS
# --------------------------------------------
PRIVATE_FILESYSTEM_DISK=local
PUBLIC_FILESYSTEM_DISK=local_public
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=mysql
DB_HOST={{database_host}}
DB_PORT={{database_port}}
DB_DATABASE={{database_name}}
DB_USERNAME={{database_username}}
DB_PASSWORD={{database_password}}
{% if not applications | is_feature_enabled('central_database',application_id) %}
MYSQL_ROOT_PASSWORD={{database_password}}
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
{% endif %}
# --------------------------------------------
# OPTIONAL: SSL DATABASE SETTINGS
# --------------------------------------------
DB_SSL=false
DB_SSL_IS_PAAS=false
DB_SSL_KEY_PATH=null
DB_SSL_CERT_PATH=null
DB_SSL_CA_PATH=null
DB_SSL_CIPHER=null
DB_SSL_VERIFY_SERVER=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
# --------------------------------------------
MAIL_MAILER = smtp
MAIL_HOST = {{system_email.host}}
MAIL_PORT = {{system_email.port}}
MAIL_USERNAME = {{ users['no-reply'].email }}
MAIL_PASSWORD = {{ users['no-reply'].mailu_token }}
MAIL_TLS_VERIFY_PEER = {{ system_email.tls | capitalize }}
MAIL_FROM_ADDR = {{ users['no-reply'].email }}
MAIL_FROM_NAME = {{ service_provider.company.titel }} - Snipe-IT
MAIL_REPLYTO_ADDR = {{ users['no-reply'].email }}
MAIL_REPLYTO_NAME = {{ service_provider.company.titel }} - Snipe-IT
MAIL_AUTO_EMBED_METHOD = 'attachment'
# --------------------------------------------
# REQUIRED: DATA PROTECTION
# --------------------------------------------
ALLOW_BACKUP_DELETE=false
ALLOW_DATA_PURGE=false
# --------------------------------------------
# REQUIRED: IMAGE LIBRARY
# This should be gd or imagick
# --------------------------------------------
IMAGE_LIB=gd
# --------------------------------------------
# OPTIONAL: BACKUP SETTINGS
# --------------------------------------------
MAIL_BACKUP_NOTIFICATION_DRIVER=null
MAIL_BACKUP_NOTIFICATION_ADDRESS=null
BACKUP_ENV=true
# --------------------------------------------
# OPTIONAL: SESSION SETTINGS
# --------------------------------------------
SESSION_LIFETIME=12000
EXPIRE_ON_CLOSE=false
ENCRYPT=false
COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=true
API_TOKEN_EXPIRATION_YEARS=40
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
# --------------------------------------------
APP_TRUSTED_PROXIES=**
ALLOW_IFRAMING=false
REFERRER_POLICY=same-origin
ENABLE_CSP=false
CORS_ALLOWED_ORIGINS=null
ENABLE_HSTS=true # Certificates managed by nginx
# --------------------------------------------
# OPTIONAL: CACHE SETTINGS
# --------------------------------------------
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
CACHE_PREFIX=snipeit
# --------------------------------------------
# OPTIONAL: REDIS SETTINGS
# --------------------------------------------
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
# --------------------------------------------
# OPTIONAL: MEMCACHED SETTINGS
# --------------------------------------------
MEMCACHED_HOST=null
MEMCACHED_PORT=null
# --------------------------------------------
# OPTIONAL: PUBLIC S3 Settings
# --------------------------------------------
PUBLIC_AWS_SECRET_ACCESS_KEY=null
PUBLIC_AWS_ACCESS_KEY_ID=null
PUBLIC_AWS_DEFAULT_REGION=null
PUBLIC_AWS_BUCKET=null
PUBLIC_AWS_URL=null
PUBLIC_AWS_BUCKET_ROOT=null
# --------------------------------------------
# OPTIONAL: PRIVATE S3 Settings
# --------------------------------------------
PRIVATE_AWS_ACCESS_KEY_ID=null
PRIVATE_AWS_SECRET_ACCESS_KEY=null
PRIVATE_AWS_DEFAULT_REGION=null
PRIVATE_AWS_BUCKET=null
PRIVATE_AWS_URL=null
PRIVATE_AWS_BUCKET_ROOT=null
# --------------------------------------------
# OPTIONAL: AWS Settings
# --------------------------------------------
AWS_ACCESS_KEY_ID=null
AWS_SECRET_ACCESS_KEY=null
AWS_DEFAULT_REGION=null
# --------------------------------------------
# OPTIONAL: LOGIN THROTTLING
# --------------------------------------------
LOGIN_MAX_ATTEMPTS=5
LOGIN_LOCKOUT_DURATION=60
RESET_PASSWORD_LINK_EXPIRES=900
# --------------------------------------------
# OPTIONAL: MISC
# --------------------------------------------
LOG_CHANNEL=stderr
LOG_MAX_DAYS=10
APP_LOCKED=false
APP_CIPHER=AES-256-CBC
APP_FORCE_TLS=true
GOOGLE_MAPS_API=
LDAP_MEM_LIM=500M
LDAP_TIME_LIM=600

View File

@@ -0,0 +1,35 @@
version: "latest"
features:
matomo: true
css: false
portfolio_iframe: true
central_database: true
ldap: true
oauth2: true
domains:
canonical:
- "inventory.{{ primary_domain }}"
csp:
flags:
script-src:
unsafe-inline: true
unsafe-eval: true
script-src-elem:
unsafe-inline: true
style-src:
unsafe-inline: true
whitelist:
font-src:
- "data:"
oauth2_proxy:
application: "application"
port: "80"
acl:
blacklist:
- "/login"
docker:
services:
redis:
enabled: true
database:
enabled: true

View File

@@ -0,0 +1,4 @@
application_id: "snipe-it"
database_password: "{{ applications[application_id].credentials.database_password }}"
database_type: "mariadb"
snipe_it_url: "{{ domains | get_url(application_id, web_protocol) }}"