diff --git a/conf/type/__key_value/explorer/value b/conf/type/__key_value/explorer/state
similarity index 54%
rename from conf/type/__key_value/explorer/value
rename to conf/type/__key_value/explorer/state
index b4e1fafd..7e66cb69 100755
--- a/conf/type/__key_value/explorer/value
+++ b/conf/type/__key_value/explorer/state
@@ -17,19 +17,34 @@
# You should have received a copy of the GNU General Public License
# along with cdist. If not, see .
#
-#
-# Get the current value of key or __NOTSET__ if the key doesn't exist.
-#
key="$(cat "$__object/parameter/key" 2>/dev/null \
|| echo "$__object_id")"
-
+state="$(cat "$__object/parameter/state" 2>/dev/null \
+ || echo "present")"
file="$(cat "$__object/parameter/file")"
delimiter="$(cat "$__object/parameter/delimiter")"
+value="$(cat "$__object/parameter/value" 2>/dev/null \
+ || echo "__CDIST_NOTSET__")"
-awk -F "$delimiter" '
-BEGIN { found=0 }
-/^'$key'/ { print $2; found=1 }
-END { if (found) exit 0; else exit 1 }' "$file" \
-|| echo "__NOTSET__"
-
+case "$state" in
+ absent)
+ # if the key exists, with whatever value, we will have to remove it
+ # so report it as present
+ if egrep -q "^$key$delimiter+" "$file"; then
+ echo present
+ fi
+ ;;
+ present)
+ if egrep -q "^$key$delimiter+$value$" "$file"; then
+ # key exists and value is same
+ echo present
+ elif egrep -q "^$key$delimiter+" "$file"; then
+ # key exists, but value is empty or different
+ echo wrongvalue
+ else
+ # key does not exist
+ echo absent
+ fi
+ ;;
+esac
diff --git a/conf/type/__key_value/gencode-remote b/conf/type/__key_value/gencode-remote
index 08b3a0f3..0846dca1 100755
--- a/conf/type/__key_value/gencode-remote
+++ b/conf/type/__key_value/gencode-remote
@@ -18,32 +18,40 @@
# along with cdist. If not, see .
#
-value_is="$(cat "$__object/explorer/value")"
-value_should="$(cat "$__object/parameter/value")"
-
key="$(cat "$__object/parameter/key")"
file="$(cat "$__object/parameter/file")"
delimiter="$(cat "$__object/parameter/delimiter")"
+value="$(cat "$__object/parameter/value")"
-if [ "$value_is" != "$value_should" ]; then
- case "$value_is" in
- __NOTSET__)
- # add key and value
- echo "echo \"${key}${delimiter}${value_should}\" >> \"$file\""
- ;;
- *)
- if [ "$value_should" = '__NOTSET__' ]; then
- # remove key and value
- cat << DONE
-sed -i '/^${key}/d' "$file"
-DONE
- else
- # change value
- cat << DONE
-sed -i "s|^$key\($delimiter\+\).*|$key\1$value_should|" "$file"
-DONE
- fi
- ;;
- esac
+state_is="$(cat "$__object/explorer/state")"
+state_should="$(cat "$__object/parameter/state")"
+
+if [ "$state_is" = "$state_should" ]; then
+ # nothing to do
+ exit 0
fi
+case "$state_should" in
+ absent)
+ # remove lines starting with key
+ echo "sed -i '/^$key\($delimiter\+\)/d' \"$file\""
+ ;;
+ present)
+ case "$state_is" in
+ absent)
+ # add new key and value
+ echo "echo \"${key}${delimiter}${value}\" >> \"$file\""
+ ;;
+ wrongvalue)
+ # change exisiting value
+ echo "sed -i \"s|^$key\($delimiter\+\).*|$key\1$value|\" \"$file\""
+ ;;
+ *)
+ echo "Unknown explorer state: $state_is" >&2
+ exit 1
+ esac
+ ;;
+ *)
+ echo "Unknown state: $state_should" >&2
+ exit 1
+esac
diff --git a/conf/type/__key_value/man.text b/conf/type/__key_value/man.text
index 3e4e8013..1423fc7d 100644
--- a/conf/type/__key_value/man.text
+++ b/conf/type/__key_value/man.text
@@ -16,9 +16,6 @@ file.
REQUIRED PARAMETERS
-------------------
-value::
- The value for the key. Setting the value to `__NOTSET__` will remove the key
- from the file.
file::
The file to operate on.
delimiter::
@@ -27,8 +24,13 @@ delimiter::
OPTIONAL PARAMETERS
-------------------
+state::
+ present or absent, defaults to present. If present, sets the key to value,
+ if absent, removes the key from the file.
key::
The key to change. Defaults to object_id.
+value::
+ The value for the key. Optional if state=absent, required otherwise.
EXAMPLES
@@ -45,6 +47,9 @@ __key_value my-fancy-id --file /etc/login.defs --key SYS_UID_MAX --value 666 \
# Enable packet forwarding
__key_value net.ipv4.ip_forward --file /etc/sysctl.conf --value 1 \
--delimiter '='
+
+# Remove existing key/value
+__key_value LEGACY_KEY --file /etc/somefile --state absent --delimiter '='
--------------------------------------------------------------------------------
diff --git a/conf/type/__key_value/manifest b/conf/type/__key_value/manifest
index 84c06352..2e75e175 100755
--- a/conf/type/__key_value/manifest
+++ b/conf/type/__key_value/manifest
@@ -19,5 +19,12 @@
#
# set defaults
-[ -f "$__object/parameter/key" ] \
- || echo "$__object_id" > "$__object/parameter/key"
+key="$(cat "$__object/parameter/key" 2>/dev/null \
+ || echo "$__object_id" | tee "$__object/parameter/key")"
+state="$(cat "$__object/parameter/state" 2>/dev/null \
+ || echo "present" | tee "$__object/parameter/state")"
+
+if [ "$state" = "present" -a ! -f "$__object/parameter/value" ]; then
+ echo "Missing required parameter 'value'" >&2
+ exit 1
+fi
diff --git a/conf/type/__key_value/parameter/optional b/conf/type/__key_value/parameter/optional
index 06bfde49..483e3192 100644
--- a/conf/type/__key_value/parameter/optional
+++ b/conf/type/__key_value/parameter/optional
@@ -1 +1,3 @@
key
+value
+state
diff --git a/conf/type/__key_value/parameter/required b/conf/type/__key_value/parameter/required
index 8f4aa53c..3ae10da3 100644
--- a/conf/type/__key_value/parameter/required
+++ b/conf/type/__key_value/parameter/required
@@ -1,3 +1,2 @@
-value
file
delimiter