Implemented Jenkins views enforcing.
diff --git a/README.rst b/README.rst
index f74f006..1ccd8c2 100644
--- a/README.rst
+++ b/README.rst
@@ -369,6 +369,26 @@
 
 `Common matrix strategies <https://github.com/arbabnazar/configuration/blob/c08a5eaf4e04a68d2481375502a926517097b253/playbooks/roles/tools_jenkins/templates/projectBasedMatrixSecurity.groovy.j2>`_
 
+Views enforcing from client
+
+.. code-block:: yaml
+
+    jenkins:
+      client:
+        view:
+         my-list-view:
+           enabled: true
+           type: ListView
+           include_regex: ".\*."
+         my-view:
+           # set false to disable
+           enabled: true
+           type: MyView
+
+View specific params:
+
+- include_regex for ListView
+
 
 Credentials enforcing from client
 
diff --git a/_states/jenkins_view.py b/_states/jenkins_view.py
new file mode 100644
index 0000000..e14d3fd
--- /dev/null
+++ b/_states/jenkins_view.py
@@ -0,0 +1,101 @@
+import logging
+logger = logging.getLogger(__name__)
+
+add_view_groovy = """\
+view = Jenkins.instance.getView("{view_name}")
+if(view){{
+  if(view.getClass().getName().equals("hudson.model.ListView")){{
+    include_regex="{include_regex}"
+    if(include_regex != "" && !view.getIncludeRegex().equals(include_regex)){{
+        view.setIncludeRegex(include_regex)
+        print("ADDED/CHANGED")
+    }}else{{
+        print("EXISTS")
+    }}
+  }}else{{
+    print("EXISTS")
+  }}
+}}else{{
+  try{{
+    {view_def}
+    Jenkins.instance.addView(view)
+    print("ADDED/CHANGED")
+  }}catch(Exception e){{
+    print("FAILED")
+  }}
+}}
+""" # noqa
+
+remove_view_groovy = """\
+view = Jenkins.instance.getView("{view_name}")
+if(view){{
+  try{{
+    Jenkins.instance.deleteView(view)
+    print("REMOVED")
+  }}catch(Exception e){{
+    print("FAILED")
+  }}
+}}else{{
+  print("NOT PRESENT")
+}}
+""" # noqa
+
+
+def present(name, type="ListView", **kwargs):
+    """
+    Jenkins view present state method
+
+    :param name: view name
+    :param type: view type (default ListView)
+    :returns: salt-specified state dict
+    """
+    return _plugin_call(name, type, add_view_groovy, ["ADDED/CHANGED", "EXISTS"], **kwargs)
+
+
+def absent(name, **kwargs):
+    """
+    Jenkins view absent state method
+
+    :param name: view name
+    :returns: salt-specified state dict
+    """
+    return _plugin_call(name, None, remove_view_groovy, ["REMOVED", "NOT PRESENT"], **kwargs)
+
+
+def _plugin_call(name, type, template, success_msgs, **kwargs):
+    test = __opts__['test']  # noqa
+    ret = {
+        'name': name,
+        'changes': {},
+        'result': False,
+        'comment': '',
+    }
+    result = False
+    if test:
+        status = success_msgs[0]
+        ret['changes'][name] = status
+        ret['comment'] = 'Jenkins view %s %s' % (name, status.lower())
+    else:
+        view_def = "view = new {}(\"{}\")".format(type, name)
+        # handle view specific params
+        include_regex = kwargs.get('include_regex')
+        if type == "ListView":
+            if include_regex:
+                view_def += "\nview.setIncludeRegex(\"{}\")".format(include_regex)
+
+        call_result = __salt__['jenkins_common.call_groovy_script'](
+            template, {"view_def": view_def, "view_name": name, "type": type if type else "", "include_regex": include_regex if include_regex else ""})
+        if call_result["code"] == 200 and call_result["msg"] in success_msgs:
+            status = call_result["msg"]
+            if status == success_msgs[0]:
+                ret['changes'][name] = status
+            ret['comment'] = 'Jenkins view %s %s' % (name, status.lower())
+            result = True
+        else:
+            status = 'FAILED'
+            logger.error(
+                "Jenkins view API call failure: %s", call_result["msg"])
+            ret['comment'] = 'Jenkins view API call failure: %s' % (call_result[
+                                                                           "msg"])
+    ret['result'] = None if test else result
+    return ret
diff --git a/jenkins/client/init.sls b/jenkins/client/init.sls
index 852aadc..855ac9d 100644
--- a/jenkins/client/init.sls
+++ b/jenkins/client/init.sls
@@ -23,6 +23,9 @@
 {%- if client.node is defined %}
   - jenkins.client.node
 {%- endif %}
+{%- if client.view is defined %}
+  - jenkins.client.view
+{%- endif %}
 
 jenkins_client_install:
   pkg.installed:
diff --git a/jenkins/client/view.sls b/jenkins/client/view.sls
new file mode 100644
index 0000000..7ac0b07
--- /dev/null
+++ b/jenkins/client/view.sls
@@ -0,0 +1,17 @@
+{% from "jenkins/map.jinja" import client with context %}
+{% for name, view in client.get('view',{}).iteritems() %}
+{% if view.get('enabled', True) %}
+view_{{ name }}:
+  jenkins_view.present:
+  - name: {{ view.get('name', name) }}
+  {%- for key, value in view.iteritems() %}
+  {%- if key != "name" %}
+  - {{ key }}: {{ value }}
+  {%- endif %}
+  {%- endfor %}
+{% else %}
+view_{{ name }}_disable:
+   jenkins_view.absent:
+   - name: {{ view.get('name', name) }}
+{% endif %}
+{% endfor %}
\ No newline at end of file