Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions servers/maas/00-get-ca-certs-commission.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
#
# 00-get-ca-certs-commission.sh - Get CA and casub from Artifactory
#
# --- Start MAAS 1.0 script metadata ---
# name: 00-get-ca-certs-commission.sh
# title: Get CA and casub from Artifactory
# description: Get CA and casub from Artifactory
# tags: comissioning
# script_type: commissioning
# --- End MAAS 1.0 script metadata --

mkdir -p /usr/local/share/ca-certificates
wget --no-check-certificate -O /usr/local/share/ca-certificates/nso-casub21.crt https://artifactory.company.com/artifactory/generic-local/com//ca-certificates/our-casub.crt
wget --no-check-certificate -O /usr/local/share/ca-certificates/RootCA.crt https://artifactory.company.com/artifactory/generic-local/com/ca-certificates/RootCA.cer
touch /etc/apt/apt.conf.d/99verify-peer.conf
echo "Acquire { https::Verify-Peer false }" >> /etc/apt/apt.conf.d/99verify-peer.conf
apt update && apt install -y ca-certificates
update-ca-certificates
75 changes: 75 additions & 0 deletions servers/maas/45-set-lvm-layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
#
# 45-set-lvm-layout - Commissioning script to set custom LVM layout
#
# --- Start MAAS 1.0 script metadata ---
# name: 45-set-lvm-layout
# title: Set LVM layout
# description: Set LVM layout
# script_type: commissioning
# timeout: 60
# --- End MAAS 1.0 script metadata ---

import json
import os
import sys

def read_json_file(path):
try:
with open(path) as fd:
return json.load(fd)
except OSError as e:
sys.exit(f"Failed to read {path}: {e}")
except json.JSONDecodeError as e:
sys.exit(f"Failed to parse {path}: {e}")

# Read the hardware data from MAAS_RESOURCES_FILE. You can parse the info in it, but this script only sets it so that we can write our static data into it.
hardware = read_json_file(os.environ["MAAS_RESOURCES_FILE"])

# Create hardcoded JSON structure for storage layout on sda
# - Partition #1 => 536M FAT32 for EFI
# - Partition #2 => 479G for LVM

storage_layout = '''{
"layout": {
"sda": {
"type": "disk",
"ptable": "gpt",
"boot": true,
"partitions": [
{ "name": "sda1", "fs": "fat32", "size": "536M", "bootable": true },
{ "name": "sda2", "size": "479G" }
]
},
"vg-root": {
"type": "lvm",
"members": [ "sda2" ],
"volumes": [
{ "name": "lv-root", "size": "50G", "fs": "ext4" },
{ "name": "lv-var", "size": "20G", "fs": "ext4" },
{ "name": "lv-var-lib", "size": "70G", "fs": "ext4" },
{ "name": "lv-run", "size": "30G", "fs": "ext4" }
]
}
},
"mounts": {
"/": { "device": "lv-root" },
"/var": { "device": "lv-var" },
"/var/lib": { "device": "lv-var-lib" },
"/run": { "device": "lv-run" },
"/boot/efi": { "device": "sda1" }
}
}'''

# Load the above JSON template as a Python object
layoutDetail = json.loads(storage_layout)

# Put the layout into hardware["storage-extra"], which MAAS will read
hardware["storage-extra"] = layoutDetail

print("Saving custom storage layout to", os.environ["MAAS_RESOURCES_FILE"])
print(json.dumps(hardware))

# Write the updated hardware JSON back to MAAS_RESOURCES_FILE
with open(os.environ["MAAS_RESOURCES_FILE"], "w") as file:
json.dump(hardware, file)
92 changes: 92 additions & 0 deletions servers/maas/cloud-init.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#cloud-config

# Example cloud init userdata script that sets a machine to a certain well known state.

## Create "devops" user with sudo privileges and SSH key access
users:
- name: devops
gecos: Devops User
sudo: ['ALL=(ALL) NOPASSWD:ALL']
passwd: "{{ 'REPLACE_DEVOPS_PASSWORD_HERE' | password_hash('sha512') }}"
groups: sudo
lock_passwd: false
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa AAAAB3NzXXXXX...XXXXGls7 devops@allhosts

runcmd:
- mkdir -p /home/devops/.ssh
- chown -R devops:devops /home/devops/.ssh
- chmod 0700 /home/devops/.ssh
- chmod 0600 /home/devops/.ssh/authorized_keys

## Get builduser SSH key for cloning infra baseline
write_files:
- path: /root/.ssh/builduser
content: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAv2sPNEAhEljA1KlGjfJz1b96A+a22Xfpa9Q98nWtE74LtYH8

REDACTED! REPLACE THIS WITH THE ACTUAL VALUE BEFORE RUNNING!

1Bwg3GRwRyM1jlwyrOrqgfbwmLBS4EnuLA+VuVSn6G5ujT8RAYUj2Q==
-----END RSA PRIVATE KEY-----
permissions: '0600'
- path: /home/kcaps//.ssh/config
content: |
Host github.com
IdentityFile = /home/kcaps/.ssh/id_rsa
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
StrictHostKeyChecking no
permissions: '0600'
- path: /home/kcaps/vault-pass
content: |
REPLACE_DEVOPS_PASSWORD_HERE
permissions: '0600'
- path: /root/inventory.yaml
content: |
---
all:
vars:
children:
ubuntu:
vars:
ansible_user: root
ansible_python_interpreter: "/usr/bin/python3"
children:
baseline:
hosts:
baseline:
ansible_host: localhost
ansible_connection: local
permissions: '0644'
- path: /root/cloud-init-final.sh
content: |
#!/bin/bash

## Setup custom certificates & disable SSL verification for APT
echo 'Acquire { https::Verify-Peer false }' > /etc/apt/apt.conf.d/99verify-peer.conf
chmod 0644 /etc/apt/apt.conf.d/99verify-peer.conf
mkdir -p /usr/local/share/ca-certificates
wget --no-check-certificate -O /usr/local/share/ca-certificates/nso-casub21.crt https://artifactory.company.com/artifactory/generic-local/ca-certificates/our-casub.crt
apt update
apt install -y ca-certificates
update-ca-certificates

# Clone, adapt, and run Infra baseline on localhost
GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=no"
git clone ssh://git@github.nsogroup.com/k-caps/scripts.git /home/kcaps/maas/scripts
mv /home/kcaps/maas/inventory.yaml /home/kcaps/maas/scripts/inventory.yaml
mv /home/kcaps/maas/vault-pass /home/kcaps/maas/scripts/vault-pass

apt install -y ansible
cd /home/kcaps/maas/scripts/
ansible-playbook /home/kcaps/maas/scripts/playbooks/deploy_baseline.yml -i /home/kcaps/maas/scripts/inventory.yaml -b --vault-pass-file /home/kcaps/maas/scripts/vault-pass
apt remove -y ansible
rm -rf /home/kcaps/maas/scripts/
rm -f /etc/apt/apt.conf.d/99verify-peer.conf
permissions: '0744'

runcmd:
- bash /root/cloud-init-final.sh
75 changes: 75 additions & 0 deletions servers/maas/deploy-machine.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "You must supply a machine name, such as 'homelab-k8s-worker-02'"
exit 1
fi

WORKDIR=/home/kcaps/maas

echo "Logging into MAAS API..."
maas login admin http://127.0.0.1:5240/MAAS/api/2.0 Lh8KUcfGZpgMmmzVd4:5J9skJbb2TuD3VKjxn:nRx6aPYaHGdfiduywmk7eRNn4YG4jZ

# Get machine ID by name
mids() {
maas admin machines read | jq -r '(["HOSTNAME","SYSID"] | (., map(length*"-"))),(.[] | [.hostname, .system_id]) | @tsv' | column -t
}
getmid() {
mids | grep $1 | awk '{print $2}'
}
machine_id=$(getmid $1)
check_deploy_status() {
maas admin machine read $machine_id | jq -r .status_name
}


echo "Machine ID for $1 is: $machine_id"

echo "Disabling Swap for $1"
maas admin machine update $machine_id swap_size=0 > /dev/null

# If there is eth0, rename it to vnic1 - to deploy we need vnic1 vnic2 and bond0 linking them
echo "Reading interface names for machine $machine_id..."
interface_names=$(maas admin interfaces read "$machine_id" | jq -r '.[].name')
interface_count=$(echo "$interface_names" | wc -l)

if [[ "$interface_count" -eq 1 && "$interface_names" == "eth0" ]]; then
echo "Renaming default interface from eth0 to vnic1"
maas admin interface update $machine_id eth0 name=vnic1 > /dev/null

echo "Getting vnic2 MAC from mapping file ($WORKDIR/machine_mac_addresses.txt).."
vnic2_mac_address=$(grep $1 machine_mac_addresses.txt | awk '{print $5}')
echo "vnic2 MAC address: $vnic2_mac_address"

echo "Creating second interface:"
maas admin interfaces create-physical $machine_id name=vnic2 mac_address=$vnic2_mac_address vlan=2 > /dev/null
maas admin interface link-subnet $machine_id vnic2 mode=LINK_UP subnet=2 > /dev/null
maas admin interface update $machine_id vnic2 link_connected=True > /dev/null
fi

# Start bond creation procedure
if [[ "$interface_count" -eq 2 ]]; then
echo "Getting existing IP addresses from vnic1"
read -r ip_address gateway_ip < <(maas admin interfaces read $machine_id | jq -r '.[].links[] | "\(.ip_address) \(.subnet.gateway_ip)"')
echo "IP address: $ip_address"
echo "Default gateway IP address: $gateway_ip"

echo "Getting interface IDs for Bond creation..."
parent_interface_ids=$(maas admin interfaces read $machine_id | jq -r '[.[] | "parents=" + (.id | tostring)] | join(" ")')

echo "Creating 'bond0' Bond interface..."
maas admin interfaces create-bond $machine_id name=bond0 vlan=2 $parent_interface_ids bond_mode=balance-alb bond_miimon=0 bond_xmit_hash_policy=layer3+4 > /dev/null

echo "Attaching subnet and IP settings to bond0..."
maas admin interface link-subnet $machine_id bond0 subnet=2 mode=STATIC ip_address=$ip_address default_gateway=$gateway_ip > /dev/null
maas admin interface update $machine_id bond0 link_connected=True > /dev/null

echo "Waiting 10s to ensure bond creation before beginning deploy..."
sleep 10
fi

echo "Interfaces and bond set up, beginning deploy..."

maas admin machine deploy $machine_id user_data="$(base64 -w0 $WORKDIR/cloud-init-baseline.yml)" > /dev/null
echo "Started Deploying machine $1 at $(date)."
echo "Follow progress at:"
echo "http://192.168.1.45:5240/MAAS/r/machine/$machine_id/summary"
Loading