From 6d45a492191458f35235b95e8d1107abde610d1b Mon Sep 17 00:00:00 2001
From: Steven Armstrong <steven@icarus.ethz.ch>
Date: Mon, 14 Nov 2011 17:30:52 +0100
Subject: [PATCH] new type: __nfs_export manage /etc/exports

Signed-off-by: Steven Armstrong <steven@icarus.ethz.ch>
---
 conf/type/__nfs_export/explorer/entry     | 42 +++++++++++++++
 conf/type/__nfs_export/explorer/exports.d | 25 +++++++++
 conf/type/__nfs_export/gencode-remote     | 62 +++++++++++++++++++++++
 conf/type/__nfs_export/man.text           | 55 ++++++++++++++++++++
 conf/type/__nfs_export/manifest           | 49 ++++++++++++++++++
 conf/type/__nfs_export/parameter/optional |  3 ++
 conf/type/__nfs_export/parameter/required |  1 +
 7 files changed, 237 insertions(+)
 create mode 100755 conf/type/__nfs_export/explorer/entry
 create mode 100755 conf/type/__nfs_export/explorer/exports.d
 create mode 100755 conf/type/__nfs_export/gencode-remote
 create mode 100644 conf/type/__nfs_export/man.text
 create mode 100755 conf/type/__nfs_export/manifest
 create mode 100644 conf/type/__nfs_export/parameter/optional
 create mode 100644 conf/type/__nfs_export/parameter/required

diff --git a/conf/type/__nfs_export/explorer/entry b/conf/type/__nfs_export/explorer/entry
new file mode 100755
index 00000000..4cb10883
--- /dev/null
+++ b/conf/type/__nfs_export/explorer/entry
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+
+export="$(cat "$__object/parameter/export" 2>/dev/null || echo "/$__object_id")"
+
+name="$(echo "${export#/}" | sed 's;/;-;g')"
+prefix="#cdist:__cron/$export"
+suffix="#/cdist:__cron/$export"
+
+if [ -f "/etc/exports.d/$name" ]; then
+   cat "/etc/exports.d/$name"
+else
+   awk -v prefix="$prefix" -v suffix="$suffix" '{
+   if (index($0,prefix)) {
+      triggered=1
+   }
+   if (triggered) {
+      if (index($0,suffix)) {
+            triggered=0
+      }
+      print
+   }
+}' /etc/exports
+fi
+
diff --git a/conf/type/__nfs_export/explorer/exports.d b/conf/type/__nfs_export/explorer/exports.d
new file mode 100755
index 00000000..ce370573
--- /dev/null
+++ b/conf/type/__nfs_export/explorer/exports.d
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+
+if [ -d /etc/exports.d ]; then
+   echo present
+else
+   echo absent
+fi
diff --git a/conf/type/__nfs_export/gencode-remote b/conf/type/__nfs_export/gencode-remote
new file mode 100755
index 00000000..d0e1e1a1
--- /dev/null
+++ b/conf/type/__nfs_export/gencode-remote
@@ -0,0 +1,62 @@
+#!/bin/sh
+#
+# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+
+exports_d="$(cat "$__object/explorer/exports.d")"
+state_should="$(cat "$__object/parameter/state")"
+state_is=$(diff -q "$__object/parameter/entry" "$__object/explorer/entry" \
+   && echo present \
+   || echo absent
+)
+
+if [ "$exports_d" != "present" ]; then
+   if [ "$state_is" != "$state_should" ]; then
+      case "$state_should" in
+         present)
+         cat << DONE
+cat >> /etc/exports << EOC
+$(cat "$__object/parameter/entry")"
+EOC
+DONE
+         ;;
+         absent)
+            # defined in type manifest
+            prefix="$(cat "$__object/parameter/prefix")"
+            suffix="$(cat "$__object/parameter/suffix")"
+            cat << DONE
+cat /etc/exports
+awk -v prefix="$prefix" -v suffix="$suffix" '
+{
+   if (index(\$0,prefix)) {
+      triggered=1
+   }
+   if (triggered) {
+      if (index(\$0,suffix)) {
+            triggered=0
+      }
+   } else {
+      print
+   }
+}' /etc/exports > /etc/exports+
+mv -f /etc/exports+ /etc/exports
+DONE
+         ;;
+      esac
+   fi
+fi
diff --git a/conf/type/__nfs_export/man.text b/conf/type/__nfs_export/man.text
new file mode 100644
index 00000000..41ff64e8
--- /dev/null
+++ b/conf/type/__nfs_export/man.text
@@ -0,0 +1,55 @@
+cdist-type__nfs_export(7)
+=========================
+Steven Armstrong <steven-cdist--@--armstrong.cc>
+
+
+NAME
+----
+cdist-type__nfs_export - manage nfs exports
+
+
+DESCRIPTION
+-----------
+This cdist type allows you to manage entries in /etc/exports.d.
+For older distributions (currently ubuntu lucid) that don't support 
+/etc/exports.d the entries are merged into the /etc/exports file.
+
+
+REQUIRED PARAMETERS
+-------------------
+client::
+   space delimited list of client ip/networks for use in /etc/exports. See exports(5)
+
+
+OPTIONAL PARAMETERS
+-------------------
+options::
+   export options for use in /etc/exports. See exports(5)
+
+export::
+   the directory to export. Defaults to object_id
+
+state::
+   Either present or absent. Defaults to present.
+
+
+EXAMPLES
+--------
+
+--------------------------------------------------------------------------------
+__nfs_export /local/chroot/lucid-amd64 \
+   --client "192.168.0.1/24 10.0.0.1/16" \
+   --options "ro,async,no_all_squash,no_root_squash,subtree_check"
+--------------------------------------------------------------------------------
+
+
+SEE ALSO
+--------
+- cdist-type(7)
+- exports(5)
+
+
+COPYING
+-------
+Copyright \(C) 2011 Steven Armstrong. Free use of this software is
+granted under the terms of the GNU General Public License version 3 (GPLv3).
diff --git a/conf/type/__nfs_export/manifest b/conf/type/__nfs_export/manifest
new file mode 100755
index 00000000..1a267412
--- /dev/null
+++ b/conf/type/__nfs_export/manifest
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# 2011 Steven Armstrong (steven-cdist at armstrong.cc)
+#
+# This file is part of cdist.
+#
+# cdist is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cdist is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with cdist. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# required
+client="$(cat "$__object/parameter/client")"
+
+# optional
+export="$(cat "$__object/parameter/export" 2>/dev/null \
+   || echo "/$__object_id" | tee "$__object/parameter/export")"
+options="$(cat "$__object/parameter/options" 2>/dev/null || true)"
+state="$(cat "$__object/parameter/state" 2>/dev/null \
+   || echo "present" | tee "$__object/parameter/state")"
+
+entry="$export"
+[ -n "$options" ] && entry="$entry -${options}"
+entry="$entry $client"
+
+# NOTE: if changed, also change in explorers
+prefix="#cdist:__nfs_export/$export"
+suffix="#/cdist:__nfs_export/$export"
+echo "$prefix" | tee "$__object/parameter/prefix" > "$__object/parameter/entry"
+echo "$entry" >> "$__object/parameter/entry"
+echo "$suffix" | tee "$__object/parameter/suffix" >> "$__object/parameter/entry"
+
+exports_d="$(cat "$__object/explorer/exports.d")"
+if [ "$exports_d" = "present" ]; then
+   name="$(echo "$export" | sed 's;/;-;g')"
+   __file "/etc/exports.d/$name" \
+      --source "$__object/parameter/entry" \
+      --owner root --group root --mode 644
+#      --state "$state"
+fi
diff --git a/conf/type/__nfs_export/parameter/optional b/conf/type/__nfs_export/parameter/optional
new file mode 100644
index 00000000..f6cd84ea
--- /dev/null
+++ b/conf/type/__nfs_export/parameter/optional
@@ -0,0 +1,3 @@
+options
+export
+state
diff --git a/conf/type/__nfs_export/parameter/required b/conf/type/__nfs_export/parameter/required
new file mode 100644
index 00000000..b051c6c5
--- /dev/null
+++ b/conf/type/__nfs_export/parameter/required
@@ -0,0 +1 @@
+client