Add OneLab Helm chart, Argo CD Application, and GitOps values for k3s
Made-with: Cursor
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
*.local.yaml
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
3
app/backup.sh
Normal file
3
app/backup.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
ANSIBLE_LOG_PATH=./logs/ansible/$(date +%F)-ansible.log ansible-playbook ./installation/1.27.0/app/playbooks/backup.yml
|
||||||
154
app/configurations.yml
Normal file
154
app/configurations.yml
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
---
|
||||||
|
onelab:
|
||||||
|
domain: https://localhost
|
||||||
|
logs:
|
||||||
|
# path: "/path/to/onelab/logs"
|
||||||
|
level: info
|
||||||
|
assets:
|
||||||
|
# path: "/path/to/onelab/data"
|
||||||
|
purge: 1d
|
||||||
|
shared:
|
||||||
|
inputs:
|
||||||
|
path: "./data/shared/inputs"
|
||||||
|
archive_path: "./data/shared/archived"
|
||||||
|
security:
|
||||||
|
cors: '*'
|
||||||
|
auth:
|
||||||
|
token:
|
||||||
|
expiration: 5m
|
||||||
|
key: TokenAuthPlaceholder
|
||||||
|
password:
|
||||||
|
expiration: 90d
|
||||||
|
min_length: 8
|
||||||
|
prevent_reuse: 5
|
||||||
|
allow_list: []
|
||||||
|
block_list: []
|
||||||
|
authentifier: "email"
|
||||||
|
ratelimit:
|
||||||
|
ip:
|
||||||
|
max: 1000
|
||||||
|
duration: 1d
|
||||||
|
auth:
|
||||||
|
max: 5
|
||||||
|
duration: 5m
|
||||||
|
delay_after: 2
|
||||||
|
delay_ms: 1000
|
||||||
|
devices:
|
||||||
|
cors: '*'
|
||||||
|
monitoring:
|
||||||
|
token: TokenMonitoringPlaceholder
|
||||||
|
params:
|
||||||
|
session:
|
||||||
|
idle: 45m
|
||||||
|
remember_me: true
|
||||||
|
lab:
|
||||||
|
creation_policy: many
|
||||||
|
# compliance:
|
||||||
|
# require_electronic_signature: true
|
||||||
|
# execution_operator_restriction_policy: 'reviewed'
|
||||||
|
# execution_admin_expert_restriction_policy: 'reviewed'
|
||||||
|
# prevent_csv_import: true
|
||||||
|
# prevent_manual_metadata_edit: true
|
||||||
|
# device_restart: true
|
||||||
|
signup: false
|
||||||
|
# Google Analytics
|
||||||
|
# ga: XXXXX
|
||||||
|
# Intercom Andrew Alliance
|
||||||
|
intercom:
|
||||||
|
appid: zxvgsagz
|
||||||
|
secret: QUw2jEV8utIpe9DeYjOqBjhBY9VxjXddKUCISUNu
|
||||||
|
# Recaptcha Andrew Alliance
|
||||||
|
# recaptcha:
|
||||||
|
# client: XXXXXXXXXXXX
|
||||||
|
# secret: XXXXXXXXXXXX
|
||||||
|
#links:
|
||||||
|
# terms: https://www.andrewalliance.com/onelab-service-agreement.pdf
|
||||||
|
# privacy: https://www.andrewalliance.com/onelab-privacy-policy.pdf
|
||||||
|
# cookies: https://www.andrewalliance.com/onelab-cookie-policy.pdf
|
||||||
|
mailer:
|
||||||
|
#
|
||||||
|
# SMTP
|
||||||
|
# smtp:
|
||||||
|
# host: XXX (optional)
|
||||||
|
# port: XXX (optional)
|
||||||
|
# auth: (optional)
|
||||||
|
# user: XXX
|
||||||
|
# pass: XXX
|
||||||
|
# type: custom | login | oauth2 (optional)
|
||||||
|
# method: XXX (optional)
|
||||||
|
# secure: true | false (optional)
|
||||||
|
#
|
||||||
|
# Amazon SES
|
||||||
|
# ses:
|
||||||
|
# accessKeyId: XXXX
|
||||||
|
# secretAccessKey: XXXX
|
||||||
|
#
|
||||||
|
# MailGun
|
||||||
|
# mailgun:
|
||||||
|
# auth:
|
||||||
|
# api: XXXX
|
||||||
|
# domain: XXXX
|
||||||
|
#
|
||||||
|
# Debug
|
||||||
|
# debug:
|
||||||
|
# type: file | mail
|
||||||
|
# path: XXXX
|
||||||
|
# redirect: XXX@andrewalliance.com
|
||||||
|
#
|
||||||
|
noreply: no-reply@andrewalliance.com
|
||||||
|
queue:
|
||||||
|
scheduling: 15
|
||||||
|
maxsize: 50
|
||||||
|
error:
|
||||||
|
maxtries: 3
|
||||||
|
timeout: 60
|
||||||
|
ldap:
|
||||||
|
enabled: false
|
||||||
|
# timeout: 10
|
||||||
|
# encryption: plain | tls | start_tls
|
||||||
|
# policy: all | changes_only
|
||||||
|
# verify_certificates: true | false
|
||||||
|
# tls:
|
||||||
|
# ca: file_path
|
||||||
|
# cert: file_path
|
||||||
|
# key: file_path
|
||||||
|
# ciphers: string
|
||||||
|
# ssl_version: string
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
# host: db
|
||||||
|
# Note: port 5432 is the standard port for postgres however a custom port can be used if 5432 is occupied already
|
||||||
|
# port: 5432
|
||||||
|
database: postgres
|
||||||
|
username: postgres
|
||||||
|
password: DBPasswordPlaceholder
|
||||||
|
schema: onelab
|
||||||
|
# replicas: 1
|
||||||
|
# redis:
|
||||||
|
# host: redis
|
||||||
|
# port: '6379'
|
||||||
|
# replicas: 1
|
||||||
|
rabbit:
|
||||||
|
# url: rabbitmq
|
||||||
|
# port: 5671
|
||||||
|
token: TokenRabbitPlaceholder
|
||||||
|
# replicas: 1
|
||||||
|
api:
|
||||||
|
replicas: 2
|
||||||
|
# apidevice:
|
||||||
|
# replicas: 1
|
||||||
|
# apirabbit:
|
||||||
|
# replicas: 1
|
||||||
|
# devices:
|
||||||
|
# replicas: 1
|
||||||
|
# experiments:
|
||||||
|
# replicas: 1
|
||||||
|
# images:
|
||||||
|
# replicas: 1
|
||||||
|
# manual:
|
||||||
|
# replicas: 1
|
||||||
|
# website:
|
||||||
|
# ssr: false
|
||||||
|
# ws:
|
||||||
|
# replicas: 1
|
||||||
|
|
||||||
319
app/docker-compose.yml
Normal file
319
app/docker-compose.yml
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
version: "3.3"
|
||||||
|
services:
|
||||||
|
# If the database isn't accessed other than by services present in this file, remove port instruction.
|
||||||
|
# It exposes the database to the host system and if the server isn't secure, it exposes the database to attacks.
|
||||||
|
# That doesn't exclude the need to secure the servers on which the containers are run.
|
||||||
|
db:
|
||||||
|
image: hub.andrewalliance.com/releases/postgres:17.8
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_PASSWORD={{ onelab.services.db.password }}
|
||||||
|
- POSTGRES_DB=postgres
|
||||||
|
{% if onelab.services.db.port is defined %}
|
||||||
|
ports:
|
||||||
|
- "{{ onelab.services.db.port }}:5432"
|
||||||
|
{% endif %}
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.db.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
redis:
|
||||||
|
image: hub.andrewalliance.com/releases/redis:7.4.7-alpine
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.db.redis.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
rabbitmq:
|
||||||
|
image: hub.andrewalliance.com/releases/rabbitmq:3.13.7
|
||||||
|
hostname: "onelab"
|
||||||
|
volumes:
|
||||||
|
- rabbitmq_data:/var/lib/rabbitmq/mnesia
|
||||||
|
configs:
|
||||||
|
- source: enable_plugins
|
||||||
|
target: /etc/rabbitmq/enabled_plugins
|
||||||
|
- source: rabbit.conf
|
||||||
|
target: /etc/rabbitmq/rabbitmq.conf
|
||||||
|
- source: advanced.conf
|
||||||
|
target: /etc/rabbitmq/advanced.conf
|
||||||
|
- source: definitions.json
|
||||||
|
target: /opt/definitions.json
|
||||||
|
- source: rabbit.crt
|
||||||
|
target: /etc/rabbitmq/ssl/rabbit.crt
|
||||||
|
- source: rabbit.key
|
||||||
|
target: /etc/rabbitmq/ssl/rabbit.key
|
||||||
|
- source: rabbit.fullchain.pem
|
||||||
|
target: /etc/rabbitmq/ssl/rabbit.fullchain.pem
|
||||||
|
ports:
|
||||||
|
- "5671:5671"
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.rabbit.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
supervisor:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-supervisor-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
file-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-file-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
- {{ onelab.shared.inputs.path|default('./data/shared/inputs') }}:/shared-inputs
|
||||||
|
- {{ onelab.shared.inputs.archived_path|default('./data/shared/archived') }}:/shared-archived
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
api:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-api:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.api.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
api-device:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-api-device:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.apidevice.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
api-rabbit:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-api-rabbit:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.apirabbit.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
devices-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-devices-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.devices.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
experiments-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-experiments-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.experiments.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
images-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-images-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.images.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
|
||||||
|
{% if (onelab.ldap|default(false)) != false %}
|
||||||
|
ldap-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-ldap-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
{% if onelab.ldap.tls.ca is defined %}
|
||||||
|
- source: ldap-ca.crt
|
||||||
|
target: /ldap/ca.crt
|
||||||
|
{% endif %}
|
||||||
|
{% if onelab.ldap.tls.key is defined %}
|
||||||
|
- source: ldap-private.key
|
||||||
|
target: /ldap/private.key
|
||||||
|
{% endif %}
|
||||||
|
{% if onelab.ldap.tls.cert is defined %}
|
||||||
|
- source: ldap-cert.crt
|
||||||
|
target: /ldap/cert.crt
|
||||||
|
{% endif %}
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.ldap.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
{% endif %}
|
||||||
|
{% if (onelab.mailer.smtp|default(false)) != false or (onelab.mailer.ses|default(false)) != false %}
|
||||||
|
mailer-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-mailer-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.mailer.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
{% endif %}
|
||||||
|
manual-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-manual-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.manual.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
websocket-worker:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-websocket-worker:1.27.0
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.logs.path|default('./logs') }}:/logs
|
||||||
|
configs:
|
||||||
|
- source: configurations.yml
|
||||||
|
target: /conf/configurations.yml
|
||||||
|
deploy:
|
||||||
|
replicas: {{ onelab.services.ws.replicas|default('1') }}
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
static:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-static:1.27.0
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
main:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-main:1.27.0
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
designer:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-designer:1.27.0
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
runner:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-runner:1.27.0
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
website:
|
||||||
|
image: hub.andrewalliance.com/releases/onelab-website:1.27.0
|
||||||
|
{% if (onelab.services.website.ssr|default(true)) != true %}
|
||||||
|
environment:
|
||||||
|
- RENDERING_MODE=no-ssr
|
||||||
|
{% endif %}
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
revproxy:
|
||||||
|
image: hub.andrewalliance.com/releases/nginx:1.29.5-alpine
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
volumes:
|
||||||
|
- {{ onelab.assets.path|default('./data') }}:/data
|
||||||
|
configs:
|
||||||
|
- source: nginx.conf
|
||||||
|
target: /etc/nginx/nginx.conf
|
||||||
|
- source: error-404.html
|
||||||
|
target: /data/error-404.html
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == {{ deploy_on|default('manager') }}
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
driver: local
|
||||||
|
rabbitmq_data:
|
||||||
|
driver: local
|
||||||
|
configs:
|
||||||
|
configurations.yml:
|
||||||
|
file: ./configurations.yml
|
||||||
|
nginx.conf:
|
||||||
|
file: ./nginx/onelab.conf
|
||||||
|
error-404.html:
|
||||||
|
file: ./proxy/error-404.html
|
||||||
|
rabbit.crt:
|
||||||
|
file: ./rabbit/ssl/rabbit.crt
|
||||||
|
rabbit.key:
|
||||||
|
file: ./rabbit/ssl/rabbit.key
|
||||||
|
rabbit.fullchain.pem:
|
||||||
|
file: ./rabbit/ssl/rabbit.fullchain.pem
|
||||||
|
enable_plugins:
|
||||||
|
file: ./rabbit/enable_plugins
|
||||||
|
rabbit.conf:
|
||||||
|
file: ./rabbit/rabbit.conf
|
||||||
|
advanced.conf:
|
||||||
|
file: ./rabbit/advanced.conf
|
||||||
|
definitions.json:
|
||||||
|
file: ./rabbit/definitions.json
|
||||||
|
{% if onelab.ldap.tls.ca is defined %}
|
||||||
|
ldap-ca.crt:
|
||||||
|
file: {{ onelab.ldap.tls.ca }}
|
||||||
|
{% endif %}
|
||||||
|
{% if onelab.ldap.tls.key is defined %}
|
||||||
|
ldap-private.key:
|
||||||
|
file: {{ onelab.ldap.tls.key }}
|
||||||
|
{% endif %}
|
||||||
|
{% if onelab.ldap.tls.cert is defined %}
|
||||||
|
ldap-cert.crt:
|
||||||
|
file: {{ onelab.ldap.tls.cert }}
|
||||||
|
{% endif %}
|
||||||
337
app/nginx/onelab.conf
Normal file
337
app/nginx/onelab.conf
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
|
||||||
|
worker_processes 4;
|
||||||
|
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
|
client_max_body_size 2m;
|
||||||
|
|
||||||
|
# don't send the nginx version number in error pages and Server header
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
|
||||||
|
upstream website {
|
||||||
|
server website:4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream main {
|
||||||
|
server main:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api {
|
||||||
|
server api:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api-device {
|
||||||
|
server api-device:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api-rabbit {
|
||||||
|
server api-rabbit:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream designer {
|
||||||
|
server designer:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream runner {
|
||||||
|
server runner:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream static {
|
||||||
|
server static:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream websocket-worker {
|
||||||
|
server websocket-worker:3030;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore the real client IP from the upstream reverse proxy
|
||||||
|
# Trust all RFC 1918 private ranges (covers any Docker network config)
|
||||||
|
set_real_ip_from 10.0.0.0/8;
|
||||||
|
set_real_ip_from 172.16.0.0/12;
|
||||||
|
set_real_ip_from 192.168.0.0/16;
|
||||||
|
real_ip_header X-Real-IP;
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=auth:10m rate=1r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=website:10m rate=5r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;
|
||||||
|
|
||||||
|
# redirect all http traffic to https
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
{% if (onelab.services.revproxy.ipv6|default(true)) != false %}
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
{% endif %}
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 10240;
|
||||||
|
gzip_proxied expired no-cache no-store private auth;
|
||||||
|
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
gzip_disable "MSIE [1-6]\.";
|
||||||
|
|
||||||
|
root /data/;
|
||||||
|
|
||||||
|
location ^~ /lab/ {
|
||||||
|
rewrite ^/lab/(.*?) /app/lab/$1 last;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /assets/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /static/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://static;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://static;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /sitemap.xml {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /robots.txt {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/ {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/auth/ {
|
||||||
|
# apply rate limiting
|
||||||
|
limit_req zone=auth burst=5 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/firmwares {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
client_max_body_size 600M;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/rmq/ {
|
||||||
|
proxy_pass http://api-rabbit;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /device-api/ {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
client_max_body_size 600m;
|
||||||
|
|
||||||
|
proxy_pass http://api-device;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/designer/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://designer;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://designer;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/runner/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://runner;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://runner;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /ws/ {
|
||||||
|
proxy_pass http://websocket-worker;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://main;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://main;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets for website (including /media/ subdirectory)
|
||||||
|
location ~* ^/.+\.(?:css|js|woff|woff2|ttf|eot|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://website;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Website SSR routes (rate limited)
|
||||||
|
location ~ ^/(library(/[^/]+)?|login(/(reset|change))?|signup)?$ {
|
||||||
|
limit_req zone=website burst=10 nodelay;
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://website;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Catch-all for junk requests
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
app/playbooks/backup.yml
Normal file
11
app/playbooks/backup.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
- name: Backing up OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: yes
|
||||||
|
vars:
|
||||||
|
onelab_path: '../../../..'
|
||||||
|
|
||||||
|
# Call from ./installation/latest/app/playbooks/backup.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_tasks: ./tasks/backup-task.yml
|
||||||
18
app/playbooks/deploy.yml
Normal file
18
app/playbooks/deploy.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- name: Deploying OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
onelab_path: '../../../../../onelab'
|
||||||
|
|
||||||
|
# Call from ./installation/latest/app/playbooks/deploy.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# Load configuration
|
||||||
|
- include_vars:
|
||||||
|
file: "{{ onelab_path }}/configurations.yml"
|
||||||
|
|
||||||
|
# Start proxy
|
||||||
|
- include_tasks: ./tasks/start-proxy.yml
|
||||||
|
|
||||||
|
# Start OneLab
|
||||||
|
- include_tasks: ./tasks/start-onelab.yml
|
||||||
25
app/playbooks/install-swarm.yml
Normal file
25
app/playbooks/install-swarm.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
- name: Generate the command to join a node as swarm worker
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: yes
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Determine Docker swarm status
|
||||||
|
shell: >
|
||||||
|
docker info | egrep 'Swarm: '
|
||||||
|
register: swarm_status
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Prepare the command to join a node as worker in this swarm
|
||||||
|
command: docker swarm join-token worker -q
|
||||||
|
become: true
|
||||||
|
when: "' Swarm: active' in swarm_status.stdout_lines"
|
||||||
|
register: worker_join_token
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
run_on_worker: "sudo docker swarm join --token {{ worker_join_token.stdout }} {{ ansible_eth0.ipv4.address }}:2377"
|
||||||
|
|
||||||
|
- debug: var=run_on_worker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
13
app/playbooks/install.yml
Normal file
13
app/playbooks/install.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
- name: Installing OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: yes
|
||||||
|
vars:
|
||||||
|
main_path: '../../..'
|
||||||
|
onelab_path: '../../../onelab'
|
||||||
|
installer_path: '../../../onelab-enterprise-installer-1.27.0'
|
||||||
|
|
||||||
|
# Call from ./onelab-enterprise-installer-1.27.0/app/playbooks/install.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_tasks: ./tasks/install-task.yml
|
||||||
15
app/playbooks/reconfigure.yml
Normal file
15
app/playbooks/reconfigure.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Reconfiguring OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
main_path: '../../../../..'
|
||||||
|
onelab_path: '../../../../../onelab'
|
||||||
|
|
||||||
|
# Call from ./installation/latest/app/playbooks/reconfigure.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# Load configuration
|
||||||
|
- include_vars:
|
||||||
|
file: "{{ onelab_path }}/configurations.yml"
|
||||||
|
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/reconfigure-task.yml"
|
||||||
12
app/playbooks/stop.yml
Normal file
12
app/playbooks/stop.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
- name: Stopping OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
onelab_path: '../../../../../onelab'
|
||||||
|
|
||||||
|
# Call from ./installation/latest/app/playbooks/stop.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- include_tasks: ./tasks/stop-onelab.yml
|
||||||
|
|
||||||
|
- include_tasks: ./tasks/stop-proxy.yml
|
||||||
37
app/playbooks/tasks/backup-task.yml
Normal file
37
app/playbooks/tasks/backup-task.yml
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
- name: Checking if OneLab is running
|
||||||
|
shell: docker stack ls | grep 'onelab' | grep -v 'onelab_proxy' | wc -l
|
||||||
|
become: true
|
||||||
|
register: backup_stack_count
|
||||||
|
|
||||||
|
# Start DB if OneLab is not running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-db-only.yml"
|
||||||
|
when: backup_stack_count.stdout == "0"
|
||||||
|
|
||||||
|
- name: Creating backup directory
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}/backups/{{ ansible_date_time.iso8601_basic_short }}_1.27.0"
|
||||||
|
state: directory
|
||||||
|
register: backup_path
|
||||||
|
|
||||||
|
- name: Backing up files
|
||||||
|
shell:
|
||||||
|
tar --exclude='temp' -czvf {{ backup_path.path }}/onelab.tar.gz -C {{ onelab_path }} ./data ./installation ./nginx ./proxy ./rabbit ./ssl ./backup.sh ./configurations.yml ./docker-compose.yml ./reconfigure.sh ./start.sh ./stop.sh ./update.sh
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: Backing up database
|
||||||
|
shell:
|
||||||
|
docker exec -i $(docker ps --filter "name=onelab_db|onelab-db" -q) pg_dump -Upostgres -Fc > {{ backup_path.path }}/db.tar.gz
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- name: Creating restore script files
|
||||||
|
copy:
|
||||||
|
src: "{{ onelab_path }}/installation/latest/resources/restore/{{ item }}"
|
||||||
|
dest: "{{ backup_path.path }}"
|
||||||
|
with_items:
|
||||||
|
- 'restore.yml'
|
||||||
|
- 'restore.sh'
|
||||||
|
|
||||||
|
# Stop DB if OneLab was not running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-db-only.yml"
|
||||||
|
when: backup_stack_count.stdout == "0"
|
||||||
7
app/playbooks/tasks/check-offline-resources.yml
Normal file
7
app/playbooks/tasks/check-offline-resources.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
# Check if Docker images are existing locally
|
||||||
|
- name: Checking local Docker images bundle
|
||||||
|
stat:
|
||||||
|
path: "{{ main_path }}/onelab-images-1.27.0.tar.gz"
|
||||||
|
get_checksum: no
|
||||||
|
register: docker_images_tar
|
||||||
71
app/playbooks/tasks/check-requirements.yml
Normal file
71
app/playbooks/tasks/check-requirements.yml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
- name: Checking internet connection
|
||||||
|
uri:
|
||||||
|
url: "https://hub.andrewalliance.com"
|
||||||
|
register: pingresult
|
||||||
|
until:
|
||||||
|
- pingresult.status == 200
|
||||||
|
retries: 3 # 3 * 5 seconds = 15s
|
||||||
|
delay: 5 # Every 5 seconds
|
||||||
|
when: (docker_images_tar is undefined) or (not docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Getting current logged-in user
|
||||||
|
shell: whoami
|
||||||
|
register: login_user
|
||||||
|
- debug: var=login_user.stdout
|
||||||
|
|
||||||
|
# User running the process may have to enter their sudo password at this step
|
||||||
|
|
||||||
|
- name: Checking if the logged-in user has sudo privileges
|
||||||
|
shell: sudo whoami
|
||||||
|
register: sudo_check
|
||||||
|
failed_when: sudo_check.stdout != "root"
|
||||||
|
|
||||||
|
- name: Checking Ansible
|
||||||
|
debug:
|
||||||
|
msg: "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- "{{ ansible_distribution }}"
|
||||||
|
- "{{ ansible_distribution_version }}"
|
||||||
|
- "{{ ansible_distribution_major_version }}"
|
||||||
|
|
||||||
|
- name: Checking Docker version
|
||||||
|
shell: docker -v | cut -d ' ' -f 3 | cut -d ',' -f 1
|
||||||
|
become: true
|
||||||
|
register: docker_version
|
||||||
|
- debug: var=docker_version.stdout
|
||||||
|
|
||||||
|
# workaround: add a dumb failed condition to avoid any failure here as the service is maybe not installed/existing
|
||||||
|
- name: Check if "docker compose" is available
|
||||||
|
shell: docker compose version
|
||||||
|
become: true
|
||||||
|
register: docker_compose_check
|
||||||
|
failed_when: "'FAILED' in docker_compose_check.stderr"
|
||||||
|
|
||||||
|
- name: Set the compose command to "docker compose"
|
||||||
|
set_fact:
|
||||||
|
compose_command: "docker compose"
|
||||||
|
when: docker_compose_check.rc == 0
|
||||||
|
|
||||||
|
- name: Fallback to "docker-compose" if "docker compose" is not available
|
||||||
|
set_fact:
|
||||||
|
compose_command: "docker-compose"
|
||||||
|
when: docker_compose_check.rc != 0
|
||||||
|
|
||||||
|
- name: Checking Docker Compose version
|
||||||
|
shell: "{{ compose_command }} version"
|
||||||
|
become: true
|
||||||
|
register: compose_version_output
|
||||||
|
- debug: var=compose_version_output.stdout
|
||||||
|
|
||||||
|
- name: Checking tar pacakge
|
||||||
|
shell: tar --usage
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Checking unzip pacakge
|
||||||
|
shell: unzip
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Checking openssl package
|
||||||
|
shell: openssl
|
||||||
|
become: true
|
||||||
49
app/playbooks/tasks/check-ssl-files.yml
Normal file
49
app/playbooks/tasks/check-ssl-files.yml
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
# Check SSL files
|
||||||
|
- name: Getting the list of Docker secrets
|
||||||
|
shell: docker secret ls | tail -n +2 | awk '{print $2}'
|
||||||
|
register: docker_secrets
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Checking if dhparam.pem file exists in /onelab/ssl
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/ssl/dhparam.pem"
|
||||||
|
register: dhparam
|
||||||
|
failed_when: not dhparam.stat.exists
|
||||||
|
|
||||||
|
- name: Checking if server.pem file exists in /onelab/ssl
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/ssl/server.pem"
|
||||||
|
register: serverpem
|
||||||
|
failed_when: not serverpem.stat.exists
|
||||||
|
|
||||||
|
- name: Checking if server.key file exists in /onelab/ssl
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/ssl/server.key"
|
||||||
|
register: serverkey
|
||||||
|
failed_when: not serverkey.stat.exists
|
||||||
|
|
||||||
|
- name: Checking if chain.pem file exists in /onelab/ssl
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/ssl/chain.pem"
|
||||||
|
register: chain
|
||||||
|
failed_when: not chain.stat.exists
|
||||||
|
|
||||||
|
- name: Checking if certificate and key are matching (part 1/2)
|
||||||
|
shell: >
|
||||||
|
openssl rsa -noout -modulus -in {{ onelab_path }}/ssl/server.key | openssl md5
|
||||||
|
register: serverkey_modulus
|
||||||
|
become: true
|
||||||
|
when:
|
||||||
|
- "'ssl_passphrase' not in docker_secrets.stdout_lines"
|
||||||
|
- (onelab.deployment.skip_ssl is undefined) or (onelab.deployment.skip_ssl == false)
|
||||||
|
|
||||||
|
- name: Checking if certificate and key are matching (part 2/2)
|
||||||
|
shell: >
|
||||||
|
openssl x509 -noout -modulus -in {{ onelab_path }}/ssl/server.pem | openssl md5
|
||||||
|
register: serverpem_modulus
|
||||||
|
failed_when: serverpem_modulus.stdout != serverkey_modulus.stdout
|
||||||
|
become: true
|
||||||
|
when:
|
||||||
|
- "'ssl_passphrase' not in docker_secrets.stdout_lines"
|
||||||
|
- (onelab.deployment.skip_ssl is undefined) or (onelab.deployment.skip_ssl == false)
|
||||||
21
app/playbooks/tasks/init-docker.yml
Normal file
21
app/playbooks/tasks/init-docker.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Configure Docker
|
||||||
|
#
|
||||||
|
|
||||||
|
- name: Ensuring Docker status
|
||||||
|
service:
|
||||||
|
name: "docker"
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Determining Docker swarm status
|
||||||
|
shell: >
|
||||||
|
docker info | egrep 'Swarm: '
|
||||||
|
register: swarm_status
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Configuring Docker Swarm
|
||||||
|
shell: >
|
||||||
|
docker swarm init --advertise-addr "{{ ansible_default_ipv4.address }}"
|
||||||
|
when: "' Swarm: inactive' in swarm_status.stdout_lines"
|
||||||
|
become: true
|
||||||
119
app/playbooks/tasks/init-onelab.yml
Normal file
119
app/playbooks/tasks/init-onelab.yml
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Start Installation
|
||||||
|
#
|
||||||
|
|
||||||
|
# Folders creation
|
||||||
|
- name: Creating OneLab directory
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Creating OneLab directory structure
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
with_items:
|
||||||
|
- 'backups'
|
||||||
|
- 'data'
|
||||||
|
- 'data/shared'
|
||||||
|
- 'data/shared/inputs'
|
||||||
|
- 'data/shared/archived'
|
||||||
|
- 'logs'
|
||||||
|
- 'installation'
|
||||||
|
- 'ssl'
|
||||||
|
- 'rabbit'
|
||||||
|
|
||||||
|
- name: Creating directory for rabbit SSL certificates
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}/rabbit/ssl"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Creating directory for Ansible logs
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}/logs/ansible"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
# Copy version
|
||||||
|
- name: Cleaning latest installation
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ onelab_path }}/installation/latest"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Copying current installation bundle
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ installer_path }}/"
|
||||||
|
dest: "{{ onelab_path }}/installation/{{ item }}"
|
||||||
|
directory_mode: no
|
||||||
|
remote_src: yes
|
||||||
|
with_items:
|
||||||
|
- 'latest'
|
||||||
|
- '1.27.0'
|
||||||
|
|
||||||
|
# Copy files
|
||||||
|
- name: Copying applicative files
|
||||||
|
copy:
|
||||||
|
src: "{{ onelab_path }}/installation/latest/app/{{ item }}"
|
||||||
|
dest: "{{ onelab_path }}/"
|
||||||
|
directory_mode: yes
|
||||||
|
remote_src: yes
|
||||||
|
with_items:
|
||||||
|
- 'nginx'
|
||||||
|
- 'proxy'
|
||||||
|
- 'rabbit'
|
||||||
|
|
||||||
|
- name: Copying routine scripts
|
||||||
|
copy:
|
||||||
|
src: "{{ onelab_path }}/installation/latest/app/{{ item }}.sh"
|
||||||
|
dest: "{{ onelab_path }}/"
|
||||||
|
directory_mode: yes
|
||||||
|
remote_src: yes
|
||||||
|
with_items:
|
||||||
|
- 'start'
|
||||||
|
- 'stop'
|
||||||
|
- 'reconfigure'
|
||||||
|
- 'backup'
|
||||||
|
- 'update'
|
||||||
|
|
||||||
|
|
||||||
|
- name: Initializing custom config proxy files
|
||||||
|
file:
|
||||||
|
path: "{{ onelab_path }}/proxy/{{ item }}"
|
||||||
|
state: touch
|
||||||
|
with_items:
|
||||||
|
- 'custom-http.conf'
|
||||||
|
- 'custom-server.conf'
|
||||||
|
when: not is_update
|
||||||
|
|
||||||
|
# Initialize configurations.yml file
|
||||||
|
- name: Initializing configurations.yml file
|
||||||
|
copy:
|
||||||
|
src: "{{ onelab_path }}/installation/latest/app/configurations.yml"
|
||||||
|
dest: "{{ onelab_path }}/configurations.yml"
|
||||||
|
remote_src: yes
|
||||||
|
when: not is_update
|
||||||
|
|
||||||
|
- name: Initializing unique Password and Tokens
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: "{{ onelab_path }}/configurations.yml"
|
||||||
|
regexp: '{{ item.placeholder }}'
|
||||||
|
replace: '{{ item.value }}'
|
||||||
|
with_items:
|
||||||
|
- { placeholder: DBPasswordPlaceholder, value: '{{ lookup("password", "/dev/null length=16 chars=ascii_letters,digits") }}' }
|
||||||
|
- { placeholder: TokenAuthPlaceholder, value: '{{ lookup("password", "/dev/null length=32 chars=ascii_letters,digits") }}' }
|
||||||
|
- { placeholder: TokenRabbitPlaceholder, value: '{{ lookup("password", "/dev/null length=32 chars=ascii_letters,digits") }}' }
|
||||||
|
- { placeholder: TokenMonitoringPlaceholder, value: '{{ lookup("password", "/dev/null length=32 chars=ascii_letters,digits") }}' }
|
||||||
|
when: not is_update
|
||||||
|
|
||||||
|
- name: Initializing Rabbit SSL certificate
|
||||||
|
shell: |
|
||||||
|
openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout {{ onelab_path }}/rabbit/ssl/rabbit.key -out {{ onelab_path }}/rabbit/ssl/rabbit.crt -subj "/C=CH/ST=Geneva/L=Geneva/O=Andrew Alliance/OU=OneLab/CN=andrewalliance.com"
|
||||||
|
cat {{ onelab_path }}/rabbit/ssl/rabbit.crt > {{ onelab_path }}/rabbit/ssl/rabbit.fullchain.pem
|
||||||
|
become: true
|
||||||
|
when: not is_update
|
||||||
|
|
||||||
|
- name: Initializing DH Param
|
||||||
|
shell: |
|
||||||
|
openssl dhparam -out {{ onelab_path }}/ssl/dhparam.pem 2048
|
||||||
|
become: true
|
||||||
|
when: not is_update
|
||||||
33
app/playbooks/tasks/init-service.yml
Normal file
33
app/playbooks/tasks/init-service.yml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Create onelab.service
|
||||||
|
#
|
||||||
|
- name: Check ansible-playbook bin
|
||||||
|
shell: whereis ansible-playbook | cut -d ' ' -f 2
|
||||||
|
register: ansiblebin_result
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# workaround: add a dumb failed condition to avoid any failure here as the service is maybe not installed/existing
|
||||||
|
- name: Check onelab.service
|
||||||
|
shell: |
|
||||||
|
systemctl disable onelab.service
|
||||||
|
rm /etc/systemd/system/onelab.service
|
||||||
|
register: command_result
|
||||||
|
failed_when: "'FAILED' in command_result.stderr"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# playbook_dir will be /home/ubuntu/onelab/test/onelab-enterprise-installer-release-1.13.0/app/playbooks for install.sh
|
||||||
|
# but will be /home/ubuntu/onelab/test/onelab/installation/latest/app/playbooks/ for update.sh
|
||||||
|
- debug: var=playbook_dir
|
||||||
|
|
||||||
|
- name: Creating onelab.service
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ installer_path }}/resources/services/onelab.service"
|
||||||
|
dest: "/etc/systemd/system/onelab.service"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Configuring onelab.service
|
||||||
|
shell: |
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable onelab.service
|
||||||
|
become: true
|
||||||
81
app/playbooks/tasks/install-task.yml
Normal file
81
app/playbooks/tasks/install-task.yml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Offline-resources-check
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/check-offline-resources.yml"
|
||||||
|
#
|
||||||
|
# Pre-check
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/check-requirements.yml"
|
||||||
|
#
|
||||||
|
# Configure Docker
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/init-docker.yml"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Loading Docker images
|
||||||
|
debug:
|
||||||
|
msg:
|
||||||
|
- "Loading images could take few minutes, please do not interrupt"
|
||||||
|
when: (docker_images_tar is defined) and (docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Loading OneLab images from the tar file
|
||||||
|
shell:
|
||||||
|
docker load --input {{ main_path }}/onelab-images-1.27.0.tar.gz
|
||||||
|
become: true
|
||||||
|
when: (docker_images_tar is defined) and (docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check if we are running a fresh installation or an update on an existing installation
|
||||||
|
#
|
||||||
|
- name: Checking if OneLab is already installed
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/docker-compose.yml"
|
||||||
|
register: onelab_result
|
||||||
|
|
||||||
|
#
|
||||||
|
# Pre-migration task
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/pre-update.yml"
|
||||||
|
when: onelab_result.stat.exists
|
||||||
|
|
||||||
|
#
|
||||||
|
# Install OneLab
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/init-onelab.yml"
|
||||||
|
vars:
|
||||||
|
is_update: "{{ onelab_result.stat.exists|bool }}"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Init Service
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/init-service.yml"
|
||||||
|
|
||||||
|
# Checking Docker volumes
|
||||||
|
|
||||||
|
- name: Checking if RabbitMQ exists
|
||||||
|
shell: docker volume ls
|
||||||
|
become: true
|
||||||
|
register: list_volumes
|
||||||
|
|
||||||
|
|
||||||
|
# Cleaning cache
|
||||||
|
- name: Cleaning RabbitMQ cache
|
||||||
|
shell: docker volume rm onelab_rabbitmq_data
|
||||||
|
become: true
|
||||||
|
when: "'onelab_rabbitmq_data' in list_volumes.stdout"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Reconfigure
|
||||||
|
#
|
||||||
|
- include_vars:
|
||||||
|
file: "{{ onelab_path }}/configurations.yml"
|
||||||
|
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/update-conf-files.yml"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Post-migration task
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/post-update.yml"
|
||||||
|
when: onelab_result.stat.exists
|
||||||
40
app/playbooks/tasks/manage-images.yml
Normal file
40
app/playbooks/tasks/manage-images.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
- name: Connecting to Docker Hub
|
||||||
|
shell: >
|
||||||
|
docker login -u {{ onelab.docker.login.user|default('public') }} -p {{ onelab.docker.login.password|default('Andrew01..Release') }} hub.andrewalliance.com
|
||||||
|
become: true
|
||||||
|
when: (docker_images_tar is undefined) or (not docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Checking current OneLab images
|
||||||
|
shell: >
|
||||||
|
{% raw %}
|
||||||
|
docker image ls --format '{{.ID}} {{.Repository}}:{{.Tag}}' |
|
||||||
|
egrep 'onelab-' |
|
||||||
|
egrep -v '1.27.0' |
|
||||||
|
awk '{ print $1 }'
|
||||||
|
{% endraw %}
|
||||||
|
register: onelab_old_images
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Pruning OneLab old images
|
||||||
|
shell:
|
||||||
|
docker rmi {{ item }}
|
||||||
|
become: true
|
||||||
|
loop: "{{ onelab_old_images.stdout_lines }}"
|
||||||
|
|
||||||
|
- name: Gathering OneLab images
|
||||||
|
shell: >
|
||||||
|
cat {{ onelab_path }}/docker-compose.yml | egrep 'image: ' | awk '{ print $2 }'
|
||||||
|
register: onelab_images
|
||||||
|
become: true
|
||||||
|
when: (docker_images_tar is undefined) or (not docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Pulling OneLab images
|
||||||
|
shell: >
|
||||||
|
docker image pull {{ item }}
|
||||||
|
become: true
|
||||||
|
register: pullimages
|
||||||
|
loop: "{{ onelab_images.stdout_lines }}"
|
||||||
|
until: pullimages is not failed
|
||||||
|
retries: 10
|
||||||
|
delay: 5
|
||||||
|
when: (docker_images_tar is undefined) or (not docker_images_tar.stat.exists)
|
||||||
28
app/playbooks/tasks/post-db-migration.yml
Normal file
28
app/playbooks/tasks/post-db-migration.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Pull new postgres image
|
||||||
|
shell: |
|
||||||
|
docker image pull hub.andrewalliance.com/releases/postgres:17.8
|
||||||
|
become: true
|
||||||
|
when: (docker_images_tar is undefined) or (not docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Cleaning database
|
||||||
|
shell: >
|
||||||
|
docker volume rm onelab_pgdata
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-db-only.yml"
|
||||||
|
|
||||||
|
- name: Restoring & Migrating database
|
||||||
|
shell: |
|
||||||
|
docker exec -i $(docker ps --filter "name=onelab_db|onelab-db" -q) pg_restore -Upostgres -dpostgres -v -Fc < {{ onelab_path }}/db-migration-postgres.tar.gz
|
||||||
|
rm {{ onelab_path }}/db-migration-postgres.tar.gz
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-db-only.yml"
|
||||||
|
|
||||||
|
- name: Removing lock file
|
||||||
|
shell: >
|
||||||
|
rm {{ onelab_path }}/.lock_db_migration
|
||||||
|
become: true
|
||||||
|
|
||||||
21
app/playbooks/tasks/post-update.yml
Normal file
21
app/playbooks/tasks/post-update.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Specfic update tasks for version
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Migrate SSL structure (1.12.0 -> 1.13.0)
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/ssl-cert-migration.yml"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Postgres13 post-migration
|
||||||
|
#
|
||||||
|
- name: Checking if database has to be migrated
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/.lock_db_migration"
|
||||||
|
register: onelab_lock_db_result
|
||||||
|
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/post-db-migration.yml"
|
||||||
|
when: onelab_lock_db_result.stat.exists
|
||||||
14
app/playbooks/tasks/pre-db-migration.yml
Normal file
14
app/playbooks/tasks/pre-db-migration.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/start-db-only.yml"
|
||||||
|
|
||||||
|
- name: Backing up database
|
||||||
|
shell:
|
||||||
|
docker exec -i $(docker ps --filter "name=onelab_db|onelab-db" -q) pg_dump -Upostgres -Fc > {{ onelab_path }}/db-migration-postgres.tar.gz
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/stop-db-only.yml"
|
||||||
|
|
||||||
|
- name: Creating lock file
|
||||||
|
shell: >
|
||||||
|
touch {{ onelab_path }}/.lock_db_migration
|
||||||
|
become: true
|
||||||
12
app/playbooks/tasks/pre-update.yml
Normal file
12
app/playbooks/tasks/pre-update.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
- name: Checking current database
|
||||||
|
shell: >
|
||||||
|
cat {{ onelab_path }}/docker-compose.yml | egrep 'image: postgres' | awk '{ print $2 }'
|
||||||
|
register: onelab_db
|
||||||
|
become: true
|
||||||
|
|
||||||
|
#
|
||||||
|
# Postgres pre-migration
|
||||||
|
#
|
||||||
|
- include_tasks: "{{ installer_path }}/app/playbooks/tasks/pre-db-migration.yml"
|
||||||
|
when: onelab_db.stdout != 'hub.andrewalliance.com/releases/postgres:17.8'
|
||||||
17
app/playbooks/tasks/reconfigure-task.yml
Normal file
17
app/playbooks/tasks/reconfigure-task.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
# Evaluate Docker images bundle
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/check-offline-resources.yml"
|
||||||
|
when: (policy | default('')) != "no-pull" and (onelab.docker.policy | default('')) != "no-pull"
|
||||||
|
|
||||||
|
# Update conf files
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/update-conf-files.yml"
|
||||||
|
|
||||||
|
# Check SSL files
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/check-ssl-files.yml"
|
||||||
|
|
||||||
|
# Rotate Rabbit SSL files
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/rotate-ssl-files-for-rabbit.yml"
|
||||||
|
|
||||||
|
# Connect to Docker and pull images, and clean up old images
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/manage-images.yml"
|
||||||
|
when: (policy | default('')) != "no-pull" and (onelab.docker.policy | default('')) != "no-pull"
|
||||||
8
app/playbooks/tasks/rotate-ssl-files-for-rabbit.yml
Normal file
8
app/playbooks/tasks/rotate-ssl-files-for-rabbit.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
# Check SSL files
|
||||||
|
- name: Rotate Rabbit SSL certificate
|
||||||
|
shell: |
|
||||||
|
openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout {{ onelab_path }}/rabbit/ssl/rabbit.key -out {{ onelab_path }}/rabbit/ssl/rabbit.crt -subj "/C=CH/ST=Geneva/L=Geneva/O=Andrew Alliance/OU=OneLab/CN=andrewalliance.com"
|
||||||
|
cat {{ onelab_path }}/rabbit/ssl/rabbit.crt > {{ onelab_path }}/rabbit/ssl/rabbit.fullchain.pem
|
||||||
|
become: true
|
||||||
|
|
||||||
18
app/playbooks/tasks/ssl-cert-migration.yml
Normal file
18
app/playbooks/tasks/ssl-cert-migration.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Checking if fullchain.pem file exists in /onelab/ssl
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_path }}/ssl/fullchain.pem"
|
||||||
|
register: fullchain
|
||||||
|
|
||||||
|
- name: Migrating legacy SSL structure to the new one
|
||||||
|
shell: |
|
||||||
|
cp {{ onelab_path }}/ssl/fullchain.pem {{ onelab_path }}/ssl/server.pem
|
||||||
|
cp {{ onelab_path }}/ssl/fullchain.pem {{ onelab_path }}/ssl/chain.pem
|
||||||
|
rm {{ onelab_path }}/ssl/server.crt
|
||||||
|
rm {{ onelab_path }}/ssl/fullchain.pem
|
||||||
|
when: fullchain.stat.exists
|
||||||
|
register: command_result
|
||||||
|
failed_when: "'FAILED' in command_result.stderr"
|
||||||
|
become: true
|
||||||
|
|
||||||
23
app/playbooks/tasks/start-db-only.yml
Normal file
23
app/playbooks/tasks/start-db-only.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
# workaround: add a dumb failed condition to avoid any failure here as the service is maybe not installed/existing
|
||||||
|
- name: Check if "docker compose" is available
|
||||||
|
shell: docker compose version
|
||||||
|
become: true
|
||||||
|
register: docker_compose_check
|
||||||
|
failed_when: "'FAILED' in docker_compose_check.stderr"
|
||||||
|
|
||||||
|
- name: Set the compose command to "docker compose"
|
||||||
|
set_fact:
|
||||||
|
compose_command: "docker compose"
|
||||||
|
when: docker_compose_check.rc == 0
|
||||||
|
|
||||||
|
- name: Fallback to "docker-compose" if "docker compose" is not available
|
||||||
|
set_fact:
|
||||||
|
compose_command: "docker-compose"
|
||||||
|
when: docker_compose_check.rc != 0
|
||||||
|
|
||||||
|
- name: Starting database service
|
||||||
|
shell: |
|
||||||
|
{{ compose_command }} -f {{ onelab_path }}/docker-compose.yml up -d db
|
||||||
|
sleep 30
|
||||||
|
become: true
|
||||||
19
app/playbooks/tasks/start-onelab.yml
Normal file
19
app/playbooks/tasks/start-onelab.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
- name: Starting OneLab
|
||||||
|
shell: >
|
||||||
|
docker stack deploy onelab --compose-file {{ onelab_path }}/docker-compose.yml --with-registry-auth --prune
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Checking OneLab health status (could take up to 5min to be alive)
|
||||||
|
uri:
|
||||||
|
url: "{{ onelab.domain }}/api/status?token={{ onelab.security.monitoring.token }}"
|
||||||
|
return_content: yes
|
||||||
|
validate_certs: no
|
||||||
|
register: json_response
|
||||||
|
until:
|
||||||
|
- json_response.status == 200
|
||||||
|
- (json_response is defined) and (json_response.content|length > 0)
|
||||||
|
- json_response.content is search('status')
|
||||||
|
- "(json_response.content | from_json).status == 'running'"
|
||||||
|
retries: 60 # 60 * 10 seconds = 10m
|
||||||
|
delay: 10 # Every 10 seconds
|
||||||
6
app/playbooks/tasks/start-proxy.yml
Normal file
6
app/playbooks/tasks/start-proxy.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Starting Proxy
|
||||||
|
shell: |
|
||||||
|
docker stack deploy onelab_proxy --compose-file {{ onelab_path }}/proxy/docker-compose.yml
|
||||||
|
sleep 10
|
||||||
|
become: true
|
||||||
6
app/playbooks/tasks/stop-db-only.yml
Normal file
6
app/playbooks/tasks/stop-db-only.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Stopping database service
|
||||||
|
shell: |
|
||||||
|
{{ compose_command }} -f {{ onelab_path }}/docker-compose.yml down
|
||||||
|
sleep 30
|
||||||
|
become: true
|
||||||
6
app/playbooks/tasks/stop-onelab.yml
Normal file
6
app/playbooks/tasks/stop-onelab.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Stopping OneLab
|
||||||
|
shell: |
|
||||||
|
docker stack rm onelab
|
||||||
|
sleep 30
|
||||||
|
become: true
|
||||||
6
app/playbooks/tasks/stop-proxy.yml
Normal file
6
app/playbooks/tasks/stop-proxy.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Stopping Proxy
|
||||||
|
shell: |
|
||||||
|
docker stack rm onelab_proxy
|
||||||
|
sleep 20
|
||||||
|
become: true
|
||||||
24
app/playbooks/tasks/update-conf-files.yml
Normal file
24
app/playbooks/tasks/update-conf-files.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- name: Loading Docker Swarm configuration
|
||||||
|
shell: >
|
||||||
|
docker node ls | grep "Ready" | wc -l
|
||||||
|
register: nodecount
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
deploy_on: "{{ 'manager' if (nodecount.stdout == '1') else 'worker' }}"
|
||||||
|
|
||||||
|
- name: Getting the list of Docker secrets
|
||||||
|
shell: docker secret ls | tail -n +2 | awk '{print $2}'
|
||||||
|
register: docker_secrets
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Reconfiguring files
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ onelab_path }}/installation/latest/app/{{ item }}"
|
||||||
|
dest: "{{ onelab_path }}/{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- 'docker-compose.yml'
|
||||||
|
- 'nginx/onelab.conf'
|
||||||
|
- 'proxy/proxy.conf'
|
||||||
|
- 'proxy/docker-compose.yml'
|
||||||
53
app/playbooks/uninstall.yml
Normal file
53
app/playbooks/uninstall.yml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
- name: Uninstalling OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
vars_prompt:
|
||||||
|
- name: "userchoice"
|
||||||
|
prompt: "Do you want to uninstall OneLab and remove all the data? Type: yes/no"
|
||||||
|
private: no
|
||||||
|
|
||||||
|
# Call from ./installation/latest/app/playbooks/uninstall.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
- name: Aborting the uninstall process
|
||||||
|
fail:
|
||||||
|
msg: Aborting the uninstall process
|
||||||
|
when: userchoice != "yes"
|
||||||
|
|
||||||
|
# Stop OneLab if OneLab is running
|
||||||
|
- name: Checking if OneLab is running
|
||||||
|
shell: docker stack ls | grep 'onelab' | wc -l
|
||||||
|
become: true
|
||||||
|
register: stack_count
|
||||||
|
|
||||||
|
- include_tasks: ./tasks/stop-onelab.yml
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
- include_tasks: ./tasks/stop-proxy.yml
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
|
||||||
|
# Remove Docker volumes (onelab_pgdata, onelab_rabbitmq_data)
|
||||||
|
- name: Removing Docker data
|
||||||
|
shell: |
|
||||||
|
docker volume rm onelab_pgdata -f
|
||||||
|
docker volume rm onelab_rabbitmq_data -f
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# Remove Docker images
|
||||||
|
- name: Checking current OneLab images
|
||||||
|
shell: >
|
||||||
|
docker image ls | egrep 'onelab-' | egrep -v '1.27.0' | awk '{ print $3}'
|
||||||
|
register: onelab_old_images
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Pruning OneLab old images
|
||||||
|
shell:
|
||||||
|
docker rmi {{ item }}
|
||||||
|
become: true
|
||||||
|
loop: "{{ onelab_old_images.stdout_lines }}"
|
||||||
|
|
||||||
|
# Remove Docker login credentials
|
||||||
|
- name: Removing Docker login credentials
|
||||||
|
shell: |
|
||||||
|
docker logout hub.andrewalliance.com
|
||||||
|
become: true
|
||||||
115
app/playbooks/update.yml
Normal file
115
app/playbooks/update.yml
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# This playbook updates the OneLab Enterprise to latest version or a chosen version in one step
|
||||||
|
---
|
||||||
|
- name: Updating OneLab
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: yes
|
||||||
|
vars:
|
||||||
|
main_path: '../../../../..'
|
||||||
|
onelab_path: '../../../../../onelab'
|
||||||
|
|
||||||
|
vars_prompt:
|
||||||
|
- name: "userchoice"
|
||||||
|
prompt: "Confirm OneLab update: yes/no"
|
||||||
|
private: no
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
|
||||||
|
# Choice to proceed or stop the update process
|
||||||
|
- name: Aborting the update process
|
||||||
|
fail:
|
||||||
|
msg: Aborting the update process
|
||||||
|
when: userchoice != "yes"
|
||||||
|
|
||||||
|
# Gather latest version information
|
||||||
|
- name: Fetching OneLab latest version details from the repository
|
||||||
|
uri:
|
||||||
|
url: "https://hub.andrewalliance.com/enterprise/version.json"
|
||||||
|
return_content: yes
|
||||||
|
validate_certs: no
|
||||||
|
register: latest_version
|
||||||
|
become: true
|
||||||
|
when: version is undefined
|
||||||
|
- set_fact:
|
||||||
|
latest: "{{ (latest_version.content | from_json).version }}"
|
||||||
|
when: version is undefined
|
||||||
|
|
||||||
|
- name: Checking OneLab current version
|
||||||
|
fail:
|
||||||
|
msg: OneLab is already up-to-date (1.27.0)
|
||||||
|
when: (version is undefined) and (latest == "1.27.0")
|
||||||
|
|
||||||
|
- name: Starting OneLab update to {{ version | default(latest) }}
|
||||||
|
debug:
|
||||||
|
msg: Version {{ version | default(latest) }}
|
||||||
|
|
||||||
|
# Remove installer bundles if it exists already, then download & unzip
|
||||||
|
- name: Removing the bundle if it already exists
|
||||||
|
file:
|
||||||
|
state: absent
|
||||||
|
path: "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- "{{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}"
|
||||||
|
- "{{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}.zip"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Downloading the installer bundle
|
||||||
|
shell: wget --no-check-certificate https://hub.andrewalliance.com/enterprise/onelab-enterprise-installer-{{ version | default(latest)}}.zip -P {{ main_path }}
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Unzip the installer bundle
|
||||||
|
shell: unzip {{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}.zip -d {{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Checking if OneLab is running
|
||||||
|
shell: docker stack ls | grep 'onelab' | wc -l
|
||||||
|
become: true
|
||||||
|
register: stack_count
|
||||||
|
|
||||||
|
# Stop OneLab (unkown version) if OneLab is running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-onelab.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
|
||||||
|
# Start Proxy (maintenance page) if OneLab was running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
|
||||||
|
# Perform OneLab backup
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/backup-task.yml"
|
||||||
|
|
||||||
|
# Perform OneLab update
|
||||||
|
- include_tasks: "{{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}/app/playbooks/tasks/install-task.yml"
|
||||||
|
vars:
|
||||||
|
main_path: '../../../../..'
|
||||||
|
onelab_path: '../../../../../onelab'
|
||||||
|
installer_path: '../../../../../onelab-enterprise-installer-{{ version | default(latest)}}'
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
- include_vars:
|
||||||
|
file: "{{ onelab_path }}/configurations.yml"
|
||||||
|
|
||||||
|
# Perform reconfiguration
|
||||||
|
# Use dynamic path (variable) to force dynamic loading of this new task
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/reconfigure-task.yml"
|
||||||
|
|
||||||
|
# Remove installer bundles
|
||||||
|
- name: Removing the installer
|
||||||
|
file:
|
||||||
|
state: absent
|
||||||
|
path: "{{ item }}"
|
||||||
|
with_items:
|
||||||
|
- "{{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}"
|
||||||
|
- "{{ main_path }}/onelab-enterprise-installer-{{ version | default(latest)}}.zip"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
# Stop Proxy (maintenance page) if OneLab was running
|
||||||
|
# Use dynamic path (variable) to force dynamic loading of this new task
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
|
||||||
|
# Start OneLab if OneLab was running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-onelab.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
47
app/proxy/docker-compose.yml
Normal file
47
app/proxy/docker-compose.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
version: "3.2"
|
||||||
|
services:
|
||||||
|
proxy:
|
||||||
|
image: hub.andrewalliance.com/releases/nginx:1.29.5-alpine
|
||||||
|
ports:
|
||||||
|
- target: 80
|
||||||
|
published: 80
|
||||||
|
protocol: tcp
|
||||||
|
mode: host
|
||||||
|
- target: 443
|
||||||
|
published: 443
|
||||||
|
protocol: tcp
|
||||||
|
mode: host
|
||||||
|
volumes:
|
||||||
|
- ./../ssl:/etc/nginx/ssl
|
||||||
|
- ./not-supported.html:/usr/onelab/not-supported.html
|
||||||
|
- ./error-404.html:/usr/onelab/error-404.html
|
||||||
|
- ./proxy.conf:/etc/nginx/nginx.conf
|
||||||
|
- ./custom-http.conf:/etc/nginx/custom-http.conf
|
||||||
|
- ./custom-server.conf:/etc/nginx/custom-server.conf
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
{% if docker_secrets is defined and "ssl_passphrase" in docker_secrets.stdout_lines %}
|
||||||
|
secrets:
|
||||||
|
- ssl_passphrase
|
||||||
|
{% endif %}
|
||||||
|
maintenance:
|
||||||
|
image: hub.andrewalliance.com/releases/nginx:1.29.5-alpine
|
||||||
|
volumes:
|
||||||
|
- ./maintenance.html:/usr/onelab/index.html
|
||||||
|
- ./maintenance.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
placement:
|
||||||
|
constraints:
|
||||||
|
- node.role == manager
|
||||||
|
{% if docker_secrets is defined and "ssl_passphrase" in docker_secrets.stdout_lines %}
|
||||||
|
secrets:
|
||||||
|
ssl_passphrase:
|
||||||
|
external: true
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
98
app/proxy/error-404.html
Normal file
98
app/proxy/error-404.html
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>OneLab - Page Not Found</title>
|
||||||
|
<meta name="description" content="The page you are looking for does not exist or has been moved.">
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Open Sans", sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
padding: 128px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 360px;
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 64px;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: center;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
color: #888;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.47;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 32px;
|
||||||
|
padding: 12px 28px;
|
||||||
|
border-radius: 1000px;
|
||||||
|
background: #6cb644;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, .15);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-btn:hover,
|
||||||
|
a.login-btn:focus {
|
||||||
|
background: #3a8611;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page" role="main" aria-labelledby="title">
|
||||||
|
<div class="content">
|
||||||
|
<div class="img">
|
||||||
|
<img
|
||||||
|
src="data:image/png;base64,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"
|
||||||
|
alt="OneLab logo">
|
||||||
|
</div>
|
||||||
|
<div class="main" id="title">Page not found</div>
|
||||||
|
<div class="code">Error 404</div>
|
||||||
|
<div class="sub">The page you requested doesn’t exist, was removed, or is temporarily unavailable. You can return
|
||||||
|
to the application by logging in again.</div>
|
||||||
|
<a href="/login" class="login-btn" aria-label="Go to login page">Go to Home page</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
9
app/proxy/maintenance.conf
Normal file
9
app/proxy/maintenance.conf
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
location / {
|
||||||
|
root /usr/onelab;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
89
app/proxy/maintenance.html
Normal file
89
app/proxy/maintenance.html
Normal file
File diff suppressed because one or more lines are too long
82
app/proxy/not-supported.html
Normal file
82
app/proxy/not-supported.html
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>OneLab - Browser not supported</title>
|
||||||
|
<meta name="description" content="Your browser is not supported">
|
||||||
|
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="refresh" content="30">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Open Sans", sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
padding: 128px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 64px;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: center;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
margin-top: 32px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 1.47;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: center;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page">
|
||||||
|
<div class="content">
|
||||||
|
<div class="img">
|
||||||
|
<img
|
||||||
|
src="data:image/png;base64,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"
|
||||||
|
alt="OneLab logo">
|
||||||
|
</div>
|
||||||
|
<div class="main">Your browser is not supported</div>
|
||||||
|
<div class="sub">OneLab works better on <a olLink href="https://www.google.com/chrome/">Chrome</a>, <a olLink
|
||||||
|
href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> and <a olLink
|
||||||
|
href="https://www.microsoft.com/en-us/windows/microsoft-edge">Microsoft Edge</a></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
174
app/proxy/proxy.conf
Normal file
174
app/proxy/proxy.conf
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
# Load the headers-more module
|
||||||
|
load_module /etc/nginx/modules/ngx_http_headers_more_filter_module.so;
|
||||||
|
|
||||||
|
worker_processes 4;
|
||||||
|
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
|
||||||
|
http {
|
||||||
|
server_names_hash_bucket_size 128;
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
|
types {
|
||||||
|
image/svg+xml svg svgz;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_max_body_size 600m;
|
||||||
|
|
||||||
|
# don't send the nginx version number in error pages and Server header
|
||||||
|
server_tokens off;
|
||||||
|
more_set_headers 'Server: OneLab';
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
|
||||||
|
resolver 8.8.8.8;
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=proxy_global:10m rate=50r/s;
|
||||||
|
|
||||||
|
upstream onelab {
|
||||||
|
server host.docker.internal:8080;
|
||||||
|
server maintenance:80 backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
# redirect all http traffic to https
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
{% if (onelab.services.revproxy.ipv6|default(true)) != false %}
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
{% endif %}
|
||||||
|
server_name {{ onelab.domain[8:] }};
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
include /etc/nginx/custom-http.conf;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl default_server;
|
||||||
|
{% if (onelab.services.revproxy.ipv6|default(true)) != false %}
|
||||||
|
listen [::]:443 ssl default_server;
|
||||||
|
{% endif %}
|
||||||
|
http2 on;
|
||||||
|
server_name {{ onelab.domain[8:] }};
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/ssl/server.pem;
|
||||||
|
ssl_certificate_key /etc/nginx/ssl/server.key;
|
||||||
|
{% if docker_secrets is defined and "ssl_passphrase" in docker_secrets.stdout_lines %}
|
||||||
|
ssl_password_file /run/secrets/ssl_passphrase;
|
||||||
|
{% endif %}
|
||||||
|
# ssl_client_certificate /etc/nginx/ssl/ca.crt;
|
||||||
|
# ssl_verify_client off;
|
||||||
|
|
||||||
|
# enable session resumption to improve https performance
|
||||||
|
# http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html
|
||||||
|
ssl_session_cache shared:SSL:50m;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
|
||||||
|
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
|
||||||
|
|
||||||
|
# enables server-side protection from BEAST attacks
|
||||||
|
# http://blog.ivanristic.com/2013/09/is-beast-still-a-threat.html
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
# disable SSLv3(enabled by default since nginx 0.8.19) since it's less secure then TLS http://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_3.0
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
# ciphers chosen for forward secrecy and compatibility
|
||||||
|
# http://blog.ivanristic.com/2013/08/configuring-apache-nginx-and-openssl-for-forward-secrecy.html
|
||||||
|
ssl_ciphers 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
|
||||||
|
ssl_ecdh_curve X25519:P-384:P-256;
|
||||||
|
|
||||||
|
# enable ocsp stapling (mechanism by which a site can convey certificate revocation information to visitors in a privacy-preserving, scalable manner)
|
||||||
|
# http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
|
||||||
|
resolver 8.8.8.8 8.8.4.4;
|
||||||
|
ssl_stapling on;
|
||||||
|
ssl_stapling_verify on;
|
||||||
|
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
|
||||||
|
|
||||||
|
# read more here http://tautt.com/best-nginx-configuration-for-security/
|
||||||
|
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
|
||||||
|
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping
|
||||||
|
# also https://hstspreload.org/
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
|
||||||
|
|
||||||
|
# config to don't allow the browser to render the page inside an frame or iframe
|
||||||
|
# and avoid clickjacking http://en.wikipedia.org/wiki/Clickjacking
|
||||||
|
# if you need to allow [i]frames, you can use SAMEORIGIN or even set an uri with ALLOW-FROM uri
|
||||||
|
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options
|
||||||
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
|
|
||||||
|
# when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header,
|
||||||
|
# to disable content-type sniffing on some browsers.
|
||||||
|
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||||
|
# currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx
|
||||||
|
# http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx
|
||||||
|
# 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020
|
||||||
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
# This header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
|
||||||
|
# It's usually enabled by default anyway, so the role of this header is to re-enable the filter for
|
||||||
|
# this particular website if it was disabled by the user.
|
||||||
|
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||||
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
|
|
||||||
|
# with Content Security Policy (CSP) enabled(and a browser that supports it(http://caniuse.com/#feat=contentsecuritypolicy),
|
||||||
|
# you can tell the browser that it can only download content from the domains you explicitly allow
|
||||||
|
# http://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||||
|
# https://www.owasp.org/index.php/Content_Security_Policy
|
||||||
|
# I need to change our application code so we can increase security by disabling 'unsafe-inline' 'unsafe-eval'
|
||||||
|
# directives for css and js(if you have inline css or js, you will need to keep it too).
|
||||||
|
# more: http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful
|
||||||
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://app.intercom.io https://widget.intercom.io https://js.intercomcdn.com https://*.google-analytics.com https://*.googletagmanager.com https://recaptcha.net https://*.recaptcha.net https://*.gstatic.com; img-src * data:; media-src *; style-src 'self' 'unsafe-inline' https://*.google-analytics.com https://*.googletagmanager.com https://recaptcha.net https://*.recaptcha.net https://*.gstatic.com; font-src 'self' https://*.intercomcdn.com https://*.google-analytics.com https://*.googletagmanager.com https://recaptcha.net https://*.recaptcha.net https://*.gstatic.com; frame-src *; connect-src 'self' https://*.intercom.io wss://*.intercom.io https://*.intercomcdn.com https://*.intercomcdn.eu https://*.intercomusercontent.com https://*.intercom-messenger.com wss://*.intercom-messenger.com https://*.google-analytics.com https://*.googletagmanager.com https://recaptcha.net https://*.recaptcha.net https://*.gstatic.com; object-src 'none'";
|
||||||
|
|
||||||
|
add_header Referrer-Policy "same-origin";
|
||||||
|
|
||||||
|
add_header Permissions-Policy "accelerometer=(), autoplay=(), camera=(), encrypted-media=(), fullscreen=(self), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), sync-xhr=(self), usb=()";
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 10240;
|
||||||
|
gzip_proxied expired no-cache no-store private auth;
|
||||||
|
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
gzip_disable "MSIE [1-6]\.";
|
||||||
|
|
||||||
|
root /usr/onelab/;
|
||||||
|
|
||||||
|
include /etc/nginx/custom-server.conf;
|
||||||
|
|
||||||
|
location /not-supported {
|
||||||
|
index not-supported.html not-supported.htm;
|
||||||
|
try_files $uri $uri/ /not-supported.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /error-404 {
|
||||||
|
index error-404.html error-404.htm;
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Also used as workaround for a Docker swarm issue
|
||||||
|
# https://github.com/moby/moby/issues/25526
|
||||||
|
# Redirect to HTTP, but assume that we will be on the same server
|
||||||
|
location / {
|
||||||
|
limit_req zone=proxy_global burst=50 nodelay;
|
||||||
|
|
||||||
|
if ($http_user_agent ~* '(MSIE 11.0|MSIE 10.0|MSIE 9.0|MSIE 8.0|MSIE 7.0|MSIE 6.0)') {
|
||||||
|
return 301 https://$host/not-supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy_pass http://onelab;
|
||||||
|
proxy_next_upstream error;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
5
app/rabbit/advanced.conf
Normal file
5
app/rabbit/advanced.conf
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
{rabbit, [
|
||||||
|
{tcp_listeners, []}
|
||||||
|
]}
|
||||||
|
].
|
||||||
20
app/rabbit/definitions.json
Normal file
20
app/rabbit/definitions.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"rabbit_version": "3.6.5",
|
||||||
|
"users": [
|
||||||
|
],
|
||||||
|
"vhosts": [
|
||||||
|
{
|
||||||
|
"name": "devices"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
],
|
||||||
|
"parameters": [],
|
||||||
|
"policies": [],
|
||||||
|
"queues": [],
|
||||||
|
"exchanges": [],
|
||||||
|
"bindings": []
|
||||||
|
}
|
||||||
1
app/rabbit/enable_plugins
Normal file
1
app/rabbit/enable_plugins
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[rabbitmq_auth_backend_http, rabbitmq_auth_backend_cache, rabbitmq_management, rabbitmq_event_exchange].
|
||||||
54
app/rabbit/rabbit.conf
Normal file
54
app/rabbit/rabbit.conf
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Auth server config
|
||||||
|
|
||||||
|
auth_backends.1 = cache
|
||||||
|
|
||||||
|
auth_cache.cached_backend = http
|
||||||
|
auth_cache.cache_ttl = 5000
|
||||||
|
|
||||||
|
auth_http.user_path = http://revproxy/api/v1/rmq/user
|
||||||
|
auth_http.vhost_path = http://revproxy/api/v1/rmq/vhost
|
||||||
|
auth_http.resource_path = http://revproxy/api/v1/rmq/resource
|
||||||
|
auth_http.topic_path = http://revproxy/api/v1/rmq/topic
|
||||||
|
|
||||||
|
listeners.ssl.default = 5671
|
||||||
|
|
||||||
|
# generated with "cat server.crt server.key > server.pem"
|
||||||
|
# fullchain
|
||||||
|
ssl_options.cacertfile = /etc/rabbitmq/ssl/rabbit.fullchain.pem
|
||||||
|
|
||||||
|
ssl_options.certfile = /etc/rabbitmq/ssl/rabbit.crt
|
||||||
|
ssl_options.keyfile = /etc/rabbitmq/ssl/rabbit.key
|
||||||
|
|
||||||
|
# not very secure
|
||||||
|
ssl_options.verify = verify_peer
|
||||||
|
ssl_options.fail_if_no_peer_cert = false
|
||||||
|
|
||||||
|
# for TLS version and cipher
|
||||||
|
ssl_options.versions.1 = tlsv1.2
|
||||||
|
|
||||||
|
# these MUST be disabled if TLSv1.3 is used
|
||||||
|
ssl_options.honor_cipher_order = true
|
||||||
|
ssl_options.honor_ecc_order = true
|
||||||
|
|
||||||
|
# These are highly recommended for TLSv1.2 but cannot be used
|
||||||
|
# with TLSv1.3. If TLSv1.3 is enabled, these lines MUST be removed.
|
||||||
|
ssl_options.client_renegotiation = false
|
||||||
|
ssl_options.secure_renegotiate = true
|
||||||
|
|
||||||
|
ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.3 = ECDH-ECDSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.4 = ECDH-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.5 = DHE-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.6 = DHE-DSS-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.7 = ECDHE-ECDSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.8 = ECDHE-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.9 = ECDH-ECDSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.10 = ECDH-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.11 = DHE-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.12 = DHE-DSS-AES128-GCM-SHA256
|
||||||
|
|
||||||
|
management.load_definitions = /opt/definitions.json
|
||||||
|
|
||||||
|
# For connection events
|
||||||
|
event_exchange.vhost = devices
|
||||||
23
app/rabbit/ssl/rabbit.crt
Normal file
23
app/rabbit/ssl/rabbit.crt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDwTCCAqmgAwIBAgIJANBW7LFskUGkMA0GCSqGSIb3DQEBCwUAMHcxCzAJBgNV
|
||||||
|
BAYTAkNIMQ8wDQYDVQQIDAZHZW5ldmExDzANBgNVBAcMBkdlbmV2YTEYMBYGA1UE
|
||||||
|
CgwPQW5kcmV3IEFsbGlhbmNlMQ8wDQYDVQQLDAZPbmVMYWIxGzAZBgNVBAMMEmFu
|
||||||
|
ZHJld2FsbGlhbmNlLmNvbTAeFw0xOTA5MzAxNTE5NDJaFw0zOTA5MjUxNTE5NDJa
|
||||||
|
MHcxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIDAZHZW5ldmExDzANBgNVBAcMBkdlbmV2
|
||||||
|
YTEYMBYGA1UECgwPQW5kcmV3IEFsbGlhbmNlMQ8wDQYDVQQLDAZPbmVMYWIxGzAZ
|
||||||
|
BgNVBAMMEmFuZHJld2FsbGlhbmNlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||||
|
ADCCAQoCggEBAMxODu2ql2+397wUYVRjuNppa2+nLZwSvzsnyfG5RwmQX/Q3V9sy
|
||||||
|
17RluFW42WLFv5TfS/soRILbShyHmYJL9iGfsa1nkg9XAs681ebHESrGP9jZZ25x
|
||||||
|
alg97IaVI6rQcUN/7WrB183sAokL4AinY2Zh+wOt9LQWsovKO3TB3Oetxw3AImqX
|
||||||
|
onuzTZkzlbJ0KTHGpn8dZ/xjGMvkd1ByjKLQ/gb630vZOJErjcLEWji20fWhwA5S
|
||||||
|
7vhGy4dqivEpLrnEjd2njclADphOxYoHr2rN11n7ASl1+Lu5HhCAFNoeaDi+rliu
|
||||||
|
pupKcbFYCPLIpTq2yw81BOkKn0fPMn5C+m0CAwEAAaNQME4wHQYDVR0OBBYEFGYz
|
||||||
|
XZCPfN8IfCDjPVS0NUcK+c6zMB8GA1UdIwQYMBaAFGYzXZCPfN8IfCDjPVS0NUcK
|
||||||
|
+c6zMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAABxoVD1aZ8NJU2+
|
||||||
|
cL8lMFfrrQEg3vSNzYWuI78OHixGYDF3NPARFL6m20hLusxtmtsM+OsWios58RoO
|
||||||
|
0b9unY3ce0S/567LFpBZgKvo7hdEwDBY2cuX5p8snWfucn4j8KZhebtz4kvcSPOH
|
||||||
|
VTWtgfobKxcryiM8pYA8uRzu/WQKr2q92oYliiOoUg6ZQEWhBCqXzcHJ7D32UcuW
|
||||||
|
fHfZCp48D9LqfSXALNOHyXWaLXRIiQHBuWMhBI57tgbPA4m2hHN8c8y1rc0cSNGt
|
||||||
|
Og8tQoRlj9PRM3WMMrdGuG4TvBe3y5666wo1ZLErfyCbM4/sIPHdrp1cCXFDyyVj
|
||||||
|
nKZ2gjE=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
51
app/rabbit/ssl/rabbit.fullchain.pem
Normal file
51
app/rabbit/ssl/rabbit.fullchain.pem
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDwTCCAqmgAwIBAgIJANBW7LFskUGkMA0GCSqGSIb3DQEBCwUAMHcxCzAJBgNV
|
||||||
|
BAYTAkNIMQ8wDQYDVQQIDAZHZW5ldmExDzANBgNVBAcMBkdlbmV2YTEYMBYGA1UE
|
||||||
|
CgwPQW5kcmV3IEFsbGlhbmNlMQ8wDQYDVQQLDAZPbmVMYWIxGzAZBgNVBAMMEmFu
|
||||||
|
ZHJld2FsbGlhbmNlLmNvbTAeFw0xOTA5MzAxNTE5NDJaFw0zOTA5MjUxNTE5NDJa
|
||||||
|
MHcxCzAJBgNVBAYTAkNIMQ8wDQYDVQQIDAZHZW5ldmExDzANBgNVBAcMBkdlbmV2
|
||||||
|
YTEYMBYGA1UECgwPQW5kcmV3IEFsbGlhbmNlMQ8wDQYDVQQLDAZPbmVMYWIxGzAZ
|
||||||
|
BgNVBAMMEmFuZHJld2FsbGlhbmNlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||||
|
ADCCAQoCggEBAMxODu2ql2+397wUYVRjuNppa2+nLZwSvzsnyfG5RwmQX/Q3V9sy
|
||||||
|
17RluFW42WLFv5TfS/soRILbShyHmYJL9iGfsa1nkg9XAs681ebHESrGP9jZZ25x
|
||||||
|
alg97IaVI6rQcUN/7WrB183sAokL4AinY2Zh+wOt9LQWsovKO3TB3Oetxw3AImqX
|
||||||
|
onuzTZkzlbJ0KTHGpn8dZ/xjGMvkd1ByjKLQ/gb630vZOJErjcLEWji20fWhwA5S
|
||||||
|
7vhGy4dqivEpLrnEjd2njclADphOxYoHr2rN11n7ASl1+Lu5HhCAFNoeaDi+rliu
|
||||||
|
pupKcbFYCPLIpTq2yw81BOkKn0fPMn5C+m0CAwEAAaNQME4wHQYDVR0OBBYEFGYz
|
||||||
|
XZCPfN8IfCDjPVS0NUcK+c6zMB8GA1UdIwQYMBaAFGYzXZCPfN8IfCDjPVS0NUcK
|
||||||
|
+c6zMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAABxoVD1aZ8NJU2+
|
||||||
|
cL8lMFfrrQEg3vSNzYWuI78OHixGYDF3NPARFL6m20hLusxtmtsM+OsWios58RoO
|
||||||
|
0b9unY3ce0S/567LFpBZgKvo7hdEwDBY2cuX5p8snWfucn4j8KZhebtz4kvcSPOH
|
||||||
|
VTWtgfobKxcryiM8pYA8uRzu/WQKr2q92oYliiOoUg6ZQEWhBCqXzcHJ7D32UcuW
|
||||||
|
fHfZCp48D9LqfSXALNOHyXWaLXRIiQHBuWMhBI57tgbPA4m2hHN8c8y1rc0cSNGt
|
||||||
|
Og8tQoRlj9PRM3WMMrdGuG4TvBe3y5666wo1ZLErfyCbM4/sIPHdrp1cCXFDyyVj
|
||||||
|
nKZ2gjE=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMTg7tqpdvt/e8
|
||||||
|
FGFUY7jaaWtvpy2cEr87J8nxuUcJkF/0N1fbMte0ZbhVuNlixb+U30v7KESC20oc
|
||||||
|
h5mCS/Yhn7GtZ5IPVwLOvNXmxxEqxj/Y2WducWpYPeyGlSOq0HFDf+1qwdfN7AKJ
|
||||||
|
C+AIp2NmYfsDrfS0FrKLyjt0wdznrccNwCJql6J7s02ZM5WydCkxxqZ/HWf8YxjL
|
||||||
|
5HdQcoyi0P4G+t9L2TiRK43CxFo4ttH1ocAOUu74RsuHaorxKS65xI3dp43JQA6Y
|
||||||
|
TsWKB69qzddZ+wEpdfi7uR4QgBTaHmg4vq5YrqbqSnGxWAjyyKU6tssPNQTpCp9H
|
||||||
|
zzJ+QvptAgMBAAECggEBAMNTqcAeBdSgvTBLB9bH1Ja0jSvdWKTL45qp6s+5BKqn
|
||||||
|
JqX1N4DxNftZ+Qezx9pAF288oYcJM58sCsoF9oT1HOd+pz+TMriJxrxjG9oc3lPX
|
||||||
|
4HjxOYsE0dh1s6nj8oq/6FnRd+pGU42jo7Tk7pc3ebgL2xHkgXyf6qntejShmBLC
|
||||||
|
gbXM86sPp1GYFNrVh6JveL8UBQzsXnY1u8tm4J2xA47+UvF0uPV5b7xzblplqycv
|
||||||
|
K/cijsqiaBhDZR71Nj7/HnHqcJqs4pYjnNplkfJ5fjkifJh8xZcX0vdJnc7hgC/x
|
||||||
|
BLFuMVLUSXoWtBmajVoJaD/46b0pFTEeGmXs6h3TMj0CgYEA+26WRyiyDGl3wgYJ
|
||||||
|
dm9ITuwBZQo1HiA8wGgAEqyM8BcxNh7zGhYTBKPUYJtuJsUZcFCAbXlD5nIDOYeR
|
||||||
|
bODqEgtN6RQPtQHU4My1gtd8Aaa2IlVD+GVYFSldpcud0pswbiE0xA3GcknGM3hf
|
||||||
|
Jh/7pDEYoN0DkSgyVwL5+d/irVcCgYEA0ARIZC/NyhHC17FGXF5qIG45b+pyvpAE
|
||||||
|
+ytjRHZ09WPErONnD29Q7dhNaYqi6ZtLS1XuG7GVo5VnV+xdr75e93sQuyXzAKnx
|
||||||
|
f1zn+qEDDY/K0qPeh96sHxJjwE6Ha5mO/kL7mx1yV9QEPHTNEynZMM1n2ahgv0kW
|
||||||
|
LM3vymDdN9sCgYAxCrX3NUHdV+kLCEBqQHR7KF9xRNdtg941rVNuUQfAgNWRd+H1
|
||||||
|
EZ8uBYKUQVzv5Pv8Q0d5kvCij1R/sSi1cv1U/a15q/cQWEYcfvFcjwlaDRlzguwa
|
||||||
|
FDJlFkd04k1rWefNY162avVtL2Sgf3cXqZ9cvFLQdauPcaa4ABWgHoJJSwKBgQCF
|
||||||
|
3JuxTUoC5Vcbcosy2dc1s3jm2lqo4wkxkQQ6hHhTibaBA33I4vuTc4StjHe2GSdk
|
||||||
|
/ZFS5P7E3Fo6rHLFq551aA6mQI+WN8afDWyDTqYmTghZcPa9PMBK5oymrmJbDeCF
|
||||||
|
IxnDAjoY5ukq9ocZ8+4+h5By8vX/YssQXh4XgCobzQKBgDMgav9ABc0idoE8sQ0g
|
||||||
|
bnPI/QX+bRhm+yYUQM/zB0h/CRuUC44ZP7dssST7c4L/OirYiZQEtXnHdxZ2DmV3
|
||||||
|
v/5MNbLnx+1z75KLwtg4f24BRB6p26/YxN1Wtudu7QwSSjffGRcUucbS5X3//Fjb
|
||||||
|
3YIcbL9y2FZJHQFybilFQJgu
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
28
app/rabbit/ssl/rabbit.key
Normal file
28
app/rabbit/ssl/rabbit.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMTg7tqpdvt/e8
|
||||||
|
FGFUY7jaaWtvpy2cEr87J8nxuUcJkF/0N1fbMte0ZbhVuNlixb+U30v7KESC20oc
|
||||||
|
h5mCS/Yhn7GtZ5IPVwLOvNXmxxEqxj/Y2WducWpYPeyGlSOq0HFDf+1qwdfN7AKJ
|
||||||
|
C+AIp2NmYfsDrfS0FrKLyjt0wdznrccNwCJql6J7s02ZM5WydCkxxqZ/HWf8YxjL
|
||||||
|
5HdQcoyi0P4G+t9L2TiRK43CxFo4ttH1ocAOUu74RsuHaorxKS65xI3dp43JQA6Y
|
||||||
|
TsWKB69qzddZ+wEpdfi7uR4QgBTaHmg4vq5YrqbqSnGxWAjyyKU6tssPNQTpCp9H
|
||||||
|
zzJ+QvptAgMBAAECggEBAMNTqcAeBdSgvTBLB9bH1Ja0jSvdWKTL45qp6s+5BKqn
|
||||||
|
JqX1N4DxNftZ+Qezx9pAF288oYcJM58sCsoF9oT1HOd+pz+TMriJxrxjG9oc3lPX
|
||||||
|
4HjxOYsE0dh1s6nj8oq/6FnRd+pGU42jo7Tk7pc3ebgL2xHkgXyf6qntejShmBLC
|
||||||
|
gbXM86sPp1GYFNrVh6JveL8UBQzsXnY1u8tm4J2xA47+UvF0uPV5b7xzblplqycv
|
||||||
|
K/cijsqiaBhDZR71Nj7/HnHqcJqs4pYjnNplkfJ5fjkifJh8xZcX0vdJnc7hgC/x
|
||||||
|
BLFuMVLUSXoWtBmajVoJaD/46b0pFTEeGmXs6h3TMj0CgYEA+26WRyiyDGl3wgYJ
|
||||||
|
dm9ITuwBZQo1HiA8wGgAEqyM8BcxNh7zGhYTBKPUYJtuJsUZcFCAbXlD5nIDOYeR
|
||||||
|
bODqEgtN6RQPtQHU4My1gtd8Aaa2IlVD+GVYFSldpcud0pswbiE0xA3GcknGM3hf
|
||||||
|
Jh/7pDEYoN0DkSgyVwL5+d/irVcCgYEA0ARIZC/NyhHC17FGXF5qIG45b+pyvpAE
|
||||||
|
+ytjRHZ09WPErONnD29Q7dhNaYqi6ZtLS1XuG7GVo5VnV+xdr75e93sQuyXzAKnx
|
||||||
|
f1zn+qEDDY/K0qPeh96sHxJjwE6Ha5mO/kL7mx1yV9QEPHTNEynZMM1n2ahgv0kW
|
||||||
|
LM3vymDdN9sCgYAxCrX3NUHdV+kLCEBqQHR7KF9xRNdtg941rVNuUQfAgNWRd+H1
|
||||||
|
EZ8uBYKUQVzv5Pv8Q0d5kvCij1R/sSi1cv1U/a15q/cQWEYcfvFcjwlaDRlzguwa
|
||||||
|
FDJlFkd04k1rWefNY162avVtL2Sgf3cXqZ9cvFLQdauPcaa4ABWgHoJJSwKBgQCF
|
||||||
|
3JuxTUoC5Vcbcosy2dc1s3jm2lqo4wkxkQQ6hHhTibaBA33I4vuTc4StjHe2GSdk
|
||||||
|
/ZFS5P7E3Fo6rHLFq551aA6mQI+WN8afDWyDTqYmTghZcPa9PMBK5oymrmJbDeCF
|
||||||
|
IxnDAjoY5ukq9ocZ8+4+h5By8vX/YssQXh4XgCobzQKBgDMgav9ABc0idoE8sQ0g
|
||||||
|
bnPI/QX+bRhm+yYUQM/zB0h/CRuUC44ZP7dssST7c4L/OirYiZQEtXnHdxZ2DmV3
|
||||||
|
v/5MNbLnx+1z75KLwtg4f24BRB6p26/YxN1Wtudu7QwSSjffGRcUucbS5X3//Fjb
|
||||||
|
3YIcbL9y2FZJHQFybilFQJgu
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
21
app/reconfigure.sh
Normal file
21
app/reconfigure.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
# Usage: ./reconfigure.sh [--no-pull]
|
||||||
|
|
||||||
|
onelab_no_pull=""
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
if [[ "$arg" == "--no-pull" ]]; then
|
||||||
|
onelab_no_pull="no-pull"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
LOG_PATH="./logs/ansible/$(date +%F)-ansible.log"
|
||||||
|
PLAYBOOK="./installation/1.27.0/app/playbooks/reconfigure.yml"
|
||||||
|
EXTRA_VARS=()
|
||||||
|
|
||||||
|
if [[ -n "$onelab_no_pull" ]]; then
|
||||||
|
EXTRA_VARS+=("-e" "policy=$onelab_no_pull")
|
||||||
|
fi
|
||||||
|
|
||||||
|
ANSIBLE_LOG_PATH="$LOG_PATH" ansible-playbook "$PLAYBOOK" "${EXTRA_VARS[@]}"
|
||||||
3
app/start.sh
Normal file
3
app/start.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
ANSIBLE_LOG_PATH=./logs/ansible/$(date +%F)-ansible.log ansible-playbook ./installation/latest/app/playbooks/deploy.yml
|
||||||
3
app/stop.sh
Normal file
3
app/stop.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
ANSIBLE_LOG_PATH=./logs/ansible/$(date +%F)-ansible.log ansible-playbook ./installation/latest/app/playbooks/stop.yml
|
||||||
2
app/uninstall.sh
Normal file
2
app/uninstall.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
ansible-playbook ./installation/1.27.0/app/playbooks/uninstall.yml
|
||||||
26
app/update.sh
Normal file
26
app/update.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Usage: ./update.sh [version] [--force]
|
||||||
|
|
||||||
|
onelab_version=""
|
||||||
|
onelab_force_update=""
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
if [[ "$arg" == "--force" ]]; then
|
||||||
|
onelab_force_update="--force"
|
||||||
|
else
|
||||||
|
onelab_version="$arg"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
LOG_PATH="./logs/ansible/$(date +%F)-ansible.log"
|
||||||
|
PLAYBOOK="./installation/1.27.0/app/playbooks/update.yml"
|
||||||
|
EXTRA_VARS=()
|
||||||
|
|
||||||
|
if [[ -n "$onelab_version" ]]; then
|
||||||
|
EXTRA_VARS+=("-e" "version=$onelab_version")
|
||||||
|
fi
|
||||||
|
if [[ -n "$onelab_force_update" ]]; then
|
||||||
|
EXTRA_VARS+=("-e" "userchoice=yes")
|
||||||
|
fi
|
||||||
|
|
||||||
|
ANSIBLE_LOG_PATH="$LOG_PATH" ansible-playbook "$PLAYBOOK" "${EXTRA_VARS[@]}"
|
||||||
52
gitops/README.md
Normal file
52
gitops/README.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# OneLab GitOps (k3s + Argo CD)
|
||||||
|
|
||||||
|
This directory holds the **Helm chart** that replaces `docker stack deploy` from the legacy Swarm installer (`app/docker-compose.yml`).
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
| Path | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `charts/onelab` | Helm chart (StatefulSets, Deployments, Services, ConfigMaps, Secrets) |
|
||||||
|
| `values/*.yaml` | Environment-specific overrides (non-secret defaults; use sealed/external secrets for prod) |
|
||||||
|
| `argocd/application.yaml` | Example `Application` — set `repoURL` / `targetRevision` to your remote |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. **k3s** (or any Kubernetes) with default storage class for Postgres/Rabbit PVCs (e.g. `local-path`).
|
||||||
|
2. **Image pull access** to `hub.andrewalliance.com` — create a docker-registry secret and reference it in `imagePullSecrets`:
|
||||||
|
```bash
|
||||||
|
kubectl create namespace onelab
|
||||||
|
kubectl create secret docker-registry hub-andrewalliance -n onelab \
|
||||||
|
--docker-server=hub.andrewalliance.com --docker-username=... --docker-password=...
|
||||||
|
```
|
||||||
|
3. **RabbitMQ TLS secret** (name `onelab-rabbit-tls` by default) — see `values/k3s-example.yaml` comments, or set `rabbitmq.tls.embed: true` with PEM strings in a **private** values file.
|
||||||
|
4. **Host paths** (default): ensure `/opt/onelab/data` and `/opt/onelab/logs` exist on nodes that run workloads using `persistence.mode: hostPath`, or switch to RWX storage for multi-node.
|
||||||
|
|
||||||
|
## Helm (without Argo CD)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd gitops/charts/onelab
|
||||||
|
helm upgrade --install onelab . -n onelab --create-namespace \
|
||||||
|
-f ../../values/k3s-example.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argo CD
|
||||||
|
|
||||||
|
1. Push this repository to a Git remote Argo CD can read.
|
||||||
|
2. Edit `argocd/application.yaml`: `repoURL`, `targetRevision`, and values file as needed.
|
||||||
|
3. `kubectl apply -f gitops/argocd/application.yaml` (from a machine with a working kubeconfig).
|
||||||
|
|
||||||
|
Sync waves order Postgres → Redis/Rabbit/config → application pods.
|
||||||
|
|
||||||
|
## kubectl / credentials
|
||||||
|
|
||||||
|
If `kubectl` reports *You must be logged in*, refresh your kubeconfig (e.g. copy `/etc/rancher/k3s/k3s.yaml` from the server or re-run your auth plugin) before applying manifests.
|
||||||
|
|
||||||
|
## Helm note (Windows)
|
||||||
|
|
||||||
|
Helm 3.19 may return empty content for `.Files.Get` on Windows; this chart uses `fromYaml (.Files.AsConfig)` as a workaround so packaged files still render correctly.
|
||||||
|
|
||||||
|
## Not migrated in this chart
|
||||||
|
|
||||||
|
- **Edge proxy stack** (`app/proxy/docker-compose.yml`, host 80/443) — use k3s **Traefik** / **Ingress** + **cert-manager**, or a separate DaemonSet/nginx chart.
|
||||||
|
- **Swarm-only secrets** (e.g. `ssl_passphrase`) — handle via Kubernetes Secrets or external operators.
|
||||||
26
gitops/argocd/application.yaml
Normal file
26
gitops/argocd/application.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Syncs chart from Git; ensure Argo CD can clone repoURL (add credentials in Argo if private).
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: onelab
|
||||||
|
namespace: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://git.luneski.fr/luneski/onelab-k8s.git
|
||||||
|
targetRevision: main
|
||||||
|
path: gitops/charts/onelab
|
||||||
|
helm:
|
||||||
|
valueFiles:
|
||||||
|
- ../../values/k3s-example.yaml
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: onelab
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
6
gitops/charts/onelab/Chart.yaml
Normal file
6
gitops/charts/onelab/Chart.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: onelab
|
||||||
|
description: OneLab stack for Kubernetes (migrated from Docker Swarm compose)
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "1.27.0"
|
||||||
5
gitops/charts/onelab/files/advanced.conf
Normal file
5
gitops/charts/onelab/files/advanced.conf
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
{rabbit, [
|
||||||
|
{tcp_listeners, []}
|
||||||
|
]}
|
||||||
|
].
|
||||||
91
gitops/charts/onelab/files/configurations.gotmpl
Normal file
91
gitops/charts/onelab/files/configurations.gotmpl
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
---
|
||||||
|
onelab:
|
||||||
|
domain: {{ .Values.onelab.domain | quote }}
|
||||||
|
logs:
|
||||||
|
level: info
|
||||||
|
assets:
|
||||||
|
purge: 1d
|
||||||
|
shared:
|
||||||
|
inputs:
|
||||||
|
path: "./data/shared/inputs"
|
||||||
|
archive_path: "./data/shared/archived"
|
||||||
|
security:
|
||||||
|
cors: '*'
|
||||||
|
auth:
|
||||||
|
token:
|
||||||
|
expiration: 5m
|
||||||
|
key: {{ .Values.onelab.secrets.authTokenKey | quote }}
|
||||||
|
password:
|
||||||
|
expiration: 90d
|
||||||
|
min_length: 8
|
||||||
|
prevent_reuse: 5
|
||||||
|
allow_list: []
|
||||||
|
block_list: []
|
||||||
|
authentifier: "email"
|
||||||
|
ratelimit:
|
||||||
|
ip:
|
||||||
|
max: 1000
|
||||||
|
duration: 1d
|
||||||
|
auth:
|
||||||
|
max: 5
|
||||||
|
duration: 5m
|
||||||
|
delay_after: 2
|
||||||
|
delay_ms: 1000
|
||||||
|
devices:
|
||||||
|
cors: '*'
|
||||||
|
monitoring:
|
||||||
|
token: {{ .Values.onelab.secrets.monitoringToken | quote }}
|
||||||
|
params:
|
||||||
|
session:
|
||||||
|
idle: 45m
|
||||||
|
remember_me: true
|
||||||
|
lab:
|
||||||
|
creation_policy: many
|
||||||
|
signup: false
|
||||||
|
{{- if .Values.onelab.intercom.appid }}
|
||||||
|
intercom:
|
||||||
|
appid: {{ .Values.onelab.intercom.appid | quote }}
|
||||||
|
secret: {{ .Values.onelab.intercom.secret | quote }}
|
||||||
|
{{- end }}
|
||||||
|
mailer:
|
||||||
|
noreply: {{ .Values.onelab.mailer.noreply | quote }}
|
||||||
|
queue:
|
||||||
|
scheduling: 15
|
||||||
|
maxsize: 50
|
||||||
|
error:
|
||||||
|
maxtries: 3
|
||||||
|
timeout: 60
|
||||||
|
ldap:
|
||||||
|
enabled: {{ .Values.features.ldapWorker }}
|
||||||
|
services:
|
||||||
|
db:
|
||||||
|
host: db
|
||||||
|
database: postgres
|
||||||
|
username: postgres
|
||||||
|
password: {{ .Values.postgresql.auth.password | quote }}
|
||||||
|
schema: onelab
|
||||||
|
redis:
|
||||||
|
host: redis
|
||||||
|
port: "6379"
|
||||||
|
rabbit:
|
||||||
|
url: rabbitmq
|
||||||
|
port: 5671
|
||||||
|
token: {{ .Values.onelab.secrets.rabbitToken | quote }}
|
||||||
|
api:
|
||||||
|
replicas: {{ .Values.replicas.api }}
|
||||||
|
apidevice:
|
||||||
|
replicas: {{ .Values.replicas.apidevice }}
|
||||||
|
apirabbit:
|
||||||
|
replicas: {{ .Values.replicas.apirabbit }}
|
||||||
|
devices:
|
||||||
|
replicas: {{ .Values.replicas.devices }}
|
||||||
|
experiments:
|
||||||
|
replicas: {{ .Values.replicas.experiments }}
|
||||||
|
images:
|
||||||
|
replicas: {{ .Values.replicas.images }}
|
||||||
|
manual:
|
||||||
|
replicas: {{ .Values.replicas.manual }}
|
||||||
|
website:
|
||||||
|
ssr: {{ .Values.website.ssr }}
|
||||||
|
ws:
|
||||||
|
replicas: {{ .Values.replicas.ws }}
|
||||||
1
gitops/charts/onelab/files/enable_plugins
Normal file
1
gitops/charts/onelab/files/enable_plugins
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[rabbitmq_auth_backend_http, rabbitmq_auth_backend_cache, rabbitmq_management, rabbitmq_event_exchange].
|
||||||
98
gitops/charts/onelab/files/error-404.html
Normal file
98
gitops/charts/onelab/files/error-404.html
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>OneLab - Page Not Found</title>
|
||||||
|
<meta name="description" content="The page you are looking for does not exist or has been moved.">
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Open Sans", sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
padding: 128px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
width: 360px;
|
||||||
|
max-width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 64px;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: center;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
color: #888;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sub {
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.47;
|
||||||
|
color: #4a4a4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-btn {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 32px;
|
||||||
|
padding: 12px 28px;
|
||||||
|
border-radius: 1000px;
|
||||||
|
background: #6cb644;
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, .15);
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.login-btn:hover,
|
||||||
|
a.login-btn:focus {
|
||||||
|
background: #3a8611;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="page" role="main" aria-labelledby="title">
|
||||||
|
<div class="content">
|
||||||
|
<div class="img">
|
||||||
|
<img
|
||||||
|
src="data:image/png;base64,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"
|
||||||
|
alt="OneLab logo">
|
||||||
|
</div>
|
||||||
|
<div class="main" id="title">Page not found</div>
|
||||||
|
<div class="code">Error 404</div>
|
||||||
|
<div class="sub">The page you requested doesn’t exist, was removed, or is temporarily unavailable. You can return
|
||||||
|
to the application by logging in again.</div>
|
||||||
|
<a href="/login" class="login-btn" aria-label="Go to login page">Go to Home page</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
337
gitops/charts/onelab/files/nginx.conf.tpl
Normal file
337
gitops/charts/onelab/files/nginx.conf.tpl
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
|
||||||
|
worker_processes 4;
|
||||||
|
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
|
client_max_body_size 2m;
|
||||||
|
|
||||||
|
# don't send the nginx version number in error pages and Server header
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
sendfile on;
|
||||||
|
|
||||||
|
upstream website {
|
||||||
|
server website:4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream main {
|
||||||
|
server main:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api {
|
||||||
|
server api:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api-device {
|
||||||
|
server api-device:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream api-rabbit {
|
||||||
|
server api-rabbit:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream designer {
|
||||||
|
server designer:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream runner {
|
||||||
|
server runner:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream static {
|
||||||
|
server static:80;
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream websocket-worker {
|
||||||
|
server websocket-worker:3030;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore the real client IP from the upstream reverse proxy
|
||||||
|
# Trust all RFC 1918 private ranges (covers any Docker network config)
|
||||||
|
set_real_ip_from 10.0.0.0/8;
|
||||||
|
set_real_ip_from 172.16.0.0/12;
|
||||||
|
set_real_ip_from 192.168.0.0/16;
|
||||||
|
real_ip_header X-Real-IP;
|
||||||
|
|
||||||
|
limit_req_zone $binary_remote_addr zone=auth:10m rate=1r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=website:10m rate=5r/s;
|
||||||
|
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;
|
||||||
|
|
||||||
|
# redirect all http traffic to https
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
{{- if .Values.revproxy.ipv6Listen }}
|
||||||
|
listen [::]:80 default_server;
|
||||||
|
{{- end }}
|
||||||
|
server_name localhost;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_min_length 10240;
|
||||||
|
gzip_proxied expired no-cache no-store private auth;
|
||||||
|
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||||
|
gzip_disable "MSIE [1-6]\.";
|
||||||
|
|
||||||
|
root /data/;
|
||||||
|
|
||||||
|
location ^~ /lab/ {
|
||||||
|
rewrite ^/lab/(.*?) /app/lab/$1 last;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /assets/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /static/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://static;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://static;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /sitemap.xml {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /robots.txt {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/ {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/auth/ {
|
||||||
|
# apply rate limiting
|
||||||
|
limit_req zone=auth burst=5 nodelay;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/firmwares {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
|
||||||
|
client_max_body_size 600M;
|
||||||
|
|
||||||
|
proxy_pass http://api;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /api/v1/rmq/ {
|
||||||
|
proxy_pass http://api-rabbit;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /device-api/ {
|
||||||
|
limit_req zone=global burst=10 nodelay;
|
||||||
|
client_max_body_size 600m;
|
||||||
|
|
||||||
|
proxy_pass http://api-device;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/designer/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://designer;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://designer;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/runner/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://runner;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://runner;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /ws/ {
|
||||||
|
proxy_pass http://websocket-worker;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
location ^~ /app/ {
|
||||||
|
location ~* \.(?:css|js|woff|woff2|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://main;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://main;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets for website (including /media/ subdirectory)
|
||||||
|
location ~* ^/.+\.(?:css|js|woff|woff2|ttf|eot|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||||
|
expires 1M;
|
||||||
|
access_log off;
|
||||||
|
add_header Cache-Control "public";
|
||||||
|
|
||||||
|
proxy_pass http://website;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Website SSR routes (rate limited)
|
||||||
|
location ~ ^/(library(/[^/]+)?|login(/(reset|change))?|signup)?$ {
|
||||||
|
limit_req zone=website burst=10 nodelay;
|
||||||
|
|
||||||
|
expires -1;
|
||||||
|
add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
|
||||||
|
|
||||||
|
proxy_pass http://website;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Cookie $http_cookie;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Catch-all for junk requests
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /error-404.html =404;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
gitops/charts/onelab/files/rabbit-definitions.json
Normal file
20
gitops/charts/onelab/files/rabbit-definitions.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"rabbit_version": "3.6.5",
|
||||||
|
"users": [
|
||||||
|
],
|
||||||
|
"vhosts": [
|
||||||
|
{
|
||||||
|
"name": "devices"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "internal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
],
|
||||||
|
"parameters": [],
|
||||||
|
"policies": [],
|
||||||
|
"queues": [],
|
||||||
|
"exchanges": [],
|
||||||
|
"bindings": []
|
||||||
|
}
|
||||||
54
gitops/charts/onelab/files/rabbit.conf
Normal file
54
gitops/charts/onelab/files/rabbit.conf
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Auth server config
|
||||||
|
|
||||||
|
auth_backends.1 = cache
|
||||||
|
|
||||||
|
auth_cache.cached_backend = http
|
||||||
|
auth_cache.cache_ttl = 5000
|
||||||
|
|
||||||
|
auth_http.user_path = http://revproxy/api/v1/rmq/user
|
||||||
|
auth_http.vhost_path = http://revproxy/api/v1/rmq/vhost
|
||||||
|
auth_http.resource_path = http://revproxy/api/v1/rmq/resource
|
||||||
|
auth_http.topic_path = http://revproxy/api/v1/rmq/topic
|
||||||
|
|
||||||
|
listeners.ssl.default = 5671
|
||||||
|
|
||||||
|
# generated with "cat server.crt server.key > server.pem"
|
||||||
|
# fullchain
|
||||||
|
ssl_options.cacertfile = /etc/rabbitmq/ssl/rabbit.fullchain.pem
|
||||||
|
|
||||||
|
ssl_options.certfile = /etc/rabbitmq/ssl/rabbit.crt
|
||||||
|
ssl_options.keyfile = /etc/rabbitmq/ssl/rabbit.key
|
||||||
|
|
||||||
|
# not very secure
|
||||||
|
ssl_options.verify = verify_peer
|
||||||
|
ssl_options.fail_if_no_peer_cert = false
|
||||||
|
|
||||||
|
# for TLS version and cipher
|
||||||
|
ssl_options.versions.1 = tlsv1.2
|
||||||
|
|
||||||
|
# these MUST be disabled if TLSv1.3 is used
|
||||||
|
ssl_options.honor_cipher_order = true
|
||||||
|
ssl_options.honor_ecc_order = true
|
||||||
|
|
||||||
|
# These are highly recommended for TLSv1.2 but cannot be used
|
||||||
|
# with TLSv1.3. If TLSv1.3 is enabled, these lines MUST be removed.
|
||||||
|
ssl_options.client_renegotiation = false
|
||||||
|
ssl_options.secure_renegotiate = true
|
||||||
|
|
||||||
|
ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.3 = ECDH-ECDSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.4 = ECDH-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.5 = DHE-RSA-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.6 = DHE-DSS-AES256-GCM-SHA384
|
||||||
|
ssl_options.ciphers.7 = ECDHE-ECDSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.8 = ECDHE-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.9 = ECDH-ECDSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.10 = ECDH-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.11 = DHE-RSA-AES128-GCM-SHA256
|
||||||
|
ssl_options.ciphers.12 = DHE-DSS-AES128-GCM-SHA256
|
||||||
|
|
||||||
|
management.load_definitions = /opt/definitions.json
|
||||||
|
|
||||||
|
# For connection events
|
||||||
|
event_exchange.vhost = devices
|
||||||
25
gitops/charts/onelab/templates/_helpers.tpl
Normal file
25
gitops/charts/onelab/templates/_helpers.tpl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{{- define "onelab.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "onelab.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride }}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||||
|
{{- if contains $name .Release.Name }}
|
||||||
|
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- else }}
|
||||||
|
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "onelab.labels" -}}
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | quote }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
18
gitops/charts/onelab/templates/configmap-rabbit.yaml
Normal file
18
gitops/charts/onelab/templates/configmap-rabbit.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{- $cfg := fromYaml (.Files.AsConfig) }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: onelab-rabbit-config
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.statefulDeps | quote }}
|
||||||
|
data:
|
||||||
|
rabbit.conf: |
|
||||||
|
{{ index $cfg "rabbit.conf" | nindent 4 }}
|
||||||
|
advanced.conf: |
|
||||||
|
{{ index $cfg "advanced.conf" | nindent 4 }}
|
||||||
|
enable_plugins: |
|
||||||
|
{{ index $cfg "enable_plugins" | nindent 4 }}
|
||||||
|
definitions.json: |
|
||||||
|
{{ index $cfg "rabbit-definitions.json" | nindent 4 }}
|
||||||
14
gitops/charts/onelab/templates/configmap-revproxy.yaml
Normal file
14
gitops/charts/onelab/templates/configmap-revproxy.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{{- $cfg := fromYaml (.Files.AsConfig) }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: onelab-revproxy
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.apps | quote }}
|
||||||
|
data:
|
||||||
|
nginx.conf: |
|
||||||
|
{{ tpl (index $cfg "nginx.conf.tpl") . | nindent 4 }}
|
||||||
|
error-404.html: |
|
||||||
|
{{ index $cfg "error-404.html" | nindent 4 }}
|
||||||
111
gitops/charts/onelab/templates/deployment-optional-workers.yaml
Normal file
111
gitops/charts/onelab/templates/deployment-optional-workers.yaml
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
{{- $root := . }}
|
||||||
|
{{- if .Values.features.ldapWorker }}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: ldap-worker
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: ldap-worker
|
||||||
|
{{- include "onelab.labels" $root | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ $root.Values.syncWaves.apps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ $root.Values.replicas.ldap | default 1 }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: ldap-worker
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: ldap-worker
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with $root.Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: ldap-worker
|
||||||
|
image: {{ printf "%s/%s:%s" $root.Values.images.registry "onelab-ldap-worker" $root.Values.images.tag | quote }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: configurations
|
||||||
|
mountPath: /conf/configurations.yml
|
||||||
|
subPath: configurations.yml
|
||||||
|
readOnly: true
|
||||||
|
{{- if eq $root.Values.persistence.mode "hostPath" }}
|
||||||
|
- name: logs
|
||||||
|
mountPath: /logs
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: configurations
|
||||||
|
secret:
|
||||||
|
secretName: onelab-configurations
|
||||||
|
{{- if eq $root.Values.persistence.mode "hostPath" }}
|
||||||
|
- name: logs
|
||||||
|
hostPath:
|
||||||
|
path: {{ $root.Values.persistence.hostPath.logs }}
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- else }}
|
||||||
|
- name: logs
|
||||||
|
emptyDir: {}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if .Values.features.mailerWorker }}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mailer-worker
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: mailer-worker
|
||||||
|
{{- include "onelab.labels" $root | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ $root.Values.syncWaves.apps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ $root.Values.replicas.mailer | default 1 }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: mailer-worker
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: mailer-worker
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with $root.Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: mailer-worker
|
||||||
|
image: {{ printf "%s/%s:%s" $root.Values.images.registry "onelab-mailer-worker" $root.Values.images.tag | quote }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: configurations
|
||||||
|
mountPath: /conf/configurations.yml
|
||||||
|
subPath: configurations.yml
|
||||||
|
readOnly: true
|
||||||
|
{{- if eq $root.Values.persistence.mode "hostPath" }}
|
||||||
|
- name: logs
|
||||||
|
mountPath: /logs
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: configurations
|
||||||
|
secret:
|
||||||
|
secretName: onelab-configurations
|
||||||
|
{{- if eq $root.Values.persistence.mode "hostPath" }}
|
||||||
|
- name: logs
|
||||||
|
hostPath:
|
||||||
|
path: {{ $root.Values.persistence.hostPath.logs }}
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- else }}
|
||||||
|
- name: logs
|
||||||
|
emptyDir: {}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
53
gitops/charts/onelab/templates/deployment-redis.yaml
Normal file
53
gitops/charts/onelab/templates/deployment-redis.yaml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.statefulDeps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: redis
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: redis
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: redis
|
||||||
|
image: {{ printf "%s/%s:%s" .Values.images.registry .Values.images.redis .Values.images.redisTag | quote }}
|
||||||
|
ports:
|
||||||
|
- containerPort: 6379
|
||||||
|
name: redis
|
||||||
|
{{- with .Values.redis.resources }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: redis
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 6379
|
||||||
|
targetPort: redis
|
||||||
|
name: redis
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/component: redis
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
73
gitops/charts/onelab/templates/deployment-revproxy.yaml
Normal file
73
gitops/charts/onelab/templates/deployment-revproxy.yaml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: revproxy
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.apps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: revproxy
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: revproxy
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: {{ printf "%s/%s:%s" .Values.images.registry .Values.images.nginx .Values.images.nginxTag | quote }}
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
name: http
|
||||||
|
volumeMounts:
|
||||||
|
- name: nginx
|
||||||
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
subPath: nginx.conf
|
||||||
|
- name: nginx
|
||||||
|
mountPath: /data/error-404.html
|
||||||
|
subPath: error-404.html
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: nginx
|
||||||
|
configMap:
|
||||||
|
name: onelab-revproxy
|
||||||
|
- name: data
|
||||||
|
{{- if eq .Values.persistence.mode "hostPath" }}
|
||||||
|
hostPath:
|
||||||
|
path: {{ .Values.persistence.hostPath.data }}
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- else }}
|
||||||
|
emptyDir: {}
|
||||||
|
{{- end }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: revproxy
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.revproxy.serviceType }}
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: http
|
||||||
|
name: http
|
||||||
|
{{- if and (eq .Values.revproxy.serviceType "NodePort") .Values.revproxy.nodePort }}
|
||||||
|
nodePort: {{ .Values.revproxy.nodePort }}
|
||||||
|
{{- end }}
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/component: revproxy
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
13
gitops/charts/onelab/templates/secret-configurations.yaml
Normal file
13
gitops/charts/onelab/templates/secret-configurations.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{{- $cfg := fromYaml (.Files.AsConfig) }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: onelab-configurations
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.statefulDeps | quote }}
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
configurations.yml: |
|
||||||
|
{{- tpl (index $cfg "configurations.gotmpl") . | nindent 4 }}
|
||||||
11
gitops/charts/onelab/templates/secret-postgres.yaml
Normal file
11
gitops/charts/onelab/templates/secret-postgres.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: onelab-postgres
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.postgres | quote }}
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
postgres-password: {{ .Values.postgresql.auth.password | quote }}
|
||||||
18
gitops/charts/onelab/templates/secret-rabbit-tls.yaml
Normal file
18
gitops/charts/onelab/templates/secret-rabbit-tls.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{- if .Values.rabbitmq.tls.embed }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ .Values.rabbitmq.tls.secretName }}
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.statefulDeps | quote }}
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
rabbit.crt: |
|
||||||
|
{{ .Values.rabbitmq.tls.crt | nindent 4 }}
|
||||||
|
rabbit.key: |
|
||||||
|
{{ .Values.rabbitmq.tls.key | nindent 4 }}
|
||||||
|
rabbit.fullchain.pem: |
|
||||||
|
{{ .Values.rabbitmq.tls.fullchain | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
18
gitops/charts/onelab/templates/service-db.yaml
Normal file
18
gitops/charts/onelab/templates/service-db.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: db
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.postgres | quote }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 5432
|
||||||
|
targetPort: postgres
|
||||||
|
name: postgres
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/component: postgres
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
16
gitops/charts/onelab/templates/service-rabbitmq.yaml
Normal file
16
gitops/charts/onelab/templates/service-rabbitmq.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: rabbitmq
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 5671
|
||||||
|
targetPort: amqps
|
||||||
|
name: amqps
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/component: rabbitmq
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
61
gitops/charts/onelab/templates/statefulset-postgres.yaml
Normal file
61
gitops/charts/onelab/templates/statefulset-postgres.yaml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: db
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.postgres | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
serviceName: db
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: postgres
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: postgres
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: postgres
|
||||||
|
image: {{ printf "%s/%s:%s" .Values.images.registry .Values.images.postgres .Values.images.postgresTag | quote }}
|
||||||
|
ports:
|
||||||
|
- containerPort: 5432
|
||||||
|
name: postgres
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
value: postgres
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: postgres
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: onelab-postgres
|
||||||
|
key: postgres-password
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
{{- with .Values.postgresql.resources }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
{{- if .Values.persistence.storageClass }}
|
||||||
|
storageClassName: {{ .Values.persistence.storageClass | quote }}
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.persistence.postgres.size | quote }}
|
||||||
80
gitops/charts/onelab/templates/statefulset-rabbitmq.yaml
Normal file
80
gitops/charts/onelab/templates/statefulset-rabbitmq.yaml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: rabbitmq
|
||||||
|
labels:
|
||||||
|
{{- include "onelab.labels" . | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ .Values.syncWaves.statefulDeps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
serviceName: rabbitmq
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: rabbitmq
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: rabbitmq
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" . }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
spec:
|
||||||
|
hostname: onelab
|
||||||
|
{{- with .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: rabbitmq
|
||||||
|
image: {{ printf "%s/%s:%s" .Values.images.registry .Values.images.rabbitmq .Values.images.rabbitmqTag | quote }}
|
||||||
|
ports:
|
||||||
|
- containerPort: 5671
|
||||||
|
name: amqps
|
||||||
|
volumeMounts:
|
||||||
|
- name: rabbit-data
|
||||||
|
mountPath: /var/lib/rabbitmq/mnesia
|
||||||
|
- name: rabbit-config
|
||||||
|
mountPath: /etc/rabbitmq/rabbitmq.conf
|
||||||
|
subPath: rabbit.conf
|
||||||
|
- name: rabbit-config
|
||||||
|
mountPath: /etc/rabbitmq/advanced.conf
|
||||||
|
subPath: advanced.conf
|
||||||
|
- name: rabbit-config
|
||||||
|
mountPath: /etc/rabbitmq/enabled_plugins
|
||||||
|
subPath: enable_plugins
|
||||||
|
- name: rabbit-config
|
||||||
|
mountPath: /opt/definitions.json
|
||||||
|
subPath: definitions.json
|
||||||
|
- name: rabbit-tls
|
||||||
|
mountPath: /etc/rabbitmq/ssl/rabbit.crt
|
||||||
|
subPath: rabbit.crt
|
||||||
|
- name: rabbit-tls
|
||||||
|
mountPath: /etc/rabbitmq/ssl/rabbit.key
|
||||||
|
subPath: rabbit.key
|
||||||
|
- name: rabbit-tls
|
||||||
|
mountPath: /etc/rabbitmq/ssl/rabbit.fullchain.pem
|
||||||
|
subPath: rabbit.fullchain.pem
|
||||||
|
{{- with .Values.rabbitmq.resources }}
|
||||||
|
resources:
|
||||||
|
{{- toYaml . | nindent 12 }}
|
||||||
|
{{- end }}
|
||||||
|
volumes:
|
||||||
|
- name: rabbit-config
|
||||||
|
configMap:
|
||||||
|
name: onelab-rabbit-config
|
||||||
|
- name: rabbit-tls
|
||||||
|
secret:
|
||||||
|
secretName: {{ .Values.rabbitmq.tls.secretName }}
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: rabbit-data
|
||||||
|
spec:
|
||||||
|
accessModes: ["ReadWriteOnce"]
|
||||||
|
{{- if .Values.persistence.storageClass }}
|
||||||
|
storageClassName: {{ .Values.persistence.storageClass | quote }}
|
||||||
|
{{- end }}
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.persistence.rabbitmq.size | quote }}
|
||||||
116
gitops/charts/onelab/templates/workloads.yaml
Normal file
116
gitops/charts/onelab/templates/workloads.yaml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
{{- $root := . }}
|
||||||
|
{{- range .Values.workloads }}
|
||||||
|
{{- $n := .replicas | default 1 | int }}
|
||||||
|
{{- if and .replicaKey (hasKey $root.Values.replicas .replicaKey) }}
|
||||||
|
{{- $n = index $root.Values.replicas .replicaKey | int }}
|
||||||
|
{{- end }}
|
||||||
|
{{- $vols := or .config (not (empty .mounts)) }}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ .name }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: {{ .name }}
|
||||||
|
{{- include "onelab.labels" $root | nindent 4 }}
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: {{ $root.Values.syncWaves.apps | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: {{ $n }}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: {{ .name }}
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: {{ .name }}
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
spec:
|
||||||
|
{{- with $root.Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .name }}
|
||||||
|
image: {{ printf "%s/%s:%s" $root.Values.images.registry .image $root.Values.images.tag | quote }}
|
||||||
|
{{- if .port }}
|
||||||
|
ports:
|
||||||
|
- containerPort: {{ .port }}
|
||||||
|
name: http
|
||||||
|
{{- end }}
|
||||||
|
{{- if and .website (not $root.Values.website.ssr) }}
|
||||||
|
env:
|
||||||
|
- name: RENDERING_MODE
|
||||||
|
value: "no-ssr"
|
||||||
|
{{- end }}
|
||||||
|
{{- if $vols }}
|
||||||
|
volumeMounts:
|
||||||
|
{{- if .config }}
|
||||||
|
- name: configurations
|
||||||
|
mountPath: /conf/configurations.yml
|
||||||
|
subPath: configurations.yml
|
||||||
|
readOnly: true
|
||||||
|
{{- end }}
|
||||||
|
{{- if has "logs" .mounts }}
|
||||||
|
- name: logs
|
||||||
|
mountPath: /logs
|
||||||
|
{{- end }}
|
||||||
|
{{- if has "data" .mounts }}
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
{{- end }}
|
||||||
|
{{- if has "shared" .mounts }}
|
||||||
|
- name: data
|
||||||
|
mountPath: /shared-inputs
|
||||||
|
subPath: shared/inputs
|
||||||
|
- name: data
|
||||||
|
mountPath: /shared-archived
|
||||||
|
subPath: shared/archived
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if $vols }}
|
||||||
|
volumes:
|
||||||
|
{{- if .config }}
|
||||||
|
- name: configurations
|
||||||
|
secret:
|
||||||
|
secretName: onelab-configurations
|
||||||
|
{{- end }}
|
||||||
|
{{- if eq $root.Values.persistence.mode "hostPath" }}
|
||||||
|
{{- if has "logs" .mounts }}
|
||||||
|
- name: logs
|
||||||
|
hostPath:
|
||||||
|
path: {{ $root.Values.persistence.hostPath.logs }}
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- end }}
|
||||||
|
{{- if or (has "data" .mounts) (has "shared" .mounts) }}
|
||||||
|
- name: data
|
||||||
|
hostPath:
|
||||||
|
path: {{ $root.Values.persistence.hostPath.data }}
|
||||||
|
type: DirectoryOrCreate
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- if and .port (gt (int .port) 0) }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ .name }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: {{ .name }}
|
||||||
|
{{- include "onelab.labels" $root | nindent 4 }}
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: {{ .port }}
|
||||||
|
targetPort: http
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/component: {{ .name }}
|
||||||
|
app.kubernetes.io/name: {{ include "onelab.name" $root }}
|
||||||
|
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
187
gitops/charts/onelab/values.yaml
Normal file
187
gitops/charts/onelab/values.yaml
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
# Default values for onelab — override per environment (see gitops/values/).
|
||||||
|
|
||||||
|
nameOverride: ""
|
||||||
|
fullnameOverride: ""
|
||||||
|
|
||||||
|
images:
|
||||||
|
registry: hub.andrewalliance.com/releases
|
||||||
|
tag: "1.27.0"
|
||||||
|
nginx: nginx
|
||||||
|
nginxTag: "1.29.5-alpine"
|
||||||
|
postgres: postgres
|
||||||
|
postgresTag: "17.8"
|
||||||
|
redis: redis
|
||||||
|
redisTag: "7.4.7-alpine"
|
||||||
|
rabbitmq: rabbitmq
|
||||||
|
rabbitmqTag: "3.13.7"
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
# - name: hub-andrewalliance
|
||||||
|
|
||||||
|
# hostPath: matches typical single-node Swarm-style install (shared /data and /logs).
|
||||||
|
# Use persistence.mode: pvc + a ReadWriteMany class for multi-node shared storage.
|
||||||
|
persistence:
|
||||||
|
mode: hostPath
|
||||||
|
storageClass: ""
|
||||||
|
hostPath:
|
||||||
|
data: /opt/onelab/data
|
||||||
|
logs: /opt/onelab/logs
|
||||||
|
postgres:
|
||||||
|
size: 20Gi
|
||||||
|
rabbitmq:
|
||||||
|
size: 5Gi
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
auth:
|
||||||
|
password: "changeme-use-strong-password"
|
||||||
|
resources: {}
|
||||||
|
|
||||||
|
redis:
|
||||||
|
resources: {}
|
||||||
|
|
||||||
|
rabbitmq:
|
||||||
|
resources: {}
|
||||||
|
# TLS: create Secret `onelab-rabbit-tls` in the release namespace (see README), or set embed: true.
|
||||||
|
tls:
|
||||||
|
secretName: onelab-rabbit-tls
|
||||||
|
embed: false
|
||||||
|
crt: ""
|
||||||
|
key: ""
|
||||||
|
fullchain: ""
|
||||||
|
|
||||||
|
syncWaves:
|
||||||
|
postgres: "-3"
|
||||||
|
statefulDeps: "-2"
|
||||||
|
apps: "0"
|
||||||
|
|
||||||
|
onelab:
|
||||||
|
domain: "https://localhost"
|
||||||
|
mailer:
|
||||||
|
noreply: "no-reply@andrewalliance.com"
|
||||||
|
secrets:
|
||||||
|
authTokenKey: "replace-auth-token-key"
|
||||||
|
monitoringToken: "replace-monitoring-token"
|
||||||
|
rabbitToken: "replace-rabbit-token"
|
||||||
|
intercom:
|
||||||
|
appid: ""
|
||||||
|
secret: "replace-intercom-secret"
|
||||||
|
|
||||||
|
features:
|
||||||
|
ldapWorker: false
|
||||||
|
mailerWorker: false
|
||||||
|
|
||||||
|
website:
|
||||||
|
ssr: true
|
||||||
|
|
||||||
|
revproxy:
|
||||||
|
serviceType: NodePort
|
||||||
|
nodePort: 30080
|
||||||
|
ipv6Listen: true
|
||||||
|
|
||||||
|
# Replica counts (api.apidevice etc. override defaults in templates/workloads.yaml via this map)
|
||||||
|
replicas:
|
||||||
|
api: 2
|
||||||
|
apidevice: 1
|
||||||
|
apirabbit: 1
|
||||||
|
devices: 1
|
||||||
|
experiments: 1
|
||||||
|
images: 1
|
||||||
|
manual: 1
|
||||||
|
ws: 1
|
||||||
|
ldap: 1
|
||||||
|
mailer: 1
|
||||||
|
|
||||||
|
resources: {}
|
||||||
|
|
||||||
|
workloads:
|
||||||
|
- name: supervisor
|
||||||
|
image: onelab-supervisor-worker
|
||||||
|
replicas: 1
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: file-worker
|
||||||
|
image: onelab-file-worker
|
||||||
|
replicas: 1
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data, shared]
|
||||||
|
- name: api
|
||||||
|
image: onelab-api
|
||||||
|
replicaKey: api
|
||||||
|
port: 3000
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: api-device
|
||||||
|
image: onelab-api-device
|
||||||
|
replicaKey: apidevice
|
||||||
|
port: 3000
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: api-rabbit
|
||||||
|
image: onelab-api-rabbit
|
||||||
|
replicaKey: apirabbit
|
||||||
|
port: 3000
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: devices-worker
|
||||||
|
image: onelab-devices-worker
|
||||||
|
replicaKey: devices
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: experiments-worker
|
||||||
|
image: onelab-experiments-worker
|
||||||
|
replicaKey: experiments
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs]
|
||||||
|
- name: images-worker
|
||||||
|
image: onelab-images-worker
|
||||||
|
replicaKey: images
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs, data]
|
||||||
|
- name: manual-worker
|
||||||
|
image: onelab-manual-worker
|
||||||
|
replicaKey: manual
|
||||||
|
port: 0
|
||||||
|
config: true
|
||||||
|
mounts: [logs]
|
||||||
|
- name: websocket-worker
|
||||||
|
image: onelab-websocket-worker
|
||||||
|
replicaKey: ws
|
||||||
|
port: 3030
|
||||||
|
config: true
|
||||||
|
mounts: [logs]
|
||||||
|
- name: static
|
||||||
|
image: onelab-static
|
||||||
|
replicas: 1
|
||||||
|
port: 80
|
||||||
|
config: false
|
||||||
|
mounts: []
|
||||||
|
- name: main
|
||||||
|
image: onelab-main
|
||||||
|
replicas: 1
|
||||||
|
port: 80
|
||||||
|
config: false
|
||||||
|
mounts: []
|
||||||
|
- name: designer
|
||||||
|
image: onelab-designer
|
||||||
|
replicas: 1
|
||||||
|
port: 80
|
||||||
|
config: false
|
||||||
|
mounts: []
|
||||||
|
- name: runner
|
||||||
|
image: onelab-runner
|
||||||
|
replicas: 1
|
||||||
|
port: 80
|
||||||
|
config: false
|
||||||
|
mounts: []
|
||||||
|
- name: website
|
||||||
|
image: onelab-website
|
||||||
|
replicas: 1
|
||||||
|
port: 4000
|
||||||
|
config: false
|
||||||
|
mounts: []
|
||||||
|
website: true
|
||||||
31
gitops/values/k3s-example.yaml
Normal file
31
gitops/values/k3s-example.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# k3s / Argo CD overlay (private Git — rotate secrets if this file is ever made public).
|
||||||
|
# Add image pull credentials when using hub.andrewalliance.com:
|
||||||
|
# kubectl create secret docker-registry hub-andrewalliance -n onelab \
|
||||||
|
# --docker-server=hub.andrewalliance.com --docker-username=... --docker-password=...
|
||||||
|
# then set imagePullSecrets below.
|
||||||
|
|
||||||
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
mode: hostPath
|
||||||
|
hostPath:
|
||||||
|
data: /opt/onelab/data
|
||||||
|
logs: /opt/onelab/logs
|
||||||
|
|
||||||
|
postgresql:
|
||||||
|
auth:
|
||||||
|
password: "9daLpcV7vKS1zXUElQRO5h4u"
|
||||||
|
|
||||||
|
onelab:
|
||||||
|
domain: "https://onelab.example.com"
|
||||||
|
secrets:
|
||||||
|
authTokenKey: "ntH0Yd3AcsqwMu7ah8xLbWFS4BK5GUmi"
|
||||||
|
monitoringToken: "Cj4ix7wdg8XPIsDAFENKRTmh6lkvBLZp"
|
||||||
|
rabbitToken: "GmSWRv14PXZuyM5QDgb8wpxk0dh7F6IJ"
|
||||||
|
intercom:
|
||||||
|
appid: ""
|
||||||
|
secret: ""
|
||||||
|
|
||||||
|
revproxy:
|
||||||
|
serviceType: NodePort
|
||||||
|
nodePort: 30080
|
||||||
16
install.sh
Normal file
16
install.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Define OneLab along with the Ansible logs directory
|
||||||
|
|
||||||
|
directory="../onelab/logs/ansible"
|
||||||
|
|
||||||
|
# Check if the directory structure exists
|
||||||
|
if [ ! -d "$directory" ]; then
|
||||||
|
# If it doesn't exist, create it
|
||||||
|
mkdir -p "$directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# To allow writing the logs
|
||||||
|
chown -R $USER "$directory"
|
||||||
|
|
||||||
|
ANSIBLE_LOG_PATH="$directory/$(date +%F)-ansible.log" ansible-playbook ./app/playbooks/install.yml
|
||||||
3
resources/restore/restore.sh
Normal file
3
resources/restore/restore.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
#!/bin/bash
|
||||||
|
ANSIBLE_LOG_PATH=../../logs/ansible/$(date +%F)-ansible.log ansible-playbook ./restore.yml
|
||||||
104
resources/restore/restore.yml
Normal file
104
resources/restore/restore.yml
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
- name: Restoring OneLab (1.27.0)
|
||||||
|
hosts: localhost
|
||||||
|
vars_prompt:
|
||||||
|
- name: "userchoice"
|
||||||
|
prompt: "Confirm OneLab 1.27.0 restore: yes/no"
|
||||||
|
private: no
|
||||||
|
vars:
|
||||||
|
onelab_path: '../..'
|
||||||
|
onelab_images_path: '../../../onelab-images-1.27.0.tar.gz'
|
||||||
|
main_path: '../../..'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Checking if the OneLab images bundle is existing
|
||||||
|
stat:
|
||||||
|
path: "{{ onelab_images_path }}"
|
||||||
|
get_checksum: no
|
||||||
|
register: docker_images_tar
|
||||||
|
|
||||||
|
- name: Aborting the restore process
|
||||||
|
fail:
|
||||||
|
msg: Aborting the restore process
|
||||||
|
when: userchoice != "yes"
|
||||||
|
|
||||||
|
# Stop OneLab if OneLab is running
|
||||||
|
- name: Checking if OneLab is running
|
||||||
|
shell: docker stack ls | grep 'onelab' | wc -l
|
||||||
|
become: true
|
||||||
|
register: stack_count
|
||||||
|
|
||||||
|
# Stop OneLab (unkown version) if OneLab is running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-onelab.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
|
||||||
|
# Load docker images
|
||||||
|
- name: Loading Docker images
|
||||||
|
debug:
|
||||||
|
msg:
|
||||||
|
- "Loading images could take few minutes, please do not interrupt"
|
||||||
|
when: (docker_images_tar is defined) and (docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Loading OneLab images from the tar file
|
||||||
|
shell:
|
||||||
|
docker load --input {{ onelab_images_path }}
|
||||||
|
become: true
|
||||||
|
when: (docker_images_tar is defined) and (docker_images_tar.stat.exists)
|
||||||
|
|
||||||
|
- name: Unzipping backup
|
||||||
|
shell: |
|
||||||
|
tar xzvf ./onelab.tar.gz -C ./../..
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Cleaning latest installation
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ onelab_path }}/installation/latest"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Flagging restored version as current
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../../installation/1.27.0/
|
||||||
|
dest: ../../installation/latest
|
||||||
|
directory_mode: no
|
||||||
|
remote_src: yes
|
||||||
|
|
||||||
|
# Load configuration
|
||||||
|
- include_vars:
|
||||||
|
file: "{{ onelab_path }}/configurations.yml"
|
||||||
|
|
||||||
|
# Perform reconfiguration
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/reconfigure-task.yml"
|
||||||
|
|
||||||
|
# Checking if volumes are existing
|
||||||
|
- name: Getting the list of docker volumes
|
||||||
|
shell: docker volume ls
|
||||||
|
become: true
|
||||||
|
register: volumes_result
|
||||||
|
|
||||||
|
# Removing volumes
|
||||||
|
|
||||||
|
- name: Resetting postgres database & cleaning cache
|
||||||
|
shell: |
|
||||||
|
docker volume rm onelab_pgdata -f
|
||||||
|
docker volume rm onelab_rabbitmq_data -f
|
||||||
|
become: true
|
||||||
|
when: "'rabbitmq' in volumes_result.stdout or 'pgdata' in volumes_result.stdout"
|
||||||
|
|
||||||
|
# Restoring database
|
||||||
|
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-db-only.yml"
|
||||||
|
|
||||||
|
- name: Restoring database
|
||||||
|
shell: >
|
||||||
|
docker exec -i $(docker ps --filter "name=onelab_db|onelab-db" -q) pg_restore -Upostgres -dpostgres -v -Fc < ./db.tar.gz
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/stop-db-only.yml"
|
||||||
|
|
||||||
|
# Start OneLab if OneLab was running
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-proxy.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
|
- include_tasks: "{{ onelab_path }}/installation/latest/app/playbooks/tasks/start-onelab.yml"
|
||||||
|
when: stack_count.stdout != "0"
|
||||||
27
resources/scripts/centos/install_ansible.sh
Normal file
27
resources/scripts/centos/install_ansible.sh
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo yum install dnf
|
||||||
|
|
||||||
|
# update the DNF package repository cache
|
||||||
|
sudo dnf makecache
|
||||||
|
|
||||||
|
# To enable EPEL repository, install the epel-release package
|
||||||
|
sudo dnf install epel-release -y
|
||||||
|
|
||||||
|
# update the DNF package repository cache again
|
||||||
|
sudo dnf makecache
|
||||||
|
|
||||||
|
# Install Ansible
|
||||||
|
sudo dnf install ansible -y
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
# Update Ansible hosts file for local connection
|
||||||
|
sudo sed -i '$ a localhost ansible_connection=local' /etc/ansible/hosts
|
||||||
|
|
||||||
|
# Update Ansible configuration file with logs path
|
||||||
|
sudo sed -i '13 a log_path = /var/log/ansible.log' /etc/ansible/ansible.cfg
|
||||||
17
resources/scripts/centos/install_docker.sh
Normal file
17
resources/scripts/centos/install_docker.sh
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install the yum-utils package (which provides the yum-config-manager utility) and set up the stable repository
|
||||||
|
|
||||||
|
sudo yum install -y yum-utils
|
||||||
|
sudo yum-config-manager \
|
||||||
|
--add-repo \
|
||||||
|
https://download.docker.com/linux/centos/docker-ce.repo
|
||||||
|
|
||||||
|
# Install Docker Engine
|
||||||
|
sudo yum install docker-ce docker-ce-cli containerd.io -y
|
||||||
|
|
||||||
|
# Start Docker
|
||||||
|
sudo systemctl start docker
|
||||||
|
|
||||||
|
# Enable Docker
|
||||||
|
sudo systemctl enable docker
|
||||||
22
resources/scripts/debian10/install_ansible.sh
Normal file
22
resources/scripts/debian10/install_ansible.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo sed -i '$ a deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main' /etc/apt/sources.list
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y gnupg2
|
||||||
|
|
||||||
|
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y ansible
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
# Update Ansible hosts file for local connection
|
||||||
|
sudo sed -i '$ a localhost ansible_connection=local' /etc/ansible/hosts
|
||||||
|
|
||||||
|
# Update Ansible configuration file with logs path
|
||||||
|
sudo sed -i '13 a log_path = /var/log/ansible.log' /etc/ansible/ansible.cfg
|
||||||
|
|
||||||
26
resources/scripts/debian10/install_docker.sh
Normal file
26
resources/scripts/debian10/install_docker.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install Dependencies
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install \
|
||||||
|
apt-transport-https \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release -y
|
||||||
|
|
||||||
|
# Install Docker
|
||||||
|
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor --yes -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
|
||||||
|
echo \
|
||||||
|
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
|
||||||
|
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install docker-ce docker-ce-cli containerd.io -y
|
||||||
|
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
# Add user to docker group
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
13
resources/scripts/debian11/install_ansible.sh
Normal file
13
resources/scripts/debian11/install_ansible.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
sudo apt update
|
||||||
|
|
||||||
|
sudo apt install ansible
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
resources/scripts/debian11/install_docker.sh
Normal file
16
resources/scripts/debian11/install_docker.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Add Docker's official GPG key:
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install ca-certificates curl
|
||||||
|
sudo install -m 0755 -d /etc/apt/keyrings
|
||||||
|
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||||
|
|
||||||
|
# Add the repository to Apt sources:
|
||||||
|
echo \
|
||||||
|
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
|
||||||
|
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||||
|
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
13
resources/scripts/debian12/install_ansible.sh
Normal file
13
resources/scripts/debian12/install_ansible.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
sudo apt update
|
||||||
|
|
||||||
|
sudo apt install ansible
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
resources/scripts/debian12/install_docker.sh
Normal file
16
resources/scripts/debian12/install_docker.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Add Docker's official GPG key:
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install ca-certificates curl
|
||||||
|
sudo install -m 0755 -d /etc/apt/keyrings
|
||||||
|
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||||
|
|
||||||
|
# Add the repository to Apt sources:
|
||||||
|
echo \
|
||||||
|
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
|
||||||
|
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||||
|
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
19
resources/scripts/fedora/install_ansible.sh
Normal file
19
resources/scripts/fedora/install_ansible.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo dnf install ansible -y
|
||||||
|
|
||||||
|
#Install openssl
|
||||||
|
sudo yum install openssl -y
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
# Update Ansible hosts file for local connection
|
||||||
|
sudo sed -i '$ a localhost ansible_connection=local' /etc/ansible/hosts
|
||||||
|
|
||||||
|
# Update Ansible configuration file with logs path
|
||||||
|
sudo sed -i '13 a log_path = /var/log/ansible.log' /etc/ansible/ansible.cfg
|
||||||
|
|
||||||
21
resources/scripts/fedora/install_docker.sh
Normal file
21
resources/scripts/fedora/install_docker.sh
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install the dnf-plugins-core package (which provides the commands to manage your DNF repositories)
|
||||||
|
|
||||||
|
sudo dnf -y install dnf-plugins-core -y
|
||||||
|
|
||||||
|
# Setup stable repository
|
||||||
|
|
||||||
|
sudo dnf config-manager \
|
||||||
|
--add-repo \
|
||||||
|
https://download.docker.com/linux/fedora/docker-ce.repo -y
|
||||||
|
|
||||||
|
# Install the latest version of Docker Engine and containerd
|
||||||
|
|
||||||
|
sudo dnf install docker-ce docker-ce-cli containerd.io -y
|
||||||
|
|
||||||
|
sudo systemctl start docker
|
||||||
|
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
20
resources/scripts/redhat7/install_ansible.sh
Normal file
20
resources/scripts/redhat7/install_ansible.sh
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install Extra Packages for Linux
|
||||||
|
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -y
|
||||||
|
|
||||||
|
# Install Ansible
|
||||||
|
sudo yum install ansible -y
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
# Update Ansible hosts file for local connection
|
||||||
|
sudo sed -i '$ a localhost ansible_connection=local' /etc/ansible/hosts
|
||||||
|
|
||||||
|
# Update Ansible configuration file with logs path
|
||||||
|
sudo sed -i '13 a log_path = /var/log/ansible.log' /etc/ansible/ansible.cfg
|
||||||
|
|
||||||
27
resources/scripts/redhat7/install_docker.sh
Normal file
27
resources/scripts/redhat7/install_docker.sh
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install the yum-utils package
|
||||||
|
|
||||||
|
sudo yum install -y yum-utils
|
||||||
|
|
||||||
|
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||||
|
|
||||||
|
# RHEL-7 requires the below dependencies to be installed to setup Docker
|
||||||
|
|
||||||
|
sudo yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm -y
|
||||||
|
|
||||||
|
sudo yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/fuse3-libs-3.6.1-4.el7.x86_64.rpm -y
|
||||||
|
|
||||||
|
sudo yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/fuse-overlayfs-0.7.2-6.el7_8.x86_64.rpm -y
|
||||||
|
|
||||||
|
sudo yum install http://mirror.centos.org/centos/7/extras/x86_64/Packages/slirp4netns-0.4.3-4.el7_8.x86_64.rpm -y
|
||||||
|
|
||||||
|
# Ended dependencies installation
|
||||||
|
|
||||||
|
sudo yum install docker-ce -y
|
||||||
|
|
||||||
|
sudo systemctl start docker
|
||||||
|
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
5
resources/scripts/redhat8/install_ansible.sh
Normal file
5
resources/scripts/redhat8/install_ansible.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo dnf update
|
||||||
|
|
||||||
|
sudo dnf install ansible-core
|
||||||
15
resources/scripts/redhat8/install_docker.sh
Normal file
15
resources/scripts/redhat8/install_docker.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo dnf update -y
|
||||||
|
|
||||||
|
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
|
||||||
|
|
||||||
|
# To verify which version of docker is available for installation
|
||||||
|
# sudo dnf list docker-ce
|
||||||
|
|
||||||
|
sudo dnf install docker-ce --nobest -y
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
# Get current user and add to 'docker' group
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
5
resources/scripts/redhat9/install_ansible.sh
Normal file
5
resources/scripts/redhat9/install_ansible.sh
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo dnf update
|
||||||
|
|
||||||
|
sudo dnf install ansible-core
|
||||||
15
resources/scripts/redhat9/install_docker.sh
Normal file
15
resources/scripts/redhat9/install_docker.sh
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
sudo dnf update -y
|
||||||
|
|
||||||
|
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
|
||||||
|
|
||||||
|
# To verify which version of docker is available for installation
|
||||||
|
# sudo dnf list docker-ce
|
||||||
|
|
||||||
|
sudo dnf install docker-ce --nobest -y
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
# Get current user and add to 'docker' group
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
22
resources/scripts/ubuntu/install_ansible.sh
Normal file
22
resources/scripts/ubuntu/install_ansible.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install Dependencies
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install software-properties-common
|
||||||
|
|
||||||
|
# Install Ansible
|
||||||
|
sudo add-apt-repository --yes --update ppa:ansible/ansible
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install ansible
|
||||||
|
|
||||||
|
# Create the ansible log file
|
||||||
|
sudo touch /var/log/ansible.log
|
||||||
|
|
||||||
|
# Provide permissions for ansible log file
|
||||||
|
sudo chmod 666 /var/log/ansible.log
|
||||||
|
|
||||||
|
# Update Ansible hosts file for local connection
|
||||||
|
sudo sed -i '$ a localhost ansible_connection=local' /etc/ansible/hosts
|
||||||
|
|
||||||
|
# Update Ansible configuration file with logs path
|
||||||
|
sudo sed -i '13 a log_path = /var/log/ansible.log' /etc/ansible/ansible.cfg
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user