Skip to content

Instantly share code, notes, and snippets.

@johnliu55tw
Created August 16, 2018 06:22
Show Gist options
  • Save johnliu55tw/e2541c509c917fc21bbd1960fb09031d to your computer and use it in GitHub Desktop.
Save johnliu55tw/e2541c509c917fc21bbd1960fb09031d to your computer and use it in GitHub Desktop.
The attempt to replace First Time Setup with shell script.
#!/bin/bash
SCRIPT_NAME="first_time_setup.sh"
info() {
printf -- "$SCRIPT_NAME INFO: $*\n" >&2
}
error() {
printf -- "$SCRIPT_NAME ERROR: $*\n" >&2
}
abort() {
printf -- "$SCRIPT_NAME ABORT: $*\n" >&2
exit 1
}
print_help() {
printf -- "Usage:\n"
printf -- " $SCRIPT_NAME --esxi <IP> --vm_name <NAME>\n"
printf -- " $SCRIPT_NAME --appliance <IP>\n"
}
cirrus_wait_for_started() {
info "Waiting for Cirrus to be ready"
retry_limit=40
for i in $(seq $retry_limit); do
resp=$(cirrus_get_session_id "Administrator" "admin")
if [ $? -ne 0 ]; then
info "Waiting..."
sleep 30
else
return 0
fi
done
printf -- "Wait timeout"
return 1
}
cirrus_get_session_id() {
info "Getting login session ID"
url="https://$1/rest/login-sessions"
json_data="{\"userName\": \"$2\", \"password\": \"$3\", \"authLoginDomain\": \"LOCAL\"}"
resp=$(curl -k -s -f \
-X POST \
-H "Content-Type: application/json" \
-d "$json_data" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
sessionID=$(echo $resp | jq --raw-output ".sessionID")
if [ -z $sessionID ]; then
printf -- "Failded to retrieve key 'sessionID' from HTTP response"
return 1
fi
printf -- "$sessionID"
return 0
}
cirrus_accept_eula() {
info "Accepting EULA"
url="https://$1/rest/appliance/eula/save"
json_data='{"supportAccess": "yes"}'
resp=$(curl -k -s -f \
-X POST \
-H "Content-Type: application/json" \
-d "$json_data" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
return 0
}
cirrus_change_initial_password() {
info "Change initial password"
url="https://$1/rest/users/changePassword"
json_data='{"userName": "Administrator", "oldPassword": "admin", "newPassword": "Compaq123"}'
resp=$(curl -k -s -f \
-X POST \
-H "Content-Type: application/json" \
-d "$json_data" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
return 0
}
cirrus_get_network_interfaces() {
info "Get network interfaces"
url="https://$1/rest/appliance/network-interfaces"
session_id="$2"
resp=$(curl -k -s -f \
-X GET \
-H "Content-Type: application/json" \
-H "auth: $session_id" \
-H "X-Api-Version: 300" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
printf -- "$resp"
return 0
}
cirrus_set_dhcp_network() {
info "Configuring network to DHCP"
url="https://$1/rest/appliance/network-interfaces"
session_id="$2"
resp=$(cirrus_get_network_interfaces $1 $session_id)
if [ $? -ne 0 ]; then
printf -- "Failed to retrieve network interfaces settings: $resp"
return 1
fi
# Update the retrieved network setting
dhcp_setting=$(update_to_dhcp_setting $resp)
resp=$(curl -k -s -f \
-X POST \
-H "Content-Type: application/json" \
-H "auth: $session_id" \
-H "X-Api-Version: 300" \
-d "$dhcp_setting" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
return 0
}
update_to_dhcp_setting() {
echo $1 | jq --raw-output \
'.applianceNetworks[0].app1Ipv4Addr = "" |
.applianceNetworks[0].overrideIpv4DhcpDnsServers = false |
.applianceNetworks[0].ipv4Type = "DHCP" |
.applianceNetworks[0].hostname = "cirrus.net"'
}
cirrus_wait_for_network_config() {
info "Waiting for network configuration to finish"
for i in $(seq 6); do
resp=$(cirrus_get_network_config_percent_complete $1 $2)
if [ $? -ne 0 ]; then
printf -- "Failed to get network config percent complete: $resp"
return 1
fi
if [ $resp == "100" ]; then
return 0
fi
info "Waiting...\n" >&2
sleep 1
done
printf -- "Failed to wait for network configuration to finished"
return 1
}
cirrus_get_network_config_percent_complete() {
url="https://$1/rest/tasks"
session_id=$2
resp=$(curl -k -s -f \
-X GET \
-H "auth: $session_id" \
$url)
if [ $? -ne 0 ]; then
printf -- "HTTP request failed"
return 1
fi
percent=$(echo $resp | jq --raw-output \
'.members |
map(select(.name == "Network Configuration")) |
reverse |
.[0].percentComplete')
if [ $percent == 'null' ]; then
printf -- "No percentage information found in server response"
return 1
fi
printf -- $percent
return 0
}
init_setup() {
ip=$1
resp=$(cirrus_accept_eula $ip) || \
error "Failed to accept EULA: $resp"
resp=$(cirrus_change_initial_password $ip) || \
error "Faild to change initial password: $resp"
resp=$(cirrus_get_session_id $ip Administrator Compaq123) || \
error "Failed to get session ID: $resp"
session_id=$resp
resp=$(cirrus_set_dhcp_network $ip $session_id) || \
error "Failed to configure DHCP network: $resp"
resp=$(cirrus_wait_for_network_config $ip $session_id) || \
error "Failed to wait for network config: $resp"
}
main() {
if [ $# -eq 0 ]; then
abort "Missing required arguments.\nTry '$SCRIPT_NAME --help' for more information."
fi
if ! (command -v jq > /dev/null); then
abort "Missing required command: jq"
fi
# Parsing command-line argument
while [ $# -gt 0 ]; do
arg_name=$1
case $arg_name in
--help)
print_help
exit 0
;;
--esxi)
mode="esxi"
ip=$2
shift
shift
;;
--vm_name)
vm_name=$2
shift
shift
;;
--appliance)
mode="appliance"
ip=$2
shift
shift
;;
*)
abort "unrecognized argument: $1"
;;
esac
done
# Checking the arguments
if [ ! "$mode" ]; then
abort "either --esxi or --appliance is requried."
elif [ "$mode" = "esxi" ] && [ ! "$vm_name" ]; then
abort "--esxi mode also requires --vm_name argument."
fi
# Get appliance IP
if [ "$mode" = "appliance" ]; then
appliance_ip=$ip
elif [ "$mode" = "esxi" ]; then
abort "ESXi is not supported for now."
fi
# Run setup
init_setup $appliance_ip
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment