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.

435 lines
15KB

  1. #!/bin/bash
  2. #
  3. # Copyright 2018 AT&T Intellectual Property. All other rights reserved.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. ###############################################################################
  17. # #
  18. # Set up and deploy an Airship environment for development/testing purposes. #
  19. # Many of the defaults and sources used here are NOT production ready, and #
  20. # this should not be used as a copy/paste source for any production use. #
  21. # #
  22. ###############################################################################
  23. set -x
  24. # The last step to run through in this script. Valid Values are "collect",
  25. # "genesis", "deploy", and "demo". By default this will run through to the end
  26. # of the genesis steps
  27. LAST_STEP_NAME=${1:-"genesis"}
  28. if [[ ${LAST_STEP_NAME} == "collect" ]]; then
  29. STEP_BREAKPOINT=10
  30. elif [[ ${LAST_STEP_NAME} == "genesis" ]]; then
  31. STEP_BREAKPOINT=20
  32. elif [[ ${LAST_STEP_NAME} == "deploy" ]]; then
  33. STEP_BREAKPOINT=30
  34. elif [[ ${LAST_STEP_NAME} == "demo" ]]; then
  35. STEP_BREAKPOINT=40
  36. else
  37. STEP_BREAKPOINT=20
  38. fi
  39. # The directory of the repo where current script is located.
  40. REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../../../../ >/dev/null 2>&1 && pwd )"
  41. # The directory that will contain the copies of designs and repos from this
  42. # script. By default it is a directory where the repository is cloned.
  43. export WORKSPACE=${WORKSPACE:-"${REPO_DIR}/../"}
  44. # The site to deploy
  45. TARGET_SITE=${TARGET_SITE:-"aiab"}
  46. # Setup blank defaults for proxy variables
  47. http_proxy=${http_proxy:-""}
  48. https_proxy=${https_proxy:-""}
  49. no_proxy=${no_proxy:-""}
  50. # The host name for the single-node deployment. e.g.: 'genesis'
  51. SHORT_HOSTNAME=${SHORT_HOSTNAME:-""}
  52. # The host ip for this single-node deployment. e.g.: '10.0.0.9'
  53. HOSTIP=${HOSTIP:-""}
  54. # The cidr for the network for the host. e.g.: '10.0.0.0/24'
  55. HOSTCIDR=${HOSTCIDR:-""}
  56. # The interface on the host/genesis node. e.g.: 'ens3'
  57. NODE_NET_IFACE=${NODE_NET_IFACE:-""}
  58. # Allowance for Genesis/Armada to settle in seconds:
  59. POST_GENESIS_DELAY=${POST_GENESIS_DELAY:-60}
  60. # Command shortcuts
  61. PEGLEG="${REPO_DIR}/tools/airship pegleg"
  62. SHIPYARD="${REPO_DIR}/tools/airship shipyard"
  63. PROMENADE="${REPO_DIR}/tools/airship promenade"
  64. function check_preconditions() {
  65. set +x
  66. fail=false
  67. if ! [ $(id -u) = 0 ] ; then
  68. echo "Please execute this script as root!"
  69. fail=true
  70. fi
  71. if [ -z ${HOSTIP} ] ; then
  72. echo "The HOSTIP variable must be set. E.g. 10.0.0.9"
  73. fail=true
  74. fi
  75. if [ -z ${SHORT_HOSTNAME} ] ; then
  76. echo "The SHORT_HOSTNAME variable must be set. E.g. testvm1"
  77. fail=true
  78. fi
  79. if [ -z ${HOSTCIDR} ] ; then
  80. echo "The HOSTCIDR variable must be set. E.g. 10.0.0.0/24"
  81. fail=true
  82. fi
  83. if [ -z ${NODE_NET_IFACE} ] ; then
  84. echo "The NODE_NET_IFACE variable must be set. E.g. ens3"
  85. fail=true
  86. fi
  87. if [[ -z $(grep $SHORT_HOSTNAME /etc/hosts | grep $HOSTIP) ]]
  88. then
  89. echo "No /etc/hosts entry found for $SHORT_HOSTNAME. Please add one."
  90. fail=true
  91. fi
  92. if [ $fail = true ] ; then
  93. echo "Preconditions failed"
  94. exit 1
  95. fi
  96. set -x
  97. }
  98. function setup_workspace() {
  99. # Setup workspace directories
  100. mkdir -p ${WORKSPACE}/collected
  101. mkdir -p ${WORKSPACE}/genesis
  102. # Open permissions for output from Promenade
  103. chmod -R 777 ${WORKSPACE}/genesis
  104. }
  105. function configure_docker() {
  106. if [[ ! -z "${https_proxy}" ]] || [[ ! -z "${http_proxy}" ]]
  107. then
  108. echo "Configuring Docker to use a proxy..."
  109. mkdir -p /etc/systemd/system/docker.service.d/
  110. cat << EOF > /etc/systemd/system/docker.service.d/http-proxy.conf
  111. [Service]
  112. Environment="HTTP_PROXY=${http_proxy}"
  113. Environment="HTTPS_PROXY=${https_proxy}"
  114. Environment="NO_PROXY=${no_proxy}"
  115. EOF
  116. systemctl daemon-reload
  117. systemctl restart docker
  118. fi
  119. }
  120. function configure_apt() {
  121. if [[ ! -z "${https_proxy}" ]] || [[ ! -z "${http_proxy}" ]]
  122. then
  123. echo "Configuring apt to use a proxy..."
  124. mkdir -p /etc/apt/
  125. cat << EOF > /etc/apt/apt.conf
  126. Acquire::http::proxy "${http_proxy}";
  127. Acquire::https::proxy "${https_proxy}";
  128. EOF
  129. fi
  130. }
  131. function configure_dev_configurables() {
  132. cat << EOF >> ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/deployment/dev-configurables.yaml
  133. data:
  134. hostname: ${SHORT_HOSTNAME}
  135. hostip: ${HOSTIP}
  136. hostcidr: ${HOSTCIDR}
  137. interface: ${NODE_NET_IFACE}
  138. maas-ingress: '192.169.1.5/32'
  139. EOF
  140. }
  141. function install_dependencies() {
  142. apt -qq update
  143. # Install docker
  144. apt -y install --no-install-recommends docker.io jq nmap nfs-common
  145. }
  146. function run_pegleg_collect() {
  147. pushd ${WORKSPACE}
  148. # Make sure certificates generated during prior runs are deleted.
  149. rm -f treasuremap/site/${TARGET_SITE}/secrets/certificates.yaml
  150. # Run pegleg collect to get the documents combined.
  151. ${PEGLEG} site -r /target/treasuremap collect ${TARGET_SITE} -s /target/collected
  152. popd
  153. }
  154. function generate_certs() {
  155. # Runs the generation of certs by Promenade and builds bootstrap scripts
  156. # Note: In the really real world, CAs and certs would be provided as part of
  157. # the supplied design. In this dev/test environment, self signed is fine.
  158. # Moves the generated certificates from /genesis to the design, so that a
  159. # Lint can be run
  160. set +x
  161. echo "=== Generating updated certificates ==="
  162. set -x
  163. pushd ${WORKSPACE}
  164. # Copy the collected yamls into the target for the certs
  165. cp collected/*.yaml genesis/
  166. # Generate certificates
  167. ${PROMENADE} generate-certs -o /target/genesis /target/genesis/treasuremap.yaml
  168. # Copy the generated certs back into the deployment_files structure
  169. cp genesis/certificates.yaml treasuremap/site/${TARGET_SITE}/secrets/
  170. popd
  171. }
  172. function lint_design() {
  173. # After the certificates are in the deployment files run a pegleg lint
  174. pushd ${WORKSPACE}
  175. ${PEGLEG} site -r /target/treasuremap lint -x P001 ${TARGET_SITE}
  176. popd
  177. }
  178. function generate_genesis() {
  179. # Generate the genesis scripts
  180. pushd ${WORKSPACE}
  181. ${PROMENADE} build-all -o /target/genesis --validators \
  182. /target/genesis/treasuremap.yaml \
  183. /target/genesis/certificates.yaml
  184. popd
  185. }
  186. function run_genesis() {
  187. # Runs the genesis script that was generated
  188. ${WORKSPACE}/genesis/genesis.sh
  189. }
  190. function validate_genesis() {
  191. # Vaidates the genesis deployment
  192. ${WORKSPACE}/genesis/validate-genesis.sh
  193. }
  194. function genesis_complete() {
  195. # Setup kubeconfig
  196. if [ ! -d "$HOME/.kube" ] ; then
  197. mkdir ~/.kube
  198. fi
  199. cp -r /etc/kubernetes/admin/pki ~/.kube/pki
  200. cat /etc/kubernetes/admin/kubeconfig.yaml | sed -e 's/\/etc\/kubernetes\/admin/./' > ~/.kube/config
  201. set +x
  202. echo "-----------"
  203. echo "Waiting ${POST_GENESIS_DELAY} seconds for Genesis process to settle. This is a good time to grab one more coffee :)"
  204. echo "-----------"
  205. sleep ${POST_GENESIS_DELAY}
  206. echo " "
  207. echo "Genesis complete. "
  208. print_shipyard_info1
  209. set -x
  210. }
  211. function print_shipyard_info1() {
  212. SHIPYARD_KEYSTONE_PASS=$(awk '/^data:/ {print $2}' ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/secrets/passphrases/ucp_shipyard_keystone_password.yaml)
  213. set +x
  214. # signals that genesis completed
  215. echo " "
  216. echo "The .yaml files in ${WORKSPACE} contain the site design that may be suitable for use with Shipyard. "
  217. echo "The Shipyard Keystone password ${SHIPYARD_KEYSTONE_PASS} may be found in ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/secrets/passphrases/ucp_shipyard_keystone_password.yaml"
  218. echo " "
  219. set -x
  220. }
  221. function setup_deploy_site() {
  222. # creates a directory /${WORKSPACE}/site with all the things necessary to run
  223. # deploy_site
  224. mkdir -p ${WORKSPACE}/site
  225. cp ${WORKSPACE}/treasuremap/tools/deployment/aiab/common/creds.sh ${WORKSPACE}/site
  226. cp ${WORKSPACE}/genesis/*.yaml ${WORKSPACE}/site
  227. print_shipyard_info2
  228. }
  229. function print_shipyard_info2() {
  230. set +x
  231. echo " "
  232. echo "${WORKSPACE}/site is set up with creds.sh which can be sourced to set up credentials for use in running Shipyard"
  233. echo "${WORKSPACE}/site contains .yaml files that represent the single-node site deployment. (treasuremap.yaml, certificates.yaml)"
  234. echo " "
  235. echo "----------------------------------------------------------------------------------"
  236. echo "The following commands will execute Shipyard to setup and run a deploy_site action"
  237. echo "----------------------------------------------------------------------------------"
  238. echo "cd ${WORKSPACE}/site"
  239. echo "source creds.sh"
  240. echo "${SHIPYARD} create configdocs design --filename=/home/shipyard/host/treasuremap.yaml"
  241. echo "${SHIPYARD} create configdocs secrets --filename=/home/shipyard/host/certificates.yaml --append"
  242. echo "${SHIPYARD} commit configdocs"
  243. echo "${SHIPYARD} create action deploy_site"
  244. echo " "
  245. echo "-----------"
  246. echo "Other Notes"
  247. echo "-----------"
  248. echo "If you need to run Armada directly to deploy charts (fix something broken?), the following may be of use:"
  249. echo "export ARMADA_IMAGE=quay.io/airshipit/armada"
  250. echo "docker run -t -v ~/.kube:/armada/.kube -v ${WORKSPACE}/site:/target --net=host \${ARMADA_IMAGE} apply /target/your-yaml.yaml"
  251. echo " "
  252. set -x
  253. }
  254. function execute_deploy_site() {
  255. set +x
  256. echo " "
  257. echo "This is an automated deployment using Shipyard, running commands noted previously"
  258. echo "Please stand by while Shipyard deploys the site"
  259. echo " "
  260. pushd ${WORKSPACE}/site
  261. source creds.sh
  262. set -x
  263. ${SHIPYARD} create configdocs design --filename=/target/treasuremap.yaml
  264. ${SHIPYARD} create configdocs secrets --filename=/target/certificates.yaml --append
  265. ${SHIPYARD} commit configdocs
  266. ${SHIPYARD} create action deploy_site
  267. ${REPO_DIR}/tools/gate/wait-for-shipyard.sh
  268. popd
  269. }
  270. function execute_create_heat_stack() {
  271. # TODO: (bryan-strassner) prevent this running unless we're running from a
  272. # compatible site defintion that includes OpenStack
  273. set +x
  274. echo " "
  275. echo "Performing basic sanity checks by creating heat stacks"
  276. echo " "
  277. set -x
  278. # Switch to directory where the script is located
  279. pushd ${WORKSPACE}/treasuremap/tools/deployment/aiab/common/
  280. bash test_create_heat_stack.sh
  281. popd
  282. }
  283. function publish_horizon_dashboard() {
  284. kubectl -n openstack expose service/horizon-int --type=NodePort --name=horizon-dashboard
  285. }
  286. function print_dashboards() {
  287. AIRFLOW_PORT=$(kubectl -n ucp get service airflow-web-int -o jsonpath="{.spec.ports[0].nodePort}")
  288. HORIZON_PORT=$(kubectl -n openstack get service horizon-dashboard -o jsonpath="{.spec.ports[0].nodePort}")
  289. MAAS_PORT=$(kubectl -n ucp get service maas-region-ui -o jsonpath="{.spec.ports[0].nodePort}")
  290. MASS_PASS=$(awk '/^data:/ {print $2}' ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/secrets/passphrases/ucp_maas_admin_password.yaml)
  291. HORIZON_PASS=$(awk '/^data:/ {print $2}' ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/secrets/passphrases/osh_horizon_oslo_db_password.yaml)
  292. set +x
  293. echo " "
  294. echo "OpenStack Horizon dashboard is available on this host at the following URL:"
  295. echo " "
  296. echo " http://${HOSTIP}:${HORIZON_PORT}"
  297. echo " "
  298. # TODO: (roman_g) can we source it from somewhere?
  299. echo "Credentials:"
  300. echo " Domain: default"
  301. echo " Username: admin"
  302. echo " Password: ${HORIZON_PASS}"
  303. echo " "
  304. echo "OpenStack CLI commands could be launched via \`./openstack\` script, e.g.:"
  305. echo " # cd ${WORKSPACE}/treasuremap/tools/"
  306. echo " # ./openstack stack list"
  307. echo " ..."
  308. echo " "
  309. echo "Other dashboards:"
  310. echo " "
  311. echo " MAAS: http://${HOSTIP}:${MAAS_PORT}/MAAS/ admin/${MASS_PASS}"
  312. echo " Airship Shipyard Airflow DAG: http://${HOSTIP}:${AIRFLOW_PORT}/"
  313. echo " "
  314. echo "Airship itself does not have a dashboard."
  315. echo " "
  316. # TODO: (roman_g) endpoints.yaml path below does not seem to be a reliable location
  317. echo "Other endpoints and credentials are listed in the following locations:"
  318. echo " ${WORKSPACE}/type/sloop/config/endpoints.yaml"
  319. echo " ${WORKSPACE}/treasuremap/site/${TARGET_SITE}/secrets/passphrases/"
  320. echo "Exposed ports of services can be listed with the following command:"
  321. echo " # kubectl get services --all-namespaces | grep -v ClusterIP"
  322. echo " ..."
  323. echo " "
  324. set -x
  325. }
  326. function your_next_steps() {
  327. set +x
  328. echo " "
  329. echo "---------------------------------------------------------------"
  330. echo " "
  331. echo "Airship has completed deployment of OpenStack (OpenStack-Helm)."
  332. echo " "
  333. echo "Explore Airship Treasuremap repository and documentation"
  334. echo "available at the following URLs:"
  335. echo " "
  336. echo " https://opendev.org/airship/treasuremap/"
  337. echo " https://airship-treasuremap.readthedocs.io/"
  338. echo " "
  339. echo "---------------------------------------------------------------"
  340. echo " "
  341. set -x
  342. }
  343. function clean() {
  344. # Perform any cleanup of temporary or unused artifacts
  345. set +x
  346. echo "To remove files generated during this script's execution, delete ${WORKSPACE}."
  347. echo "This VM is disposable. Re-deployment in this same VM will lead to unpredictable results."
  348. set -x
  349. }
  350. function error() {
  351. # Processes errors
  352. set +x
  353. echo "Error when $1."
  354. set -x
  355. exit 1
  356. }
  357. trap clean EXIT
  358. # Common steps for all breakpoints specified
  359. check_preconditions || error "checking for preconditions"
  360. configure_apt || error "configuring apt behind proxy"
  361. setup_workspace || error "setting up workspace directories"
  362. configure_dev_configurables || error "adding dev-configurables values"
  363. install_dependencies || error "installing dependencies"
  364. configure_docker || error "configuring docker behind proxy"
  365. # collect
  366. if [[ ${STEP_BREAKPOINT} -ge 10 ]]; then
  367. echo "This is a good time to grab a coffee :)"
  368. run_pegleg_collect || error "running pegleg collect"
  369. fi
  370. # genesis
  371. if [[ ${STEP_BREAKPOINT} -ge 20 ]]; then
  372. generate_certs || error "setting up certs with Promenade"
  373. lint_design || error "linting the design"
  374. generate_genesis || error "generating genesis"
  375. run_genesis || error "running genesis"
  376. validate_genesis || error "validating genesis"
  377. genesis_complete || error "printing out some info about next steps"
  378. setup_deploy_site || error "preparing the /site directory for deploy_site"
  379. fi
  380. # deploy
  381. if [[ ${STEP_BREAKPOINT} -ge 30 ]]; then
  382. execute_deploy_site || error "executing deploy_site from the /site directory"
  383. fi
  384. # demo
  385. if [[ ${STEP_BREAKPOINT} -ge 40 ]]; then
  386. execute_create_heat_stack || error "creating heat stack"
  387. publish_horizon_dashboard || error "publishing Horizon dashboard"
  388. print_shipyard_info1
  389. print_shipyard_info2
  390. print_dashboards || error "printing dashboards list"
  391. ## Done
  392. your_next_steps
  393. fi