Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5b0cedc
Added Google Cloud Platform support to `machine_operations` & `connec…
AllRWeak Jun 22, 2026
868e791
Added Google Cloud support to `powerstate` role
AllRWeak Jun 22, 2026
0b32af9
Using custom heatlcheck for `gitlab` to really wait for it to be running
AllRWeak Jun 25, 2026
08f9668
Set WSL version to 2.7.10 in `docker` role
AllRWeak Jun 26, 2026
d30efb6
Set `nexus` version to 3.93.2
AllRWeak Jun 26, 2026
a713ee7
Set `keycloak` version to 26.6.4
AllRWeak Jun 28, 2026
92efd5a
Redsesigned the Providentia inventory plugin creds lookup so the most…
AllRWeak Jun 29, 2026
4b7f693
Removed unneeded OPNsense auth configuration tasks from `template_os_…
AllRWeak Jun 29, 2026
ce13296
Added OPNsense and pfSense support to `updates` role
AllRWeak Jun 29, 2026
44383ad
Added support to new kali.sources format to `configure_package_mirrors`
AllRWeak Jun 30, 2026
b41d066
Set WSL version to 2.9.3 in `docker` role
AllRWeak Jun 30, 2026
b27e23b
Fixed an issue where `nova.core.addresses` did not always report corr…
AllRWeak Jun 30, 2026
a066fc6
Printing an error when EC2 image is not found
AllRWeak Jul 1, 2026
2099bc3
Using a raw reboot command when cleaning up stale MacOS accounts
AllRWeak Jul 1, 2026
5c5cd1e
Allowing custom UPN to be set for AD user with the `accounts` role
AllRWeak Jul 2, 2026
ccdcc9f
Fixed an issue where `trusted_certificates` failed for MacOS when src…
AllRWeak Jul 3, 2026
3af83be
Added extra up check for `gitlab` to improve fresh deploy stability
AllRWeak Jul 7, 2026
535190e
Trying to run updates again on rescue when installing Gnome or Xfce o…
AllRWeak Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nova/core/galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace: nova
name: core
version: 11.0.1
version: 11.0.3
readme: README.md
authors:
- https://github.com/novateams
Expand Down
4 changes: 2 additions & 2 deletions nova/core/plugins/filter/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def get_mgmt_addresses(self, interfaces, interface_type, mode):
for interface in interfaces:
if interface.get(interface_type):
for address in interface.get('addresses', []):
if self.validate_mgmt_address(address, mode) and re.match(r'^mgmt-.*', address['pool_id']):
if self.validate_mgmt_address(address, mode):
address_val = address['address']
addresses.append(address_val if address_val else 'null') # Append 'null' if address is an empty string
return addresses
Expand All @@ -208,7 +208,7 @@ def get_connection_address_info(self, interfaces):
return address_info

def validate_address(self, address, mode):
return address.get('mode') == mode and address.get('address') and address.get('pool_id').startswith('default-')
return address.get('mode') == mode and address.get('address')

def validate_mgmt_address(self, address, mode):
return address.get('mode') == mode and address.get('address') and address.get('pool_id').startswith('mgmt-')
Expand Down
13 changes: 7 additions & 6 deletions nova/core/plugins/inventory/providentia_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,21 +230,22 @@ async def fetch_from_providentia(self, endpoint=""):
def fetch_creds(self):
"""
Retrieve deployer credentials from Ansible Vault in the following order of precedence:
1. Environment specific credentials eg. dev_providentia_api_token or dev_deployer_username and dev_deployer_password
1. Environment and project specific credentials eg. dev_projectA_providentia_api_token or dev_projectA_deployer_username and dev_projectA_deployer_password
2. Project specific credentials eg. projectA_providentia_api_token or projectA_deployer_username and projectA_deployer_password
3. Environment and project specific credentials eg. dev_projectA_providentia_api_token or dev_projectA_deployer_username and dev_projectA_deployer_password
3. Environment specific credentials eg. dev_providentia_api_token or dev_deployer_username and dev_deployer_password

4. Default credentials eg. providentia_api_token or deployer_username and deployer_password

API token is preferred over username/password when both are available.
"""
# Build prefixes in precedence order
prefixes = []
if self.environment:
prefixes.append((f"{self.environment}_", 'env_'))
if self.project:
prefixes.append((f"{self.project}_", 'project_'))
if self.environment and self.project:
prefixes.append((f"{self.environment}_{self.project}_", 'project_'))
if self.project:
prefixes.append((f"{self.project}_", 'project_'))
if self.environment:
prefixes.append((f"{self.environment}_", 'env_'))

# Check for API token first (preferred over username/password)
for option_prefix, inv_prefix in prefixes:
Expand Down
31 changes: 9 additions & 22 deletions nova/core/roles/accounts/tasks/macos_remove.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
# Filtering out empty lines
- name: Getting profiles not defined in accounts list...
ansible.builtin.set_fact:
user_profiles_to_remove: "{{ home_profiles.stdout_lines | select('string') | select('regex', '.+')
user_profiles_to_remove:
"{{ home_profiles.stdout_lines | select('string') | select('regex', '.+')
| difference(local_accounts_with_password | map(attribute='username')) }}"

- name: Removing stale user accounts and profiles...
Expand All @@ -28,28 +29,14 @@
rescue:
- name: Handling reboot before removing accounts...
when: accounts_reboot_before_remove | bool
delegate_to: localhost
become: false
block:
- name: Restarting {{ custom_vm_name | default(vm_name) }} VM...
ansible.builtin.include_role:
name: nova.core.powerstate
vars:
restart: true

- name: Waiting until ssh is down for {{ inventory_hostname }}...
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 22
state: stopped
timeout: 300

- name: Waiting until ssh is up for {{ inventory_hostname }}...
ansible.builtin.wait_for:
host: "{{ ansible_host }}"
port: 22
state: started
timeout: 300
- name: Rebooting
ansible.builtin.raw: reboot
changed_when: true
# Running reboot from ansible.builtin.raw can cause a race condition where the task is marked as failed
# because the connection is lost before the reboot command completes.
# To avoid this, we can ignore unreachable hosts after issuing the reboot command.
ignore_unreachable: true

- name: Removing following accounts...
ansible.builtin.raw: |
Expand Down
11 changes: 10 additions & 1 deletion nova/core/roles/accounts/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
when: ansible_facts.system | default('') == "Darwin"
or ansible_custom_facts.system | default('') == "Darwin"

# Cloud temp keys removal
# Cloud temp SSH keys removal
- name: Removing {{ infra_env }} temp ssh key for {{ inventory_hostname }}...
ansible.builtin.file:
path: "{{ lookup('vars', 'machine_operations_' ~ infra_env ~ '_temp_ssh_key_path') | default('') }}"
Expand All @@ -113,6 +113,15 @@
become: false
when: lookup('vars', 'machine_operations_' ~ infra_env ~ '_temp_ssh_key_path') is defined

# Cloud temp SSHD config removal
- name: Removing {{ infra_env }} temp SSHD config for {{ inventory_hostname }}...
ansible.builtin.file:
path: "{{ lookup('vars', 'machine_operations_' ~ infra_env ~ '_temp_sshd_config_path') | default('') }}"
state: absent
when:
- ansible_facts.system | default('') in ["FreeBSD", "Linux"]
- lookup('vars', 'machine_operations_' ~ infra_env ~ '_temp_sshd_config_path') is defined

- name: Including following accounts post-roles...
ansible.builtin.include_role:
name: "{{ account_post_role }}"
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/accounts/tasks/windows_create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
spn: "{{ item.spn | default(omit) }}" # https://docs.ansible.com/ansible/latest/collections/microsoft/ad/user_module.html#parameter-spn
state: present
update_password: "{{ item.update_password | default('always') }}" # always, on_create or when_changed
upn: "{{ item.username }}@{{ ad_domain_name }}"
upn: "{{ item.upn | default(item.username ~ '@' ~ ad_domain_name) }}"
groups:
add: "{{ item.groups | default(windows_domain_admin_groups if item.username in admin_accounts | map(attribute='username') else omit) }}"
register: win_domain_user
Expand Down
66 changes: 49 additions & 17 deletions nova/core/roles/configure_package_mirrors/tasks/kali.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,58 @@
---
- name: Checking if sources.list backup exists...
- name: Checking if kali.sources is used...
ansible.builtin.stat:
path: /etc/apt/sources.list_backup
register: apt_backup_file
path: /etc/apt/sources.list.d/kali.sources
register: kali_sources

- name: Backing up existing sources.list...
ansible.builtin.copy:
src: /etc/apt/sources.list
dest: /etc/apt/sources.list_backup
remote_src: true
mode: "0644"
when: not apt_backup_file.stat.exists
- name: Configuring kali.sources...
when: kali_sources.stat.exists
block:
- name: Checking if /etc/apt/kali.sources_backup exists...
ansible.builtin.stat:
path: /etc/apt/kali.sources_backup
register: kali_sources_backup

- name: Templating custom kali.list to {{ inventory_hostname }}...
ansible.builtin.template:
src: kali-sources.list
dest: /etc/apt/sources.list
mode: "0644"
register: apt_sources
- name: Backing up existing kali.sources...
ansible.builtin.copy:
src: /etc/apt/sources.list.d/kali.sources
dest: /etc/apt/kali.sources_backup
remote_src: true
mode: "0644"
when: not kali_sources_backup.stat.exists

- name: Templating custom kali.sources to {{ inventory_hostname }}...
ansible.builtin.template:
src: kali.sources
dest: /etc/apt/sources.list.d/kali.sources
mode: "0644"
register: kali_sources_templated

- name: Configuring sources.list...
when: not kali_sources.stat.exists
block:
- name: Checking if sources.list backup exists...
ansible.builtin.stat:
path: /etc/apt/sources.list_backup
register: apt_backup_file

- name: Backing up existing sources.list...
ansible.builtin.copy:
src: /etc/apt/sources.list
dest: /etc/apt/sources.list_backup
remote_src: true
mode: "0644"
when: not apt_backup_file.stat.exists

- name: Templating custom kali.list to {{ inventory_hostname }}...
ansible.builtin.template:
src: kali-sources.list
dest: /etc/apt/sources.list
mode: "0644"
register: list_apt_sources

- name: Running apt update... # noqa: no-handler
ansible.builtin.apt:
update_cache: true
retries: 2
when: apt_sources.changed
when: list_apt_sources.changed | default(false)
or kali_sources_templated.changed | default(false)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# The original kali.sources is backed up as /etc/apt/kali.sources_backup

Types: deb
URIs: {{ package_mirror_kali_uri.general }}
Suites: kali-rolling
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/kali-archive-keyring.gpg
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/aws.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- name:
Connecting as {{ aws_template_username | default(template_username) if fresh_deploy else ansible_deployer_username
}} to {{ inventory_hostname }} using {{ ansible_connection | default('ssh') | upper
}} over {{ connection_address_custom | default(connection_address) }}... # noqa: name[template]
}} over {{ connection_address_custom | default(connection_address) }} # noqa: name[template]
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ aws_template_username | default(template_username) if fresh_deploy else ansible_deployer_username }}"
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/azure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Connecting as {{ azure_template_username if fresh_deploy else ansible_deployer_username }}
to {{ inventory_hostname }}
using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(connection_address) }}...
over {{ connection_address_custom | default(connection_address) }}
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ azure_template_username if fresh_deploy else ansible_deployer_username }}"
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/external.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- name: Connecting as {{ ansible_deployer_username }}
to {{ inventory_hostname }}
using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(connection_address) }}...
over {{ connection_address_custom | default(connection_address) }}
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ ansible_deployer_username }}"
Expand Down
13 changes: 13 additions & 0 deletions nova/core/roles/connection/tasks/google.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name:
Connecting as {{ template_username | default(admin_account) if fresh_deploy else ansible_deployer_username }}
to {{ inventory_hostname }} using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(connection_address) }}
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ template_username | default(admin_account) if fresh_deploy else ansible_deployer_username }}"
ansible_password: "{{ template_password if fresh_deploy else omit if connection_no_password else ansible_deployer_password }}"

# Initial connection will forced to password to bypass default SSHD config
ansible_ssh_extra_args: "{{ connection_custom_ansible_ssh_extra_args
| default('-o PreferredAuthentications=password' if fresh_deploy else omit) }}"
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/linode.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- name:
Connecting as {{ template_username if fresh_deploy else ansible_deployer_username }}
to {{ inventory_hostname }} using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(connection_address) }}...
over {{ connection_address_custom | default(connection_address) }}
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ template_username if fresh_deploy else ansible_deployer_username }}"
Expand Down
20 changes: 12 additions & 8 deletions nova/core/roles/connection/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
---
- name: Configuring VM connection in vSphere environment...
ansible.builtin.include_tasks: vsphere.yml
when: infra_env == 'vsphere'
when: infra_env == "vsphere"

- name: Configuring VM connection in VMware Workstation environment...
ansible.builtin.include_tasks: vmware_workstation.yml
when: infra_env == "vmware_workstation"

- name: Configuring connection for your host... # The laptop or desktop you are running Ansible from
ansible.builtin.include_tasks: my_host.yml
when: infra_env == 'my_host'
when: infra_env == "my_host"

- name: Configuring connection in AWS environment...
ansible.builtin.include_tasks: aws.yml
when: infra_env == 'aws'
when: infra_env == "aws"

- name: Configuring connection in Azure environment...
ansible.builtin.include_tasks: azure.yml
when: infra_env == 'azure'
when: infra_env == "azure"

- name: Configuring connection in Linode environment...
ansible.builtin.include_tasks: linode.yml
when: infra_env == 'linode'
when: infra_env == "linode"

- name: Configuring connection in Proxmox environment...
ansible.builtin.include_tasks: proxmox.yml
when: infra_env == 'proxmox'
when: infra_env == "proxmox"

- name: Configuring connection in OpenStack environment...
ansible.builtin.include_tasks: openstack.yml
when: infra_env == 'openstack'
when: infra_env == "openstack"

- name: Configuring connection in Google Cloud environment...
ansible.builtin.include_tasks: google.yml
when: infra_env == "google"

- name: Configuring connection for external or pre-existing machine...
ansible.builtin.include_tasks: external.yml
when: infra_env == 'external'
when: infra_env == "external"

# Setting PanOS connection parameters here because the correct ansible_host is calculated no matter what infra_env is used
- name: Setting connection parameters for PanOS {{ inventory_hostname }}...
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/openstack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
- name:
Connecting as {{ openstack_template_username | default(template_username) if fresh_deploy else ansible_deployer_username
}} to {{ inventory_hostname }} using {{ ansible_connection | default('ssh') | upper
}} over {{ connection_address_custom | default(connection_address) }}... # noqa: name[template]
}} over {{ connection_address_custom | default(connection_address) }} # noqa: name[template]
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ openstack_template_username | default(template_username) if fresh_deploy else ansible_deployer_username }}"
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/connection/tasks/proxmox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
- name:
Connecting as {{ template_username if fresh_deploy else ansible_deployer_username }} to {{ inventory_hostname }}
using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(connection_address) }}... # noqa: name[template]
over {{ connection_address_custom | default(connection_address) }} # noqa: name[template]
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(connection_address) }}"
ansible_user: "{{ template_username if fresh_deploy else ansible_deployer_username }}"
Expand Down
4 changes: 2 additions & 2 deletions nova/core/roles/connection/tasks/vsphere.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
Connecting as {{ template_username if fresh_deploy else ansible_deployer_username }}
to {{ inventory_hostname }}
using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) }}...
over {{ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) }}
ansible.builtin.set_fact:
ansible_host: "{{ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) }}"
ansible_user: "{{ template_username if fresh_deploy else ansible_deployer_username }}"
Expand All @@ -41,7 +41,7 @@

- name: Connecting to {{ inventory_hostname }}
using {{ ansible_connection | default('ssh') | upper }}
over {{ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) }}... # noqa: name[template] jinja[invalid]
over {{ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) }} # noqa: name[template] jinja[invalid]
ansible.builtin.set_fact:
ansible_host:
"{{ '[' ~ connection_address_custom | default(detect_dhcp.instance.guest.ipAddress) | default(connection_address) ~ ']'
Expand Down
21 changes: 21 additions & 0 deletions nova/core/roles/deploy_vars/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,27 @@ openstack_defaults:
| default(openstack_project_domain_name)
| default('Default') }}"

################
# Google Cloud #
################

# The content of the service account is the base64 encoded in the json file downloaded from Google Cloud Console.
# Use base64 -w 0 <service_account_file.json> to encode the file content to base64 and then save it to Ansible Vault
google_cloud_service_account:
"{{ lookup('vars', environment_name | default('') ~ '_gc_service_account')
| default(lookup('vars', project_fullname | default('') ~ '_gc_service_account'))
| default(lookup('vars', environment_name | default('') ~ '_' ~ project_fullname | default('') ~ '_gc_service_account'))
| default(gc_service_account) | default('') }}"

# Zone and Region are not in module_defaults since not all modules require them and these modules fail if they are in defaults
google_cloud_zone: europe-north1-b
google_cloud_region: europe-north1

google_cloud_defaults:
auth_kind: serviceaccount
project: "{{ google_cloud_project_id | default('') }}"
service_account_contents: "{{ google_cloud_service_account | b64decode }}"

###########
# FortiOS #
###########
Expand Down
2 changes: 1 addition & 1 deletion nova/core/roles/deploy_vars/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
when: deploy_vars_pre_roles != []

- name: Delegating required tasks to localhost...
delegate_to: localhost
become: false
delegate_to: localhost
block:
- name: Using {{ deploy_vars_vault_auth_method | upper }} to get auth token for {{ vault_address }}...
community.hashi_vault.vault_login:
Expand Down
Loading