diff --git a/cdist/conf/type/__ssh_authorized_key/manifest b/cdist/conf/type/__ssh_authorized_key/gencode-remote similarity index 63% rename from cdist/conf/type/__ssh_authorized_key/manifest rename to cdist/conf/type/__ssh_authorized_key/gencode-remote index eb7ae859..478826db 100755 --- a/cdist/conf/type/__ssh_authorized_key/manifest +++ b/cdist/conf/type/__ssh_authorized_key/gencode-remote @@ -18,31 +18,36 @@ # along with cdist. If not, see . # -file="$(cat "$__object/parameter/file")" -state="$(cat "$__object/parameter/state")" -mkdir "$__object/files" - -_cksum() { - echo "$1" | cksum | cut -d' ' -f 1 -} - -_do_line() { +remove_line() { file="$1" line="$2" - state="$3" - line_id="$(_cksum "$file")-$(_cksum "$line")" - - set -- "$line_id" - set -- "$@" --file "$file" - set -- "$@" --line "$line" - set -- "$@" --state "$state" - # Ensure __line does not read stdin - __line "$@" < /dev/null + cat << DONE +tmpfile=\$(mktemp ${file}.cdist.XXXXXXXXXX) +# preserve ownership and permissions of existing file +if [ -f "$file" ]; then + cp -p "$file" "\$tmpfile" +fi +grep -v -F -x '$line' '$file' > \$tmpfile || true +mv -f "\$tmpfile" "$file" +DONE } +add_line() { + file="$1" + line="$2" + # escape single quotes + line_sanitised=$(echo "$line" | sed -e "s/'/'\"'\"'/g") + printf '%s' "printf '%s\n' '$line_sanitised' >> $file" +} + + +file="$(cat "$__object/parameter/file")" +mkdir "$__object/files" + # Generate the entry as it should be ( if [ -f "$__object/parameter/option" ]; then + # comma seperated list of options options="$(cat "$__object/parameter/option" | tr '\n' ',')" printf '%s ' "${options%*,}" fi @@ -56,20 +61,37 @@ _do_line() { fi ) > "$__object/files/should" -# Check for existing and conflicting entries and remove them +# Remove conflicting entries if any if [ -s "$__object/explorer/entry" ]; then - # We have existing entries for this key. - # Check if any of them are in conflict to how the entry should be. - # Note that the file has to be sorted for comparison with `comm`. + # Note that the files have to be sorted for comparison with `comm`. sort "$__object/explorer/entry" > "$__object/files/is" comm -13 "$__object/files/should" "$__object/files/is" | { - # Remove conflicting entries while read entry; do - _do_line "$file" "$entry" absent + remove_line "$file" "$entry" done } fi +# Determine the current state +state_should="$(cat "$__object/parameter/state")" +if grep -q -F -x "$entry" "$__object/explorer/entry"; then + state_is="present" +else + state_is="absent" +fi + # Manage the actual entry as it should be +if [ "$state_should" = "$state_is" ]; then + # Nothing to do + exit 0 +fi + entry="$(cat "$__object/files/should")" -_do_line "$file" "$entry" "$state" +case "$state_should" in + present) + add_line "$file" "$entry" + ;; + absent) + remove_line "$file" "$entry" + ;; +esac