Reference Airship manifests, CICD, and reference architecture.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

516 lines
12 KiB

#!/bin/bash
export TEMP_DIR=${TEMP_DIR:-$(mktemp -d -p /var/tmp)}
export NAMEKEY_FILE=${NAMEKEY_FILE:-"$HOME/.airship_key"}
export DEFINITION_DEPOT="${TEMP_DIR}/site_yaml/"
export RENDERED_DEPOT="${TEMP_DIR}/rendered_yaml/"
export CERT_DEPOT="${TEMP_DIR}/cert_yaml/"
export GATE_DEPOT="${TEMP_DIR}/gate_yaml/"
export SCRIPT_DEPOT="${TEMP_DIR}/scripts/"
export BUILD_WORK_DIR=${BUILD_WORK_DIR:-/work}
export BASE_IMAGE_SIZE=${BASE_IMAGE_SIZE:-68719476736}
export BASE_IMAGE_URL=${BASE_IMAGE_URL:-https://cloud-images.ubuntu.com/releases/xenial/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img}
export IMAGE_PROMENADE_CLI=${IMAGE_PROMENADE_CLI:-quay.io/airshipit/promenade:cfb8aa498c294c2adbc369ba5aaee19b49550d22}
export IMAGE_PEGLEG_CLI=${IMAGE_PEGLEG_CLI:-quay.io/airshipit/pegleg:50ce7a02e08a0a5277c2fbda96ece6eb5782407a}
export IMAGE_SHIPYARD_CLI=${IMAGE_SHIPYARD_CLI:-quay.io/airshipit/shipyard:4dd6b484d11e86ad51da733841b9ef137421d461}
export IMAGE_COREDNS=${IMAGE_COREDNS:-docker.io/coredns/coredns:1.2.2}
export IMAGE_QUAGGA=${IMAGE_QUAGGA:-docker.io/cumulusnetworks/quagga:CL3.3.2}
export IMAGE_DRYDOCK_CLI=${IMAGE_DRYDOCK_CLI:-quay.io/airshipit/drydock:d93d6d5a0a370ced536180612d1ade708e29cd47}
export IMAGE_DOCKER_REGISTRY=${IMAGE_DOCKER_REGISTRY:-"docker.io/registry:2"}
export IMAGE_HYPERKUBE=${IMAGE_HYPERKUBE:-gcr.io/google_containers/hyperkube-amd64:v1.12.9}
export PROMENADE_DEBUG=${PROMENADE_DEBUG:-0}
export PROMENADE_TMP_LOCAL=${PROMENADE_TMP_LOCAL:-cache}
export REGISTRY_DATA_DIR=${REGISTRY_DATA_DIR:-/mnt/registry}
export VIRSH_POOL=${VIRSH_POOL:-airship}
export VIRSH_POOL_PATH=${VIRSH_POOL_PATH:-/var/lib/libvirt/airship}
export VIRSH_CPU_OPTS=${VIRSH_CPU_OPTS:-host}
export UPSTREAM_DNS=${UPSTREAM_DNS:-"8.8.8.8 8.8.4.4"}
export NTP_POOLS=${NTP_POOLS:-"0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org"}
export NTP_SERVERS=${NTP_SERVERS:-""}
export PROMENADE_ENCRYPTION_KEY=${PROMENADE_ENCRYPTION_KEY:-MjI1N2ZiMjMzYjI0ZmVkZDU4}
export PEGLEG_PASSPHRASE=${PEGLEG_PASSPHRASE:-ewd?egnPWL0Q?hzzGwEBmII5}
export PEGLEG_SALT=${PEGLEG_SALT:-9EX&uapdz1ka17WOQMG-FjTA}
# key-pair used for drydock/maas auth towards libvirt and access to
# the virtual nodes; auto-generated if no value provided
export GATE_SSH_KEY=${GATE_SSH_KEY:-""}
# skip generation of certificates, and other security manifests
# auto-generated by default
export USE_EXISTING_SECRETS=${USE_EXISTING_SECRETS:-""}
export SHIPYARD_PASSWORD=${SHIPYARD_OS_PASSWORD:-'password18'}
export AIRSHIP_KEYSTONE_URL=${AIRSHIP_KEYSTONE_URL:-'http://keystone.gate.local:80/v3'}
config_vm_memory() {
nodename=${1}
jq -cr ".vm.${nodename}.memory" < "${GATE_MANIFEST}"
}
config_vm_names() {
jq -cr '.vm | keys | join(" ")' < "${GATE_MANIFEST}"
}
config_vm_iface_list() {
nodename="$1"
jq -cr ".vm.${nodename}.networking | del(.addresses) | keys | .[]" < "${GATE_MANIFEST}"
}
config_vm_iface_mac() {
nodename="$1"
interface="$2"
jq -cr ".vm.${nodename}.networking.${interface}.mac" < "${GATE_MANIFEST}"
}
# What network this VM interface should be attached to
config_vm_iface_network() {
nodename="$1"
interface="$2"
jq -cr ".vm.${nodename}.networking.${interface}.attachment.network" < "${GATE_MANIFEST}"
}
# What VLANs on a network should be attached to this node
config_vm_iface_vlans() {
nodename="$1"
interface="$2"
jq -cr ".vm.${nodename}.networking.${interface}.attachment.vlans | select(.!=null)" < "${GATE_MANIFEST}"
}
# PCI slot for this VM interface
config_vm_iface_slot() {
nodename="$1"
interface="$2"
jq -cr ".vm.${nodename}.networking.${interface}.pci.slot" < "${GATE_MANIFEST}"
}
# PCI card port for this VM interface
config_vm_iface_port() {
nodename="$1"
interface="$2"
jq -cr ".vm.${nodename}.networking.${interface}.pci.port" < "${GATE_MANIFEST}"
}
# The IP address for the VM for a network. If vlan is also specified, the VLAN
# on the network
config_vm_net_ip() {
nodename="$1"
network="$2"
vlan="$3"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".vm.${nodename}.networking.addresses.${network}.ip"
else
query=".vm.${nodename}.networking.addresses.${network}.vlans.${vlan}.ip"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_vm_vcpus() {
nodename=${1}
jq -cr ".vm.${nodename}.vcpus" < "${GATE_MANIFEST}"
}
config_vm_bootstrap() {
nodename=${1}
val=$(jq -cr ".vm.${nodename}.bootstrap" < "${GATE_MANIFEST}")
if [[ "${val}" == "true" ]]
then
echo "true"
else
echo "false"
fi
}
config_disk_list() {
layout_name="${1}"
jq -cr ".disk_layouts.${layout_name} | keys | join(\" \")" < "${GATE_MANIFEST}"
}
config_disk_details() {
layout_name="${1}"
disk_device="${2}"
jq -cr ".disk_layouts.${layout_name}.${disk_device}" < "${GATE_MANIFEST}"
}
config_disk_size() {
layout_name="$1"
disk_device="$2"
jq -cr ".disk_layouts.${layout_name}.${disk_device}.size" < "${GATE_MANIFEST}"
}
config_disk_format() {
layout_name="$1"
disk_device="$2"
do_format=$(jq -cr ".disk_layouts.${layout_name}.${disk_device} | has(\"format\")")
if [[ "$do_format" == "true" && "$disk_device" != "$(config_layout_bootstrap "$layout_name")" ]]
then
jq -cr ".disk_layouts.${layout_name}.${disk_device}.format" < "${GATE_MANIFEST}"
else
echo ""
fi
}
config_format_type() {
JSON="$1"
echo "$JSON" | jq -cr '.type'
}
config_format_mount() {
JSON="$1"
echo "$JSON" | jq -cr '.mountpoint'
}
config_disk_ioprofile() {
layout_name="$1"
disk_device="$2"
jq -cr ".disk_layouts.${layout_name}.${disk_device}.io_profile" < "${GATE_MANIFEST}"
}
# Find which disk in a layout should
# get the bootstrap image
config_layout_bootstrap() {
layout_name="${1}"
jq -cr ".disk_layouts.${layout_name} | keys[] as \$k | {device: (\$k)} + (.[\$k]) | select(.bootstrap) | .device " < "${GATE_MANIFEST}"
}
config_vm_disk_layout() {
nodename=${1}
jq -cr ".vm.${nodename}.disk_layout" < "${GATE_MANIFEST}"
}
config_vm_userdata() {
nodename=${1}
val=$(jq -cr ".vm.${nodename}.userdata" < "${GATE_MANIFEST}")
if [[ "${val}" != "null" ]]
then
echo "${val}"
fi
}
config_bgp_as() {
as_number=${1}
jq -cr ".bgp.${as_number}" < "${GATE_MANIFEST}"
}
config_net_list() {
jq -cr '.networking | keys | .[]' < "${GATE_MANIFEST}"
}
config_net_vlan_list() {
network="$1"
jq -cr ".networking.${network}.layer2.vlans // {} | keys | .[]" < "${GATE_MANIFEST}"
}
config_net_cidr() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer3.cidr"
else
query=".networking.${network}.vlans.${vlan}.layer3.cidr"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_net_is_layer3() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network} | has(\"layer3\")"
else
query=".network.${network}.vlans.${vlan} | has(\"layer3\")"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
# Find the layer 3 network tagged for a particular
# role - this can be either a native or vlan network
# If multiple networks have a role, the results is
# undefined
config_netspec_for_role() {
role="$1"
set -e
for net in $(config_net_list)
do
if config_net_has_role "$net" "$role"
then
netspec="$net"
fi
for vlan in $(config_net_vlan_list "$net")
do
if config_vlan_has_role "$net" "$vlan" "$role"
then
netspec="${vlan}@${net}"
fi
done
done
echo -n "$netspec"
}
config_net_has_role() {
netname="$1"
role="$2"
value="$(jq -cr ".networking.${netname}.roles | contains([\"${role}\"])" < "$GATE_MANIFEST")"
if [ "$value" == "true" ]
then
return 0
else
return 1
fi
}
config_vlan_has_role() {
netname="$1"
vlan="$2"
role="$3"
value="$(jq -cr " .networking.${netname}.vlans.${vlan}.roles | contains([\"${role}\"])" < "$GATE_MANIFEST")"
if [ "$value" == "true" ]
then
return 0
else
return 1
fi
}
config_net_selfip() {
network="$1"
vlan="$2"
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer3.address"
else
query=".networking.${network}.vlans.${vlan}.layer3.address"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_net_selfip_cidr() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
selfip=$(config_net_selfip "$network" "$vlan")
netcidr=$(config_net_cidr "$network" "$vlan")
netbits=$(echo "$netcidr" | awk -F '/' '{print $2}')
printf "%s/%s" "$selfip" "$netbits"
}
config_net_gateway() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer3.gateway"
else
query=".networking.${network}.vlans.${vlan}.layer3.gateway"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_net_routemode() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer3.routing.mode"
else
query=".networking.${network}.vlans.${vlan}.layer3.routing.mode"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_net_mtu() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer2.mtu // 1500"
else
query=".networking.${network}.vlans.${vlan}.layer2.mtu // 1500"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_net_mac() {
network="$1"
vlan="$2"
if is_netspec "$network"
then
vlan=$(netspec_vlan "$network")
network=$(netspec_netname "$network")
fi
if [[ -z "$vlan" ]]
then
query=".networking.${network}.layer2.address"
else
query=".networking.${network}.vlans.${vlan}.layer2.address"
fi
jq -cr "$query" < "${GATE_MANIFEST}"
}
config_ingress_domain() {
jq -cr '.ingress.domain' < "${GATE_MANIFEST}"
}
config_ingress_ca() {
if [[ ! -z "$GATE_MANIFEST" ]]
then
jq -cr '.ingress.ca' < "${GATE_MANIFEST}"
fi
}
config_ingress_ips() {
jq -cr '.ingress | keys | map(select(test("([0-9]{1,3}.?){4}"))) | join(" ")' < "${GATE_MANIFEST}"
}
config_ingress_entries() {
IP=$1
jq -cr ".ingress[\"${IP}\"] | join(\" \")" < "${GATE_MANIFEST}"
}
config_pegleg_primary_repo() {
jq -cr ".configuration.primary_repo" < "${GATE_MANIFEST}"
}
config_pegleg_sitename() {
jq -cr ".configuration.site" < "${GATE_MANIFEST}"
}
config_pegleg_aux_repos() {
jq -cr '.configuration.aux_repos | join(" ")' < "${GATE_MANIFEST}"
}
join_array() {
local IFS=$1
shift
echo "$*"
}
besteffort() {
set +e
"$@"
set -e
}
get_namekey() {
if [[ -r "$NAMEKEY_FILE" ]]
then
key=$(cat "$NAMEKEY_FILE")
else
key=$(openssl rand -hex 4)
echo -n "$key" > "$NAMEKEY_FILE"
fi
echo -n "$key"
}
is_netspec(){
value="$1"
if echo -n "$value" | grep -q "[0-9]+@.+"
then
return 0
else
return 1
fi
}
netspec_netname(){
netspec="$1"
echo -n "$netspec" | awk -F'@' '{print $2}'
}
netspec_vlan(){
netspec="$1"
echo -n "$netspec" | awk -F'@' '{print $1}'
}
# We'll just add the conversions as needed
cidr_to_netmask() {
cidr="$1"
netbits="$(echo "$cidr" | awk -F'/' '{print $2}')"
case "$netbits" in
32)
netmask="255.255.255.255"
;;
24)
netmask="255.255.255.0"
;;
esac
echo "$netmask"
}