Add ability to configure policy file

Related: PROD-33994
Related: PROD-31956

Change-Id: I84458da9fea585fb036d65fcd3ef8e443ecd20ad
diff --git a/README.rst b/README.rst
index 6c9c9e4..4bae229 100644
--- a/README.rst
+++ b/README.rst
@@ -287,6 +287,19 @@
             admin_password: password
             admin_tenant_name: tenant1
 
+Change default service policy configuration
+===========================================
+
+.. code-block:: yaml
+
+    designate:
+      server:
+        policy:
+          admin: 'role:admin'
+          primary_zone: 'target.zone_type:PRIMARY'
+          # Add key without value to remove line from policy.json
+          get_quotas:
+
 Upgrades
 ========
 
diff --git a/designate/files/pike/policy.json b/designate/files/pike/policy.json
new file mode 100644
index 0000000..d27f435
--- /dev/null
+++ b/designate/files/pike/policy.json
@@ -0,0 +1,113 @@
+{
+    "admin": "role:admin or is_admin:True",
+    "primary_zone": "target.zone_type:SECONDARY",
+    "owner": "tenant:%(tenant_id)s",
+    "admin_or_owner": "rule:admin or rule:owner",
+    "default": "rule:admin_or_owner",
+    "target": "tenant:%(target_tenant_id)s",
+    "owner_or_target": "rule:target or rule:owner",
+    "admin_or_owner_or_target": "rule:owner_or_target or rule:admin",
+    "admin_or_target": "rule:admin or rule:target",
+    "zone_primary_or_admin": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+
+    "create_blacklist": "rule:admin",
+    "find_blacklist": "rule:admin",
+    "find_blacklists": "rule:admin",
+    "get_blacklist": "rule:admin",
+    "update_blacklist": "rule:admin",
+    "delete_blacklist": "rule:admin",
+    "use_blacklisted_zone": "rule:admin",
+
+    "all_tenants": "rule:admin",
+
+    "edit_managed_records": "rule:admin",
+
+    "use_low_ttl": "rule:admin",
+
+    "use_sudo": "rule:admin",
+
+    "diagnostics_ping": "rule:admin",
+    "diagnostics_sync_zones": "rule:admin",
+    "diagnostics_sync_zone": "rule:admin",
+    "diagnostics_sync_record": "rule:admin",
+
+    "create_pool": "rule:admin",
+    "find_pools": "rule:admin",
+    "find_pool": "rule:admin",
+    "get_pool": "rule:admin",
+    "update_pool": "rule:admin",
+    "delete_pool": "rule:admin",
+    "zone_create_forced_pool": "rule:admin",
+
+    "get_quotas": "rule:admin_or_owner",
+    "get_quota": "rule:admin_or_owner",
+    "set_quota": "rule:admin",
+    "reset_quotas": "rule:admin",
+
+    "find_records": "rule:admin_or_owner",
+    "count_records": "rule:admin_or_owner",
+    "create_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "get_recordsets": "rule:admin_or_owner",
+    "get_recordset": "rule:admin_or_owner",
+    "update_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "delete_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "count_recordset": "rule:admin_or_owner",
+
+    "find_service_status": "rule:admin",
+    "find_service_statuses": "rule:admin",
+    "update_service_status": "rule:admin",
+
+    "find_tenants": "rule:admin",
+    "get_tenant": "rule:admin",
+    "count_tenants": "rule:admin",
+
+    "create_tld": "rule:admin",
+    "find_tlds": "rule:admin",
+    "get_tld": "rule:admin",
+    "update_tld": "rule:admin",
+    "delete_tld": "rule:admin",
+
+    "create_tsigkey": "rule:admin",
+    "find_tsigkeys": "rule:admin",
+    "get_tsigkey": "rule:admin",
+    "update_tsigkey": "rule:admin",
+    "delete_tsigkey": "rule:admin",
+
+    "create_zone": "rule:admin_or_owner",
+    "get_zones": "rule:admin_or_owner",
+    "get_zone": "rule:admin_or_owner",
+    "get_zone_servers": "rule:admin_or_owner",
+    "find_zones": "rule:admin_or_owner",
+    "update_zone": "rule:admin_or_owner",
+    "delete_zone": "rule:admin_or_owner",
+    "xfr_zone": "rule:admin_or_owner",
+    "abandon_zone": "rule:admin",
+    "count_zones": "rule:admin_or_owner",
+    "count_zones_pending_notify": "rule:admin_or_owner",
+    "purge_zones": "rule:admin",
+    "touch_zone": "rule:admin_or_owner",
+
+    "zone_export": "rule:admin_or_owner",
+    "create_zone_export": "rule:admin_or_owner",
+    "find_zone_exports": "rule:admin_or_owner",
+    "get_zone_export": "rule:admin_or_owner",
+    "update_zone_export": "rule:admin_or_owner",
+    "create_zone_import": "rule:admin_or_owner",
+    "find_zone_imports": "rule:admin_or_owner",
+    "get_zone_import": "rule:admin_or_owner",
+    "update_zone_import": "rule:admin_or_owner",
+
+    "create_zone_transfer_accept": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_accept": "rule:admin_or_owner",
+    "find_zone_transfer_accepts": "rule:admin",
+    "find_zone_transfer_accept": "rule:admin",
+    "update_zone_transfer_accept": "rule:admin",
+    "delete_zone_transfer_accept": "rule:admin",
+    "create_zone_transfer_request": "rule:admin_or_owner",
+    "get_zone_transfer_request": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_request_detailed": "rule:admin_or_owner",
+    "find_zone_transfer_requests": "@",
+    "find_zone_transfer_request": "@",
+    "update_zone_transfer_request": "rule:admin_or_owner",
+    "delete_zone_transfer_request": "rule:admin_or_owner"
+}
diff --git a/designate/files/queens/policy.json b/designate/files/queens/policy.json
new file mode 100644
index 0000000..d27f435
--- /dev/null
+++ b/designate/files/queens/policy.json
@@ -0,0 +1,113 @@
+{
+    "admin": "role:admin or is_admin:True",
+    "primary_zone": "target.zone_type:SECONDARY",
+    "owner": "tenant:%(tenant_id)s",
+    "admin_or_owner": "rule:admin or rule:owner",
+    "default": "rule:admin_or_owner",
+    "target": "tenant:%(target_tenant_id)s",
+    "owner_or_target": "rule:target or rule:owner",
+    "admin_or_owner_or_target": "rule:owner_or_target or rule:admin",
+    "admin_or_target": "rule:admin or rule:target",
+    "zone_primary_or_admin": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+
+    "create_blacklist": "rule:admin",
+    "find_blacklist": "rule:admin",
+    "find_blacklists": "rule:admin",
+    "get_blacklist": "rule:admin",
+    "update_blacklist": "rule:admin",
+    "delete_blacklist": "rule:admin",
+    "use_blacklisted_zone": "rule:admin",
+
+    "all_tenants": "rule:admin",
+
+    "edit_managed_records": "rule:admin",
+
+    "use_low_ttl": "rule:admin",
+
+    "use_sudo": "rule:admin",
+
+    "diagnostics_ping": "rule:admin",
+    "diagnostics_sync_zones": "rule:admin",
+    "diagnostics_sync_zone": "rule:admin",
+    "diagnostics_sync_record": "rule:admin",
+
+    "create_pool": "rule:admin",
+    "find_pools": "rule:admin",
+    "find_pool": "rule:admin",
+    "get_pool": "rule:admin",
+    "update_pool": "rule:admin",
+    "delete_pool": "rule:admin",
+    "zone_create_forced_pool": "rule:admin",
+
+    "get_quotas": "rule:admin_or_owner",
+    "get_quota": "rule:admin_or_owner",
+    "set_quota": "rule:admin",
+    "reset_quotas": "rule:admin",
+
+    "find_records": "rule:admin_or_owner",
+    "count_records": "rule:admin_or_owner",
+    "create_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "get_recordsets": "rule:admin_or_owner",
+    "get_recordset": "rule:admin_or_owner",
+    "update_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "delete_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "count_recordset": "rule:admin_or_owner",
+
+    "find_service_status": "rule:admin",
+    "find_service_statuses": "rule:admin",
+    "update_service_status": "rule:admin",
+
+    "find_tenants": "rule:admin",
+    "get_tenant": "rule:admin",
+    "count_tenants": "rule:admin",
+
+    "create_tld": "rule:admin",
+    "find_tlds": "rule:admin",
+    "get_tld": "rule:admin",
+    "update_tld": "rule:admin",
+    "delete_tld": "rule:admin",
+
+    "create_tsigkey": "rule:admin",
+    "find_tsigkeys": "rule:admin",
+    "get_tsigkey": "rule:admin",
+    "update_tsigkey": "rule:admin",
+    "delete_tsigkey": "rule:admin",
+
+    "create_zone": "rule:admin_or_owner",
+    "get_zones": "rule:admin_or_owner",
+    "get_zone": "rule:admin_or_owner",
+    "get_zone_servers": "rule:admin_or_owner",
+    "find_zones": "rule:admin_or_owner",
+    "update_zone": "rule:admin_or_owner",
+    "delete_zone": "rule:admin_or_owner",
+    "xfr_zone": "rule:admin_or_owner",
+    "abandon_zone": "rule:admin",
+    "count_zones": "rule:admin_or_owner",
+    "count_zones_pending_notify": "rule:admin_or_owner",
+    "purge_zones": "rule:admin",
+    "touch_zone": "rule:admin_or_owner",
+
+    "zone_export": "rule:admin_or_owner",
+    "create_zone_export": "rule:admin_or_owner",
+    "find_zone_exports": "rule:admin_or_owner",
+    "get_zone_export": "rule:admin_or_owner",
+    "update_zone_export": "rule:admin_or_owner",
+    "create_zone_import": "rule:admin_or_owner",
+    "find_zone_imports": "rule:admin_or_owner",
+    "get_zone_import": "rule:admin_or_owner",
+    "update_zone_import": "rule:admin_or_owner",
+
+    "create_zone_transfer_accept": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_accept": "rule:admin_or_owner",
+    "find_zone_transfer_accepts": "rule:admin",
+    "find_zone_transfer_accept": "rule:admin",
+    "update_zone_transfer_accept": "rule:admin",
+    "delete_zone_transfer_accept": "rule:admin",
+    "create_zone_transfer_request": "rule:admin_or_owner",
+    "get_zone_transfer_request": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_request_detailed": "rule:admin_or_owner",
+    "find_zone_transfer_requests": "@",
+    "find_zone_transfer_request": "@",
+    "update_zone_transfer_request": "rule:admin_or_owner",
+    "delete_zone_transfer_request": "rule:admin_or_owner"
+}
diff --git a/designate/files/rocky/policy.json b/designate/files/rocky/policy.json
new file mode 100644
index 0000000..d27f435
--- /dev/null
+++ b/designate/files/rocky/policy.json
@@ -0,0 +1,113 @@
+{
+    "admin": "role:admin or is_admin:True",
+    "primary_zone": "target.zone_type:SECONDARY",
+    "owner": "tenant:%(tenant_id)s",
+    "admin_or_owner": "rule:admin or rule:owner",
+    "default": "rule:admin_or_owner",
+    "target": "tenant:%(target_tenant_id)s",
+    "owner_or_target": "rule:target or rule:owner",
+    "admin_or_owner_or_target": "rule:owner_or_target or rule:admin",
+    "admin_or_target": "rule:admin or rule:target",
+    "zone_primary_or_admin": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+
+    "create_blacklist": "rule:admin",
+    "find_blacklist": "rule:admin",
+    "find_blacklists": "rule:admin",
+    "get_blacklist": "rule:admin",
+    "update_blacklist": "rule:admin",
+    "delete_blacklist": "rule:admin",
+    "use_blacklisted_zone": "rule:admin",
+
+    "all_tenants": "rule:admin",
+
+    "edit_managed_records": "rule:admin",
+
+    "use_low_ttl": "rule:admin",
+
+    "use_sudo": "rule:admin",
+
+    "diagnostics_ping": "rule:admin",
+    "diagnostics_sync_zones": "rule:admin",
+    "diagnostics_sync_zone": "rule:admin",
+    "diagnostics_sync_record": "rule:admin",
+
+    "create_pool": "rule:admin",
+    "find_pools": "rule:admin",
+    "find_pool": "rule:admin",
+    "get_pool": "rule:admin",
+    "update_pool": "rule:admin",
+    "delete_pool": "rule:admin",
+    "zone_create_forced_pool": "rule:admin",
+
+    "get_quotas": "rule:admin_or_owner",
+    "get_quota": "rule:admin_or_owner",
+    "set_quota": "rule:admin",
+    "reset_quotas": "rule:admin",
+
+    "find_records": "rule:admin_or_owner",
+    "count_records": "rule:admin_or_owner",
+    "create_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "get_recordsets": "rule:admin_or_owner",
+    "get_recordset": "rule:admin_or_owner",
+    "update_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "delete_recordset": "('PRIMARY':%(zone_type)s and rule:admin_or_owner) OR ('SECONDARY':%(zone_type)s AND is_admin:True)",
+    "count_recordset": "rule:admin_or_owner",
+
+    "find_service_status": "rule:admin",
+    "find_service_statuses": "rule:admin",
+    "update_service_status": "rule:admin",
+
+    "find_tenants": "rule:admin",
+    "get_tenant": "rule:admin",
+    "count_tenants": "rule:admin",
+
+    "create_tld": "rule:admin",
+    "find_tlds": "rule:admin",
+    "get_tld": "rule:admin",
+    "update_tld": "rule:admin",
+    "delete_tld": "rule:admin",
+
+    "create_tsigkey": "rule:admin",
+    "find_tsigkeys": "rule:admin",
+    "get_tsigkey": "rule:admin",
+    "update_tsigkey": "rule:admin",
+    "delete_tsigkey": "rule:admin",
+
+    "create_zone": "rule:admin_or_owner",
+    "get_zones": "rule:admin_or_owner",
+    "get_zone": "rule:admin_or_owner",
+    "get_zone_servers": "rule:admin_or_owner",
+    "find_zones": "rule:admin_or_owner",
+    "update_zone": "rule:admin_or_owner",
+    "delete_zone": "rule:admin_or_owner",
+    "xfr_zone": "rule:admin_or_owner",
+    "abandon_zone": "rule:admin",
+    "count_zones": "rule:admin_or_owner",
+    "count_zones_pending_notify": "rule:admin_or_owner",
+    "purge_zones": "rule:admin",
+    "touch_zone": "rule:admin_or_owner",
+
+    "zone_export": "rule:admin_or_owner",
+    "create_zone_export": "rule:admin_or_owner",
+    "find_zone_exports": "rule:admin_or_owner",
+    "get_zone_export": "rule:admin_or_owner",
+    "update_zone_export": "rule:admin_or_owner",
+    "create_zone_import": "rule:admin_or_owner",
+    "find_zone_imports": "rule:admin_or_owner",
+    "get_zone_import": "rule:admin_or_owner",
+    "update_zone_import": "rule:admin_or_owner",
+
+    "create_zone_transfer_accept": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_accept": "rule:admin_or_owner",
+    "find_zone_transfer_accepts": "rule:admin",
+    "find_zone_transfer_accept": "rule:admin",
+    "update_zone_transfer_accept": "rule:admin",
+    "delete_zone_transfer_accept": "rule:admin",
+    "create_zone_transfer_request": "rule:admin_or_owner",
+    "get_zone_transfer_request": "rule:admin_or_owner OR tenant:%(target_tenant_id)s OR None:%(target_tenant_id)s",
+    "get_zone_transfer_request_detailed": "rule:admin_or_owner",
+    "find_zone_transfer_requests": "@",
+    "find_zone_transfer_request": "@",
+    "update_zone_transfer_request": "rule:admin_or_owner",
+    "delete_zone_transfer_request": "rule:admin_or_owner"
+}
diff --git a/designate/server.sls b/designate/server.sls
index 9525d55..eddbf8f 100644
--- a/designate/server.sls
+++ b/designate/server.sls
@@ -155,6 +155,37 @@
     - service: designate_server_services
 {%- endif %}
 
+/etc/designate/{{ server.get('oslo_policy', {}).get('policy_file', 'policy.json') }}:
+  file.managed:
+    - source: salt://designate/files/{{ server.version }}/policy.json
+    - user: designate
+    - group: designate
+
+{%- for name, rule in server.get('policy', {}).iteritems() %}
+
+  {%- if rule != None %}
+designate_keystone_rule_{{ name }}_present:
+  keystone_policy.rule_present:
+  - path: /etc/designate/{{ server.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+  - name: {{ name }}
+  - rule: {{ rule }}
+  - require:
+    - pkg: designate_server_packages
+    - file: /etc/designate/{{ server.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+
+  {%- else %}
+
+designate_keystone_rule_{{ name }}_absent:
+  keystone_policy.rule_absent:
+  - path: /etc/designate/{{ server.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+  - name: {{ name }}
+  - require:
+    - pkg: designate_server_packages
+    - file: /etc/designate/{{ server.get('oslo_policy', {}).get('policy_file', 'policy.json') }}
+
+  {%- endif %}
+{%- endfor %}
+
 designate_pool_sync:
   cmd.run:
     - name: designate-manage pool-manager-cache sync