diff --git a/.zuul.yaml b/.zuul.yaml index f2dc6eb83..a45220f09 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -62,7 +62,7 @@ nslookup_target: 'opendev.org' - job: - name: designate-bind9-scoped-tokens + name: designate-bind9-keystone-default-roles post-run: playbooks/designate-bind9/post.yaml parent: designate-base vars: @@ -70,12 +70,9 @@ post-config: $DESIGNATE_CONF: oslo_policy: - enforce_scope: True enforce_new_defaults: True test-config: "$TEMPEST_CONFIG": - enforce_scope: - designate: True dns_feature_enabled: enforce_new_defaults: True @@ -189,7 +186,7 @@ voting: false - designate-bind9-centos-9-stream: voting: false - - designate-bind9-scoped-tokens + - designate-bind9-keystone-default-roles - designate-pdns4 - designate-grenade-bind9 - designate-grenade-pdns4 @@ -199,7 +196,7 @@ fail-fast: true jobs: - designate-bind9 - - designate-bind9-scoped-tokens + - designate-bind9-keystone-default-roles - designate-pdns4 - designate-grenade-pdns4 - designate-ipv6-only-pdns4 diff --git a/designate/api/middleware.py b/designate/api/middleware.py index 9451b8428..932ee874f 100644 --- a/designate/api/middleware.py +++ b/designate/api/middleware.py @@ -202,11 +202,22 @@ class TestContextMiddleware(ContextMiddleware): all_tenants = strutils.bool_from_string( headers.get('X-Test-All-Tenants', 'False')) + role_header = headers.get('X-Test-Role', None) + role_header = role_header.lower() if role_header else None + if role_header == 'admin': + roles = ['admin', 'member', 'reader'] + elif role_header == 'member': + roles = ['member', 'reader'] + elif role_header == 'reader': + roles = ['reader'] + else: + roles = [] + self.make_context( request, user_id=headers.get('X-Test-User-ID', self.default_user_id), project_id=headers.get('X-Test-Tenant-ID', self.default_tenant_id), - all_tenants=all_tenants + all_tenants=all_tenants, roles=roles ) diff --git a/designate/common/constants.py b/designate/common/constants.py index cf837271e..ada9cc031 100644 --- a/designate/common/constants.py +++ b/designate/common/constants.py @@ -49,3 +49,6 @@ QUOTA_ZONE_RECORDSETS = 'zone_recordsets' QUOTA_ZONES = 'zones' VALID_QUOTAS = [QUOTA_API_EXPORT_SIZE, QUOTA_RECORDSET_RECORDS, QUOTA_ZONE_RECORDS, QUOTA_ZONE_RECORDSETS, QUOTA_ZONES] + +# RBAC scopes +PROJECT = 'project' diff --git a/designate/common/policies/base.py b/designate/common/policies/base.py index 90e3fda22..41bdcf075 100644 --- a/designate/common/policies/base.py +++ b/designate/common/policies/base.py @@ -27,13 +27,13 @@ RULE_ANY = "@" # They're allowed to create, read, update, or delete any system-specific # resource. They can also operate on project-specific resources where # applicable (e.g., cleaning up blacklists) -SYSTEM_ADMIN = 'role:admin and system_scope:all' +SYSTEM_ADMIN = 'role:admin' # Generic policy check string for read-only access to system-level resources. # This persona is useful for someone who needs access for auditing or even # support. These uses are also able to view project-specific resources where # applicable (e.g., listing all pools) -SYSTEM_READER = 'role:reader and system_scope:all' +SYSTEM_READER = 'role:admin' # This check string is reserved for actions that require the highest level of # authorization on a project or resources within the project diff --git a/designate/common/policies/blacklist.py b/designate/common/policies/blacklist.py index af23db7df..432d3027a 100644 --- a/designate/common/policies/blacklist.py +++ b/designate/common/policies/blacklist.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -64,7 +65,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_blacklist", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Create blacklist.', operations=[ { @@ -77,7 +78,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_blacklists", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Find blacklists.', operations=[ { @@ -90,7 +91,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_blacklist", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Get blacklist.', operations=[ { @@ -103,7 +104,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_blacklist", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Update blacklist.', operations=[ { @@ -116,7 +117,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_blacklist", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Delete blacklist.', operations=[ { @@ -129,7 +130,7 @@ rules = [ policy.DocumentedRuleDefault( name="use_blacklisted_zone", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Allowed bypass the blacklist.', operations=[ { diff --git a/designate/common/policies/context.py b/designate/common/policies/context.py index e5959d0e6..47ff705b7 100644 --- a/designate/common/policies/context.py +++ b/designate/common/policies/context.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base @@ -54,31 +55,31 @@ rules = [ policy.RuleDefault( name="all_tenants", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Action on all tenants.', deprecated_rule=deprecated_all_tenants), policy.RuleDefault( name="edit_managed_records", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Edit managed records.', deprecated_rule=deprecated_edit_managed_records), policy.RuleDefault( name="use_low_ttl", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Use low TTL.', deprecated_rule=deprecated_use_low_ttl), policy.RuleDefault( name="use_sudo", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Accept sudo from user to tenant.', deprecated_rule=deprecated_use_sudo), policy.RuleDefault( name="hard_delete", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Clean backend resources associated with zone", deprecated_rule=deprecated_hard_delete), ] diff --git a/designate/common/policies/pool.py b/designate/common/policies/pool.py index da39ef16f..2ca4f9ba9 100644 --- a/designate/common/policies/pool.py +++ b/designate/common/policies/pool.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -70,14 +71,14 @@ rules = [ policy.RuleDefault( name="create_pool", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Create pool.', deprecated_rule=deprecated_create_pool ), policy.DocumentedRuleDefault( name="find_pools", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Find pool.', operations=[ { @@ -90,7 +91,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_pool", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Find pools.', operations=[ { @@ -103,7 +104,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_pool", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Get pool.', operations=[ { @@ -116,21 +117,21 @@ rules = [ policy.RuleDefault( name="update_pool", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Update pool.', deprecated_rule=deprecated_update_pool ), policy.RuleDefault( name="delete_pool", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Delete pool.', deprecated_rule=deprecated_delete_pool ), policy.DocumentedRuleDefault( name="zone_create_forced_pool", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='load and set the pool to the one provided in the Zone attributes.', # noqa operations=[ { diff --git a/designate/common/policies/quota.py b/designate/common/policies/quota.py index 7b28d8411..3f01c0ae4 100644 --- a/designate/common/policies/quota.py +++ b/designate/common/policies/quota.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -45,7 +46,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_quotas", check_str=base.SYSTEM_OR_PROJECT_READER_OR_ALL_TENANTS_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="View Current Project's Quotas.", operations=[ { @@ -58,7 +59,7 @@ rules = [ policy.DocumentedRuleDefault( name="set_quota", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Set Quotas.', operations=[ { @@ -71,7 +72,7 @@ rules = [ policy.DocumentedRuleDefault( name="reset_quotas", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description='Reset Quotas.', operations=[ { diff --git a/designate/common/policies/record.py b/designate/common/policies/record.py index 61efe4f9b..f6a0ab4d2 100644 --- a/designate/common/policies/record.py +++ b/designate/common/policies/record.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -40,7 +41,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_records", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description='Find records.', operations=[ { @@ -56,7 +57,7 @@ rules = [ policy.RuleDefault( name="count_records", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_count_records ) ] diff --git a/designate/common/policies/recordset.py b/designate/common/policies/recordset.py index 0b6f16143..5ac25747d 100644 --- a/designate/common/policies/recordset.py +++ b/designate/common/policies/recordset.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -125,7 +126,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_recordset", check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER_ZONE_TYPE, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Recordset", operations=[ { @@ -138,13 +139,13 @@ rules = [ policy.RuleDefault( name="get_recordsets", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_get_recordsets ), policy.DocumentedRuleDefault( name="get_recordset", check_str=base.SYSTEM_OR_PROJECT_READER_OR_SHARED, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get recordset", operations=[ { @@ -157,14 +158,14 @@ rules = [ policy.RuleDefault( name="find_recordset", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="List a Recordset in a Zone", deprecated_rule=deprecated_find_recordset ), policy.DocumentedRuleDefault( name="find_recordsets", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="List Recordsets in a Zone", operations=[ { @@ -177,7 +178,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_recordset", check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER_RECORD_OWNER_ZONE_TYPE, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Update recordset", operations=[ { @@ -190,7 +191,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_recordset", check_str=SYSTEM_ADMIN_OR_PROJECT_MEMBER_RECORD_OWNER_ZONE_TYPE, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Delete RecordSet", operations=[ { @@ -203,7 +204,7 @@ rules = [ policy.RuleDefault( name="count_recordset", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Count recordsets", deprecated_rule=deprecated_count_recordset, ) diff --git a/designate/common/policies/service_status.py b/designate/common/policies/service_status.py index 4672aa3bb..03f4eaff3 100644 --- a/designate/common/policies/service_status.py +++ b/designate/common/policies/service_status.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -46,7 +47,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_service_status", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Find a single Service Status", operations=[ { @@ -59,7 +60,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_service_statuses", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="List service statuses.", operations=[ { @@ -72,7 +73,7 @@ rules = [ policy.RuleDefault( name="update_service_status", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_update_service_status ) ] diff --git a/designate/common/policies/shared_zones.py b/designate/common/policies/shared_zones.py index 80e85dee4..853dc6603 100644 --- a/designate/common/policies/shared_zones.py +++ b/designate/common/policies/shared_zones.py @@ -14,6 +14,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base @@ -53,7 +54,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_zone_share", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get a Zone Share", operations=[ { @@ -66,7 +67,7 @@ rules = [ policy.DocumentedRuleDefault( name="share_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Share a Zone", operations=[ { @@ -92,14 +93,14 @@ rules = [ policy.RuleDefault( name="find_project_zone_share", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Check the can query for a specific projects shares.", deprecated_rule=deprecated_find_project_zone_share ), policy.DocumentedRuleDefault( name="unshare_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Unshare Zone", operations=[ { diff --git a/designate/common/policies/tenant.py b/designate/common/policies/tenant.py index e70b3f7a4..6a2a23cc5 100644 --- a/designate/common/policies/tenant.py +++ b/designate/common/policies/tenant.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -46,21 +47,21 @@ rules = [ policy.RuleDefault( name="find_tenants", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Find all Tenants.", deprecated_rule=deprecated_find_tenants ), policy.RuleDefault( name="get_tenant", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Get all Tenants.", deprecated_rule=deprecated_get_tenant ), policy.RuleDefault( name="count_tenants", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Count tenants", deprecated_rule=deprecated_count_tenants ) diff --git a/designate/common/policies/tld.py b/designate/common/policies/tld.py index 798983925..64135d4fe 100644 --- a/designate/common/policies/tld.py +++ b/designate/common/policies/tld.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -58,7 +59,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_tld", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Create Tld", operations=[ { @@ -71,7 +72,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_tlds", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="List Tlds", operations=[ { @@ -84,7 +85,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_tld", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Show Tld", operations=[ { @@ -97,7 +98,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_tld", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Update Tld", operations=[ { @@ -110,7 +111,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_tld", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Delete Tld", operations=[ { diff --git a/designate/common/policies/tsigkey.py b/designate/common/policies/tsigkey.py index b8d593110..f047b6ee2 100644 --- a/designate/common/policies/tsigkey.py +++ b/designate/common/policies/tsigkey.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -58,7 +59,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_tsigkey", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Create Tsigkey", operations=[ { @@ -71,7 +72,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_tsigkeys", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="List Tsigkeys", operations=[ { @@ -84,7 +85,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_tsigkey", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Show a Tsigkey", operations=[ { @@ -97,7 +98,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_tsigkey", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Update Tsigkey", operations=[ { @@ -110,7 +111,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_tsigkey", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Delete a Tsigkey", operations=[ { diff --git a/designate/common/policies/zone.py b/designate/common/policies/zone.py index a5ad56872..669f2c112 100644 --- a/designate/common/policies/zone.py +++ b/designate/common/policies/zone.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -106,7 +107,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Zone", operations=[ { @@ -119,13 +120,13 @@ rules = [ policy.RuleDefault( name="get_zones", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_get_zones ), policy.DocumentedRuleDefault( name="get_zone", check_str=base.SYSTEM_OR_PROJECT_READER_OR_SHARED, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get Zone", operations=[ { @@ -138,13 +139,13 @@ rules = [ policy.RuleDefault( name="get_zone_servers", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_get_zone_servers ), policy.DocumentedRuleDefault( name="get_zone_ns_records", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get the Name Servers for a Zone", operations=[ { @@ -157,7 +158,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_zones", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="List existing zones", operations=[ { @@ -170,7 +171,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Update Zone", operations=[ { @@ -183,7 +184,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Delete Zone", operations=[ { @@ -196,7 +197,7 @@ rules = [ policy.DocumentedRuleDefault( name="xfr_zone", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Manually Trigger an Update of a Secondary Zone", operations=[ { @@ -209,7 +210,7 @@ rules = [ policy.DocumentedRuleDefault( name="abandon_zone", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], description="Abandon Zone", operations=[ { @@ -222,19 +223,19 @@ rules = [ policy.RuleDefault( name="count_zones", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_count_zones ), policy.RuleDefault( name="count_zones_pending_notify", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_count_zones_pending_notify ), policy.RuleDefault( name="purge_zones", check_str=base.SYSTEM_ADMIN, - scope_types=['system'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_purge_zones ), ] diff --git a/designate/common/policies/zone_export.py b/designate/common/policies/zone_export.py index ca45971b9..15285ea99 100644 --- a/designate/common/policies/zone_export.py +++ b/designate/common/policies/zone_export.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -64,7 +65,7 @@ rules = [ policy.DocumentedRuleDefault( name="zone_export", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Retrive a Zone Export from the Designate Datastore", operations=[ { @@ -77,7 +78,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_zone_export", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Zone Export", operations=[ { @@ -90,7 +91,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_zone_exports", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="List Zone Exports", operations=[ { @@ -103,7 +104,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_zone_export", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get Zone Exports", operations=[ { @@ -116,7 +117,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_zone_export", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Update Zone Exports", operations=[ { @@ -129,7 +130,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_zone_export", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Delete a zone export", operations=[ { diff --git a/designate/common/policies/zone_import.py b/designate/common/policies/zone_import.py index 8d4f2b171..fb4ad7ffb 100644 --- a/designate/common/policies/zone_import.py +++ b/designate/common/policies/zone_import.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -58,7 +59,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_zone_import", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Zone Import", operations=[ { @@ -71,7 +72,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_zone_imports", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="List all Zone Imports", operations=[ { @@ -84,7 +85,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_zone_import", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get Zone Imports", operations=[ { @@ -97,7 +98,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_zone_import", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Update Zone Imports", operations=[ { @@ -110,7 +111,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_zone_import", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Delete a Zone Import", operations=[ { diff --git a/designate/common/policies/zone_transfer_accept.py b/designate/common/policies/zone_transfer_accept.py index ae718b2e0..65394314f 100644 --- a/designate/common/policies/zone_transfer_accept.py +++ b/designate/common/policies/zone_transfer_accept.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -46,7 +47,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_zone_transfer_accept", check_str=base.RULE_ZONE_TRANSFER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Zone Transfer Accept", operations=[ { @@ -59,7 +60,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_zone_transfer_accept", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Get Zone Transfer Accept", operations=[ { @@ -72,7 +73,7 @@ rules = [ policy.DocumentedRuleDefault( name="find_zone_transfer_accepts", check_str=base.SYSTEM_READER, - scope_types=['system'], + scope_types=[constants.PROJECT], description="List Zone Transfer Accepts", operations=[ { diff --git a/designate/common/policies/zone_transfer_request.py b/designate/common/policies/zone_transfer_request.py index 7fdbd1c47..cf4d29b40 100644 --- a/designate/common/policies/zone_transfer_request.py +++ b/designate/common/policies/zone_transfer_request.py @@ -16,6 +16,7 @@ from oslo_log import versionutils from oslo_policy import policy +from designate.common import constants from designate.common.policies import base DEPRECATED_REASON = """ @@ -58,7 +59,7 @@ rules = [ policy.DocumentedRuleDefault( name="create_zone_transfer_request", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Create Zone Transfer Accept", operations=[ { @@ -71,7 +72,7 @@ rules = [ policy.DocumentedRuleDefault( name="get_zone_transfer_request", check_str=base.RULE_ZONE_TRANSFER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Show a Zone Transfer Request", operations=[ { @@ -84,7 +85,7 @@ rules = [ policy.RuleDefault( name="get_zone_transfer_request_detailed", check_str=base.SYSTEM_OR_PROJECT_READER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], deprecated_rule=deprecated_create_zone_transfer_request ), policy.DocumentedRuleDefault( @@ -101,7 +102,7 @@ rules = [ policy.DocumentedRuleDefault( name="update_zone_transfer_request", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Update a Zone Transfer Request", operations=[ { @@ -114,7 +115,7 @@ rules = [ policy.DocumentedRuleDefault( name="delete_zone_transfer_request", check_str=base.SYSTEM_ADMIN_OR_PROJECT_MEMBER, - scope_types=['system', 'project'], + scope_types=[constants.PROJECT], description="Delete a Zone Transfer Request", operations=[ { diff --git a/designate/context.py b/designate/context.py index 8a804ac76..0d9cb4120 100644 --- a/designate/context.py +++ b/designate/context.py @@ -151,7 +151,6 @@ class DesignateContext(context.RequestContext): # TODO(kiall): Remove Me kwargs['is_admin'] = True kwargs['roles'] = ['admin', 'reader'] - kwargs['system_scope'] = 'all' return cls(None, **kwargs) diff --git a/designate/tests/test_api/test_v2/__init__.py b/designate/tests/test_api/test_v2/__init__.py index cd49c1b56..938b803a6 100644 --- a/designate/tests/test_api/test_v2/__init__.py +++ b/designate/tests/test_api/test_v2/__init__.py @@ -120,7 +120,8 @@ class ApiV2TestCase(ApiTestCase): if marker is not None: params['marker'] = marker - r = self.client.get(url, params, status=expected_status) + r = self.client.get(url, params, status=expected_status, + headers={'X-Test-Role': 'member'}) if expected_status != 200: if expected_type: self._assert_exception(expected_type, expected_status, r) diff --git a/designate/tests/test_api/test_v2/test_floatingips.py b/designate/tests/test_api/test_v2/test_floatingips.py index f7cf20f1e..546f3beed 100644 --- a/designate/tests/test_api/test_v2/test_floatingips.py +++ b/designate/tests/test_api/test_v2/test_floatingips.py @@ -202,7 +202,8 @@ class ApiV2ReverseFloatingIPTest(ApiV2TestCase): response = self.client.patch_json( '/reverse/floatingips/%s' % ":".join([fip['region'], fip['id']]), fixture.to_dict(), - headers={'X-Test-Tenant-Id': 'tenant'}) + headers={'X-Test-Tenant-Id': 'tenant', + 'X-Test-Role': 'member'}) self.assertEqual(202, response.status_int) self.assertEqual('application/json', response.content_type) diff --git a/designate/tests/test_api/test_v2/test_hostheaders.py b/designate/tests/test_api/test_v2/test_hostheaders.py index 65d83739b..f82f3731d 100644 --- a/designate/tests/test_api/test_v2/test_hostheaders.py +++ b/designate/tests/test_api/test_v2/test_hostheaders.py @@ -30,7 +30,8 @@ class ApiV2HostHeadersTest(ApiV2TestCase): fixture = self.get_zone_fixture(fixture=0) response = self.client.post_json('/zones/', fixture, - headers={'Host': 'testhost.com'}) + headers={'Host': 'testhost.com', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) self.assertEqual('application/json', response.content_type) @@ -41,7 +42,8 @@ class ApiV2HostHeadersTest(ApiV2TestCase): # Get zone with host header response = self.client.get('/zones/', - headers={'Host': 'testhost.com'}) + headers={'Host': 'testhost.com', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) diff --git a/designate/tests/test_api/test_v2/test_import_export.py b/designate/tests/test_api/test_v2/test_import_export.py index a8af5f05c..7c7ec4f8d 100644 --- a/designate/tests/test_api/test_v2/test_import_export.py +++ b/designate/tests/test_api/test_v2/test_import_export.py @@ -50,14 +50,15 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): fixture = self.get_zonefile_fixture(variant='noorigin') response = self.client.post_json('/zones/tasks/imports', fixture, - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) import_id = response.json_body['id'] self.wait_for_import(import_id, error_is_ok=True) url = '/zones/tasks/imports/%s' % import_id - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual('ERROR', response.json['status']) origin_msg = ("The $ORIGIN statement is required and must be the" " first statement in the zonefile.") @@ -67,14 +68,15 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): fixture = self.get_zonefile_fixture(variant='nosoa') response = self.client.post_json('/zones/tasks/imports', fixture, - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) import_id = response.json_body['id'] self.wait_for_import(import_id, error_is_ok=True) url = '/zones/tasks/imports/%s' % import_id - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual('ERROR', response.json['status']) origin_msg = ("Malformed zonefile.") self.assertEqual(origin_msg, response.json['message']) @@ -83,14 +85,15 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): fixture = self.get_zonefile_fixture(variant='malformed') response = self.client.post_json('/zones/tasks/imports', fixture, - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) import_id = response.json_body['id'] self.wait_for_import(import_id, error_is_ok=True) url = '/zones/tasks/imports/%s' % import_id - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual('ERROR', response.json['status']) origin_msg = ("Malformed zonefile.") self.assertEqual(origin_msg, response.json['message']) @@ -100,13 +103,14 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): # fixture, making sure they're the same according to dnspython post_response = self.client.post('/zones/tasks/imports', self.get_zonefile_fixture(), - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) import_id = post_response.json_body['id'] self.wait_for_import(import_id) url = '/zones/tasks/imports/%s' % import_id - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.policy({'zone_export': '@'}) get_response = self.adminclient.get('/zones/export/%s' % @@ -134,7 +138,8 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): def test_delete_import(self): post_response = self.client.post('/zones/tasks/imports', self.get_zonefile_fixture(), - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) import_id = post_response.json_body['id'] @@ -142,6 +147,7 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): delete_response = self.client.delete( '/zones/tasks/imports/%s' % import_id, + headers={'X-Test-Role': 'member'} ) self.assertEqual('', delete_response.text) @@ -151,14 +157,16 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): # Metadata tests def test_metadata_exists_imports(self): - response = self.client.get('/zones/tasks/imports') + response = self.client.get('/zones/tasks/imports', + headers={'X-Test-Role': 'member'}) # Make sure the fields exist self.assertIn('metadata', response.json) self.assertIn('total_count', response.json['metadata']) def test_metadata_exists_exports(self): - response = self.client.get('/zones/tasks/imports') + response = self.client.get('/zones/tasks/imports', + headers={'X-Test-Role': 'member'}) # Make sure the fields exist self.assertIn('metadata', response.json) @@ -166,7 +174,8 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): @unittest.skip("See bug 1582241 and 1570859") def test_total_count_imports(self): - response = self.client.get('/zones/tasks/imports') + response = self.client.get('/zones/tasks/imports', + headers={'X-Test-Role': 'member'}) # There are no imported zones by default self.assertEqual(0, response.json['metadata']['total_count']) @@ -174,15 +183,18 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): # Create a zone import self.client.post('/zones/tasks/imports', self.get_zonefile_fixture(), - headers={'Content-type': 'text/dns'}) + headers={'Content-type': 'text/dns', + 'X-Test-Role': 'member'}) - response = self.client.get('/zones/tasks/imports') + response = self.client.get('/zones/tasks/imports', + headers={'X-Test-Role': 'member'}) # Make sure total_count picked it up self.assertEqual(1, response.json['metadata']['total_count']) def test_total_count_exports(self): - response = self.client.get('/zones/tasks/exports') + response = self.client.get('/zones/tasks/exports', + headers={'X-Test-Role': 'member'}) # There are no exported zones by default self.assertEqual(0, response.json['metadata']['total_count']) @@ -190,14 +202,16 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): def test_create_export(self): zone = self.create_zone() create_response = self.client.post( - '/zones/%s/tasks/export' % zone['id'] + '/zones/%s/tasks/export' % zone['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('PENDING', create_response.json_body['status']) self.assertEqual(zone['id'], create_response.json_body['zone_id']) get_response = self.client.get( - '/zones/tasks/exports/%s' % create_response.json_body['id'] + '/zones/tasks/exports/%s' % create_response.json_body['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('PENDING', get_response.json_body['status']) @@ -206,39 +220,45 @@ class APIV2ZoneImportExportTest(ApiV2TestCase): def test_update_export(self): zone = self.create_zone() create_response = self.client.post( - '/zones/%s/tasks/export' % zone['id'] + '/zones/%s/tasks/export' % zone['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('PENDING', create_response.json_body['status']) self.assertEqual(zone['id'], create_response.json_body['zone_id']) delete_response = self.client.delete( - '/zones/tasks/exports/%s' % create_response.json_body['id'] + '/zones/tasks/exports/%s' % create_response.json_body['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('', delete_response.text) self._assert_exception( 'zone_export_not_found', 404, self.client.get, - '/zones/tasks/exports/%s' % create_response.json_body['id'] + '/zones/tasks/exports/%s' % create_response.json_body['id'], + headers={'X-Test-Role': 'member'} ) def test_delete_export(self): zone = self.create_zone() create_response = self.client.post( - '/zones/%s/tasks/export' % zone['id'] + '/zones/%s/tasks/export' % zone['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('PENDING', create_response.json_body['status']) self.assertEqual(zone['id'], create_response.json_body['zone_id']) delete_response = self.client.delete( - '/zones/tasks/exports/%s' % create_response.json_body['id'] + '/zones/tasks/exports/%s' % create_response.json_body['id'], + headers={'X-Test-Role': 'member'} ) self.assertEqual('', delete_response.text) self._assert_exception( 'zone_export_not_found', 404, self.client.get, - '/zones/tasks/exports/%s' % create_response.json_body['id'] + '/zones/tasks/exports/%s' % create_response.json_body['id'], + headers={'X-Test-Role': 'member'} ) diff --git a/designate/tests/test_api/test_v2/test_quotas.py b/designate/tests/test_api/test_v2/test_quotas.py index be79981e9..330b11985 100644 --- a/designate/tests/test_api/test_v2/test_quotas.py +++ b/designate/tests/test_api/test_v2/test_quotas.py @@ -24,12 +24,10 @@ class ApiV2QuotasTest(ApiV2TestCase): def test_get_quotas(self): self.config(quota_api_export_size=1) - context = self.get_context(project_id='a') + result = self.client.get('/quotas/a', status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) - result = self.client.get( - '/quotas/%s' % context.project_id, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) self.assertEqual( { 'zones': 10, @@ -44,9 +42,8 @@ class ApiV2QuotasTest(ApiV2TestCase): def test_get_all_quotas(self): self.config(quota_zone_recordsets=1) - result = self.client.get( - '/quotas', status=200, - ) + result = self.client.get('/quotas', status=200, + headers={'X-Test-Role': 'member'}) self.assertEqual( { @@ -62,16 +59,14 @@ class ApiV2QuotasTest(ApiV2TestCase): def test_set_quotas(self): self.policy({'set_quota': '@'}) - context = self.get_context(project_id='a') - self.client.patch_json( - '/quotas/%s' % context.project_id, {'zones': 123}, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) + self.client.patch_json('/quotas/a', {'zones': 123}, status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) + + result = self.client.get('/quotas/a', status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) - result = self.client.get( - '/quotas/%s' % context.project_id, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) self.assertEqual( { 'zones': 123, @@ -91,16 +86,14 @@ class ApiV2QuotasTest(ApiV2TestCase): self.policy({'set_quota': '@'}) - context = self.get_context(project_id='a') - self.client.patch_json( - '/quotas/%s' % context.project_id, {'zones': 123}, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) + self.client.patch_json('/quotas/a', {'zones': 123}, status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) + + result = self.client.get('/quotas/a', status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) - result = self.client.get( - '/quotas/%s' % context.project_id, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) self.assertEqual( { 'zones': 123, @@ -117,13 +110,11 @@ class ApiV2QuotasTest(ApiV2TestCase): self.policy({'set_quota': '@'}) - context = self.get_context(project_id='a') - # Update recordset_records quota. result = self.client.patch_json( - '/quotas/%s' % context.project_id, {'recordset_records': 123}, - status=200, - headers={'X-Test-Tenant-Id': context.project_id} + '/quotas/a', {'recordset_records': 123}, + status=200, headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'} ) self.assertEqual( { @@ -137,16 +128,15 @@ class ApiV2QuotasTest(ApiV2TestCase): ) # Delete quota. - self.client.delete( - '/quotas/%s' % context.project_id, status=204, - headers={'X-Test-Tenant-Id': context.project_id} - ) + self.client.delete('/quotas/a', status=204, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) # Make sure we are back to the default quotas. - result = self.client.get( - '/quotas/%s' % context.project_id, status=200, - headers={'X-Test-Tenant-Id': context.project_id} - ) + result = self.client.get('/quotas/a', status=200, + headers={'X-Test-Tenant-Id': 'a', + 'X-Test-Role': 'member'}) + self.assertEqual( { 'zones': 10, diff --git a/designate/tests/test_api/test_v2/test_recordsets.py b/designate/tests/test_api/test_v2/test_recordsets.py index c9d750f6f..fa03e9347 100644 --- a/designate/tests/test_api/test_v2/test_recordsets.py +++ b/designate/tests/test_api/test_v2/test_recordsets.py @@ -37,7 +37,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Prepare a RecordSet fixture fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(201, response.status_int) @@ -60,7 +61,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) fixture['ttl'] = 0 response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(201, response.status_int) @@ -75,7 +77,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.put_json(url, body, status=200) + response = self.client.put_json(url, body, status=200, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -89,7 +92,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']), - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -106,7 +110,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): ) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -120,7 +125,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % self.zone['id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -147,7 +153,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_name_too_long(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -155,7 +162,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_name_missing(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -163,7 +171,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_type_is_missing(self): # Prepare a RecordSet fixture @@ -186,7 +195,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_invalid_type(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -194,7 +204,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_description_too_long(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -202,7 +213,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_negative_ttl(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -210,7 +222,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_ttl_greater_than_max(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -218,7 +231,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_with_invalid_ttl(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -226,10 +240,12 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = fixture url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_invalid_id(self): - self._assert_invalid_uuid(self.client.post, '/zones/%s/recordsets') + self._assert_invalid_uuid(self.client.post, '/zones/%s/recordsets', + headers={'X-Test-Role': 'member'}) def test_create_recordset_validation(self): # NOTE: The schemas should be tested separatly to the API. So we @@ -245,7 +261,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception( - 'invalid_object', 400, self.client.post_json, url, body) + 'invalid_object', 400, self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'create_recordset', side_effect=messaging.MessagingTimeout()) @@ -257,7 +274,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception('timeout', 504, self.client.post_json, url, - body) + body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'create_recordset', side_effect=exceptions.DuplicateRecordSet()) @@ -269,7 +286,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets' % self.zone['id'] self._assert_exception('duplicate_recordset', 409, - self.client.post_json, url, body) + self.client.post_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_recordset_invalid_zone(self): fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) @@ -279,24 +297,28 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/ba751950-6193-11e3-949a-0800200c9a66/recordsets' self._assert_exception('zone_not_found', 404, self.client.post_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) def test_recordsets_invalid_url(self): url = '/zones/recordsets' - self._assert_exception('not_found', 404, self.client.get, url) - self._assert_exception('not_found', 404, self.client.post_json, url) + self._assert_exception('not_found', 404, self.client.get, url, + headers={'X-Test-Role': 'member'}) + self._assert_exception('not_found', 404, self.client.post_json, url, + headers={'X-Test-Role': 'member'}) # Pecan returns a 405 for Patch and delete operations - response = self.client.patch_json(url, status=405) + response = self.client.patch_json(url, status=405, + headers={'X-Test-Role': 'member'}) self.assertEqual(405, response.status_int) - response = self.client.delete(url, status=405) + response = self.client.delete(url, status=405, + headers={'X-Test-Role': 'member'}) self.assertEqual(405, response.status_int) def test_get_recordsets(self): url = '/zones/%s/recordsets' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -352,7 +374,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): for fixture in fixtures: response = self.client.post_json( '/zones/%s/recordsets' % self.zone['id'], - fixture) + fixture, headers={'X-Test-Role': 'member'}) get_urls = [ # Filter by Name @@ -380,7 +402,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): correct_results = [1, 1, 2, 1, 1, 2, 1, 1] for get_url, correct_result in zip(get_urls, correct_results): - response = self.client.get(get_url) + response = self.client.get(get_url, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -397,21 +420,22 @@ class ApiV2RecordSetsTest(ApiV2TestCase): def test_get_recordsets_timeout(self, _): url = '/zones/ba751950-6193-11e3-949a-0800200c9a66/recordsets' - self._assert_exception('timeout', 504, self.client.get, url) + self._assert_exception('timeout', 504, self.client.get, url, + headers={'X-Test-Role': 'member'}) def test_get_deleted_recordsets(self): zone = self.create_zone(fixture=1) recordset = self.create_recordset(zone, records=[]) url = '/zones/%s/recordsets' % zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) # Now delete the recordset url = '/zones/%s/recordsets/%s' % (zone['id'], recordset.id) - self.client.delete(url, status=202) + self.client.delete(url, status=202, headers={'X-Test-Role': 'member'}) # Simulate the zone having been deleted on the backend zone_serial = self.central_service.get_zone( @@ -423,20 +447,21 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Try to get the record and ensure that we get a # recordset_not_found error self._assert_exception('recordset_not_found', 404, self.client.get, - url) + url, headers={'X-Test-Role': 'member'}) def test_get_deleted_recordset_after_deleting_zone(self): zone = self.create_zone(fixture=1) self.create_recordset(zone) url = '/zones/%s/recordsets' % zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) # Now delete the zone - self.client.delete('/zones/%s' % zone['id'], status=202) + self.client.delete('/zones/%s' % zone['id'], status=202, + headers={'X-Test-Role': 'member'}) # Simulate the zone having been deleted on the backend zone_serial = self.central_service.get_zone( @@ -447,14 +472,15 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Try to get the record and ensure that we get a # zone_not_found error - self._assert_exception('zone_not_found', 404, self.client.get, url) + self._assert_exception('zone_not_found', 404, self.client.get, url, + headers={'X-Test-Role': 'member'}) def test_get_recordset(self): # Create a recordset recordset = self.create_recordset(self.zone, records=[]) url = '/zones/%s/recordsets/%s' % (self.zone['id'], recordset['id']) - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -474,7 +500,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): self.assertEqual('ACTIVE', response.json['status']) def test_get_recordset_invalid_id(self): - self._assert_invalid_uuid(self.client.get, '/zones/%s/recordsets/%s') + self._assert_invalid_uuid(self.client.get, '/zones/%s/recordsets/%s', + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_recordset', side_effect=messaging.MessagingTimeout()) @@ -483,7 +510,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): self.zone['id']) self._assert_exception('timeout', 504, self.client.get, url, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_recordset', side_effect=exceptions.RecordSetNotFound()) @@ -493,7 +521,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): self._assert_exception('recordset_not_found', 404, self.client.get, url, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) def test_update_recordset(self): # Create a recordset @@ -504,7 +533,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.put_json(url, body, status=200) + response = self.client.put_json(url, body, status=200, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -524,7 +554,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -547,7 +578,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.put_json(url, body, status=202) + response = self.client.put_json(url, body, status=202, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -563,7 +595,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -581,7 +614,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.put_json(url, body, status=202) + response = self.client.put_json(url, body, status=202, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -595,7 +629,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -611,7 +646,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - self.client.put_json(url, body, status=202) + self.client.put_json(url, body, status=202, + headers={'X-Test-Role': 'member'}) def test_create_txt_record_too_long(self): # See bug #1474012 @@ -621,7 +657,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) self._assert_exception('invalid_object', 400, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_create_txt_record_multiple_strings(self): # create TXT record with string split in 2 @@ -631,7 +668,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = {'description': 'Tester', 'records': [record]} url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - self.client.put_json(url, body, status=202) + self.client.put_json(url, body, status=202, + headers={'X-Test-Role': 'member'}) def test_update_recordset_with_record_clear(self): # Create a recordset with one record @@ -642,7 +680,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.put_json(url, body, status=200) + response = self.client.put_json(url, body, status=200, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -654,7 +693,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -664,7 +704,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): def test_update_recordset_invalid_id(self): self._assert_invalid_uuid( - self.client.put_json, '/zones/%s/recordsets/%s') + self.client.put_json, '/zones/%s/recordsets/%s', + headers={'X-Test-Role': 'member'}) def test_update_recordset_validation(self): # NOTE: The schemas should be tested separatly to the API. So we @@ -682,14 +723,14 @@ class ApiV2RecordSetsTest(ApiV2TestCase): recordset['id']) self._assert_exception('invalid_object', 400, self.client.put_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) # Prepare an update body with junk in the body body = {'description': 'Tester', 'junk': 'Junk Field'} # Ensure it fails with a 400 self._assert_exception('invalid_object', 400, self.client.put_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_recordset', side_effect=exceptions.DuplicateRecordSet()) @@ -702,7 +743,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): % (self.zone['id'])) self._assert_exception('duplicate_recordset', 409, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_recordset', side_effect=messaging.MessagingTimeout()) @@ -715,7 +757,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): % (self.zone['id'])) self._assert_exception('timeout', 504, self.client.put_json, url, - body) + body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_recordset', side_effect=exceptions.RecordSetNotFound()) @@ -728,7 +770,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): % (self.zone['id'])) self._assert_exception('recordset_not_found', 404, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_update_recordset_invalid_ttl(self): recordset = self.create_recordset(self.zone) @@ -736,7 +779,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) self._assert_exception('invalid_object', 400, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_update_recordset_negative_ttl(self): recordset = self.create_recordset(self.zone) @@ -744,7 +788,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) self._assert_exception('invalid_object', 400, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_update_recordset_ttl_greater_than_max(self): recordset = self.create_recordset(self.zone) @@ -752,7 +797,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) self._assert_exception('invalid_object', 400, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_update_recordset_description_too_long(self): recordset = self.create_recordset(self.zone) @@ -760,14 +806,16 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) self._assert_exception('invalid_object', 400, - self.client.put_json, url, body) + self.client.put_json, url, body, + headers={'X-Test-Role': 'member'}) def test_delete_recordset(self): recordset = self.create_recordset(self.zone, records=[]) url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.delete(url, status=202) + response = self.client.delete(url, status=202, + headers={'X-Test-Role': 'member'}) self.assertEqual('application/json', response.content_type) # Currently recordset does not have a status field. As there are no @@ -777,7 +825,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -791,7 +840,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - response = self.client.delete(url, status=202) + response = self.client.delete(url, status=202, + headers={'X-Test-Role': 'member'}) self.assertEqual('application/json', response.content_type) self.assertEqual('DELETE', response.json['action']) @@ -799,7 +849,8 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Check the zone's status is as expected response = self.client.get('/zones/%s' % recordset['zone_id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) self.assertEqual('application/json', response.content_type) @@ -814,16 +865,18 @@ class ApiV2RecordSetsTest(ApiV2TestCase): % (self.zone['id'])) self._assert_exception('recordset_not_found', 404, - self.client.delete, url) + self.client.delete, url, + headers={'X-Test-Role': 'member'}) def test_delete_recordset_invalid_id(self): self._assert_invalid_uuid( - self.client.delete, '/zones/%s/recordsets/%s') + self.client.delete, '/zones/%s/recordsets/%s', + headers={'X-Test-Role': 'member'}) def test_metadata_exists(self): url = '/zones/%s/recordsets' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Make sure the fields exist self.assertIn('metadata', response.json) @@ -832,7 +885,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): def test_total_count(self): url = '/zones/%s/recordsets' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # The NS and SOA records are there by default self.assertEqual(2, response.json['metadata']['total_count']) @@ -840,9 +893,10 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Create a recordset fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Make sure total_count picked up the change self.assertEqual(3, response.json['metadata']['total_count']) @@ -854,19 +908,20 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Create a recordset fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Make sure total_count picked up the change self.assertEqual(3, response.json['metadata']['total_count']) url = '/zones/%s/recordsets?data=nyan' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual(0, response.json['metadata']['total_count']) url = '/zones/%s/recordsets?data=ns1.example.org.' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual(1, response.json['metadata']['total_count']) # Test paging @@ -885,23 +940,25 @@ class ApiV2RecordSetsTest(ApiV2TestCase): # Even with paging enabled, total_count is still the total number of # recordsets matching the "data" filter url = '/zones/%s/recordsets?limit=1&data=nyan' % new_zone.id - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) self.assertEqual(2, response.json['metadata']['total_count']) def test_total_count_pagination(self): # Create two recordsets fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) fixture = self.get_recordset_fixture(self.zone['name'], fixture=1) response = self.client.post_json( - '/zones/%s/recordsets' % self.zone['id'], fixture) + '/zones/%s/recordsets' % self.zone['id'], fixture, + headers={'X-Test-Role': 'member'}) # Paginate the recordsets to two, there should be four now url = '/zones/%s/recordsets?limit=2' % self.zone['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # There are two recordsets returned self.assertEqual(2, len(response.json['recordsets'])) @@ -919,7 +976,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): recordset = self.create_recordset(secondary) url = '/zones/%s/recordsets/%s' % (secondary['id'], recordset['id']) - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -942,7 +999,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets' % secondary['id'] - response = self.client.get(url) + response = self.client.get(url, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -977,7 +1034,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets' % secondary['id'] self._assert_exception('forbidden', 403, self.client.post_json, url, - fixture) + fixture, headers={'X-Test-Role': 'member'}) def test_update_secondary_zone_recordset(self): fixture = self.get_zone_fixture('SECONDARY', 1) @@ -991,7 +1048,7 @@ class ApiV2RecordSetsTest(ApiV2TestCase): recordset['id']) self._assert_exception('forbidden', 403, self.client.put_json, url, - {'ttl': 100}) + {'ttl': 100}, headers={'X-Test-Role': 'member'}) def test_delete_secondary_zone_recordset(self): fixture = self.get_zone_fixture('SECONDARY', 1) @@ -1004,17 +1061,19 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - self._assert_exception('forbidden', 403, self.client.delete, url) + self._assert_exception('forbidden', 403, self.client.delete, url, + headers={'X-Test-Role': 'member'}) def test_no_create_rs_deleting_zone(self): # Prepare a create fixture = self.get_recordset_fixture(self.zone['name'], fixture=0) body = fixture - self.client.delete('/zones/%s' % self.zone['id'], status=202) + self.client.delete('/zones/%s' % self.zone['id'], status=202, + headers={'X-Test-Role': 'member'}) self._assert_exception('bad_request', 400, self.client.post_json, '/zones/%s/recordsets' % self.zone['id'], - body) + body, headers={'X-Test-Role': 'member'}) def test_no_update_rs_deleting_zone(self): # Create a recordset @@ -1024,9 +1083,10 @@ class ApiV2RecordSetsTest(ApiV2TestCase): body = {'description': 'Tester'} url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - self.client.delete('/zones/%s' % self.zone['id'], status=202) + self.client.delete('/zones/%s' % self.zone['id'], status=202, + headers={'X-Test-Role': 'member'}) self._assert_exception('bad_request', 400, self.client.put_json, url, - body) + body, headers={'X-Test-Role': 'member'}) def test_no_delete_rs_deleting_zone(self): # Create a recordset @@ -1035,10 +1095,13 @@ class ApiV2RecordSetsTest(ApiV2TestCase): url = '/zones/%s/recordsets/%s' % (recordset['zone_id'], recordset['id']) - self.client.delete('/zones/%s' % self.zone['id'], status=202) - self._assert_exception('bad_request', 400, self.client.delete, url) + self.client.delete('/zones/%s' % self.zone['id'], status=202, + headers={'X-Test-Role': 'member'}) + self._assert_exception('bad_request', 400, self.client.delete, url, + headers={'X-Test-Role': 'member'}) def test_invalid_recordset_filter(self): invalid_url = '/zones/%s/recordsets?action=NONE' % self.zone['id'] self._assert_exception( - 'bad_request', 400, self.client.get, invalid_url) + 'bad_request', 400, self.client.get, invalid_url, + headers={'X-Test-Role': 'member'}) diff --git a/designate/tests/test_api/test_v2/test_shared_zones.py b/designate/tests/test_api/test_v2/test_shared_zones.py index a49e034ff..d100df7f6 100644 --- a/designate/tests/test_api/test_v2/test_shared_zones.py +++ b/designate/tests/test_api/test_v2/test_shared_zones.py @@ -27,7 +27,7 @@ class ApiV2SharedZonesTest(ApiV2TestCase): self.endpoint_url.format(self.zone.id), { 'target_project_id': self.target_project_id, - } + }, headers={'X-Test-Role': 'member'} ) def test_share_zone(self): @@ -55,19 +55,22 @@ class ApiV2SharedZonesTest(ApiV2TestCase): def test_share_zone_with_no_target_id_no_zone_id(self): self._assert_exception( 'invalid_uuid', 400, self.client.post_json, - self.endpoint_url.format(""), {"target_project_id": ""} + self.endpoint_url.format(""), {"target_project_id": ""}, + headers={'X-Test-Role': 'member'} ) def test_share_zone_with_target_id_no_zone_id(self): self._assert_exception( 'invalid_uuid', 400, self.client.post_json, - self.endpoint_url.format(""), {"target_project_id": "2"} + self.endpoint_url.format(""), {"target_project_id": "2"}, + headers={'X-Test-Role': 'member'} ) def test_share_zone_with_invalid_zone_id(self): self._assert_exception( 'invalid_uuid', 400, self.client.post_json, - self.endpoint_url.format("invalid"), {"target_project_id": "2"} + self.endpoint_url.format("invalid"), {"target_project_id": "2"}, + headers={'X-Test-Role': 'member'} ) def test_get_zone_share(self): @@ -75,7 +78,8 @@ class ApiV2SharedZonesTest(ApiV2TestCase): response = self.client.get( '{}/{}'.format(self.endpoint_url.format(self.zone.id), - shared_zone.json['id']) + shared_zone.json['id']), + headers={'X-Test-Role': 'member'} ) # Check the headers are what we expect @@ -98,7 +102,8 @@ class ApiV2SharedZonesTest(ApiV2TestCase): self.assertIn('updated_at', response.json) def test_list_zone_shares(self): - response = self.client.get(self.endpoint_url.format(self.zone.id)) + response = self.client.get(self.endpoint_url.format(self.zone.id), + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -114,7 +119,8 @@ class ApiV2SharedZonesTest(ApiV2TestCase): self._create_valid_shared_zone() - data = self.client.get(self.endpoint_url.format(self.zone.id)) + data = self.client.get(self.endpoint_url.format(self.zone.id), + headers={'X-Test-Role': 'member'}) self.assertEqual(1, len(data.json['shared_zones'])) @@ -123,7 +129,8 @@ class ApiV2SharedZonesTest(ApiV2TestCase): response = self.client.delete( '{}/{}'.format(self.endpoint_url.format(self.zone.id), - shared_zone.json['id']) + shared_zone.json['id']), + headers={'X-Test-Role': 'member'} ) # Check the headers are what we expect diff --git a/designate/tests/test_api/test_v2/test_zones.py b/designate/tests/test_api/test_v2/test_zones.py index 2718cbd65..7e39c944e 100644 --- a/designate/tests/test_api/test_v2/test_zones.py +++ b/designate/tests/test_api/test_v2/test_zones.py @@ -36,7 +36,8 @@ class ApiV2ZonesTest(ApiV2TestCase): def test_create_zone(self): # Create a zone fixture = self.get_zone_fixture(fixture=0) - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) self.assertEqual('application/json', response.content_type) @@ -61,7 +62,8 @@ class ApiV2ZonesTest(ApiV2TestCase): fixture = self.get_zone_fixture(fixture=0) del fixture['type'] - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -95,14 +97,16 @@ class ApiV2ZonesTest(ApiV2TestCase): body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_email_too_long(self): fixture = self.get_zone_fixture(fixture=0) fixture.update({'email': 'a' * 255 + '@abc.com'}) body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_invalid_email(self): invalid_emails = [ @@ -117,29 +121,32 @@ class ApiV2ZonesTest(ApiV2TestCase): for email in invalid_emails: fixture.update({'email': email}) body = fixture - self._assert_exception('invalid_object', 400, - self.client.post_json, - '/zones', body) + self._assert_exception( + 'invalid_object', 400, self.client.post_json, + '/zones', body, headers={'X-Test-Role': 'member'}) def test_create_zone_email_missing(self): fixture = self.get_zone_fixture(fixture=0) del fixture['email'] body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_ttl_less_than_zero(self): fixture = self.get_zone_fixture(fixture=0) fixture['ttl'] = -1 body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_ttl_is_zero(self): fixture = self.get_zone_fixture(fixture=0) fixture['ttl'] = 0 body = fixture - response = self.client.post_json('/zones', body) + response = self.client.post_json('/zones', body, + headers={'X-Test-Role': 'member'}) self.assertEqual(202, response.status_int) def test_create_zone_ttl_is_greater_than_max(self): @@ -147,19 +154,22 @@ class ApiV2ZonesTest(ApiV2TestCase): fixture['ttl'] = 2174483648 body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_ttl_is_invalid(self): fixture = self.get_zone_fixture(fixture=0) fixture['ttl'] = "!@?>" body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_ttl_is_not_required_field(self): fixture = self.get_zone_fixture(fixture=0) body = fixture - response = self.client.post_json('/zones', body) + response = self.client.post_json('/zones', body, + headers={'X-Test-Role': 'member'}) self.assertEqual(202, response.status_int) self.assertEqual('application/json', response.content_type) @@ -168,21 +178,24 @@ class ApiV2ZonesTest(ApiV2TestCase): fixture['description'] = "a" * 161 body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_name_is_missing(self): fixture = self.get_zone_fixture(fixture=0) del fixture['name'] body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_name_too_long(self): fixture = self.get_zone_fixture(fixture=0) fixture['name'] = 'x' * 255 + ".com" body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_body_validation(self): fixture = self.get_zone_fixture(fixture=0) @@ -191,7 +204,8 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) fixture = self.get_zone_fixture(fixture=0) # Add created_at to the body @@ -199,7 +213,8 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 body = fixture self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', body) + '/zones', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_invalid_name(self): # Try to create a zone with an invalid name @@ -207,7 +222,8 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones', fixture) + '/zones', fixture, + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'create_zone', side_effect=messaging.MessagingTimeout()) @@ -217,7 +233,8 @@ class ApiV2ZonesTest(ApiV2TestCase): body = fixture self._assert_exception('timeout', 504, self.client.post_json, - '/zones/', body) + '/zones/', body, + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'create_zone', side_effect=exceptions.DuplicateZone()) @@ -227,30 +244,38 @@ class ApiV2ZonesTest(ApiV2TestCase): body = fixture self._assert_exception('duplicate_zone', 409, self.client.post_json, - '/zones/', body) + '/zones/', body, + headers={'X-Test-Role': 'member'}) def test_create_zone_missing_content_type(self): self._assert_exception('unsupported_content_type', 415, - self.client.post, '/zones') + self.client.post, '/zones', + headers={'X-Test-Role': 'member'}) def test_create_zone_bad_content_type(self): self._assert_exception( 'unsupported_content_type', 415, self.client.post, '/zones', - headers={'Content-type': 'test/goat'}) + headers={'Content-type': 'test/goat', + 'X-Test-Role': 'member'}) def test_zone_invalid_url(self): url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980/invalid' self._assert_exception('not_found', 404, self.client.get, url, - headers={'Accept': 'application/json'}) - self._assert_exception('not_found', 404, self.client.patch_json, url) - self._assert_exception('not_found', 404, self.client.delete, url) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) + self._assert_exception('not_found', 404, self.client.patch_json, url, + headers={'X-Test-Role': 'member'}) + self._assert_exception('not_found', 404, self.client.delete, url, + headers={'X-Test-Role': 'member'}) # Pecan returns a 405 for post - response = self.client.post(url, status=405) + response = self.client.post(url, status=405, + headers={'X-Test-Role': 'member'}) self.assertEqual(405, response.status_int) def test_get_zones(self): - response = self.client.get('/zones/') + response = self.client.get('/zones/', + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -276,14 +301,16 @@ class ApiV2ZonesTest(ApiV2TestCase): @patch.object(central_service.Service, 'find_zones', side_effect=messaging.MessagingTimeout()) def test_get_zones_timeout(self, _): - self._assert_exception('timeout', 504, self.client.get, '/zones/') + self._assert_exception('timeout', 504, self.client.get, '/zones/', + headers={'X-Test-Role': 'member'}) def test_get_zone(self): # Create a zone zone = self.create_zone() response = self.client.get('/zones/%s' % zone['id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -302,26 +329,30 @@ class ApiV2ZonesTest(ApiV2TestCase): self.assertEqual(zone['email'], response.json['email']) def test_get_zone_invalid_id(self): - self._assert_invalid_uuid(self.client.get, '/zones/%s') + self._assert_invalid_uuid(self.client.get, '/zones/%s', + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_zone', side_effect=messaging.MessagingTimeout()) def test_get_zone_timeout(self, _): url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980' self._assert_exception('timeout', 504, self.client.get, url, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_zone', side_effect=exceptions.ZoneNotFound()) def test_get_zone_missing(self, _): url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980' self._assert_exception('zone_not_found', 404, self.client.get, url, - headers={'Accept': 'application/json'}) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) def test_get_zone_bad_accept(self): url = '/zones/6e2146f3-87bc-4f47-adc5-4df0a5c78218' - self.client.get(url, headers={'Accept': 'test/goat'}, status=406) + self.client.get(url, status=406, headers={'Accept': 'test/goat', + 'X-Test-Role': 'member'}) def test_update_zone(self): # Create a zone @@ -331,7 +362,8 @@ class ApiV2ZonesTest(ApiV2TestCase): body = {'email': 'prefix-%s' % zone['email']} response = self.client.patch_json('/zones/%s' % zone['id'], body, - status=202) + status=202, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -349,7 +381,8 @@ class ApiV2ZonesTest(ApiV2TestCase): response.json['email']) def test_update_zone_invalid_id(self): - self._assert_invalid_uuid(self.client.patch_json, '/zones/%s') + self._assert_invalid_uuid(self.client.patch_json, '/zones/%s', + headers={'X-Test-Role': 'member'}) def test_update_zone_validation(self): # NOTE: The schemas should be tested separatly to the API. So we @@ -365,7 +398,7 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception('invalid_object', 400, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) # Prepare an update body with negative ttl in the body body = {'email': 'prefix-%s' % zone['email'], @@ -373,7 +406,7 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception('invalid_object', 400, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) # Prepare an update body with ttl > maximum (2147483647) in the body body = {'email': 'prefix-%s' % zone['email'], @@ -381,7 +414,7 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 400 self._assert_exception('invalid_object', 400, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_zone', side_effect=exceptions.DuplicateZone()) @@ -393,7 +426,7 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 409 self._assert_exception('duplicate_zone', 409, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_zone', side_effect=messaging.MessagingTimeout()) @@ -405,7 +438,7 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 504 self._assert_exception('timeout', 504, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'get_zone', side_effect=exceptions.ZoneNotFound()) @@ -417,12 +450,13 @@ class ApiV2ZonesTest(ApiV2TestCase): # Ensure it fails with a 404 self._assert_exception('zone_not_found', 404, self.client.patch_json, - url, body) + url, body, headers={'X-Test-Role': 'member'}) def test_delete_zone(self): zone = self.create_zone() - response = self.client.delete('/zones/%s' % zone['id'], status=202) + response = self.client.delete('/zones/%s' % zone['id'], status=202, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -431,18 +465,20 @@ class ApiV2ZonesTest(ApiV2TestCase): self.assertEqual('PENDING', response.json['status']) # The deleted zone should still be listed - zones = self.client.get('/zones/') + zones = self.client.get('/zones/', headers={'X-Test-Role': 'member'}) self.assertEqual(1, len(zones.json['zones'])) def test_delete_zone_invalid_id(self): - self._assert_invalid_uuid(self.client.delete, '/zones/%s') + self._assert_invalid_uuid(self.client.delete, '/zones/%s', + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'delete_zone', side_effect=messaging.MessagingTimeout()) def test_delete_zone_timeout(self, _): url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980' - self._assert_exception('timeout', 504, self.client.delete, url) + self._assert_exception('timeout', 504, self.client.delete, url, + headers={'X-Test-Role': 'member'}) @patch.object(central_service.Service, 'delete_zone', side_effect=exceptions.ZoneNotFound()) @@ -450,42 +486,48 @@ class ApiV2ZonesTest(ApiV2TestCase): url = '/zones/2fdadfb1-cf96-4259-ac6b-bb7b6d2ff980' self._assert_exception('zone_not_found', 404, self.client.delete, - url) + url, headers={'X-Test-Role': 'member'}) def test_post_abandon_zone(self): zone = self.create_zone() url = '/zones/%s/tasks/abandon' % zone.id # Ensure that we get permission denied - self._assert_exception('forbidden', 403, self.client.post_json, url) + self._assert_exception('forbidden', 403, self.client.post_json, url, + headers={'X-Test-Role': 'member'}) # Ensure that abandon zone succeeds with the right policy self.policy({'abandon_zone': '@'}) - response = self.client.post_json(url) + response = self.client.post_json(url, + headers={'X-Test-Role': 'member'}) self.assertEqual(204, response.status_int) def test_get_abandon_zone(self): zone = self.create_zone() url = '/zones/%s/tasks/abandon' % zone.id - self._assert_exception('method_not_allowed', 405, self.client.get, url) + self._assert_exception('method_not_allowed', 405, self.client.get, url, + headers={'X-Test-Role': 'member'}) def test_get_invalid_abandon(self): # This is an invalid endpoint - should return 404 url = '/zones/tasks/abandon' - self._assert_exception('not_found', 404, self.client.get, url) + self._assert_exception('not_found', 404, self.client.get, url, + headers={'X-Test-Role': 'member'}) def test_get_zone_tasks(self): # This is an invalid endpoint - should return 404 zone = self.create_zone() url = '/zones/%s/tasks' % zone.id - self._assert_exception('not_found', 404, self.client.get, url) + self._assert_exception('not_found', 404, self.client.get, url, + headers={'X-Test-Role': 'member'}) def test_create_secondary(self): # Create a zone fixture = self.get_zone_fixture('SECONDARY', 0) fixture['masters'] = ["10.0.0.1"] - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -516,7 +558,8 @@ class ApiV2ZonesTest(ApiV2TestCase): fixture = self.get_zone_fixture('SECONDARY', 0) self._assert_exception('invalid_object', 400, self.client.post_json, - '/zones/', fixture) + '/zones/', fixture, + headers={'X-Test-Role': 'member'}) def test_update_secondary(self): # Create a zone @@ -538,8 +581,9 @@ class ApiV2ZonesTest(ApiV2TestCase): # Prepare an update body body = {'masters': masters} - response = self.client.patch_json('/zones/%s' % zone['id'], body, - status=202) + response = self.client.patch_json( + '/zones/%s' % zone['id'], body, status=202, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(202, response.status_int) @@ -573,7 +617,7 @@ class ApiV2ZonesTest(ApiV2TestCase): response = self.client.post_json( '/zones/%s/tasks/xfr' % zone['id'], - None, status=202) + None, status=202, headers={'X-Test-Role': 'member'}) self.assertTrue(worker.perform_zone_xfr.called) @@ -588,7 +632,7 @@ class ApiV2ZonesTest(ApiV2TestCase): response = self.client.post_json( '/zones/%s/tasks/xfr' % zone['id'], - None, status=400) + None, status=400, headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(400, response.status_int) @@ -605,27 +649,32 @@ class ApiV2ZonesTest(ApiV2TestCase): body = {'email': 'foo@bar.io'} self._assert_exception('invalid_object', 400, self.client.patch_json, - '/zones/%s' % zone['id'], body) + '/zones/%s' % zone['id'], body, + headers={'X-Test-Role': 'member'}) # Metadata tests def test_metadata_exists(self): - response = self.client.get('/zones/') + response = self.client.get('/zones/', + headers={'X-Test-Role': 'member'}) # Make sure the fields exist self.assertIn('metadata', response.json) self.assertIn('total_count', response.json['metadata']) def test_total_count(self): - response = self.client.get('/zones/') + response = self.client.get('/zones/', + headers={'X-Test-Role': 'member'}) # There are no zones by default self.assertEqual(0, response.json['metadata']['total_count']) # Create a zone fixture = self.get_zone_fixture(fixture=0) - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) - response = self.client.get('/zones/') + response = self.client.get('/zones/', + headers={'X-Test-Role': 'member'}) # Make sure total_count picked it up self.assertEqual(1, response.json['metadata']['total_count']) @@ -633,13 +682,16 @@ class ApiV2ZonesTest(ApiV2TestCase): def test_total_count_pagination(self): # Create two zones fixture = self.get_zone_fixture(fixture=0) - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) fixture = self.get_zone_fixture(fixture=1) - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) # Paginate so that there is only one zone returned - response = self.client.get('/zones?limit=1') + response = self.client.get('/zones?limit=1', + headers={'X-Test-Role': 'member'}) self.assertEqual(1, len(response.json['zones'])) @@ -653,9 +705,11 @@ class ApiV2ZonesTest(ApiV2TestCase): # Prepare an update body body = {'zone': {'email': 'prefix-%s' % zone['email']}} - self.client.delete('/zones/%s' % zone['id'], status=202) + self.client.delete('/zones/%s' % zone['id'], status=202, + headers={'X-Test-Role': 'member'}) self._assert_exception('bad_request', 400, self.client.patch_json, - '/zones/%s' % zone['id'], body) + '/zones/%s' % zone['id'], body, + headers={'X-Test-Role': 'member'}) def test_get_nameservers(self): # Create a zone @@ -664,7 +718,8 @@ class ApiV2ZonesTest(ApiV2TestCase): # Prepare an update body response = self.client.get('/zones/%s/nameservers' % zone['id'], - headers=[('Accept', 'application/json')]) + headers={'Accept': 'application/json', + 'X-Test-Role': 'member'}) self.assertIn('nameservers', response.json) self.assertEqual(1, len(response.json['nameservers'])) @@ -689,7 +744,8 @@ class ApiV2ZonesTest(ApiV2TestCase): ] for fixture in fixtures: - response = self.client.post_json('/zones/', fixture) + response = self.client.post_json('/zones/', fixture, + headers={'X-Test-Role': 'member'}) get_urls = [ # Filter by Type @@ -714,7 +770,8 @@ class ApiV2ZonesTest(ApiV2TestCase): for get_url, correct_result in zip(get_urls, correct_results): - response = self.client.get(get_url) + response = self.client.get(get_url, + headers={'X-Test-Role': 'member'}) # Check the headers are what we expect self.assertEqual(200, response.status_int) @@ -726,4 +783,5 @@ class ApiV2ZonesTest(ApiV2TestCase): def test_invalid_zones_filter(self): invalid_url = '/zones?id=155477ef-e6c5-4b94-984d-8fc68c0c1a14' self._assert_exception( - 'bad_request', 400, self.client.get, invalid_url) + 'bad_request', 400, self.client.get, invalid_url, + headers={'X-Test-Role': 'member'}) diff --git a/designate/tests/test_central/test_service.py b/designate/tests/test_central/test_service.py index 641bac7b0..846684fa5 100644 --- a/designate/tests/test_central/test_service.py +++ b/designate/tests/test_central/test_service.py @@ -424,8 +424,10 @@ class CentralServiceTest(CentralTestCase): admin_context = self.get_admin_context() admin_context.all_tenants = True - tenant_one_context = self.get_context(project_id='1') - tenant_two_context = self.get_context(project_id='2') + tenant_one_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_two_context = self.get_context(project_id='2', + roles=['member', 'reader']) # in the beginning, there should be nothing tenants = self.central_service.count_tenants(admin_context) @@ -799,8 +801,10 @@ class CentralServiceTest(CentralTestCase): admin_context = self.get_admin_context() admin_context.all_tenants = True - tenant_one_context = self.get_context(project_id='1') - tenant_two_context = self.get_context(project_id='2') + tenant_one_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_two_context = self.get_context(project_id='2', + roles=['member', 'reader']) # Ensure we have no zones to start with. zones = self.central_service.find_zones(admin_context) @@ -1776,7 +1780,7 @@ class CentralServiceTest(CentralTestCase): def test_find_recordsets_shared_zone(self): zone = self.create_zone() - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) self.share_zone(context=self.admin_context, zone_id=zone.id, target_project_id='1') @@ -2064,7 +2068,7 @@ class CentralServiceTest(CentralTestCase): zone = self.create_zone() original_serial = zone.serial - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) self.share_zone(context=self.admin_context, zone_id=zone.id, target_project_id='1') @@ -3312,9 +3316,12 @@ class CentralServiceTest(CentralTestCase): self.assertEqual(zt_request.key, retrived_zt.key) def test_get_zone_transfer_request_scoped(self): - tenant_1_context = self.get_context(project_id='1') - tenant_2_context = self.get_context(project_id='2') - tenant_3_context = self.get_context(project_id='3') + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_2_context = self.get_context(project_id='2', + roles=['member', 'reader']) + tenant_3_context = self.get_context(project_id='3', + roles=['member', 'reader']) zone = self.create_zone(context=tenant_1_context) zt_request = self.create_zone_transfer_request( zone, @@ -3363,8 +3370,10 @@ class CentralServiceTest(CentralTestCase): exc.exc_info[0]) def test_create_zone_transfer_accept(self): - tenant_1_context = self.get_context(project_id='1') - tenant_2_context = self.get_context(project_id="2") + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_2_context = self.get_context(project_id="2", + roles=['member', 'reader']) admin_context = self.get_admin_context() admin_context.all_tenants = True @@ -3413,8 +3422,10 @@ class CentralServiceTest(CentralTestCase): 'COMPLETE', result['zt_request'].status) def test_create_zone_transfer_accept_scoped(self): - tenant_1_context = self.get_context(project_id='1') - tenant_2_context = self.get_context(project_id="2") + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_2_context = self.get_context(project_id="2", + roles=['member', 'reader']) admin_context = self.get_admin_context() admin_context.all_tenants = True @@ -3465,7 +3476,8 @@ class CentralServiceTest(CentralTestCase): 'COMPLETE', result['zt_request'].status) def test_create_zone_transfer_accept_failed_key(self): - tenant_1_context = self.get_context(project_id='1') + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) tenant_2_context = self.get_context(project_id="2") admin_context = self.get_admin_context() admin_context.all_tenants = True @@ -3492,8 +3504,10 @@ class CentralServiceTest(CentralTestCase): self.assertEqual(exceptions.IncorrectZoneTransferKey, exc.exc_info[0]) def test_create_zone_tarnsfer_accept_out_of_tenant_scope(self): - tenant_1_context = self.get_context(project_id='1') - tenant_3_context = self.get_context(project_id="3") + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_3_context = self.get_context(project_id="3", + roles=['member', 'reader']) admin_context = self.get_admin_context() admin_context.all_tenants = True @@ -3522,7 +3536,8 @@ class CentralServiceTest(CentralTestCase): # Zone Import Tests def test_create_zone_import(self): # Create a Zone Import - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import(context, request_body) @@ -3536,14 +3551,16 @@ class CentralServiceTest(CentralTestCase): self.wait_for_import(zone_import.id) def test_create_zone_import_duplicate_threading(self): - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import(context, request_body) self.wait_for_import(zone_import.id) def create_zone_import(): - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import(context, request_body) @@ -3653,7 +3670,8 @@ class CentralServiceTest(CentralTestCase): ) # Create a Zone Import - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import(context, request_body) @@ -3671,7 +3689,8 @@ class CentralServiceTest(CentralTestCase): self.assertEqual('ERROR', zone_import.status) def test_find_zone_imports(self): - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) # Ensure we have no zone_imports to start with. zone_imports = self.central_service.find_zone_imports( @@ -3708,7 +3727,8 @@ class CentralServiceTest(CentralTestCase): def test_get_zone_import(self): # Create a Zone Import - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import( context, request_body) @@ -3726,7 +3746,8 @@ class CentralServiceTest(CentralTestCase): def test_update_zone_import(self): # Create a Zone Import - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import( context, request_body) @@ -3749,7 +3770,8 @@ class CentralServiceTest(CentralTestCase): def test_delete_zone_import(self): # Create a Zone Import - context = self.get_context(project_id=utils.generate_uuid()) + context = self.get_context(project_id=utils.generate_uuid(), + roles=['member', 'reader']) request_body = self.get_zonefile_fixture() zone_import = self.central_service.create_zone_import( context, request_body) @@ -3769,7 +3791,7 @@ class CentralServiceTest(CentralTestCase): def test_share_zone(self): # Create a Shared Zone - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) zone = self.create_zone(context=context) shared_zone = self.share_zone(context=context, zone_id=zone.id) @@ -3796,7 +3818,7 @@ class CentralServiceTest(CentralTestCase): self.assertEqual(zone.id, shared_zone.zone_id) def test_unshare_zone(self): - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) zone = self.create_zone(context=context) shared_zone = self.share_zone(context=context, zone_id=zone.id) @@ -3831,7 +3853,7 @@ class CentralServiceTest(CentralTestCase): new_shared_zone_obj.project_id) def test_unshare_zone_with_child_objects(self): - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) zone = self.create_zone(context=context) shared_zone = self.share_zone(context=context, zone_id=zone.id) @@ -3855,7 +3877,7 @@ class CentralServiceTest(CentralTestCase): ) def test_find_shared_zones(self): - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) zone = self.create_zone(context=context) # Ensure we have no shared zones to start with. @@ -3923,7 +3945,7 @@ class CentralServiceTest(CentralTestCase): self.assertEqual(second_shared_zone.id, shared_zones[1].id) def test_get_shared_zone(self): - context = self.get_context(project_id='1') + context = self.get_context(project_id='1', roles=['member', 'reader']) zone = self.create_zone(context=context) shared_zone = self.share_zone(context=context, zone_id=zone.id) diff --git a/designate/tests/test_storage/__init__.py b/designate/tests/test_storage/__init__.py index 7aa2a79ae..6f2dc7f0c 100644 --- a/designate/tests/test_storage/__init__.py +++ b/designate/tests/test_storage/__init__.py @@ -2982,8 +2982,10 @@ class StorageTestCase(object): self.assertEqual(result.id, accept.id) def test_transfer_zone_ownership(self): - tenant_1_context = self.get_context(project_id='1') - tenant_2_context = self.get_context(project_id='2') + tenant_1_context = self.get_context(project_id='1', + roles=['member', 'reader']) + tenant_2_context = self.get_context(project_id='2', + roles=['member', 'reader']) admin_context = self.get_admin_context() admin_context.all_tenants = True