Merge "Allow enforcing of whole /etc/hosts"
diff --git a/README.rst b/README.rst
index 14f0cb3..bf966e4 100644
--- a/README.rst
+++ b/README.rst
@@ -529,12 +529,25 @@
 
 Linux with hosts
 
+Parameter purge_hosts will enforce whole /etc/hosts file, removing entries
+that are not defined in model except defaults for both IPv4 and IPv6 localhost
+and hostname + fqdn.
+It's good to use this option if you want to ensure /etc/hosts is always in a
+clean state however it's not enabled by default for safety.
+
 .. code-block:: yaml
 
     linux:
       network:
         ...
+        purge_hosts: true
         host:
+          # No need to define this one if purge_hosts is true
+          hostname:
+            address: 127.0.1.1
+            names:
+            - ${linux:network:fqdn}
+            - ${linux:network:hostname}
           node1:
             address: 192.168.10.200
             names:
@@ -546,6 +559,7 @@
             - node2.domain.com
             - service2.domain.com
 
+
 Setup resolv.conf, nameservers, domain and search domains
 
 .. code-block:: yaml
diff --git a/linux/files/hosts b/linux/files/hosts
new file mode 100644
index 0000000..7e7e06c
--- /dev/null
+++ b/linux/files/hosts
@@ -0,0 +1,33 @@
+{#-
+    vim: syntax=jinja
+-#}
+{%- from "linux/map.jinja" import network with context -%}
+# hosts(1) file managed by salt-minion(1)
+#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+
+{%- set hosts = {
+    '127.0.0.1': [
+        'localhost'
+    ],
+    '127.0.1.1': [
+        network.fqdn|default(grains.fqdn),
+        network.hostname|default(grains.nodename)
+    ],
+    '::1': [
+        'localhost',
+        'ip6-localhost',
+        'ip6-loopback'
+    ],
+    'ff02::1': [
+        'ip6-allnodes'
+    ],
+    'ff02::2': [
+        'ip6-allrouters'
+    ],
+} -%}
+{%- for name, host in network.host.iteritems() -%}
+{%- do hosts.update({host.address: host.names}) -%}
+{%- endfor %}
+{% for address, entries in hosts|dictsort %}
+{{ address }}   {{ entries|join(' ') }}
+{%- endfor %}
diff --git a/linux/network/host.sls b/linux/network/host.sls
index 6749350..f0811a2 100644
--- a/linux/network/host.sls
+++ b/linux/network/host.sls
@@ -1,6 +1,16 @@
 {%- from "linux/map.jinja" import network with context %}
 {%- if network.enabled %}
 
+{%- if network.get('purge_hosts', false) %}
+
+linux_hosts:
+  file.managed:
+    - name: /etc/hosts
+    - source: salt://linux/files/hosts
+    - template: jinja
+
+{%- else %}
+
 {%- for name, host in network.host.iteritems() %}
 
 {%- if host.names is defined %}
@@ -38,3 +48,5 @@
 {%- endfor %}
 
 {%- endif %}
+
+{%- endif %}
diff --git a/linux/network/init.sls b/linux/network/init.sls
index cc9008a..cdef5a7 100644
--- a/linux/network/init.sls
+++ b/linux/network/init.sls
@@ -1,7 +1,7 @@
 {%- from "linux/map.jinja" import network with context %}
 include:
 - linux.network.hostname
-{%- if network.host|length > 0 %}
+{%- if network.host|length > 0 or network.get('purge_hosts', True) %}
 - linux.network.host
 {%- endif %}
 {%- if network.resolv is defined %}