Compare commits
64 Commits
80c3565fa1
...
devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
4a516eee15
|
|||
|
15a1411f1a
|
|||
|
868ab721dd
|
|||
|
9776e9a316
|
|||
|
28f1f80d6f
|
|||
|
0f9479731a
|
|||
|
3df0115191
|
|||
|
fcb25b79ce
|
|||
|
e591db8581
|
|||
|
e4fd90c013
|
|||
|
219b03b4ee
|
|||
|
1b941a11a2
|
|||
|
12991700b9
|
|||
|
02b6460cff
|
|||
|
5f602c797f
|
|||
|
538bb26f83
|
|||
|
fa0df823ee
|
|||
|
49eacf103c
|
|||
|
4d1d28c64b
|
|||
|
5803ea337e
|
|||
|
20e9ec68d2
|
|||
|
d901c1d940
|
|||
|
875d8f1538
|
|||
|
1e1677cb4d
|
|||
|
29bccbac02
|
|||
|
80015c6535
|
|||
|
3bcbee1b85
|
|||
|
8f965c3e2b
|
|||
|
88247b4011
|
|||
|
740b73cb7d
|
|||
|
857e83a6fe
|
|||
|
745f6acc04
|
|||
|
43fbb3993b
|
|||
|
955d7e8a64
|
|||
|
614fca41c0
|
|||
|
0163d5ab18
|
|||
|
eb2ad9e60a
|
|||
|
11235ab859
|
|||
|
ce72850721
|
|||
|
d5f92811bd
|
|||
|
2d26caba54
|
|||
|
36ce40d718
|
|||
|
a7d9e1b270
|
|||
|
a6d1d46236
|
|||
|
d9c00a0d9e
|
|||
|
f3008294e4
|
|||
| 58dcf4694f | |||
|
a822fe0915
|
|||
|
cd1910c2bd
|
|||
|
421ceabd9e
|
|||
| 068a33626d | |||
| 8b4fb71160 | |||
| 72d8e7cdde | |||
| 58128eec46 | |||
| 48e7b8208e | |||
| 1c417eda10 | |||
| 14ce2dfea6 | |||
| e9974a054e | |||
| f61baa3f04 | |||
| 46e1366c4f | |||
| 924341a276 | |||
| b36bbec72a | |||
| 7bb00a3586 | |||
| 9cd0cfcb4f |
9
.ansible-lint.yaml
Normal file
9
.ansible-lint.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
skip_list:
|
||||||
|
- line-length # don't yell about line length
|
||||||
|
- meta-no-info # we don't publish to galaxy so stop yelling about it
|
||||||
|
- package-latest # we install lots of latest stuff still 😢
|
||||||
|
- experimental # no instability plz, give us a call when ur stable
|
||||||
|
|
||||||
|
warn_list:
|
||||||
|
- no-handler # good to keep, but shouldn't be fatal
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,3 +6,6 @@ playbooks/testing.yml
|
|||||||
**/__pycache__/
|
**/__pycache__/
|
||||||
.venv/
|
.venv/
|
||||||
.ansible/
|
.ansible/
|
||||||
|
.tox/
|
||||||
|
.terraform/
|
||||||
|
.terraform.lock.*
|
||||||
|
|||||||
@@ -32,3 +32,11 @@ repos:
|
|||||||
- "--wrap=90"
|
- "--wrap=90"
|
||||||
types:
|
types:
|
||||||
- markdown
|
- markdown
|
||||||
|
|
||||||
|
- id: terraform
|
||||||
|
name: terraform format
|
||||||
|
entry: terraform
|
||||||
|
language: system
|
||||||
|
args:
|
||||||
|
- fmt
|
||||||
|
files: ".*\\.tf$"
|
||||||
|
|||||||
7
.yamllintrc.yaml
Normal file
7
.yamllintrc.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
yaml-files:
|
||||||
|
- "*.yml"
|
||||||
|
- "*.yaml"
|
||||||
|
|
||||||
|
rules:
|
||||||
|
line-length: disable
|
||||||
9
Makefile
9
Makefile
@@ -1,8 +1,9 @@
|
|||||||
clean:
|
clean:
|
||||||
rm --recursive --force .ansible/
|
rm --recursive --force .ansible/
|
||||||
|
rm --recursive --force .tox/
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
poetry install --remove-untracked
|
@poetry install --sync
|
||||||
poetry run pre-commit install
|
@poetry run pre-commit install
|
||||||
poetry run ansible-galaxy collection install --requirements-file ./requirements.yaml --collections-path ./.ansible
|
@poetry run ansible-galaxy collection install --requirements-file ./requirements.yaml --collections-path ./.ansible
|
||||||
./dynamically-link-local-collections.bash
|
@bash ./link-local-collections.sh
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -2,13 +2,17 @@
|
|||||||
|
|
||||||
Ansible configs for the Skylab Homelab
|
Ansible configs for the Skylab Homelab
|
||||||
|
|
||||||
Main entrypoint is through the `ansible` script in this repository. The script sets up
|
## Local workstation setup:
|
||||||
basic environment variables to avoid conflicts with other environments and sets the
|
|
||||||
inventory.
|
|
||||||
|
|
||||||
Bootstrap checklist:
|
```bash
|
||||||
|
make dev
|
||||||
|
poetry run ansible-playbook ...
|
||||||
|
```
|
||||||
|
|
||||||
1. Install a supported operating system: [Rocky Linux](https://rockylinux.org)
|
## Boostraping remote system for management:
|
||||||
|
|
||||||
|
1. Install a supported operating system: [Rocky Linux](https://rockylinux.org),
|
||||||
|
[Fedora](https://getfedora.org)
|
||||||
2. During installation create a user named `ansible` with any password
|
2. During installation create a user named `ansible` with any password
|
||||||
3. After installation copy SSH key to the `ansible` user
|
3. After installation copy SSH key to the `ansible` user
|
||||||
4. Enable password-less sudo access for the `ansible` user with this command:
|
4. Enable password-less sudo access for the `ansible` user with this command:
|
||||||
|
|||||||
5
ansible
5
ansible
@@ -1,5 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
ANSIBLE_COLLECTIONS_PATH=$(pwd)/.ansible \
|
|
||||||
ANSIBLE_INVENTORY=$(pwd)/inventory.yaml \
|
|
||||||
"ansible-$1" "${@:2}"
|
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
[defaults]
|
[defaults]
|
||||||
host_key_checking = false
|
host_key_checking = true
|
||||||
|
collections_path = .ansible
|
||||||
|
inventory = inventory/
|
||||||
|
|
||||||
[ssh_connection]
|
[ssh_connection]
|
||||||
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes"
|
ssh_args = "-o ControlMaster=auto -o ControlPersist=60s"
|
||||||
|
|
||||||
[inventory]
|
[inventory]
|
||||||
enable_plugins = ansible.builtin.yaml
|
enable_plugins = ansible.builtin.yaml
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
---
|
---
|
||||||
all:
|
workstation:
|
||||||
vars:
|
hosts:
|
||||||
skylab_state_dir: /var/lib/skylab
|
voyager:
|
||||||
skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime"
|
skylab_description: Personal Workstation
|
||||||
skylab_pip_version: 19.3.1
|
skylab_hostname: voyager.skylab.enp.one
|
||||||
ansible_user: ansible
|
skylab_targets: [workstation]
|
||||||
ansible_ssh_common_args: "-o ControlMaster=auto -o ControlPersist=60s -o ForwardAgent=yes"
|
|
||||||
|
|
||||||
en1:
|
en1:
|
||||||
vars:
|
vars:
|
||||||
51
inventory/en1.yaml
Normal file
51
inventory/en1.yaml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
en1:
|
||||||
|
|
||||||
|
vars:
|
||||||
|
skylab_location: Cambridge
|
||||||
|
|
||||||
|
children:
|
||||||
|
domain:
|
||||||
|
children:
|
||||||
|
|
||||||
|
cluster:
|
||||||
|
hosts:
|
||||||
|
canaveral:
|
||||||
|
ansible_host: 10.42.101.10
|
||||||
|
skylab_description: Compute and Storage Node
|
||||||
|
baikonur:
|
||||||
|
ansible_host: 10.42.101.11
|
||||||
|
skylab_description: Compute and Storage Node
|
||||||
|
vandenberg:
|
||||||
|
ansible_host: 10.42.101.12
|
||||||
|
skylab_description: Compute and Storage Node
|
||||||
|
andoya:
|
||||||
|
ansible_host: 10.42.101.13
|
||||||
|
skylab_description: Auxilary Compute Node
|
||||||
|
jiuquan:
|
||||||
|
ansible_host: 10.42.101.14
|
||||||
|
skylab_description: Auxilary Compute Node
|
||||||
|
|
||||||
|
datastore:
|
||||||
|
hosts:
|
||||||
|
canaveral:
|
||||||
|
skylab_datastore_block: /dev/sda
|
||||||
|
baikonur:
|
||||||
|
skylab_datastore_block: /dev/sda
|
||||||
|
vandenberg:
|
||||||
|
skylab_datastore_block: /dev/sda
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
3d-printer: {}
|
||||||
|
mediastore: {}
|
||||||
|
backstore: {}
|
||||||
|
|
||||||
|
local:
|
||||||
|
hosts:
|
||||||
|
core: {}
|
||||||
|
switch-1: {}
|
||||||
|
switch-2: {}
|
||||||
|
wap-1: {}
|
||||||
|
wap-2: {}
|
||||||
|
wap-3: {}
|
||||||
|
printer: {}
|
||||||
39
inventory/group_vars/all.yaml
Normal file
39
inventory/group_vars/all.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
ansible_user: ansible
|
||||||
|
|
||||||
|
ansible_port: 4242
|
||||||
|
|
||||||
|
skylab_state_dir: /var/lib/skylab
|
||||||
|
|
||||||
|
skylab_ansible_venv: "{{ skylab_state_dir }}/ansible-runtime"
|
||||||
|
|
||||||
|
skylab_ansible_vault_password: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
61323762623165383963316238343539346336663864366631616339356564346636373561616237
|
||||||
|
6666363531393234636337656431366365343236346536320a346163353935366636303131313661
|
||||||
|
32623635363063383039363539303135393838376264356463646465376435616363376163373663
|
||||||
|
6366633665373939380a373234633365376632376433643034336539346338613566353537663731
|
||||||
|
34323464633165626133306464363464333539363761343831316565356266373833
|
||||||
|
|
||||||
|
skylab_tfstate_backend:
|
||||||
|
hostname: cluster.lab.enp.one
|
||||||
|
username: terraform
|
||||||
|
schema: terraform
|
||||||
|
port: 32421
|
||||||
|
password: !vault |
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
30313365393065316563323363663135313438616461356439366632303636343735653033363930
|
||||||
|
6334613931376566363064663539643639326363663933610a306138616362376435386466306538
|
||||||
|
30626330613932363339363438356430613461313335333536623931343436353330393433373630
|
||||||
|
3631343463616631380a386661336534663033383637666538316665303962353034376232356235
|
||||||
|
65323339353563623431666535366465353133343137653232326534326436323661636536373564
|
||||||
|
3466633762303966366366653531613261336561356531636461
|
||||||
|
|
||||||
|
skylab_mgmt:
|
||||||
|
sshport: 4242
|
||||||
|
group: skylab
|
||||||
|
user: ansible
|
||||||
|
id: 1400
|
||||||
|
sshkeys:
|
||||||
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5TGKururOa1Y+cbv8AWXYI5zhfZCDV0fsBG+33IYUc enpaul@ansible.voyager
|
||||||
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBf7i/8hSJDYnoD95noCJJVtSxxCp9N5EmnshALufiwm enpaul@ansible.opportunity
|
||||||
@@ -15,4 +15,14 @@ for collection_path in "$PWD"/"$ANSIBLE_NAMESPACE"/*; do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Done!"
|
echo "Finished linking local collections"
|
||||||
|
|
||||||
|
LOCAL_COLLECTION_PATH=$(dirname "$ANSIBLE_COLLECTION_DIR")
|
||||||
|
|
||||||
|
if [ -z ${ANSIBLE_COLLECTIONS_PATH+x} ]; then
|
||||||
|
echo "WARNING: Environment variable ANSIBLE_COLLECTIONS_PATH is not set, collections will not be callable"
|
||||||
|
echo " HINT: export ANSIBLE_COLLECTIONS_PATH=$LOCAL_COLLECTION_PATH"
|
||||||
|
elif [[ ${ANSIBLE_COLLECTIONS_PATH} != *"$LOCAL_COLLECTION_PATH"* ]]; then
|
||||||
|
echo "WARNING: Environment variable ANSIBLE_COLLECTIONS_PATH does not include local collection directory"
|
||||||
|
echo " HINT: export ANSIBLE_COLLECTIONS_PATH=\$ANSIBLE_COLLECTIONS_PATH:$LOCAL_COLLECTION_PATH"
|
||||||
|
fi
|
||||||
2643
poetry.lock
generated
2643
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -6,22 +6,22 @@ authors = ["Ethan Paul <me@enp.one>"]
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.8"
|
python = "^3.10"
|
||||||
ansible = "^4.9.0"
|
ansible-core = "^2.14.3"
|
||||||
docker = "^4.2.0"
|
docker = "^6.0.1"
|
||||||
docker-compose = "^1.25.4"
|
|
||||||
paramiko = "^2.7.1"
|
paramiko = "^2.7.1"
|
||||||
jsondiff = "^1.2.0"
|
jsondiff = "^2.0.0"
|
||||||
netaddr = "^0.8.0"
|
netaddr = "^0.8.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
ansible-lint = "^4.2.0"
|
ansible-lint = {version = "^6.14.0", markers = "platform_system != 'Windows'"}
|
||||||
pre-commit = "^2.9.2"
|
ipython = "^8.11.0"
|
||||||
pre-commit-hooks = "^3.3.0"
|
mdformat = "^0.7.16"
|
||||||
safety = "^1.9.0"
|
mdformat-gfm = "^0.3.5"
|
||||||
|
poetry = "^1.3.0"
|
||||||
|
pre-commit = "^3.2.0"
|
||||||
|
pre-commit-hooks = "^4.4.0"
|
||||||
|
safety = "^2.3.5"
|
||||||
tox = "^3.20.1"
|
tox = "^3.20.1"
|
||||||
tox-poetry-installer = "^0.8.1"
|
tox-poetry-installer = {extras = ["poetry"], version = "^0.10.0"}
|
||||||
yamllint = "^1.20.0"
|
yamllint = "^1.29.0"
|
||||||
mdformat = "^0.7.9"
|
|
||||||
mdformat-gfm = "^0.3.3"
|
|
||||||
ipython = "^7.28.0"
|
|
||||||
|
|||||||
@@ -17,4 +17,10 @@ build_ignore: []
|
|||||||
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
|
# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version
|
||||||
# range specifiers can be set and are separated by ','
|
# range specifiers can be set and are separated by ','
|
||||||
dependencies:
|
dependencies:
|
||||||
|
ansible.netcommon: ">=2.5.0,<3.0.0"
|
||||||
|
ansible.posix: ">=1.3.0,<2.0.0"
|
||||||
|
ansible.utils: ">=2.4.3,<3.0.0"
|
||||||
community.docker: ">=2.0.2,<3.0.0"
|
community.docker: ">=2.0.2,<3.0.0"
|
||||||
|
community.network: ">=3.0.0,<4.0.0"
|
||||||
|
community.general: ">=4.1.0,<5.0.0"
|
||||||
|
community.crypto: ">=1.0.0,<2.0.0"
|
||||||
|
|||||||
@@ -38,3 +38,10 @@
|
|||||||
roles:
|
roles:
|
||||||
- role: skylab.core.dashboard
|
- role: skylab.core.dashboard
|
||||||
dashboard_hostname: "{{ skylab_dashboard }}"
|
dashboard_hostname: "{{ skylab_dashboard }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Configure workstations
|
||||||
|
hosts: workstation
|
||||||
|
gather_facts: false
|
||||||
|
roles:
|
||||||
|
- role: skylab.core.workstation
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ function _parse_git_branch() {
|
|||||||
export PS1="\[\e[0;97m\]\[\e[37m\e[1m\]\u\[\e[1;94m\]@\[\e[94m\]\H\[\e[37m\]:\w\[\e[33m\]\[\e[0;33m\]\$(_parse_git_branch) \[\e[37m\]\[\e[0;97m\]$\[\e[0m\] "
|
export PS1="\[\e[0;97m\]\[\e[37m\e[1m\]\u\[\e[1;94m\]@\[\e[94m\]\H\[\e[37m\]:\w\[\e[33m\]\[\e[0;33m\]\$(_parse_git_branch) \[\e[37m\]\[\e[0;97m\]$\[\e[0m\] "
|
||||||
export rc=/home/$USERNAME/.bashrc
|
export rc=/home/$USERNAME/.bashrc
|
||||||
export VIRTUALENV_DIR=/home/$USERNAME/.venvs
|
export VIRTUALENV_DIR=/home/$USERNAME/.venvs
|
||||||
|
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt
|
||||||
|
|
||||||
random() {
|
function random() {
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
num=32
|
num=32
|
||||||
else
|
else
|
||||||
@@ -19,9 +20,10 @@ function up() { cd $(eval printf '../'%.0s {1..$1}); }
|
|||||||
|
|
||||||
function pipin() { pip freeze | grep $1; }
|
function pipin() { pip freeze | grep $1; }
|
||||||
|
|
||||||
|
function continuous () { while true; do ${@}; sleep 3; done; }
|
||||||
|
|
||||||
alias bk='cd -'
|
alias bk='cd -'
|
||||||
alias fuck='sudo $(history -p \!\!)'
|
alias fuck='sudo $(history -p \!\!)'
|
||||||
alias ls='ls -lshF --color --group-directories-first --time-style=long-iso'
|
|
||||||
alias version='uname -orp && lsb_release -a | grep Description'
|
alias version='uname -orp && lsb_release -a | grep Description'
|
||||||
alias activate='source ./bin/activate'
|
alias activate='source ./bin/activate'
|
||||||
alias cls='clear'
|
alias cls='clear'
|
||||||
@@ -32,3 +34,4 @@ alias whatismyip='curl https://icanhazip.com/'
|
|||||||
alias uuid="python3 -c 'import uuid; print(uuid.uuid4());'"
|
alias uuid="python3 -c 'import uuid; print(uuid.uuid4());'"
|
||||||
alias epoch="python3 -c 'import time; print(time.time());'"
|
alias epoch="python3 -c 'import time; print(time.time());'"
|
||||||
alias uptime="command uptime --pretty"
|
alias uptime="command uptime --pretty"
|
||||||
|
alias unmount="umount"
|
||||||
|
|||||||
137
skylab/core/playbooks/files/pingtest.bash
Executable file
137
skylab/core/playbooks/files/pingtest.bash
Executable file
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
declare FMT_RESET
|
||||||
|
declare FMT_BOLD
|
||||||
|
declare FMT_GREEN
|
||||||
|
declare FMT_RED
|
||||||
|
declare NL
|
||||||
|
FMT_RESET=$(printf "\\e[0m")
|
||||||
|
FMT_BOLD=$(printf "\\e[1m")
|
||||||
|
FMT_GREEN=$(printf "\\e[32m")
|
||||||
|
FMT_RED=$(printf "\\e[31m")
|
||||||
|
NL=$'\n'
|
||||||
|
readonly FMT_RESET
|
||||||
|
readonly FMT_BOLD
|
||||||
|
readonly FMT_GREEN
|
||||||
|
readonly FMT_RED
|
||||||
|
readonly NL
|
||||||
|
|
||||||
|
|
||||||
|
function usage() {
|
||||||
|
cat << __EOF__
|
||||||
|
${FMT_GREEN}$(basename "$0")${FMT_RESET}: \
|
||||||
|
|
||||||
|
Ping hosts and print status
|
||||||
|
|
||||||
|
${FMT_BOLD}Usage:${FMT_RESET}
|
||||||
|
$(basename "$0") [-h] [--service|--network]
|
||||||
|
|
||||||
|
${FMT_GREEN}-h --help${FMT_RESET}
|
||||||
|
Print this message and exit.
|
||||||
|
|
||||||
|
${FMT_GREEN}--services${FMT_RESET}
|
||||||
|
Report service status
|
||||||
|
|
||||||
|
${FMT_GREEN}--network${FMT_RESET}
|
||||||
|
Report network status
|
||||||
|
|
||||||
|
__EOF__
|
||||||
|
}
|
||||||
|
|
||||||
|
function _fmt_online() { echo "${FMT_BOLD}${FMT_GREEN}ONLINE${FMT_RESET}"; }
|
||||||
|
|
||||||
|
function _fmt_offline() { echo "${FMT_BOLD}${FMT_RED}OFFLINE${FMT_RESET}"; }
|
||||||
|
|
||||||
|
function _test_cmd() { if eval "$1" &>/dev/null ; then echo "${2}~$(_fmt_online)"; else echo "${2}~$(_fmt_offline)"; fi }
|
||||||
|
|
||||||
|
function _test_ping() { _test_cmd "ping -W 2 -c 1 ${1}" "${2}"; }
|
||||||
|
|
||||||
|
function _test_curl_head() { _test_cmd "curl --fail --head ${1}" "${2}"; }
|
||||||
|
|
||||||
|
function _test_curl_get() { _test_cmd "curl --fail --get ${1}" "${2}"; }
|
||||||
|
|
||||||
|
function _test_curl_insecure() { _test_cmd "curl --fail --head --insecure ${1}" "${2}"; }
|
||||||
|
|
||||||
|
function _test_netcat() { _test_cmd "nc -z ${1} ${2}" "${3}"; }
|
||||||
|
|
||||||
|
function network() {
|
||||||
|
local uplink_address="1.1.1.1"
|
||||||
|
|
||||||
|
declare -a infra=("core.en1.local" "switch.en1.local" "wap-1.en1.local" "wap-2.en1.local" "wap-3.en1.local" "printer.en1.local")
|
||||||
|
declare -a infra_names=("Core Router" "Core Switch" "Wireless AP 1" "Wireless AP 2" "Wireless AP 3" "Printer")
|
||||||
|
|
||||||
|
declare -a lab=("cluster.skylab.enp.one" "pegasus.skylab.enp.one" "saturn.skylab.enp.one" "orion.skylab.enp.one" "iridium.skylab.enp.one" "en2.enp.one")
|
||||||
|
declare -a lab_names=("Cluster" "Pegasus" "Saturn" "Orion" "Iridium" "Hubble")
|
||||||
|
|
||||||
|
local output=$(_test_ping "$uplink_address" "UPLINK")
|
||||||
|
output+="${NL}";
|
||||||
|
|
||||||
|
output+="${NL}INFRASTRUCTURE~STATE${NL}"
|
||||||
|
for (( index=0; index<"${#infra[@]}"; index++ )); do
|
||||||
|
output+=$(_test_ping "${infra[$index]}" "${infra_names[$index]}")
|
||||||
|
output+="${NL}"
|
||||||
|
done
|
||||||
|
|
||||||
|
output+="${NL}HOMELAB~STATE${NL}"
|
||||||
|
for (( index=0; index<"${#lab[@]}"; index++ )); do
|
||||||
|
output+=$(_test_ping "${lab[$index]}" "${lab_names[$index]}")
|
||||||
|
output+="${NL}"
|
||||||
|
done
|
||||||
|
|
||||||
|
column -e -t -s '~' <<<"$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
function services() {
|
||||||
|
local output="INTERNAL~STATE${NL}"
|
||||||
|
|
||||||
|
output+=$(_test_netcat "cluster.skylab.enp.one" "53" "AdGuard DNS")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_netcat "core.en1.local" "53" "Fallback DNS")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_insecure "https://cluster.skylab.enp.one:8443/status" "Ubiquiti WLC")
|
||||||
|
output+="${NL}"
|
||||||
|
|
||||||
|
output+="${NL}PUBLIC~STATE${NL}"
|
||||||
|
|
||||||
|
output+=$(_test_curl_head "https://pms.enp.one/web/index.html" "Plex Media Server")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_netcat "cluster.skylab.enp.one" "25565" "Minecraft Server")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_get "https://vcs.enp.one/api/v1/version" "Version Control")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_get "https://ssv.enp.one/api/alive" "Bitwarden")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_head "https://cdn.enp.one/heartbeat" "Digital Ocean CDN")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_head "https://doc.enp.one/" "Documentation")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_head "https://enpaul.net/" "enpaul.net")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_head "https://allaroundhere.org/" "allaroundhere.org")
|
||||||
|
output+="${NL}"
|
||||||
|
output+=$(_test_curl_head "https://enp.one/" "enp.one")
|
||||||
|
output+="${NL}"
|
||||||
|
|
||||||
|
column -e -t -s'~' <<<"$output"
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
if [[ "$1" =~ ^(-h|--help)$ ]]; then
|
||||||
|
usage;
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ "$1" = "--network" ]]; then
|
||||||
|
network;
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if [[ "$1" = "--services" ]]; then
|
||||||
|
services;
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
|
||||||
|
main "${@}"
|
||||||
|
fi
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
- ansible.builtin.import_playbook: node-down.yaml
|
- ansible.builtin.import_playbook: skylab.core.node_down
|
||||||
|
|
||||||
- name: Shutdown node
|
- name: Shutdown node
|
||||||
hosts: "{{ node }}"
|
hosts: "{{ node }}"
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
key: https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }}
|
key: https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }}
|
||||||
|
|
||||||
|
|
||||||
- import_playbook: update.yaml
|
- import_playbook: skylab.core.update
|
||||||
|
|
||||||
|
|
||||||
- import_playbook: configure.yaml
|
- import_playbook: skylab.core.configure
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
---
|
---
|
||||||
- name: Install CentOS 8 python bindings
|
- name: Install CentOS 8 python bindings
|
||||||
when: ansible_distribution == "Rocky"
|
when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora"
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.dnf:
|
ansible.builtin.dnf:
|
||||||
state: present
|
state: present
|
||||||
name:
|
name:
|
||||||
|
- libffi-devel
|
||||||
|
- python3-devel
|
||||||
- python3-libselinux
|
- python3-libselinux
|
||||||
- python3-policycoreutils
|
- python3-policycoreutils
|
||||||
- python3-firewall
|
- python3-firewall
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
key: edgeos
|
key: edgeos
|
||||||
|
|
||||||
- name: Group supported Linux hosts
|
- name: Group supported Linux hosts
|
||||||
when: ansible_distribution == "Rocky"
|
when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
group_by:
|
group_by:
|
||||||
key: linux
|
key: linux
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ x-global-env: &globalenv
|
|||||||
LOCAL_GID: "{{ _app_account.uid }}"
|
LOCAL_GID: "{{ _app_account.uid }}"
|
||||||
ASPNETCORE_ENVIRONMENT: Production
|
ASPNETCORE_ENVIRONMENT: Production
|
||||||
globalSettings__selfHosted: "true"
|
globalSettings__selfHosted: "true"
|
||||||
globalSettings__baseServiceUri__vault: https://{{ app.domain }}
|
globalSettings__baseServiceUri__vault: https://{{ app.publish.domain }}
|
||||||
globalSettings__baseServiceUri__api: https://{{ app.domain }}/api
|
globalSettings__baseServiceUri__api: https://{{ app.publish.domain }}/api
|
||||||
globalSettings__baseServiceUri__identity: https://{{ app.domain }}/identity
|
globalSettings__baseServiceUri__identity: https://{{ app.publish.domain }}/identity
|
||||||
globalSettings__baseServiceUri__admin: https://{{ app.domain }}/admin
|
globalSettings__baseServiceUri__admin: https://{{ app.publish.domain }}/admin
|
||||||
globalSettings__baseServiceUri__notifications: https://{{ app.domain }}/notifications
|
globalSettings__baseServiceUri__notifications: https://{{ app.publish.domain }}/notifications
|
||||||
globalSettings__baseServiceUri__internalNotifications: http://bitwarden_notifications:5000
|
globalSettings__baseServiceUri__internalNotifications: http://bitwarden_notifications:5000
|
||||||
globalSettings__baseServiceUri__internalAdmin: http://bitwarden_admin:5000
|
globalSettings__baseServiceUri__internalAdmin: http://bitwarden_admin:5000
|
||||||
globalSettings__baseServiceUri__internalIdentity: http://bitwarden_identity:5000
|
globalSettings__baseServiceUri__internalIdentity: http://bitwarden_identity:5000
|
||||||
@@ -22,7 +22,7 @@ x-global-env: &globalenv
|
|||||||
globalSettings__sqlServer__connectionString: "Data Source=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;Password=e934c0bb-3b5a-4e6b-b525-cd6d83004e1a;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=True"
|
globalSettings__sqlServer__connectionString: "Data Source=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;Password=e934c0bb-3b5a-4e6b-b525-cd6d83004e1a;MultipleActiveResultSets=False;Connect Timeout=30;Encrypt=True;TrustServerCertificate=True"
|
||||||
globalSettings__identityServer__certificatePassword: {{ app.settings.certificatePassword }}
|
globalSettings__identityServer__certificatePassword: {{ app.settings.certificatePassword }}
|
||||||
globalSettings__attachment__baseDirectory: /etc/bitwarden/core/attachments
|
globalSettings__attachment__baseDirectory: /etc/bitwarden/core/attachments
|
||||||
globalSettings__attachment__baseUrl: https://{{ app.domain }}/attachments
|
globalSettings__attachment__baseUrl: https://{{ app.publish.domain }}/attachments
|
||||||
globalSettings__dataProtection__directory: /etc/bitwarden/core/aspnet-dataprotection
|
globalSettings__dataProtection__directory: /etc/bitwarden/core/aspnet-dataprotection
|
||||||
globalSettings__logDirectory: /etc/bitwarden/logs
|
globalSettings__logDirectory: /etc/bitwarden/logs
|
||||||
globalSettings__licenseDirectory: /etc/bitwarden/core/licenses
|
globalSettings__licenseDirectory: /etc/bitwarden/core/licenses
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ services:
|
|||||||
USER_GID: "{{ _app_account.uid }}"
|
USER_GID: "{{ _app_account.uid }}"
|
||||||
APP_NAME: ENP Version Control System
|
APP_NAME: ENP Version Control System
|
||||||
RUN_MODE: prod
|
RUN_MODE: prod
|
||||||
ROOT_URL: https://{{ app.domain }}/
|
ROOT_URL: https://{{ app.publish.domain }}/
|
||||||
DB_TYPE: sqlite3
|
DB_TYPE: sqlite3
|
||||||
DISABLE_REGISTRATION: "true"
|
DISABLE_REGISTRATION: "true"
|
||||||
deploy:
|
deploy:
|
||||||
|
|||||||
@@ -76,3 +76,24 @@ services:
|
|||||||
restart_policy:
|
restart_policy:
|
||||||
condition: any
|
condition: any
|
||||||
delay: 24h
|
delay: 24h
|
||||||
|
|
||||||
|
backup:
|
||||||
|
image: rockylinux:latest
|
||||||
|
hostname: backup
|
||||||
|
command: bash /datastore/backup/mkbkup.sh /datastore/
|
||||||
|
networks:
|
||||||
|
- meta
|
||||||
|
volumes:
|
||||||
|
- type: volume
|
||||||
|
source: meta-backup
|
||||||
|
target: /datastore/backup
|
||||||
|
read_only: false
|
||||||
|
- type: volume
|
||||||
|
source: meta-appdata
|
||||||
|
target: /datastore/appdata
|
||||||
|
read_only: true
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
restart_policy:
|
||||||
|
condition: any
|
||||||
|
delay: 24h
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
---
|
||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
photoprism-database:
|
||||||
|
name: datastore/appdata/photoprism/database
|
||||||
|
driver: glusterfs
|
||||||
|
photoprism-metadata:
|
||||||
|
name: datastore/appdata/photoprism/metadata
|
||||||
|
photoprism-originals:
|
||||||
|
name: datastore/media/photoprism
|
||||||
|
driver: glusterfs
|
||||||
|
photoprism-import:
|
||||||
|
name: datastore/media/upload
|
||||||
|
driver: glusterfs
|
||||||
|
|
||||||
|
networks:
|
||||||
|
photoprism:
|
||||||
|
internal: true
|
||||||
|
name: photoprism
|
||||||
|
driver: overlay
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 192.168.109.0/24
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: photoprism/photoprism:latest
|
||||||
|
hostname: app
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- photoprism
|
||||||
|
ports:
|
||||||
|
- published: 2342
|
||||||
|
target: 2342
|
||||||
|
protocol: tcp
|
||||||
|
mode: ingress
|
||||||
|
environment:
|
||||||
|
PHOTOPRISM_ADMIN_PASSWORD: "gm2auW34GNawZ8Dqiub8W8vOlvsHCnfj"
|
||||||
|
PHOTOPRISM_SITE_URL: "http://cluster.skylab.enp.one:2342/"
|
||||||
|
PHOTOPRISM_ORIGINALS_LIMIT: 5000
|
||||||
|
PHOTOPRISM_HTTP_COMPRESSION: "gzip"
|
||||||
|
PHOTOPRISM_DEBUG: "false"
|
||||||
|
PHOTOPRISM_PUBLIC: "false"
|
||||||
|
PHOTOPRISM_READONLY: "false"
|
||||||
|
PHOTOPRISM_EXPERIMENTAL: "false"
|
||||||
|
PHOTOPRISM_DISABLE_CHOWN: "false"
|
||||||
|
PHOTOPRISM_DISABLE_WEBDAV: "false"
|
||||||
|
PHOTOPRISM_DISABLE_SETTINGS: "false"
|
||||||
|
PHOTOPRISM_DISABLE_TENSORFLOW: "false"
|
||||||
|
PHOTOPRISM_DISABLE_FACES: "false"
|
||||||
|
PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
|
||||||
|
PHOTOPRISM_DARKTABLE_PRESETS: "false"
|
||||||
|
PHOTOPRISM_DETECT_NSFW: "false"
|
||||||
|
PHOTOPRISM_UPLOAD_NSFW: "true"
|
||||||
|
PHOTOPRISM_DATABASE_DRIVER: "mysql"
|
||||||
|
PHOTOPRISM_DATABASE_SERVER: "database:3306"
|
||||||
|
PHOTOPRISM_DATABASE_NAME: "photoprism"
|
||||||
|
PHOTOPRISM_DATABASE_USER: "photoprism"
|
||||||
|
PHOTOPRISM_DATABASE_PASSWORD: "KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp" # MariaDB or MySQL database user password
|
||||||
|
PHOTOPRISM_SITE_TITLE: "Skylab Images"
|
||||||
|
PHOTOPRISM_SITE_CAPTION: "Browse Your Life"
|
||||||
|
PHOTOPRISM_SITE_DESCRIPTION: ""
|
||||||
|
PHOTOPRISM_SITE_AUTHOR: "EN Paul"
|
||||||
|
HOME: "/photoprism"
|
||||||
|
PHOTOPRISM_UID: 1408
|
||||||
|
PHOTOPRISM_GID: 1408
|
||||||
|
## Hardware video transcoding config (optional)
|
||||||
|
# PHOTOPRISM_FFMPEG_BUFFERS: "64" # FFmpeg capture buffers (default: 32)
|
||||||
|
# PHOTOPRISM_FFMPEG_BITRATE: "32" # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
|
||||||
|
# PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m" # Use Video4Linux for AVC transcoding (default: libx264)
|
||||||
|
# PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv" # Use Intel Quick Sync Video for AVC transcoding (default: libx264)
|
||||||
|
# PHOTOPRISM_INIT: "intel-graphics tensorflow-amd64-avx2" # Enable TensorFlow AVX2 & Intel Graphics support
|
||||||
|
## Enable TensorFlow AVX2 support for modern Intel CPUs (requires starting the container as root)
|
||||||
|
# PHOTOPRISM_INIT: "tensorflow-amd64-avx2"
|
||||||
|
user: "1408:1408"
|
||||||
|
working_dir: "/photoprism"
|
||||||
|
volumes:
|
||||||
|
- type: volume
|
||||||
|
source: photoprism-originals
|
||||||
|
target: /photoprism/originals
|
||||||
|
read_only: false
|
||||||
|
- type: volume
|
||||||
|
source: photoprism-metadata
|
||||||
|
target: /photoprism/storage
|
||||||
|
read_only: false
|
||||||
|
- type: volume
|
||||||
|
source: photoprism-import
|
||||||
|
target: /photoprism/import
|
||||||
|
read_only: true
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
|
|
||||||
|
database:
|
||||||
|
image: mariadb:10.6
|
||||||
|
hostname: database
|
||||||
|
command: mysqld --innodb-buffer-pool-size=128M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
|
||||||
|
networks:
|
||||||
|
- photoprism
|
||||||
|
volumes:
|
||||||
|
- type: volume
|
||||||
|
source: photoprism-database
|
||||||
|
target: /var/lib/mysql
|
||||||
|
read_only: false
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: insecure
|
||||||
|
MYSQL_DATABASE: photoprism
|
||||||
|
MYSQL_USER: photoprism
|
||||||
|
MYSQL_PASSWORD: KcIKhME9OwWKVz4tGyqI4VXzyDBs33Xp
|
||||||
|
deploy:
|
||||||
|
replicas: 1
|
||||||
@@ -103,6 +103,6 @@ services:
|
|||||||
- cache
|
- cache
|
||||||
- proxy
|
- proxy
|
||||||
environment:
|
environment:
|
||||||
VIKUNJA_API_URL: https://{{ app.domain }}/api/v1
|
VIKUNJA_API_URL: https://{{ app.publish.domain }}/api/v1
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
|||||||
34
skylab/core/playbooks/templates/stack-nginx.conf.j2
Normal file
34
skylab/core/playbooks/templates/stack-nginx.conf.j2
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Ansible managed file - do not manually edit
|
||||||
|
#
|
||||||
|
server {
|
||||||
|
server_name {{ app.publish.domain }};
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://dockerloopback:{{ app.publish.http }}/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen 443 ssl;
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ app.publish.domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ app.publish.domain }}/privkey.pem;
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
server_name {{ app.publish.domain }};
|
||||||
|
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
proxy_pass http://dockerloopback:8088/.well-known/acme-challenge/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# EOF
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
- vars/packages.yaml
|
- vars/packages.yaml
|
||||||
tasks:
|
tasks:
|
||||||
- name: Update system packages via DNF
|
- name: Update system packages via DNF
|
||||||
when: ansible_distribution == "Rocky"
|
when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora"
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.dnf:
|
ansible.builtin.dnf:
|
||||||
name: "*"
|
name: "*"
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
group: "{{ ansible_user }}"
|
group: "{{ ansible_user }}"
|
||||||
mode: 0644
|
mode: 0644
|
||||||
|
|
||||||
- name: Install universal packages
|
- name: Install universal packages on Rocky
|
||||||
when: ansible_distribution == "Rocky"
|
when: ansible_distribution == "Rocky"
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.dnf:
|
ansible.builtin.dnf:
|
||||||
@@ -47,6 +47,14 @@
|
|||||||
state: present
|
state: present
|
||||||
update_cache: true
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install universal packages on Fedora
|
||||||
|
when: ansible_distribution == "Fedora"
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "{{ skylab_packages_global + skylab_packages_fedora }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
|
||||||
- name: Update unix accounts
|
- name: Update unix accounts
|
||||||
hosts: linux
|
hosts: linux
|
||||||
@@ -132,7 +140,7 @@
|
|||||||
ansible.builtin.set_fact:
|
ansible.builtin.set_fact:
|
||||||
_determined_member_groups: "{{ _determined_member_groups | default({}) | combine({item.name: [
|
_determined_member_groups: "{{ _determined_member_groups | default({}) | combine({item.name: [
|
||||||
skylab_group.name,
|
skylab_group.name,
|
||||||
'wheel' if (item.admin | default(false) and ansible_distribution == 'Rocky') else '',
|
'wheel' if (item.admin | default(false) and ansible_os_family == 'RedHat') else '',
|
||||||
'sudo' if (item.admin | default(false) and ansible_os_family == 'Debian') else '',
|
'sudo' if (item.admin | default(false) and ansible_os_family == 'Debian') else '',
|
||||||
skylab_group_admin.name if item.admin | default(false) else '',
|
skylab_group_admin.name if item.admin | default(false) else '',
|
||||||
skylab_group_automation.name if item.service | default(false) else '',
|
skylab_group_automation.name if item.service | default(false) else '',
|
||||||
@@ -151,7 +159,11 @@
|
|||||||
groups: "{{ _determined_member_groups[item.name] }}"
|
groups: "{{ _determined_member_groups[item.name] }}"
|
||||||
comment: "{{ item.fullname | default('') }}"
|
comment: "{{ item.fullname | default('') }}"
|
||||||
system: "{{ item.service | default(false) }}"
|
system: "{{ item.service | default(false) }}"
|
||||||
generate_ssh_key: false
|
generate_ssh_key: true
|
||||||
|
ssh_key_bits: 4096
|
||||||
|
ssh_key_passphrase: "{{ item.password }}"
|
||||||
|
ssh_key_comment: "{{ item.name }}@{{ inventory_hostname }}"
|
||||||
|
ssh_key_type: ed25519
|
||||||
password: "{{ item.password }}"
|
password: "{{ item.password }}"
|
||||||
loop: "{{ _active_accounts }}"
|
loop: "{{ _active_accounts }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ skylab_accounts:
|
|||||||
- name: enpaul
|
- name: enpaul
|
||||||
uid: 1300
|
uid: 1300
|
||||||
fullname: Ethan N. Paul
|
fullname: Ethan N. Paul
|
||||||
targets: [network, datastore, cluster, cloud]
|
targets: [network, datastore, cluster, cloud, workstation]
|
||||||
admin: true
|
admin: true
|
||||||
password: $6$H7jZEL2Ey93zfMTD$CzUlZkXDudPHgUMU/OFUn8/Yhzo8nBxoSI8thD15toIFlWN.iUfq/Jp5z3KpDCGTxyv.IbRTvE8dOVWjoRfgJ.
|
password: $6$H7jZEL2Ey93zfMTD$CzUlZkXDudPHgUMU/OFUn8/Yhzo8nBxoSI8thD15toIFlWN.iUfq/Jp5z3KpDCGTxyv.IbRTvE8dOVWjoRfgJ.
|
||||||
|
|
||||||
- name: ansible
|
- name: ansible
|
||||||
uid: 1400
|
uid: 1400
|
||||||
targets: [network, datastore, cluster, cloud]
|
targets: [network, datastore, cluster, cloud, workstation]
|
||||||
admin: true
|
admin: true
|
||||||
service: true
|
service: true
|
||||||
password: $6$qNKmYg4y9YS4f5Gr$m0mAqEVbymPguj.1cS.pfclt33Okfmn1KhFC0r1iQ3eVvz/OIZY3x0qGmPnJ1zOXDWyKKs5hnlGTAeZgCh49C.
|
password: $6$qNKmYg4y9YS4f5Gr$m0mAqEVbymPguj.1cS.pfclt33Okfmn1KhFC0r1iQ3eVvz/OIZY3x0qGmPnJ1zOXDWyKKs5hnlGTAeZgCh49C.
|
||||||
|
|||||||
@@ -27,3 +27,9 @@ skylab_packages_rocky:
|
|||||||
- python3-virtualenv
|
- python3-virtualenv
|
||||||
- systemd-networkd
|
- systemd-networkd
|
||||||
- wget
|
- wget
|
||||||
|
|
||||||
|
skylab_packages_fedora:
|
||||||
|
- bind-utils
|
||||||
|
- nc
|
||||||
|
- nfs-utils
|
||||||
|
- wget
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ skylab_services:
|
|||||||
|
|
||||||
minecraft:
|
minecraft:
|
||||||
user: autocraft
|
user: autocraft
|
||||||
domain: mcs.enp.one
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.102.0/24
|
ext: 192.168.102.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -27,6 +26,8 @@ skylab_services:
|
|||||||
25565: 25565
|
25565: 25565
|
||||||
versions:
|
versions:
|
||||||
server: 1.16.5
|
server: 1.16.5
|
||||||
|
publish:
|
||||||
|
domain: mcs.enp.one
|
||||||
settings:
|
settings:
|
||||||
admins:
|
admins:
|
||||||
- ScifiGeek42
|
- ScifiGeek42
|
||||||
@@ -40,7 +41,6 @@ skylab_services:
|
|||||||
|
|
||||||
gitea:
|
gitea:
|
||||||
user: autotea
|
user: autotea
|
||||||
domain: vcs.enp.one
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.103.0/24
|
ext: 192.168.103.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -48,12 +48,14 @@ skylab_services:
|
|||||||
ports:
|
ports:
|
||||||
3000: 3000
|
3000: 3000
|
||||||
22: 2222
|
22: 2222
|
||||||
|
publish:
|
||||||
|
domain: vcs.enp.one
|
||||||
|
http: 3000
|
||||||
versions:
|
versions:
|
||||||
server: 1.15.4
|
server: 1.15.4
|
||||||
|
|
||||||
bitwarden:
|
bitwarden:
|
||||||
user: autowarden
|
user: autowarden
|
||||||
domain: ssv.enp.one
|
|
||||||
networks:
|
networks:
|
||||||
internal: 192.168.104.0/24
|
internal: 192.168.104.0/24
|
||||||
external: 192.168.105.0/24
|
external: 192.168.105.0/24
|
||||||
@@ -87,6 +89,9 @@ skylab_services:
|
|||||||
icons: 1.40.0
|
icons: 1.40.0
|
||||||
events: 1.40.0
|
events: 1.40.0
|
||||||
nginx: 1.40.0
|
nginx: 1.40.0
|
||||||
|
publish:
|
||||||
|
domain: ssv.enp.one
|
||||||
|
http: 8090
|
||||||
settings:
|
settings:
|
||||||
certificatePassword: !vault |
|
certificatePassword: !vault |
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
@@ -138,7 +143,6 @@ skylab_services:
|
|||||||
|
|
||||||
adguard:
|
adguard:
|
||||||
user: autoguard
|
user: autoguard
|
||||||
domain: adguard.en1.local
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.108.0/24
|
ext: 192.168.108.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -149,6 +153,9 @@ skylab_services:
|
|||||||
8064: 8084
|
8064: 8084
|
||||||
versions:
|
versions:
|
||||||
server: v0.106.3
|
server: v0.106.3
|
||||||
|
publish:
|
||||||
|
domain: adguard.en1.local
|
||||||
|
http: 8064
|
||||||
settings:
|
settings:
|
||||||
upstream:
|
upstream:
|
||||||
- 1.1.1.1
|
- 1.1.1.1
|
||||||
@@ -156,7 +163,6 @@ skylab_services:
|
|||||||
|
|
||||||
plex:
|
plex:
|
||||||
user: autoplex
|
user: autoplex
|
||||||
domain: pms.enp.one
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.101.0/24
|
ext: 192.168.101.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -172,6 +178,9 @@ skylab_services:
|
|||||||
32414: 32414
|
32414: 32414
|
||||||
versions:
|
versions:
|
||||||
server: latest
|
server: latest
|
||||||
|
publish:
|
||||||
|
domain: pms.enp.one
|
||||||
|
http: 32400
|
||||||
settings:
|
settings:
|
||||||
mediastore: mediastore.skylab.enp.one
|
mediastore: mediastore.skylab.enp.one
|
||||||
internal_subnets:
|
internal_subnets:
|
||||||
@@ -183,7 +192,6 @@ skylab_services:
|
|||||||
|
|
||||||
unifi:
|
unifi:
|
||||||
user: autounifi
|
user: autounifi
|
||||||
domain: unifi.en1.local
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.100.0/24
|
ext: 192.168.100.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -198,10 +206,12 @@ skylab_services:
|
|||||||
10001: 10001
|
10001: 10001
|
||||||
versions:
|
versions:
|
||||||
wlc: "6.2"
|
wlc: "6.2"
|
||||||
|
publish:
|
||||||
|
domain: unifi.en1.local
|
||||||
|
http: 8080
|
||||||
|
|
||||||
vikunja:
|
vikunja:
|
||||||
user: autollama
|
user: autollama
|
||||||
domain: org.enp.one
|
|
||||||
networks:
|
networks:
|
||||||
ext: 192.168.107.0/24
|
ext: 192.168.107.0/24
|
||||||
volumes:
|
volumes:
|
||||||
@@ -216,6 +226,9 @@ skylab_services:
|
|||||||
proxy: latest
|
proxy: latest
|
||||||
api: 0.18.1
|
api: 0.18.1
|
||||||
web: 0.18.1
|
web: 0.18.1
|
||||||
|
publish:
|
||||||
|
domain: org.enp.one
|
||||||
|
http: 8087
|
||||||
settings:
|
settings:
|
||||||
database_password: !vault |
|
database_password: !vault |
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
skylab_ssh_keys:
|
skylab_ssh_keys:
|
||||||
enpaul:
|
enpaul:
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDi9rWRC15og/+3Jc3AMHOrlIc2BHaAX9PLbklz3qfFtSOp9bIScMcH5ZR6lyVSgP8RCEjI5HuZejDUJTXUQYfvEJeno//vmxn9Vw66lpMz/FSJ3JcDbjDVI1pe3A8mTOAS+AoVOEzCUOJVZJvdI272Hgf+QRBu+ONQ12u+2XYdVfLFDe7mAG+vEJRBatwb8B7Al+/LUpIrCuPm9PzMBtCMFjWGaqQgnyJYRSPIGxz9231XIjwhHLOQG1R0jLGuS37X+J49Y5JYDaHf9q9KH76GjdO2rOq6aGvwN93Y4Z+D2hMOklhD0Ez/ZE+I3ZUPV0e5pF28gsA6L7gTeqmSGpQaKdwjCUoU12VM70OVxng5p2+7DIc0k2np7rnvd4zybgn9OMM+TIO5M3c6ocDuNsEmRgfS3V99X5oh9qNy35UdBXV08j0wFoUo1KcyGwyNBYzKzvkkvtgJezVKmqSPKeBjMgMX4UsJsMn27Zosk0ZgoUwLFPO9Pg7uShncwgsTnvYDR1ws53PV832gc7A85ud/dC9Fjn6jBsMQaCFbiZktc5J8mv3cugQHQesbq8Y2aNVRu+ECb+KUvAEdPacWdBOkk0IvZ4PvLrAs2xehF6FYVqKVtPlJMaUAAwj9vVx7Nl2HnsSRIrCgxsMOTOhbbp/3NrvM8r6K7zKBzXg2TNgQeQ== enpaul@ph-1
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDi9rWRC15og/+3Jc3AMHOrlIc2BHaAX9PLbklz3qfFtSOp9bIScMcH5ZR6lyVSgP8RCEjI5HuZejDUJTXUQYfvEJeno//vmxn9Vw66lpMz/FSJ3JcDbjDVI1pe3A8mTOAS+AoVOEzCUOJVZJvdI272Hgf+QRBu+ONQ12u+2XYdVfLFDe7mAG+vEJRBatwb8B7Al+/LUpIrCuPm9PzMBtCMFjWGaqQgnyJYRSPIGxz9231XIjwhHLOQG1R0jLGuS37X+J49Y5JYDaHf9q9KH76GjdO2rOq6aGvwN93Y4Z+D2hMOklhD0Ez/ZE+I3ZUPV0e5pF28gsA6L7gTeqmSGpQaKdwjCUoU12VM70OVxng5p2+7DIc0k2np7rnvd4zybgn9OMM+TIO5M3c6ocDuNsEmRgfS3V99X5oh9qNy35UdBXV08j0wFoUo1KcyGwyNBYzKzvkkvtgJezVKmqSPKeBjMgMX4UsJsMn27Zosk0ZgoUwLFPO9Pg7uShncwgsTnvYDR1ws53PV832gc7A85ud/dC9Fjn6jBsMQaCFbiZktc5J8mv3cugQHQesbq8Y2aNVRu+ECb+KUvAEdPacWdBOkk0IvZ4PvLrAs2xehF6FYVqKVtPlJMaUAAwj9vVx7Nl2HnsSRIrCgxsMOTOhbbp/3NrvM8r6K7zKBzXg2TNgQeQ== enpaul@ph-1
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8K74AXz6LBYfoXRbY1pKP+1rvi5BpjFOkg1uYuMM+q78toagSREpLrbjvPtoL8fkEFox4T9TUaME08ZP8560R6iRk35extTTiXquflEwvpsF+e9Lv8E712s/1ydJpkYoux1OohE4W5D9DjVMEW1tjXeb+9aDUcVml6YKMpKLpjEIVanyjHMN13XgswKZGoK3mVMnWxE36fbGVVfiFCvMr/BpjqGShRCxmvldzgq76i1BpTKi6omOjvpgRQcUJcDhYcHAUVSlNccgGLmlAPiUillA//pk84yczzH1dQBB6571Ab5ldoUDBU/hJ0W27aeOfrepup4hNuUt2oux+zAn+uetAuAWKU2Kd0Oo6L5IKObbAQLI0CXfyrmHlrYXwTyNMFleeOdw7s9lf2ra3YCYVXfMALdE6pp+HJLBxzg9kMBbTp6zkV7ZKi75AQhyBJA0s4+vRUccBtJit3Tls+aw/3rd9Dt9lLaXkE80khoKsUI0eiuXtPDlurGxkpcTe6Al/lChNA19pdKEUsBmhD6UUvMTYWlApmta/+xf0wDsSyHqJcnIGx8Qdtg3c4j1Ch+WXwbdOwk8XJrL0atWmv2ium1ll/arO2NFBmbwG1LG/lzJ1k/DoAiHrKrb1HdlwDk0O/7xF/zyC2mfVZKO36+g4XlA7wDJc0tB5vIymlEy2rw== enpaul@serico-nox
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC8K74AXz6LBYfoXRbY1pKP+1rvi5BpjFOkg1uYuMM+q78toagSREpLrbjvPtoL8fkEFox4T9TUaME08ZP8560R6iRk35extTTiXquflEwvpsF+e9Lv8E712s/1ydJpkYoux1OohE4W5D9DjVMEW1tjXeb+9aDUcVml6YKMpKLpjEIVanyjHMN13XgswKZGoK3mVMnWxE36fbGVVfiFCvMr/BpjqGShRCxmvldzgq76i1BpTKi6omOjvpgRQcUJcDhYcHAUVSlNccgGLmlAPiUillA//pk84yczzH1dQBB6571Ab5ldoUDBU/hJ0W27aeOfrepup4hNuUt2oux+zAn+uetAuAWKU2Kd0Oo6L5IKObbAQLI0CXfyrmHlrYXwTyNMFleeOdw7s9lf2ra3YCYVXfMALdE6pp+HJLBxzg9kMBbTp6zkV7ZKi75AQhyBJA0s4+vRUccBtJit3Tls+aw/3rd9Dt9lLaXkE80khoKsUI0eiuXtPDlurGxkpcTe6Al/lChNA19pdKEUsBmhD6UUvMTYWlApmta/+xf0wDsSyHqJcnIGx8Qdtg3c4j1Ch+WXwbdOwk8XJrL0atWmv2ium1ll/arO2NFBmbwG1LG/lzJ1k/DoAiHrKrb1HdlwDk0O/7xF/zyC2mfVZKO36+g4XlA7wDJc0tB5vIymlEy2rw== enpaul@discovery
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDHUXG01NQ7IahqBwLx+lqvbnhU5Cynt+Y4xCk2u5pwjU2KwKyRfqc5LUROU4mcFLuA1mP9uoMaYmiJ/rIWvM/A9OVplilCoSKXxWJW09fR/rOPmCn7pOR+CpFXBNOiRR0WoiDeu1D0tifbSuK/qOxKy6Lp9MH20Ma46d89xA57L9LX+B5CrwF9fR2FXIQGojCiFFyByaUgmzuDMi5mCafm3XlqaR1/wcqoA1YwqFFiGR3gVylSbOmB/Q4GnnyLpBbcYAc5AQnbnD4LlM5biEsLNy7vtQj9s0SeloUkzsJ112dNozdwTI/tOWbINVM+o3AH4B2baTQayWK/UrG9sivjHgEz5Jk5A4xAbUWC1MrH7WHo7vevHu4AT+DiPLkmHli9Ztu0DqJuenheJDyRLfWwDPvIpoY9/AsbVZ/UXqRVbfIB4jV00IHneEg4zj0AdWbSHDz55BZ23JItpuU4i37cO9Cbo2tQYqZjgM5VAlZXwhNPUF7pxWJJxGFqiB5MTQM0LZcrmXpToxBPa0BSDmIcjvLP6NQWk1u+Fdjunyx/q9Gmlc3vFtFEz7swWCuKp4DavyUXFeWwSKt4dDRZyPPdSYrKxDPCncSaKeCv+G5sx4RyQLJjpx14tisnnZP0O5b5S6j3PfGzjgnNBhzl/xIzM5moUqPF7R2laOKh9CBdoQ== enpaul@vigil-nox
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3ron1rnTp4t9iyB2VGY5jNuOuJcOgZD3KewjPqOijA enpaul@voyager
|
||||||
ansible:
|
ansible:
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN/E/zjwCruZf+mboBeBAtNFBInWMvdm6TjwpIg6jVoGgRmYQxEfIcqDSfBTQQ0gbyE3udTdTUDRLRu7ADktzL9J0IepEaYARfz8SANS/Hx2MR0NNy8DArrSFJCOillDA7E7UmNPIPeQl0O76p2ZjEDy6qZnTiW8eOtD7LCzJp4eGJanUPFhag8f4aSNbmiHGR25Zuk82w2/+KrqiI3gO0+jNlnPBf+XHNnFbtUIroupRfxgLdk1OahmkWHTSHkDtXiYrWIISarrHCgVqHTHo1KIX5+MPOH4S5VLB1kaY/O7+g/XlFrAciw8m0zjyBq0ILb+YTSrL9PYnSBtnHAVGJv2bB+TgCfF/nhQGqoqBqqQHFnX0y3JygmDTJMO+aE5wlvI5Laki7EHYPU4fL+Ge76l/dG9j2anw4/iHklbfk1UOxnLvJl593GAlILg1Kd8xx9VfYzVZ7GZym2zq3NI4uQ77T1H4iGoE67zarkn3peKacjX/KARq4weVvs3irHIHibnIuh/TGcS4eiQoNdPxsSA2wRKB6jeuXiV65F1rUDNGs80wcJmsAbZN8/u9Tt0o/Xc+L/LVhV0yrSeBUxzXtlaS+RfcteBXByO3xfC112Cj5grKVki5xWN9AY42Y6JhT3OyiO33dKUMEF/KfiEWWAfvQr/t1CI/rdcEbv3pyUw== enpaul@serico-nox-ansible
|
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5TGKururOa1Y+cbv8AWXYI5zhfZCDV0fsBG+33IYUc enpaul@ansible.voyager
|
||||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIbXaUzVqDDKDSC1iO/nOmxIcJoOoMvXE+CJRobEdpkkYSBmlPfburJvGMDMQ3O/88OfgBrG5S7HKlbgVPGEII0Vpsk5iwzOk5Tmo03nLz02Ilx1xXYxTrjUSwnexzbHpluHmqunKEIUVTMHpDz2m4UPgZ4ECsGp9/6n6+n//uLeJ4fQUO9x4L+VMbpDrtfpKN7/P6U30XBIb9bZuKznVPtqTmCy/BFkxTkIn9QKqDh5d49FY/xkOjy1K9zTWb78DFzBRf4sGEykrp19N6inL0eRstGSZAKhqL+qdRXOy/7n6l0u+CdXWl9ZFVXRFhVdAhYOgkEvtuqoasK1Fk3OMqP6SflFanuDiFBostfgfrf8SUV+7CFvOuSpEWgTqx/jPFZV4Vr6wx5ZFVs02OzZ6TJFaEHaLvOE/R3iLOiuFcvqVNpvstLiyiigsj1+DwhDJcwOr3DaEsNdUbv0BTI2P03wtHJtBQw5CaVr5zCBDEeUsL0bBVQdq+6d0NT+CPJNxSZlTmmrBBbgkpupxdnmX6VVBYfXnylsE8UZxY1d7yxba3+Wzp2yvlr2MVocwQmMTPEqimIsW0hsQ8iXi1nrDXecSojlDAeu+LBFuaCxO8H59GrrVWVTI2dAPLEcP+stNGLHqKZuh62t5TnmxuMMi0SY6jH7KiKmusD4fYafzrlQ== enpaul@vigil-nox-ansible
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDN/E/zjwCruZf+mboBeBAtNFBInWMvdm6TjwpIg6jVoGgRmYQxEfIcqDSfBTQQ0gbyE3udTdTUDRLRu7ADktzL9J0IepEaYARfz8SANS/Hx2MR0NNy8DArrSFJCOillDA7E7UmNPIPeQl0O76p2ZjEDy6qZnTiW8eOtD7LCzJp4eGJanUPFhag8f4aSNbmiHGR25Zuk82w2/+KrqiI3gO0+jNlnPBf+XHNnFbtUIroupRfxgLdk1OahmkWHTSHkDtXiYrWIISarrHCgVqHTHo1KIX5+MPOH4S5VLB1kaY/O7+g/XlFrAciw8m0zjyBq0ILb+YTSrL9PYnSBtnHAVGJv2bB+TgCfF/nhQGqoqBqqQHFnX0y3JygmDTJMO+aE5wlvI5Laki7EHYPU4fL+Ge76l/dG9j2anw4/iHklbfk1UOxnLvJl593GAlILg1Kd8xx9VfYzVZ7GZym2zq3NI4uQ77T1H4iGoE67zarkn3peKacjX/KARq4weVvs3irHIHibnIuh/TGcS4eiQoNdPxsSA2wRKB6jeuXiV65F1rUDNGs80wcJmsAbZN8/u9Tt0o/Xc+L/LVhV0yrSeBUxzXtlaS+RfcteBXByO3xfC112Cj5grKVki5xWN9AY42Y6JhT3OyiO33dKUMEF/KfiEWWAfvQr/t1CI/rdcEbv3pyUw== enpaul@ansible.discovery
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
listen_addr: "{{ lookup('vars', 'ansible_' + skylab_cluster.interface.internal).ipv4.address }}"
|
listen_addr: "{{ lookup('vars', 'ansible_' + skylab_cluster.interface.internal).ipv4.address }}"
|
||||||
remote_addrs: "{{ _docker_swarm_manager_addresses }}"
|
remote_addrs: "{{ _docker_swarm_manager_addresses }}"
|
||||||
join_token: "{{ _docker_swarm_join_token.stdout.strip() }}"
|
join_token: "{{ _docker_swarm_join_token.stdout.strip() }}"
|
||||||
timeout: 300
|
timeout: 1200
|
||||||
|
|
||||||
- name: Fetch node swarm ID
|
- name: Fetch node swarm ID
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
|
|||||||
2
skylab/core/roles/workstation/files/00-disable-user-list
Normal file
2
skylab/core/roles/workstation/files/00-disable-user-list
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[org/gnome/login-screen]
|
||||||
|
disable-user-list=true
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
[org/gnome/mutter]
|
||||||
|
experimental-features=['scale-monitor-framebuffer']
|
||||||
47
skylab/core/roles/workstation/files/bashrc.sh
Normal file
47
skylab/core/roles/workstation/files/bashrc.sh
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
if [ -f `which powerline-daemon` ]; then
|
||||||
|
powerline-daemon -q
|
||||||
|
POWERLINE_BASH_CONTINUATION=1
|
||||||
|
POWERLINE_BASH_SELECT=1
|
||||||
|
. /usr/share/powerline/bash/powerline.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
export NVM_DIR="$HOME/.nvm"
|
||||||
|
export PROJECTS_DIR="$HOME/projects"
|
||||||
|
|
||||||
|
function gg() {
|
||||||
|
cd "$PROJECTS_DIR/$1";
|
||||||
|
if [ -f "$PROJECTS_DIR/$1/ansible.cfg" ]; then
|
||||||
|
ANSIBLE_CONFIG="$PROJECTS_DIR/$1/ansible.cfg" ANSIBLE_COLLECTIONS_PATH="$PROJECTS_DIR/$1/.ansible" poetry shell;
|
||||||
|
elif [ -f "$PROJECTS_DIR/$1/pyproject.toml" ]; then
|
||||||
|
poetry shell;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mpw() {
|
||||||
|
_copy() {
|
||||||
|
if hash pbcopy 2>/dev/null; then
|
||||||
|
pbcopy
|
||||||
|
elif hash xclip 2>/dev/null; then
|
||||||
|
xclip -selection clip
|
||||||
|
else
|
||||||
|
cat; echo 2>/dev/null
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo >&2 "Copied!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Empty the clipboard
|
||||||
|
:| _copy 2>/dev/null
|
||||||
|
|
||||||
|
# Ask for the user's name and password if not yet known.
|
||||||
|
MPW_FULLNAME="Ethan Paul"
|
||||||
|
|
||||||
|
# Start Master Password and copy the output.
|
||||||
|
printf %s "$(MPW_FULLNAME=$MPW_FULLNAME command mpw "$@")" | _copy
|
||||||
|
}
|
||||||
|
|
||||||
|
alias explorer='nautilus'
|
||||||
|
alias doc='cd ~/Documents'
|
||||||
|
alias dn='cd ~/Downloads'
|
||||||
|
alias prun="poetry run"
|
||||||
|
alias psync="poetry install --remove-untracked"
|
||||||
3
skylab/core/roles/workstation/files/gdm-system
Normal file
3
skylab/core/roles/workstation/files/gdm-system
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
user-db:user
|
||||||
|
system-db:gdm
|
||||||
|
file-db:/usr/share/gdm/greeter-dconf-defaults
|
||||||
2
skylab/core/roles/workstation/files/gdm-user
Normal file
2
skylab/core/roles/workstation/files/gdm-user
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
user-db:user
|
||||||
|
system-db:local
|
||||||
BIN
skylab/core/roles/workstation/files/lightningbug-dark.tar.gz
Normal file
BIN
skylab/core/roles/workstation/files/lightningbug-dark.tar.gz
Normal file
Binary file not shown.
BIN
skylab/core/roles/workstation/files/multimc.png
Normal file
BIN
skylab/core/roles/workstation/files/multimc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
skylab/core/roles/workstation/files/wallpaper-discovery.jpg
Normal file
BIN
skylab/core/roles/workstation/files/wallpaper-discovery.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 664 KiB |
BIN
skylab/core/roles/workstation/files/wallpaper-voyager.jpg
Normal file
BIN
skylab/core/roles/workstation/files/wallpaper-voyager.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 243 KiB |
6
skylab/core/roles/workstation/handlers/main.yml
Normal file
6
skylab/core/roles/workstation/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: dconf-update
|
||||||
|
become: true
|
||||||
|
changed_when: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: dconf update
|
||||||
144
skylab/core/roles/workstation/tasks/environment.yml
Normal file
144
skylab/core/roles/workstation/tasks/environment.yml
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
---
|
||||||
|
- name: Install user bashrc
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: bashrc.sh
|
||||||
|
dest: ~{{ item }}/.bashrc_ansible
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ item }}"
|
||||||
|
mode: 0644
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Configure user bashrc loading
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: ~{{ item }}/.bashrc
|
||||||
|
line: source ~/.bashrc_ansible
|
||||||
|
state: present
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Configure local bash completions loading
|
||||||
|
become: true
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: ~{{ item }}/.bashrc
|
||||||
|
line: source ~/.config/bash_completions
|
||||||
|
state: present
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Configure bash completions
|
||||||
|
become: true
|
||||||
|
ansible.builtin.blockinfile:
|
||||||
|
path: ~{{ item }}/.config/bash_completions
|
||||||
|
create: true
|
||||||
|
block: >-
|
||||||
|
function _gg_completion() {
|
||||||
|
local cur=${COMP_WORDS[COMP_CWORD]};
|
||||||
|
COMPREPLY=( $(compgen -W "$(command ls $PROJECTS_DIR)" -- $cur) );
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _gg_completion gg
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ item }}"
|
||||||
|
mode: 0664
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Enforce ownership of the SSH keys
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ item.0 }}/.ssh/id_ed25519{{ item.1 }}
|
||||||
|
state: file
|
||||||
|
owner: "{{ item.0 }}"
|
||||||
|
group: "{{ item.0 }}"
|
||||||
|
loop: "{{ _local_human_users | product(['', '.pub']) }}"
|
||||||
|
|
||||||
|
- name: Configure dconf setting
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Create dconf config directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: 0755
|
||||||
|
loop:
|
||||||
|
- /etc/dconf/profile
|
||||||
|
- /etc/dconf/db/gdm.d
|
||||||
|
|
||||||
|
- name: Create global dconf config
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: gdm-system
|
||||||
|
dest: /etc/dconf/profile/gdm
|
||||||
|
owner: root
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: 0644
|
||||||
|
notify:
|
||||||
|
- dconf-update
|
||||||
|
|
||||||
|
- name: Create user dconf config
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: gdm-user
|
||||||
|
dest: /etc/dconf/profile/user
|
||||||
|
owner: root
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: 0644
|
||||||
|
notify:
|
||||||
|
- dconf-update
|
||||||
|
|
||||||
|
- name: Disable user list
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: 00-disable-user-list
|
||||||
|
dest: /etc/dconf/db/gdm.d/00-disable-user-list
|
||||||
|
owner: root
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: 0644
|
||||||
|
notify:
|
||||||
|
- dconf-update
|
||||||
|
|
||||||
|
- name: Enable fractional scaling
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: 00-enable-fractional-scaling
|
||||||
|
dest: /etc/dconf/db/local.d/00-enable-fractional-scaling
|
||||||
|
owner: root
|
||||||
|
group: "{{ ansible_user }}"
|
||||||
|
mode: 0644
|
||||||
|
notify:
|
||||||
|
- dconf-update
|
||||||
|
|
||||||
|
- name: Install themes
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: Create local themes directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ item }}/.themes
|
||||||
|
state: directory
|
||||||
|
owner: "{{ item }}"
|
||||||
|
group: "{{ item }}"
|
||||||
|
mode: 0750
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Unarchive LightningBug into local directory
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: lightningbug-dark.tar.gz
|
||||||
|
dest: ~{{ item }}/.themes
|
||||||
|
owner: "{{ item }}"
|
||||||
|
group: "{{ item }}"
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Install wallpaper
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: wallpaper-{{ inventory_hostname }}.jpg
|
||||||
|
dest: ~{{ item }}/Pictures/wallpaper.jpg
|
||||||
|
owner: "{{ item }}"
|
||||||
|
group: "{{ item }}"
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
|
||||||
|
- name: Link external media directory
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ item }}/Drives
|
||||||
|
src: /run/media/{{ item }}
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
59
skylab/core/roles/workstation/tasks/install_mpw.yml
Normal file
59
skylab/core/roles/workstation/tasks/install_mpw.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
- name: Check for MPW binary
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: /usr/local/bin/mpw
|
||||||
|
register: _mpw_binary_stat
|
||||||
|
|
||||||
|
- name: Install MPW
|
||||||
|
when: (not _mpw_binary_stat.stat.exists) or (force_reinstall | default(false))
|
||||||
|
block:
|
||||||
|
- name: Install build dependencies on Fedora
|
||||||
|
when: ansible_distribution == "Fedora"
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- libsodium-devel
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create temporary build directory
|
||||||
|
ansible.builtin.tempfile:
|
||||||
|
prefix: ansible.build.mpw
|
||||||
|
state: directory
|
||||||
|
register: _mpw_build_dir
|
||||||
|
|
||||||
|
- name: Download MPW source
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://gitlab.com/MasterPassword/MasterPassword.git
|
||||||
|
version: 344771db
|
||||||
|
recursive: false # does *not* clone submodules
|
||||||
|
dest: "{{ _mpw_build_dir.path }}"
|
||||||
|
|
||||||
|
# God I hate this
|
||||||
|
- name: Patch .gitmodules to use HTTPS
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: "{{ _mpw_build_dir.path }}/.gitmodules"
|
||||||
|
regexp: "url = git://"
|
||||||
|
replace: "url = https://"
|
||||||
|
|
||||||
|
- name: Initialize submodules
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: git submodule update --init
|
||||||
|
chdir: "{{ _mpw_build_dir.path }}"
|
||||||
|
|
||||||
|
- name: Build MasterPassword binary
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: bash build
|
||||||
|
chdir: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/"
|
||||||
|
|
||||||
|
- name: Copy binary to system path
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "{{ _mpw_build_dir.path }}/platform-independent/cli-c/mpw"
|
||||||
|
dest: "/usr/local/bin"
|
||||||
|
mode: 0755
|
||||||
|
always:
|
||||||
|
- name: Remove temporary directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ _mpw_build_dir.path }}"
|
||||||
|
state: absent
|
||||||
79
skylab/core/roles/workstation/tasks/install_multimc.yml
Normal file
79
skylab/core/roles/workstation/tasks/install_multimc.yml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
- name: Check whether binary exists
|
||||||
|
become: true
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "~{{ local_username }}/.local/bin/MultiMC"
|
||||||
|
register: _multimc_stat
|
||||||
|
|
||||||
|
- name: Install MultiMC
|
||||||
|
when: (not _multimc_stat.stat.exists) or (force_reinstall | default(false))
|
||||||
|
block:
|
||||||
|
- name: Create temp dir
|
||||||
|
ansible.builtin.tempfile:
|
||||||
|
state: directory
|
||||||
|
register: _multimc_tempdir
|
||||||
|
|
||||||
|
- name: Download and unpack distribution archive
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: https://files.multimc.org/downloads/mmc-stable-lin64.tar.gz
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ _multimc_tempdir.path }}"
|
||||||
|
|
||||||
|
- name: Ensure ~/.local/share/ exists
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ local_username }}/.local/share
|
||||||
|
state: directory
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0700
|
||||||
|
|
||||||
|
- name: Ensure ~/.local/bin/ exists
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ local_username }}/.local/bin
|
||||||
|
state: directory
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0700
|
||||||
|
|
||||||
|
- name: Copy MMC distribution to ~/.local/share/
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "{{ _multimc_tempdir.path }}/MultiMC/"
|
||||||
|
dest: "~{{ local_username }}/.local/share/multimc"
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0700
|
||||||
|
|
||||||
|
- name: Link MMC binary into ~/.local/bin/
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: link
|
||||||
|
src: ~{{ local_username }}/.local/share/multimc/MultiMC
|
||||||
|
path: ~{{ local_username }}/.local/bin/MultiMC
|
||||||
|
|
||||||
|
- name: Copy application icon
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: multimc.png
|
||||||
|
dest: ~{{ local_username }}/.local/share/icons/multimc.png
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Template application desktop entry
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: multimc.desktop.j2
|
||||||
|
dest: ~{{ local_username }}/.local/share/applications/multimc.desktop
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete temp dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ _multimc_tempdir.path }}"
|
||||||
|
state: absent
|
||||||
0
skylab/core/roles/workstation/tasks/install_nvm.yml
Normal file
0
skylab/core/roles/workstation/tasks/install_nvm.yml
Normal file
27
skylab/core/roles/workstation/tasks/install_pipx.yml
Normal file
27
skylab/core/roles/workstation/tasks/install_pipx.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
- name: Create install directory
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /opt/pipx
|
||||||
|
state: directory
|
||||||
|
owner: "{{ ansible_user }}"
|
||||||
|
group: "{{ skylab_group_admin.name }}"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Create install venv
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: python3 -m venv /opt/pipx
|
||||||
|
creates: /opt/pipx/bin/python
|
||||||
|
|
||||||
|
- name: Install pipx
|
||||||
|
ansible.builtin.pip:
|
||||||
|
name:
|
||||||
|
- pipx
|
||||||
|
executable: /opt/pipx/bin/pip
|
||||||
|
|
||||||
|
- name: Link pipx binary into system path
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: link
|
||||||
|
src: /opt/pipx/bin/pipx
|
||||||
|
path: /usr/local/bin/pipx
|
||||||
1
skylab/core/roles/workstation/tasks/install_poetry.yml
Normal file
1
skylab/core/roles/workstation/tasks/install_poetry.yml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
---
|
||||||
53
skylab/core/roles/workstation/tasks/install_tor_browser.yml
Normal file
53
skylab/core/roles/workstation/tasks/install_tor_browser.yml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
- name: Check whether Tor Browser is already installed
|
||||||
|
become: true
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "~{{ local_username }}/.local/share/tor-browser/start-tor-browser.desktop"
|
||||||
|
register: _torbrowser_stat
|
||||||
|
|
||||||
|
- name: Install Tor Browser
|
||||||
|
when: not _torbrowser_stat.stat.exists
|
||||||
|
block:
|
||||||
|
- name: Create temp dir
|
||||||
|
ansible.builtin.tempfile:
|
||||||
|
state: directory
|
||||||
|
register: _torbrowser_tempdir
|
||||||
|
|
||||||
|
- name: Download and unpack distribution archive
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: https://dist.torproject.org/torbrowser/11.0.10/tor-browser-linux64-11.0.10_en-US.tar.xz
|
||||||
|
remote_src: true
|
||||||
|
dest: "{{ _torbrowser_tempdir.path }}"
|
||||||
|
|
||||||
|
- name: Ensure ~/.local/share/ exists
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: ~{{ local_username }}/.local/share
|
||||||
|
state: directory
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0700
|
||||||
|
|
||||||
|
- name: Copy Tor Browser distribution to ~/.local/share/
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "{{ _torbrowser_tempdir.path }}/tor-browser_en-US/"
|
||||||
|
dest: "~{{ local_username }}/.local/share/tor-browser"
|
||||||
|
owner: "{{ local_username }}"
|
||||||
|
group: "{{ local_username }}"
|
||||||
|
mode: 0700
|
||||||
|
|
||||||
|
- name: Register application
|
||||||
|
become: true
|
||||||
|
become_user: "{{ local_username }}"
|
||||||
|
changed_when: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: ./start-tor-browser.desktop
|
||||||
|
chdir: ~{{ local_username }}/.local/share/tor-browser
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete temp dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ _torbrowser_tempdir.path }}"
|
||||||
|
state: absent
|
||||||
40
skylab/core/roles/workstation/tasks/main.yml
Normal file
40
skylab/core/roles/workstation/tasks/main.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
- name: Include access vars
|
||||||
|
ansible.builtin.include_vars:
|
||||||
|
file: vars/access.yaml
|
||||||
|
|
||||||
|
- name: Determine local user accounts
|
||||||
|
when: skylab_targets | intersect(item.targets | default([]))
|
||||||
|
vars:
|
||||||
|
_local_users: []
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_local_users: "{{ _local_users + [item] }}"
|
||||||
|
loop: "{{ skylab_accounts }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }},{{ item.uid }}"
|
||||||
|
|
||||||
|
- name: Determine local human user accounts
|
||||||
|
when: not (item.service | default(false))
|
||||||
|
vars:
|
||||||
|
_local_human_users: []
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_local_human_users: "{{ _local_human_users + [item.name] }}"
|
||||||
|
loop: "{{ _local_users }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }},{{ item.uid }}"
|
||||||
|
|
||||||
|
- name: Determine local admin user accounts
|
||||||
|
when: item.admin | default(false)
|
||||||
|
vars:
|
||||||
|
_local_admin_users: []
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
_local_admin_users: "{{ _local_admin_users + [item.name] }}"
|
||||||
|
loop: "{{ _local_users }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }},{{ item.uid }}"
|
||||||
|
|
||||||
|
- name: Install software
|
||||||
|
ansible.builtin.import_tasks: software.yml
|
||||||
|
|
||||||
|
- name: Configure environment
|
||||||
|
ansible.builtin.import_tasks: environment.yml
|
||||||
121
skylab/core/roles/workstation/tasks/software.yml
Normal file
121
skylab/core/roles/workstation/tasks/software.yml
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
---
|
||||||
|
- name: Install repositories on Fedora
|
||||||
|
become: true
|
||||||
|
when: ansible_distribution == "Fedora"
|
||||||
|
block:
|
||||||
|
- name: Install RPMFusion repositories
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm
|
||||||
|
- https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm
|
||||||
|
state: present
|
||||||
|
disable_gpg_check: true
|
||||||
|
|
||||||
|
- name: Install Docker CE repository
|
||||||
|
ansible.builtin.yum_repository:
|
||||||
|
name: docker-ce-stable
|
||||||
|
description: Docker CE Stable - $basearch
|
||||||
|
baseurl: https://download.docker.com/linux/fedora/$releasever/$basearch/stable
|
||||||
|
enabled: true
|
||||||
|
gpgcheck: true
|
||||||
|
gpgkey: https://download.docker.com/linux/fedora/gpg
|
||||||
|
|
||||||
|
- name: Install VSCode repository
|
||||||
|
ansible.builtin.yum_repository:
|
||||||
|
name: vscode
|
||||||
|
description: Visual Studio Code
|
||||||
|
baseurl: https://packages.microsoft.com/yumrepos/vscode
|
||||||
|
enabled: true
|
||||||
|
gpgcheck: true
|
||||||
|
gpgkey: https://packages.microsoft.com/keys/microsoft.asc
|
||||||
|
|
||||||
|
- name: Enable Signal-Desktop COPR repository
|
||||||
|
community.general.copr:
|
||||||
|
name: luminoso/Signal-Desktop
|
||||||
|
state: enabled
|
||||||
|
|
||||||
|
- name: Install packages on Fedora
|
||||||
|
become: true
|
||||||
|
when: ansible_distribution == "Fedora"
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- arc-theme
|
||||||
|
- cmake
|
||||||
|
- code # visual studio code
|
||||||
|
- deluge
|
||||||
|
- docker-ce
|
||||||
|
- gcc
|
||||||
|
- gcc-c++
|
||||||
|
- gnome-tweaks
|
||||||
|
- gnome-shell-extension-material-shell
|
||||||
|
- gnome-shell-extension-openweather
|
||||||
|
- gnome-shell-extension-system-monitor-applet
|
||||||
|
- gnome-shell-extension-vertical-overview
|
||||||
|
- gnupg2
|
||||||
|
- guvcview
|
||||||
|
- java-17-openjdk
|
||||||
|
- jq
|
||||||
|
- libffi-devel
|
||||||
|
- libvirt
|
||||||
|
- libvirt-devel
|
||||||
|
- libxml2-devel
|
||||||
|
- mediawriter
|
||||||
|
- ncurses-devel
|
||||||
|
- NetworkManager-tui
|
||||||
|
- pinta
|
||||||
|
- powerline
|
||||||
|
- python27
|
||||||
|
- python36
|
||||||
|
- python37
|
||||||
|
- python38
|
||||||
|
- python39
|
||||||
|
- python310
|
||||||
|
- ShellCheck
|
||||||
|
- signal-desktop
|
||||||
|
- steam
|
||||||
|
- systemd-devel
|
||||||
|
- texlive-fontawesome5
|
||||||
|
- texlive-roboto
|
||||||
|
- texlive-scheme-tetex
|
||||||
|
- texlive-sourcesanspro
|
||||||
|
- virt-manager
|
||||||
|
- vlc
|
||||||
|
- xclip
|
||||||
|
- yarnpkg
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install unsigned packages on Fedora
|
||||||
|
when: ansible_distribution == "Fedora"
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
# draw.io/diagrams.net
|
||||||
|
- https://github.com/jgraph/drawio-desktop/releases/download/v17.4.2/drawio-x86_64-17.4.2.rpm
|
||||||
|
# zoom
|
||||||
|
- https://zoom.us/client/latest/zoom_x86_64.rpm
|
||||||
|
state: present
|
||||||
|
disable_gpg_check: true
|
||||||
|
|
||||||
|
- ansible.builtin.import_tasks: install_mpw.yml
|
||||||
|
- ansible.builtin.import_tasks: install_nvm.yml
|
||||||
|
- ansible.builtin.import_tasks: install_pipx.yml
|
||||||
|
- ansible.builtin.import_tasks: install_poetry.yml
|
||||||
|
- ansible.builtin.import_tasks: install_postman.yml
|
||||||
|
- ansible.builtin.import_tasks: install_rustup.yml
|
||||||
|
- ansible.builtin.import_tasks: install_typora.yml
|
||||||
|
|
||||||
|
# It is now day eight hundred and thirty nine of begging the ansible devs to let
|
||||||
|
# me loop over blocks. pls bcoca i have a family
|
||||||
|
- name: Install Tor Browser
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: install_tor_browser.yml
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: local_username
|
||||||
|
|
||||||
|
- name: Install MultiMC
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: install_multimc.yml
|
||||||
|
loop: "{{ _local_human_users }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: local_username
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=MultiMC
|
||||||
|
Comment=Minecraft environment manager
|
||||||
|
Exec="/home/{{ local_username }}/.local/bin/MultiMC"
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
||||||
|
Icon="/home/{{ local_username }}/.local/share/icons/multimc.png"
|
||||||
|
Categories=Gaming;Graphics;
|
||||||
|
TryExec="/home/{{ local_username }}/.local/bin/MultiMC"
|
||||||
3
skylab/infra/README.md
Normal file
3
skylab/infra/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Ansible Collection - skylab.infra
|
||||||
|
|
||||||
|
Documentation for the collection.
|
||||||
16
skylab/infra/galaxy.yml
Normal file
16
skylab/infra/galaxy.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
namespace: skylab
|
||||||
|
name: core
|
||||||
|
version: 0.0.0
|
||||||
|
description: Network deployment procedures and configuration state management
|
||||||
|
authors:
|
||||||
|
- Ethan Paul <me@enp.one>
|
||||||
|
license:
|
||||||
|
- MIT
|
||||||
|
readme: README.md
|
||||||
|
tags: []
|
||||||
|
repository: https://vcs.enp.one/skylab/skylab-ansible/
|
||||||
|
build_ignore: []
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
community.general: ">=6.5.0,<7.0"
|
||||||
|
ansible.posix: ">=1.5.1,<2.0"
|
||||||
2
skylab/infra/meta/runtime.yml
Normal file
2
skylab/infra/meta/runtime.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
requires_ansible: '>=2.9.10'
|
||||||
230
skylab/infra/playbooks/bootstrap.yml
Normal file
230
skylab/infra/playbooks/bootstrap.yml
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
---
|
||||||
|
- name: Prompt for parameters
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars_prompt:
|
||||||
|
- name: bootstrap_hostname
|
||||||
|
prompt: Enter hostname (or IP address) of bootstrap target
|
||||||
|
private: false
|
||||||
|
- name: bootstrap_username
|
||||||
|
prompt: Enter username to use for connecting to boostrap target
|
||||||
|
default: root
|
||||||
|
private: false
|
||||||
|
- name: bootstrap_password
|
||||||
|
prompt: Enter password to use for connecting to boostrap target
|
||||||
|
private: true
|
||||||
|
default: skylab
|
||||||
|
- name: bootstrap_port
|
||||||
|
prompt: Enter SSH port to connect to on bootstrap target
|
||||||
|
default: 22
|
||||||
|
private: false
|
||||||
|
tasks:
|
||||||
|
- name: Add boostrap host
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.add_host:
|
||||||
|
hostname: bootstrap
|
||||||
|
ansible_host: "{{ bootstrap_hostname }}"
|
||||||
|
ansible_user: "{{ bootstrap_username }}"
|
||||||
|
ansible_ssh_pass: "{{ bootstrap_password }}"
|
||||||
|
ansible_port: "{{ bootstrap_port }}"
|
||||||
|
|
||||||
|
- name: Test connection
|
||||||
|
delegate_to: bootstrap
|
||||||
|
delegate_facts: true
|
||||||
|
vars:
|
||||||
|
ansible_host_key_checking: false
|
||||||
|
ansible.builtin.ping: {}
|
||||||
|
|
||||||
|
- name: Bootstrap remote
|
||||||
|
hosts: bootstrap
|
||||||
|
vars:
|
||||||
|
ansible_host_key_checking: false
|
||||||
|
vars_prompt:
|
||||||
|
- name: skylab_ansible_vault_password
|
||||||
|
prompt: Enter Ansible vault password for generating user secrets
|
||||||
|
private: true
|
||||||
|
confirm: true
|
||||||
|
tasks:
|
||||||
|
- name: Check OS requirements
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- ansible_distribution == 'Rocky'
|
||||||
|
- ansible_distribution_major_version in ['8', '9']
|
||||||
|
success_msg: >-
|
||||||
|
Host is running supported OS {{ ansible_distribution }} {{ ansible_distribution_version }}
|
||||||
|
fail_msg: >-
|
||||||
|
Unsupported operating system ({{ ansible_distribution }} {{ ansible_distribution_major_version }}),
|
||||||
|
only RockyLinux 8 and RockyLinux 9 are supported.
|
||||||
|
|
||||||
|
- name: Check that management keys are defined
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- skylab_mgmt is defined
|
||||||
|
- skylab_mgmt.sshkeys != []
|
||||||
|
success_msg: >-
|
||||||
|
Found {{ skylab_mgmt.sshkeys | length }} SSH keys to install to the Ansible management user
|
||||||
|
fail_msg: >-
|
||||||
|
No management keys were found for installation to the Ansible management user. Aborting to avoid
|
||||||
|
locking out SSH access to the boostrap host. Please define the 'skylab_mgmt.sshkeys' variable with
|
||||||
|
a list of SSH public keys to install to the Ansible management user.
|
||||||
|
|
||||||
|
- name: Install RockyLinux python bindings
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
state: present
|
||||||
|
name:
|
||||||
|
- libffi-devel
|
||||||
|
- python3-devel
|
||||||
|
- python3-libselinux
|
||||||
|
- python3-policycoreutils
|
||||||
|
- python3-firewall
|
||||||
|
|
||||||
|
- name: Create mgmt group
|
||||||
|
become: true
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ skylab_mgmt.group }}"
|
||||||
|
state: present
|
||||||
|
gid: "{{ skylab_mgmt.id }}"
|
||||||
|
|
||||||
|
- name: Generate mgmt user account password
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: >
|
||||||
|
command mpw -qq -F none -t max -u {{ skylab_mgmt.user }} {{ ansible_host }} -p <<<
|
||||||
|
'{{ skylab_ansible_vault_password }}' |
|
||||||
|
python3 -c 'import crypt; print(crypt.crypt(input(), crypt.mksalt(crypt.METHOD_SHA512)))'
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _password_mgmt
|
||||||
|
|
||||||
|
- name: Update mgmt user account
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ skylab_mgmt.user }}"
|
||||||
|
state: present
|
||||||
|
group: "{{ skylab_mgmt.group }}"
|
||||||
|
groups:
|
||||||
|
- "{{ skylab_mgmt.group }}"
|
||||||
|
- wheel
|
||||||
|
uid: "{{ skylab_mgmt.id }}"
|
||||||
|
password: "{{ _password_mgmt.stdout }}"
|
||||||
|
|
||||||
|
- name: Update mgmt user authorized keys
|
||||||
|
become: true
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ skylab_mgmt.user }}"
|
||||||
|
exclusive: true
|
||||||
|
key: "{{ skylab_mgmt.sshkeys | join('\n') }}"
|
||||||
|
|
||||||
|
- name: Remove mgmt user group
|
||||||
|
become: true
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ skylab_mgmt.user }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Update root user authorized keys
|
||||||
|
become: true
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: root
|
||||||
|
exclusive: true
|
||||||
|
key: ""
|
||||||
|
|
||||||
|
- name: Disable sudo password for WHEEL group
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "%wheel ALL=(ALL) NOPASSWD: ALL"
|
||||||
|
dest: /etc/sudoers.d/30-wheel
|
||||||
|
owner: root
|
||||||
|
group: "{{ skylab_mgmt.group }}"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Disable SSHD password auth
|
||||||
|
become: true
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^(#?)PasswordAuthentication .*$'
|
||||||
|
replace: PasswordAuthentication no
|
||||||
|
|
||||||
|
- name: Disable SSHD root login
|
||||||
|
become: true
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^(#?)PermitRootLogin .*$'
|
||||||
|
replace: PermitRootLogin no
|
||||||
|
|
||||||
|
- name: Update SSHD mgmt port
|
||||||
|
become: true
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^(#?)Port .*$'
|
||||||
|
replace: Port {{ skylab_mgmt.sshport }}
|
||||||
|
|
||||||
|
- name: Grant SSHD permissions on the mgmt port
|
||||||
|
become: true
|
||||||
|
community.general.seport:
|
||||||
|
ports: "{{ skylab_mgmt.sshport }}"
|
||||||
|
proto: tcp
|
||||||
|
setype: ssh_port_t
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install Firewalld
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: firewalld
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Enable Firewalld
|
||||||
|
become: true
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: firewalld
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Grant SSHD firewall access to the mgmt port
|
||||||
|
become: true
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
port: "{{ skylab_mgmt.sshport }}/tcp"
|
||||||
|
state: enabled
|
||||||
|
permanent: true
|
||||||
|
|
||||||
|
- name: Revoke SSHD firewall access to default port
|
||||||
|
become: true
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
service: ssh
|
||||||
|
permanent: true
|
||||||
|
state: disabled
|
||||||
|
|
||||||
|
- name: Update OS
|
||||||
|
become: true
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: "*"
|
||||||
|
state: latest
|
||||||
|
allowerasing: true
|
||||||
|
|
||||||
|
- name: Generate root user account password
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: >
|
||||||
|
command mpw -qq -F none -t max -u root {{ ansible_host }} -p <<<
|
||||||
|
'{{ skylab_ansible_vault_password }}' |
|
||||||
|
python3 -c 'import crypt; print(crypt.crypt(input(), crypt.mksalt(crypt.METHOD_SHA512)))'
|
||||||
|
executable: /bin/bash
|
||||||
|
register: _password_root
|
||||||
|
|
||||||
|
- name: Update root user account
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: root
|
||||||
|
state: present
|
||||||
|
password: "{{ _password_root.stdout }}"
|
||||||
|
|
||||||
|
- name: Create SkyLab directory
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
state: directory
|
||||||
|
path: "{{ skylab_state_dir }}"
|
||||||
|
owner: "{{ skylab_mgmt.user }}"
|
||||||
|
group: "{{ skylab_mgmt.group }}"
|
||||||
|
mode: 0750
|
||||||
46
skylab/infra/playbooks/cloud.yml
Normal file
46
skylab/infra/playbooks/cloud.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- name: Provision DigitalOcean cloud
|
||||||
|
hosts: localhost
|
||||||
|
vars:
|
||||||
|
terraform_backend: "postgres://{{ skylab_tfstate_backend.username }}:{{ skylab_tfstate_backend.password }}@{{ skylab_tfstate_backend.hostname }}:{{ skylab_tfstate_backend.port }}/{{ skylab_tfstate_backend.schema }}"
|
||||||
|
tasks:
|
||||||
|
- name: Deploy terraform config
|
||||||
|
block:
|
||||||
|
- name: Create temp plan file
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.tempfile:
|
||||||
|
state: file
|
||||||
|
prefix: skylab
|
||||||
|
suffix: tfplan
|
||||||
|
register: _tfplan_tempfile
|
||||||
|
|
||||||
|
# Generating a plan file before yeeting a deployment into the
|
||||||
|
# wind helps to ensure that the syntax is correct, backend and
|
||||||
|
# state are valid, and all the plumbing is working as expected.
|
||||||
|
# We don't want errors when we deploy, so it's better to
|
||||||
|
# generate the plan first
|
||||||
|
- name: Initialize terraform backend and generate plan file
|
||||||
|
community.general.terraform:
|
||||||
|
state: planned
|
||||||
|
project_path: terraform/
|
||||||
|
backend_config:
|
||||||
|
conn_str: "{{ terraform_backend }}"
|
||||||
|
force_init: true
|
||||||
|
init_reconfigure: true
|
||||||
|
plan_file: "{{ _tfplan_tempfile.path }}"
|
||||||
|
|
||||||
|
# TODO: update to take DO token from invocation args rather than
|
||||||
|
# implicit env var
|
||||||
|
- name: Apply terraform plan
|
||||||
|
community.general.terraform:
|
||||||
|
state: present
|
||||||
|
project_path: terraform/
|
||||||
|
backend_config:
|
||||||
|
conn_str: "{{ terraform_backend }}"
|
||||||
|
plan_file: "{{ _tfplan_tempfile.path }}"
|
||||||
|
always:
|
||||||
|
- name: Remove temp plan file
|
||||||
|
changed_when: false
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ _tfplan_tempfile.path }}"
|
||||||
|
state: absent
|
||||||
57
skylab/infra/playbooks/terraform/domain.allaroundhere.tf
Normal file
57
skylab/infra/playbooks/terraform/domain.allaroundhere.tf
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
resource "digitalocean_domain" "allaroundhere" {
|
||||||
|
name = "allaroundhere.org"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard hostname configuration
|
||||||
|
resource "digitalocean_record" "allaroundhere" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "A"
|
||||||
|
name = "@"
|
||||||
|
value = "24.2.156.189"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "allaroundhere_www" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "www"
|
||||||
|
value = "@"
|
||||||
|
ttl = 43200
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "allaroundhere_content" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "content"
|
||||||
|
value = "en1.enp.one."
|
||||||
|
ttl = 10300
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard DO configuration for all managed domains, includes
|
||||||
|
# NS records and SOA
|
||||||
|
resource "digitalocean_record" "allaroundhere_ns1" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns1.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "allaroundhere_ns2" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns2.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "allaroundhere_ns3" {
|
||||||
|
domain = digitalocean_domain.allaroundhere.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns3.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
200
skylab/infra/playbooks/terraform/domain.enp.tf
Normal file
200
skylab/infra/playbooks/terraform/domain.enp.tf
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
resource "digitalocean_domain" "enp" {
|
||||||
|
name = "enp.one"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard hostname configuration
|
||||||
|
resource "digitalocean_record" "enp" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "A"
|
||||||
|
name = "@"
|
||||||
|
value = "24.2.156.189"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_en1" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "A"
|
||||||
|
name = "en1"
|
||||||
|
value = digitalocean_record.enp.value
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Service CNAME configuration
|
||||||
|
resource "digitalocean_record" "enp_vcs" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "vcs"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_ssv" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "ssv"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_pms" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "pms"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_cdn" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "cdn"
|
||||||
|
value = "${digitalocean_cdn.enp.endpoint}."
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_vpn" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "vpn"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_www" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "www"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_sso" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "sso"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_img" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "img"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard DO configuration for all managed domains, includes
|
||||||
|
# NS records and SOA
|
||||||
|
resource "digitalocean_record" "enp_ns1" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns1.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_ns2" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns2.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_ns3" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns3.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# DMARC and HTTPS security configuration
|
||||||
|
resource "digitalocean_record" "enp_dmarc" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "TXT"
|
||||||
|
name = "_dmarc"
|
||||||
|
value = "v=DMARC1; p=quarantine; adkim=s"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_caa" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CAA"
|
||||||
|
name = "@"
|
||||||
|
value = "letsencrypt.org."
|
||||||
|
ttl = 3600
|
||||||
|
tag = "issue"
|
||||||
|
flags = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_iodef" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CAA"
|
||||||
|
name = "@"
|
||||||
|
value = "mailto:admin@enp.one"
|
||||||
|
ttl = 3600
|
||||||
|
tag = "iodef"
|
||||||
|
flags = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Tutanota mailer integration configuration
|
||||||
|
resource "digitalocean_record" "enp_mx" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "MX"
|
||||||
|
name = "@"
|
||||||
|
value = "mail.tutanota.de."
|
||||||
|
ttl = 3600
|
||||||
|
priority = 1010
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_spf" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "TXT"
|
||||||
|
name = "@"
|
||||||
|
value = "v=spf1 include:spf.tutanota.de -all"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_domainkey1" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "s1._domainkey"
|
||||||
|
value = "s1._domainkey.tutanota.de."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_domainkey2" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "s2._domainkey"
|
||||||
|
value = "s2._domainkey.tutanota.de."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_mta1" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "_mta-sts"
|
||||||
|
value = "_mta-sts.tutanota.com."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enp_mta2" {
|
||||||
|
domain = digitalocean_domain.enp.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "mta-sts"
|
||||||
|
value = "mta-sts.tutanota.com."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
123
skylab/infra/playbooks/terraform/domain.enpaul.tf
Normal file
123
skylab/infra/playbooks/terraform/domain.enpaul.tf
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
resource "digitalocean_domain" "enpaul" {
|
||||||
|
name = "enpaul.net"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard hostname configuration
|
||||||
|
resource "digitalocean_record" "enpaul" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "A"
|
||||||
|
name = "@"
|
||||||
|
value = digitalocean_record.enp.value
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_www" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "www"
|
||||||
|
value = "@"
|
||||||
|
ttl = 10800
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard DO configuration for all managed domains, includes
|
||||||
|
# NS records and SOA
|
||||||
|
resource "digitalocean_record" "enpaul_ns1" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns1.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_ns2" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns2.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_ns3" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns3.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# DMARC and HTTPS security configuration
|
||||||
|
resource "digitalocean_record" "enpaul_dmarc" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "TXT"
|
||||||
|
name = "_dmarc"
|
||||||
|
value = "v=DMARC1; p=quarantine; adkim=s"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_caa" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CAA"
|
||||||
|
name = "@"
|
||||||
|
value = "letsencrypt.org."
|
||||||
|
ttl = 3600
|
||||||
|
tag = "issue"
|
||||||
|
flags = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Tutanota mailer integration configuration
|
||||||
|
resource "digitalocean_record" "enpaul_mx" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "MX"
|
||||||
|
name = "@"
|
||||||
|
value = "mail.tutanota.de."
|
||||||
|
ttl = 3600
|
||||||
|
priority = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_spf" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "TXT"
|
||||||
|
name = "@"
|
||||||
|
value = "v=spf1 include:spf.tutanota.de -all"
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_domainkey1" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "s1._domainkey"
|
||||||
|
value = "s1._domainkey.tutanota.de."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_domainkey2" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "s2._domainkey"
|
||||||
|
value = "s2._domainkey.tutanota.de."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_mta1" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "_mta-sts"
|
||||||
|
value = "_mta-sts.tutanota.com."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "enpaul_mta2" {
|
||||||
|
domain = digitalocean_domain.enpaul.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "mta-sts"
|
||||||
|
value = "mta-sts.tutanota.com."
|
||||||
|
ttl = 10600
|
||||||
|
}
|
||||||
72
skylab/infra/playbooks/terraform/domain.scipiocapital.tf
Normal file
72
skylab/infra/playbooks/terraform/domain.scipiocapital.tf
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
resource "digitalocean_domain" "scipiocapital" {
|
||||||
|
name = "scipiocapital.us"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard hostname configuration
|
||||||
|
resource "digitalocean_record" "scipiocapital" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "A"
|
||||||
|
name = "@"
|
||||||
|
value = digitalocean_record.enp.value
|
||||||
|
ttl = 3600
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_app" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "app"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 43200
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_notify" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "notify"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 43200
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_docs" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "docs"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 43200
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_auth" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "CNAME"
|
||||||
|
name = "auth"
|
||||||
|
value = "${digitalocean_record.enp_en1.fqdn}."
|
||||||
|
ttl = 43200
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
# Standard DO configuration for all managed domains, includes
|
||||||
|
# NS records and SOA
|
||||||
|
resource "digitalocean_record" "scipiocapital_ns1" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns1.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_ns2" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns2.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_record" "scipiocapital_ns3" {
|
||||||
|
domain = digitalocean_domain.scipiocapital.id
|
||||||
|
type = "NS"
|
||||||
|
name = "@"
|
||||||
|
value = "ns3.digitalocean.com."
|
||||||
|
ttl = 1800
|
||||||
|
}
|
||||||
10
skylab/infra/playbooks/terraform/main.tf
Normal file
10
skylab/infra/playbooks/terraform/main.tf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
terraform {
|
||||||
|
backend "pg" {}
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
digitalocean = {
|
||||||
|
source = "digitalocean/digitalocean"
|
||||||
|
version = "~> 2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
skylab/infra/playbooks/terraform/project.scipio.tf
Normal file
13
skylab/infra/playbooks/terraform/project.scipio.tf
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
resource "digitalocean_project" "scipio" {
|
||||||
|
name = "Scipio Capital"
|
||||||
|
description = "Eventual home of Scipio Capital systems"
|
||||||
|
purpose = "Service or API"
|
||||||
|
environment = "Production"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_project_resources" "scipio" {
|
||||||
|
project = digitalocean_project.scipio.id
|
||||||
|
resources = [
|
||||||
|
digitalocean_domain.scipiocapital.urn,
|
||||||
|
]
|
||||||
|
}
|
||||||
17
skylab/infra/playbooks/terraform/project.skylab.tf
Normal file
17
skylab/infra/playbooks/terraform/project.skylab.tf
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
resource "digitalocean_project" "skylab" {
|
||||||
|
name = "SkyLab"
|
||||||
|
description = "SkyLab resources, with emphasis on Sky"
|
||||||
|
purpose = "Operational / Developer tooling"
|
||||||
|
environment = "Development"
|
||||||
|
is_default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_project_resources" "skylab" {
|
||||||
|
project = digitalocean_project.skylab.id
|
||||||
|
resources = [
|
||||||
|
digitalocean_domain.allaroundhere.urn,
|
||||||
|
digitalocean_domain.enpaul.urn,
|
||||||
|
digitalocean_domain.enp.urn,
|
||||||
|
digitalocean_spaces_bucket.enp_cdn.urn
|
||||||
|
]
|
||||||
|
}
|
||||||
18
skylab/infra/playbooks/terraform/spaces.cdn.tf
Normal file
18
skylab/infra/playbooks/terraform/spaces.cdn.tf
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
resource "digitalocean_spaces_bucket" "enp_cdn" {
|
||||||
|
name = "en2-cdn"
|
||||||
|
region = "nyc3"
|
||||||
|
acl = "public-read"
|
||||||
|
force_destroy = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_certificate" "enp_cdn" {
|
||||||
|
name = "CDN"
|
||||||
|
type = "lets_encrypt"
|
||||||
|
domains = ["cdn.enp.one", "enp.one"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "digitalocean_cdn" "enp" {
|
||||||
|
origin = digitalocean_spaces_bucket.enp_cdn.bucket_domain_name
|
||||||
|
custom_domain = "cdn.enp.one"
|
||||||
|
certificate_name = digitalocean_certificate.enp_cdn.name
|
||||||
|
}
|
||||||
44
tox.ini
Normal file
44
tox.ini
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
[tox]
|
||||||
|
envlist = ansible, security
|
||||||
|
skipsdist = true
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
require_locked_deps = true
|
||||||
|
require_poetry = true
|
||||||
|
setenv =
|
||||||
|
ANSIBLE_CONFIG = {toxinidir}/ansible.cfg
|
||||||
|
whitelist_externals =
|
||||||
|
bash
|
||||||
|
|
||||||
|
[testenv:ansible]
|
||||||
|
description = Lint ansible resources
|
||||||
|
locked_deps =
|
||||||
|
ansible-core
|
||||||
|
ansible-lint
|
||||||
|
yamllint
|
||||||
|
pre-commit
|
||||||
|
pre-commit-hooks
|
||||||
|
mdformat
|
||||||
|
mdformat-gfm
|
||||||
|
commands =
|
||||||
|
yamllint --config-file {toxinidir}/.yamllintrc.yaml \
|
||||||
|
{toxinidir}/skylab/ \
|
||||||
|
{toxinidir}/inventory.yaml \
|
||||||
|
{toxinidir}/requirements.yaml
|
||||||
|
bash -c "ansible-lint -c {toxinidir}/.ansible-lint.yaml \
|
||||||
|
{toxinidir}/skylab/*/playbooks/"
|
||||||
|
pre-commit run --all-files
|
||||||
|
|
||||||
|
[testenv:security]
|
||||||
|
description = Check security parameters
|
||||||
|
ignore_errors = true
|
||||||
|
locked_deps =
|
||||||
|
poetry
|
||||||
|
safety
|
||||||
|
commands =
|
||||||
|
poetry export --format requirements.txt --without-hashes --with dev --output {envtmpdir}/req.txt
|
||||||
|
safety check --output text --file {envtmpdir}/req.txt \
|
||||||
|
# Ignore unfixed CVE-2021-3532 from ansible \
|
||||||
|
--ignore 42923 \
|
||||||
|
# https://github.com/pytest-dev/py/issues/287#issuecomment-1283567565
|
||||||
|
--ignore 51457
|
||||||
Reference in New Issue
Block a user