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.

144 lines
4.1 KiB

  1. #!/bin/bash
  2. . /etc/shlib
  3. [[ "${BASH_SOURCE[0]}" != "${0}" ]] && SOURCED=true
  4. include common
  5. include pretty
  6. include cmdline
  7. desc='Adds YAML key quite crudely in given compose.yml.'
  8. help="\
  9. $WHITE$exname$NORMAL will find a add or replace SSH key to
  10. given identifier for rsync-backup-target charm.
  11. For now, it only use detection of '## INSERTION-POINT' to manage
  12. edition of 'compose.yml', and verification it didn't break anything
  13. before overwriting.
  14. "
  15. [ "$SOURCED" ] && return 0
  16. ##
  17. ## Command line processing
  18. ##
  19. # remove all lines from regex to regex (not included).
  20. remove_lines_from_to() {
  21. local from="$1" to="$2"
  22. sed -r "/$from/,/$to/{/$to/"'!'"d};/$from/d"
  23. }
  24. check_valid_yaml() {
  25. shyaml get-value >/dev/null 2>&1;
  26. }
  27. cmdline.spec.gnu
  28. cmdline.spec.reporting
  29. service_name=${SERVICE_NAME:-rsync-backup-target}
  30. compose_file=${COMPOSE_FILE:-/etc/compose/compose.yml}
  31. cmdline.spec::valued:--compose-file,-f:usage() {
  32. echo "Compose file location. Defaults to '/etc/compose/compose.yml'"; }
  33. cmdline.spec::valued:--compose-file,-f:run() { compose_file="$1"; }
  34. cmdline.spec::valued:--service-name,-s:usage() {
  35. echo "YAML service name in compose file to check for existence of key. Defaults to 'rsync-backup-target'"; }
  36. cmdline.spec::valued:--service-name,-s:run() { service_name="$1"; }
  37. cmdline.spec::cmd:__main__:run() {
  38. : :posarg: DOMAIN 'domain identifier'
  39. : :posarg: SSH_PUBLIC_KEY 'ssh public key'
  40. if ! existing_domains=$(shyaml keys "${service_name//./\\.}.options.keys" < "$compose_file"); then
  41. err "Couldn't query file '$compose_file' for keys of" \
  42. "service ${DARKYELLOW}${service_name}${NORMAL}."
  43. exit 1
  44. fi
  45. content=$(cat "$compose_file")
  46. if echo "$existing_domains" | grep "^${DOMAIN}$" >/dev/null 2>&1; then
  47. if ! prev_key=$(shyaml get-value "${service_name//./\\.}.options.keys.${DOMAIN//./\\.}" \
  48. < "$compose_file"); then
  49. err "Couldn't query file '$compose_file' for key of domain '$DOMAIN'."
  50. exit 1
  51. fi
  52. if [ "${prev_key}" == "$SSH_PUBLIC_KEY" ]; then
  53. echo "Key was already setup."
  54. exit 0
  55. fi
  56. content=$(echo "$content" | remove_lines_from_to '^ '"${DOMAIN//./\\.}"': ".*\\$' \
  57. '^ ([A-Za-z0-9.-]+: "|## END MARKER)')
  58. if [ -z "$content" ]; then
  59. err "Didn't manage to remove key to compose file '$DOMAIN' in '$compose_file'."
  60. exit 1
  61. fi
  62. if [ "$content" == "$(cat "$compose_file")" ]; then
  63. err "Couldn't remove previous key for '$DOMAIN' in '$compose_file'."
  64. exit 1
  65. fi
  66. ## check we didn't break yaml
  67. if ! echo "$content" | check_valid_yaml; then
  68. err "Couldn't safely remove previous key for '$DOMAIN' in '$compose_file'."
  69. exit 1
  70. fi
  71. fi
  72. excerpt=$(cat <<EOF
  73. $DOMAIN: "$(
  74. echo "$SSH_PUBLIC_KEY" |
  75. fold -w 67 | sed -r 's/$/\\/g;2,$ s/^/ /g;$,$ s/\\$//g')"
  76. EOF
  77. )
  78. excerpt="${excerpt//\\/\\\\\\}"
  79. content="$(echo "$content" | sed -r '/^ ## INSERTION-POINT/a\'"${excerpt}")"
  80. if [ -z "$content" ]; then
  81. err "Didn't manage to add key to compose file '$DOMAIN' in '$compose_file'."
  82. exit 1
  83. fi
  84. if ! echo "$content" | check_valid_yaml; then
  85. err "Couldn't safely add key to compose file '$DOMAIN' in '$compose_file'."
  86. exit 1
  87. fi
  88. if diff=$(diff -u "$compose_file" <(echo "$content")); then
  89. err "No difference, this is not expected, and something went wrong."
  90. exit 1
  91. fi
  92. echo "${WHITE}Applying these changes:${NORMAL}"
  93. echo "$diff"
  94. cp "$compose_file" "${compose_file}.old"
  95. echo "$content" > "$compose_file"
  96. ## reloading (could be much faster)
  97. compose --debug down && compose --debug up
  98. if [ "$?" == 0 ]; then
  99. echo "Added key, and restarted service ${DARKYELLOW}$service_name${NORMAL}."
  100. else
  101. echo "something went wrong ! Should check the state of '$DOMAIN' !!"
  102. exit 1
  103. fi
  104. }
  105. cmdline::parse "$@"