Compare commits
	
		
			63 Commits
		
	
	
		
			9cd0cfcb4f
			...
			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 | 
							
								
								
									
										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,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