openstack-server/openstack-server

183 lines
6.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright 2020 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -Eeuo pipefail
print_help() {
echo -e 'github.com/shiftstack/shiftstack-ci'
echo -e 'Spin a server on OpenStack'
echo
echo -e 'Usage:'
echo -e "\t${0} [-p] -f <flavor> -i <image> -e <external network> -k <key> NAME"
echo
echo -e 'Required parameters:'
echo -e '\t-f\tFlavor of the Compute instance.'
echo -e '\t-i\tImage of the Compute instance.'
echo -e '\t-e\tName or ID of the public network where to create the floating IP.'
echo -e '\t-k\tName or ID of the SSH public key to add to the server.'
echo -e '\tNAME: name to give to the OpenStack resources.'
echo
echo -e 'Optional parameters:'
echo -e '\t-p\tDo not clean up the server after creation'
echo -e '\t\t(will print a cleanup script instead of executing it).'
}
declare \
persistent='' \
server_flavor='' \
server_image='' \
key_name='' \
external_network='external'
declare -r config_file="${XDG_CONFIG_HOME:-${HOME}/.config}/openstack-server/${OS_CLOUD}.conf"
if [[ -f "$config_file" ]]; then
>&2 echo "Config file found. Sourcing '${config_file}'..."
# shellcheck disable=SC1090
source "$config_file"
fi
while getopts pf:i:e:k:h opt; do
case "$opt" in
p) persistent='yes' ;;
f) server_flavor="$OPTARG" ;;
i) server_image="$OPTARG" ;;
e) external_network="$OPTARG" ;;
k) key_name="$OPTARG" ;;
h) print_help; exit 0 ;;
*) exit 1 ;;
esac
done
shift "$((OPTIND-1))"
declare -r name="${1:?This script requires one positional argument: the resource name}"
readonly \
server_flavor \
server_image \
key_name \
external_network
declare -r destroy_file="${XDG_CACHE_HOME:-${HOME}/.cache}/openstack-server/${OS_CLOUD}-${name}-destroy.sh"
if [[ -f "$destroy_file" ]]; then
>&2 echo "Destroy file found. Please be more creative with your server name. Aborting..."
exit 1
fi
declare \
sg_id='' \
network_id='' \
subnet_id='' \
router_id='' \
port_id='' \
server_id='' \
fip_id=''
cleanup() {
>&2 echo
>&2 echo
>&2 echo 'Starting the cleanup...'
if [ -n "$fip_id" ]; then
openstack floating ip delete "$fip_id" || >&2 echo "Failed to delete FIP $fip_id"
fi
if [ -n "$server_id" ]; then
openstack server delete "$server_id" || >&2 echo "Failed to delete server $server_id"
fi
if [ -n "$port_id" ]; then
openstack port delete "$port_id" || >&2 echo "Failed to delete port $port_id"
fi
if [ -n "$router_id" ]; then
openstack router remove subnet "$router_id" "$subnet_id" || >&2 echo 'Failed to remove subnet from router'
openstack router delete "$router_id" || >&2 echo "Failed to delete router $router_id"
fi
if [ -n "$subnet_id" ]; then
openstack subnet delete "$subnet_id" || >&2 echo "Failed to delete subnet $subnet_id"
fi
if [ -n "$network_id" ]; then
openstack network delete "$network_id" || >&2 echo "Failed to delete network $network_id"
fi
if [ -n "$sg_id" ]; then
openstack security group delete "$sg_id" || >&2 echo "Failed to delete security group $sg_id"
fi
>&2 echo 'Cleanup done.'
}
trap cleanup EXIT
print_cleanup_script() {
cat > "$destroy_file" <<EOF
# Below the instructions to destroy the server "${name}" on the cloud "${OS_CLOUD}".
openstack floating ip delete "$fip_id" || >&2 echo "Failed to delete FIP $fip_id"
openstack server delete "$server_id" || >&2 echo "Failed to delete server $server_id"
openstack port delete "$port_id" || >&2 echo "Failed to delete port $port_id"
openstack router remove subnet "$router_id" "$subnet_id" || >&2 echo 'Failed to remove subnet from router'
openstack router delete "$router_id" || >&2 echo "Failed to delete router $router_id"
openstack subnet delete "$subnet_id" || >&2 echo "Failed to delete subnet $subnet_id"
openstack network delete "$network_id" || >&2 echo "Failed to delete network $network_id"
openstack security group delete "$sg_id" || >&2 echo "Failed to delete security group $sg_id"
EOF
}
sg_id="$(openstack security group create -f value -c id "$name")"
>&2 echo "Created security group ${sg_id}"
openstack security group rule create --ingress --protocol tcp --dst-port 22 --description "${name} SSH" "$sg_id" >/dev/null
openstack security group rule create --ingress --protocol icmp --description "${name} ingress ping" "$sg_id" >/dev/null
openstack security group rule create --ingress --protocol tcp --dst-port 80 --description "${name} ingress HTTP" "$sg_id" >/dev/null
openstack security group rule create --ingress --protocol udp --dst-port '60000:61000' --description "${name} ingress mosh" "$sg_id" >/dev/null
>&2 echo 'Security group rules created.'
network_id="$(openstack network create -f value -c id "$name")"
>&2 echo "Created network ${network_id}"
subnet_id="$(openstack subnet create -f value -c id \
--network "$network_id" \
--subnet-range '172.16.0.0/24' \
--dns-nameserver '1.1.1.1' \
"$name")"
>&2 echo "Created subnet ${subnet_id}"
router_id="$(openstack router create -f value -c id \
"$name")"
>&2 echo "Created router ${router_id}"
openstack router add subnet "$router_id" "$subnet_id"
openstack router set --external-gateway "$external_network" "$router_id"
port_id="$(openstack port create -f value -c id \
--network "$network_id" \
--security-group "$sg_id" \
"$name")"
>&2 echo "Created port ${port_id}"
server_id="$(openstack server create -f value -c id \
--image "$server_image" \
--flavor "$server_flavor" \
--nic "port-id=$port_id" \
--security-group "$sg_id" \
--key-name "$key_name" \
"$name")"
>&2 echo "Created server ${server_id}"
fip_id="$(openstack floating ip create -f value -c id \
--description "$name" \
"$external_network")"
>&2 echo "Created floating IP ${fip_id} $(openstack floating ip show -f value -c floating_ip_address "$fip_id")"
openstack server add floating ip "$server_id" "$fip_id"
if [ "$persistent" == 'yes' ]; then
>&2 echo "Server created."
trap true EXIT
print_cleanup_script
else
>&2 echo "Server created. Press ENTER to tear down."
# shellcheck disable=SC2162,SC2034
read pause
fi