# Copyright 2016 Hewlett Packard Enterprise Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from tempest.lib.common.utils import data_utils from designate_tempest_plugin.common import constants as const from designate_tempest_plugin import data_utils as dns_data_utils from designate_tempest_plugin.common import waiters from designate_tempest_plugin.services.dns.v2.json import base class ZonesClient(base.DnsClientV2Base): """API V2 Tempest REST client for Designate API""" @base.handle_errors def create_zone(self, name=None, email=None, ttl=None, description=None, attributes=None, wait_until=False, zone_type=const.PRIMARY_ZONE_TYPE, primaries=None, params=None, project_id=None, serial=None): """Create a zone with the specified parameters. :param name: The name of the zone. Default: Random Value :param email: The email for the zone. Default: Random Value :param ttl: The ttl for the zone. Default: Random Value :param description: A description of the zone. Default: Random Value :param serial: A serial of the zone. Default: Random Value :param attributes: Key:Value pairs of information about this zone, and the pool the user would like to place the zone in. This information can be used by the scheduler to place zones on the correct pool. :param wait_until: Block until the zone reaches the desiered status :param zone_type: PRIMARY or SECONDARY Default: PRIMARY :param primaries: List of Primary nameservers. Required for SECONDARY Default: None :param params: A Python dict that represents the query parameters to include in the request URI. :param project_id: When specified, overrides the project ID the zone will be associated with. :return: A tuple with the server response and the created zone. """ zone = { 'name': name or dns_data_utils.rand_zone_name() if name != '' else '', 'email': email or dns_data_utils.rand_email() if email != '' else '', 'ttl': ttl or dns_data_utils.rand_ttl() if ttl != 0 else 0, 'description': description or data_utils.rand_name('test-zone') if description != '' else '', 'attributes': attributes or { 'attribute_key': data_utils.rand_name('attribute_value')} } if serial: zone['serial'] = serial # If SECONDARY, "email" and "ttl" cannot be supplied if zone_type == const.SECONDARY_ZONE_TYPE: zone['type'] = zone_type del zone['email'] del zone['ttl'] if primaries is None: raise AttributeError( 'Error - "primaries" is mandatory parameter' ' for a SECONDARY zone type') zone['masters'] = primaries headers = None extra_headers = False if project_id: headers = {'x-auth-sudo-project-id': project_id} extra_headers = True resp, body = self._create_request('zones', zone, params=params, headers=headers, extra_headers=extra_headers) # Create Zone should Return a HTTP 202 self.expected_success(202, resp.status) if wait_until: waiters.wait_for_zone_status(self, body['id'], wait_until, headers=headers) return resp, body @base.handle_errors def show_zone(self, uuid, params=None, headers=None): """Gets a specific zone. :param uuid: Unique identifier of the zone in UUID format. :param params: A Python dict that represents the query parameters to include in the request URI. :param headers (dict): The headers to use for the request. :return: Serialized zone as a dictionary. """ return self._show_request( 'zones', uuid, params=params, headers=headers) @base.handle_errors def show_zone_nameservers(self, zone_uuid, params=None, headers=None): """Gets list of Zone Name Servers :param zone_uuid: Unique identifier of the zone in UUID format. :param params: A Python dict that represents the query parameters to include in the request URI. :param headers (dict): The headers to use for the request. :return: Serialized nameservers as a list. """ return self._show_request( 'zones/{0}/nameservers'.format(zone_uuid), uuid=None, params=params, headers=headers) @base.handle_errors def list_zones(self, params=None, headers=None): """Gets a list of zones. :param params: A Python dict that represents the query parameters to include in the request URI. :param headers (dict): The headers to use for the request. :return: Serialized zones as a list. """ return self._list_request('zones', params=params, headers=headers) @base.handle_errors def delete_zone(self, uuid, params=None, headers=None, delete_shares=None): """Deletes a zone having the specified UUID. :param uuid: The unique identifier of the zone. :param params: A Python dict that represents the query parameters to include in the request URI. :param headers (dict): The headers to use for the request. :param delete_shares: if set, delete-shares modifier will be activated :return: A tuple with the server response and the response body. """ if delete_shares: if headers: headers['x-designate-delete-shares'] = True else: headers = {'x-designate-delete-shares': True} resp, body = self._delete_request( 'zones', uuid, params=params, headers=headers) # Delete Zone should Return a HTTP 202 self.expected_success(202, resp.status) return resp, body @base.handle_errors def update_zone(self, uuid, email=None, ttl=None, description=None, wait_until=False, params=None, headers=None): """Update a zone with the specified parameters. :param uuid: The unique identifier of the zone. :param email: The email for the zone. Default: Random Value :param ttl: The ttl for the zone. Default: Random Value :param description: A description of the zone. Default: Random Value :param wait_until: Block until the zone reaches the desiered status :param params: A Python dict that represents the query parameters to include in the request URI. :param headers (dict): The headers to use for the request. :return: A tuple with the server response and the updated zone. """ zone = { 'email': email or dns_data_utils.rand_email(), 'ttl': ttl or dns_data_utils.rand_ttl(), 'description': description or data_utils.rand_name('test-zone'), } resp, body = self._update_request('zones', uuid, zone, params=params, headers=headers) # Update Zone should Return a HTTP 202 self.expected_success(202, resp.status) if wait_until: waiters.wait_for_zone_status(self, body['id'], wait_until) return resp, body @base.handle_errors def trigger_manual_update(self, zone_id, headers=None): """Trigger manually update for secondary zone. :param zone_id: Secondary zone ID. :param headers (dict): The headers to use for the request. :return: A tuple with the server response and body. """ resp, body = self._create_request( 'zones/{}/tasks/xfr'.format(zone_id), headers=headers) # Trigger Zone Update should Return a HTTP 202 self.expected_success(202, resp.status) return resp, body @base.handle_errors def abandon_zone(self, zone_id, headers=None): """This removes a zone from the designate database without removing it from the backends. :param zone_id: Zone ID. :param headers (dict): The headers to use for the request. :return: A tuple with the server response and body. """ resp, body = self._create_request( 'zones/{}/tasks/abandon'.format(zone_id), headers=headers, expected_statuses=self.DELETE_STATUS_CODES) self.expected_success(self.DELETE_STATUS_CODES, resp.status) return resp, body