Merge "Make number of Octavia controller workers configurable"
diff --git a/.kitchen.yml b/.kitchen.yml
index e3badca..69f2c1b 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -15,6 +15,10 @@
   grains:
     noservices: True
   dependencies:
+    - name: keystone
+      repo: git
+      source: https://gerrit.mcp.mirantis.com/salt-formulas/keystone
+      branch: <%=ENV['GERRIT_BRANCH'] || 'master' %>
     - name: linux
       repo: git
       source: https://gerrit.mcp.mirantis.com/salt-formulas/linux
diff --git a/README.rst b/README.rst
index 94a76c1..649b9a2 100644
--- a/README.rst
+++ b/README.rst
@@ -134,6 +134,21 @@
           user: octavia
           group: octavia
 
+Octavia policy rules:
+
+.. code-block:: yaml
+
+    octavia:
+      api:
+        policy:
+          context_is_admin: 'role:admin or role:load-balancer_admin'
+          admin_or_owner: 'is_admin:True or project_id:%(project_id)s'
+          load-balancer:read: 'rule:admin_or_owner'
+          load-balancer:read-global: 'is_admin:True'
+          load-balancer:write: 'rule:admin_or_owner'
+          load-balancer:read-quota: 'rule:admin_or_owner'
+          load-balancer:read-quota-global: 'is_admin:True'
+          load-balancer:write-quota: 'is_admin:True'
 
 Upgrades
 ========
diff --git a/metadata.yml b/metadata.yml
index e7875d0..b37c957 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -2,6 +2,8 @@
 version: "2017.6"
 source: "https://gerrit.mcp.mirantis.com/salt-formulas/octavia"
 dependencies:
+  - name: keystone
+    source: "https://gerrit.mcp.mirantis.com/salt-formulas/keystone"
   - name: neutron
     source: "https://gerrit.mcp.mirantis.com/salt-formulas/neutron"
   - name: nova
diff --git a/octavia/api.sls b/octavia/api.sls
index b259899..689cb7e 100644
--- a/octavia/api.sls
+++ b/octavia/api.sls
@@ -30,6 +30,41 @@
   - require_in:
     - sls: octavia.db.offline_sync
 
+/etc/octavia/{{ api.get('oslo_policy', {}).get('policy_file', 'policy.json') }}:
+  file.managed:
+    - mode: 0640
+    - replace: False
+    - user: octavia
+    - group: octavia
+    - require:
+      - pkg: octavia_api_packages
+
+{%- for name, rule in api.get('policy', {}).iteritems() %}
+
+{%- if rule != None %}
+octavia_keystone_rule_{{ name }}_present:
+  keystone_policy.rule_present:
+  - path: /etc/octavia/{{ api.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+  - name: {{ name }}
+  - rule: {{ rule }}
+  - require:
+    - pkg: octavia_api_packages
+    - file: /etc/octavia/{{ api.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+
+{%- else %}
+
+octavia_keystone_rule_{{ name }}_absent:
+  keystone_policy.rule_absent:
+  - path: /etc/octavia/{{ api.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+  - name: {{ name }}
+  - require:
+    - pkg: octavia_api_packages
+    - file: /etc/octavia/{{ api.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+
+{%- endif %}
+
+{%- endfor %}
+
 {%- if pillar.octavia.manager is not defined %}
 /etc/octavia/dhcp/:
   file.directory:
diff --git a/octavia/map.jinja b/octavia/map.jinja
index fd83957..e8f98f6 100644
--- a/octavia/map.jinja
+++ b/octavia/map.jinja
@@ -14,6 +14,9 @@
         'services': ['octavia-api'],
         'notification': False,
         'cors': {},
+        'oslo_policy': {
+          'policy_file': 'policy.json'
+        },
         'audit': {
           'enabled': false
         }
@@ -23,6 +26,9 @@
         'services': ['octavia-api'],
         'notification': False,
         'cors': {},
+        'oslo_policy': {
+          'policy_file': 'policy.json'
+        },
         'audit': {
           'enabled': false
         }
diff --git a/tests/pillar/api_cluster.sls b/tests/pillar/api_cluster.sls
index 4322f07..74cdb4b 100644
--- a/tests/pillar/api_cluster.sls
+++ b/tests/pillar/api_cluster.sls
@@ -31,3 +31,12 @@
       - host: 127.0.0.1
       - host: 127.0.1.1
       - host: 127.0.2.1
+    policy:
+      context_is_admin: 'role:admin or role:load-balancer_admin'
+      admin_or_owner: 'is_admin:True or project_id:%(project_id)s'
+      load-balancer:read: 'rule:admin_or_owner'
+      load-balancer:read-global: 'is_admin:True'
+      load-balancer:write: 'rule:admin_or_owner'
+      load-balancer:read-quota: 'rule:admin_or_owner'
+      load-balancer:read-quota-global: 'is_admin:True'
+      load-balancer:write-quota: 'is_admin:True'
diff --git a/tests/pillar/api_single.sls b/tests/pillar/api_single.sls
index 4f9411c..a4d6d4d 100644
--- a/tests/pillar/api_single.sls
+++ b/tests/pillar/api_single.sls
@@ -27,3 +27,12 @@
       user: openstack
       password: password
       virtual_host: '/openstack'
+    policy:
+      context_is_admin: 'role:admin or role:load-balancer_admin'
+      admin_or_owner: 'is_admin:True or project_id:%(project_id)s'
+      load-balancer:read: 'rule:admin_or_owner'
+      load-balancer:read-global: 'is_admin:True'
+      load-balancer:write: 'rule:admin_or_owner'
+      load-balancer:read-quota: 'rule:admin_or_owner'
+      load-balancer:read-quota-global: 'is_admin:True'
+      load-balancer:write-quota: 'is_admin:True'