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.

152 lines
4.5 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. cmdline.spec::cmd:__main__:run() {
  30. : :posarg: DOMAIN 'domain identifier'
  31. : :posarg: SSH_PUBLIC_KEY 'ssh public key'
  32. : :optfla: --no-reload,-R 'Prevent reloading archiving server'
  33. : :optval: --service-name,-s "YAML service name in compose
  34. file to check for existence of key.
  35. Defaults to 'rsync-backup-target'"
  36. : :optval: --compose-file,-f "Compose file location. Defaults to
  37. '/etc/compose/compose.yml'"
  38. local service_name compose_file
  39. service_name=${opt_service_name:-rsync-backup-target}
  40. compose_file=${opt_compose_file:-/etc/compose/compose.yml}
  41. if ! existing_domains=$(shyaml keys "${service_name//./\\.}.options.keys" < "$compose_file"); then
  42. err "Couldn't query file '$compose_file' for keys of" \
  43. "service ${DARKYELLOW}${service_name}${NORMAL}."
  44. exit 1
  45. fi
  46. content=$(cat "$compose_file")
  47. if echo "$existing_domains" | grep "^${DOMAIN}$" >/dev/null 2>&1; then
  48. if ! prev_key=$(shyaml get-value "${service_name//./\\.}.options.keys.${DOMAIN//./\\.}" \
  49. < "$compose_file"); then
  50. err "Couldn't query file '$compose_file' for key of domain '$DOMAIN'."
  51. exit 1
  52. fi
  53. if [ "${prev_key}" == "$SSH_PUBLIC_KEY" ]; then
  54. info "Key is already setup correctly."
  55. exit 0
  56. fi
  57. content=$(echo "$content" | remove_lines_from_to '^ '"${DOMAIN//./\\.}"': ".*\\$' \
  58. '^ ([A-Za-z0-9.-]+: "|## END MARKER)')
  59. if [ -z "$content" ]; then
  60. err "Didn't manage to remove key to compose file '$DOMAIN' in '$compose_file'."
  61. exit 1
  62. fi
  63. if [ "$content" == "$(cat "$compose_file")" ]; then
  64. err "Couldn't remove previous key for '$DOMAIN' in '$compose_file'."
  65. exit 1
  66. fi
  67. ## check we didn't break yaml
  68. if ! echo "$content" | check_valid_yaml; then
  69. err "Couldn't safely remove previous key for '$DOMAIN' in '$compose_file'."
  70. exit 1
  71. fi
  72. fi
  73. excerpt=$(cat <<EOF
  74. $DOMAIN: "$(
  75. echo "$SSH_PUBLIC_KEY" |
  76. fold -w 67 | sed -r 's/$/\\/g;2,$ s/^/ /g;$,$ s/\\$//g')"
  77. EOF
  78. )
  79. excerpt="${excerpt//\\/\\\\\\}"
  80. content="$(echo "$content" | sed -r '/^ ## INSERTION-POINT/a\'"${excerpt}")"
  81. if [ -z "$content" ]; then
  82. err "Didn't manage to add key to compose file '$DOMAIN' in '$compose_file'."
  83. exit 1
  84. fi
  85. if ! echo "$content" | check_valid_yaml; then
  86. err "Couldn't safely add key to compose file '$DOMAIN' in '$compose_file'."
  87. exit 1
  88. fi
  89. if diff=$(diff -u "$compose_file" <(echo "$content")); then
  90. err "No difference, this is not expected, and something went wrong."
  91. exit 1
  92. fi
  93. echo "${WHITE}Applying these changes:${NORMAL}"
  94. if type -p colordiff >/dev/null; then
  95. colordiff -u "$compose_file" <(echo "$content")
  96. else
  97. echo "$diff"
  98. fi | egrep -v "^[^ ]*(---|\+\+\+)"
  99. cp "$compose_file" "${compose_file}.old"
  100. echo "$content" > "$compose_file"
  101. if [ -z "$opt_no_reload" ]; then
  102. ## reloading (could be much faster)
  103. compose --debug down && compose --debug up
  104. if [ "$?" == 0 ]; then
  105. info "Added key, and restarted service ${DARKYELLOW}$service_name${NORMAL}."
  106. else
  107. err "something went wrong ! Should check the state of '$DOMAIN' !!"
  108. exit 1
  109. fi
  110. else
  111. info "Added key, you'll need to restart service ${DARKYELLOW}$service_name${NORMAL}."
  112. fi
  113. }
  114. cmdline::parse "$@"