diff --git a/api-ref/source/index.rst b/api-ref/source/index.rst index 3b1e438d5b76..e52c84cc5269 100644 --- a/api-ref/source/index.rst +++ b/api-ref/source/index.rst @@ -60,7 +60,6 @@ the `API guide `_. .. include:: images.inc .. include:: os-baremetal-nodes.inc .. include:: os-tenant-network.inc -.. include:: os-floating-ip-dns.inc .. include:: os-floating-ip-pools.inc .. include:: os-floating-ips.inc .. include:: os-security-groups.inc @@ -81,3 +80,4 @@ Compute API in the past, but no longer exist. .. include:: os-virtual-interfaces.inc .. include:: os-fixed-ips.inc .. include:: os-floating-ips-bulk.inc +.. include:: os-floating-ip-dns.inc diff --git a/api-ref/source/os-floating-ip-dns.inc b/api-ref/source/os-floating-ip-dns.inc index 0d38277037e6..0ef989c2bf45 100644 --- a/api-ref/source/os-floating-ip-dns.inc +++ b/api-ref/source/os-floating-ip-dns.inc @@ -11,11 +11,12 @@ Since these APIs are only implemented for **nova-network**, they are deprecated. These will fail with a 404 starting from microversion 2.36. + They were removed in the 18.0.0 Rocky release. Manages DNS records associated with floating IP addresses. The API dispatches requests to a DNS driver that is selected at startup. -List Dns Domains +List DNS Domains ================ .. rest_method:: GET /os-floating-ip-dns @@ -24,7 +25,8 @@ Lists registered DNS domains published by the DNS drivers. Normal response codes: 200 -Error response codes: unauthorized(401), forbidden(403), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), gone(410), +notImplemented(501) Response -------- @@ -34,7 +36,7 @@ Response .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-list-resp.json :language: javascript -Create Or Update Dns Domain +Create Or Update DNS Domain =========================== .. rest_method:: PUT /os-floating-ip-dns/{domain} @@ -43,8 +45,8 @@ Creates or updates a DNS domain. Normal response codes: 200 -Error response codes: badRequest(400), unauthorized(401), -forbidden(403), notImplemented(501) +Error response codes: badRequest(400), unauthorized(401), forbidden(403), +gone(410), notImplemented(501) Request ------- @@ -66,7 +68,7 @@ Response .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-resp.json :language: javascript -Delete Dns Domain +Delete DNS Domain ================= .. rest_method:: DELETE /os-floating-ip-dns/{domain} @@ -75,8 +77,8 @@ Deletes a DNS domain and all associated host entries. Normal response codes: 202 -Error response codes: unauthorized(401), forbidden(403), -itemNotFound(404), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), +gone(410), notImplemented(501) Request ------- @@ -88,7 +90,7 @@ Request Response -------- -List Dns Entries +List DNS Entries ================ .. rest_method:: GET /os-floating-ip-dns/{domain}/entries/{ip} @@ -97,8 +99,8 @@ Lists DNS entries for a domain and IP. Normal response codes: 200 -Error response codes: unauthorized(401), forbidden(403), -itemNotFound(404), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), +gone(410), notImplemented(501) Request ------- @@ -111,12 +113,12 @@ Request Response -------- -**Example List Dns Entries: JSON response** +**Example List DNS Entries: JSON response** .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-entry-list-resp.json :language: javascript -Find Unique Dns Entry +Find Unique DNS Entry ===================== .. rest_method:: GET /os-floating-ip-dns/{domain}/entries/{name} @@ -125,8 +127,8 @@ Finds a unique DNS entry for a domain and name. Normal response codes: 200 -Error response codes: unauthorized(401), forbidden(403), -itemNotFound(404), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), +gone(410), notImplemented(501) Request ------- @@ -139,12 +141,12 @@ Request Response -------- -**Example Find Unique Dns Entry: JSON response** +**Example Find Unique DNS Entry: JSON response** .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-entry-get-resp.json :language: javascript -Create Or Update Dns Entry +Create Or Update DNS Entry ========================== .. rest_method:: PUT /os-floating-ip-dns/{domain}/entries/{name} @@ -153,7 +155,8 @@ Creates or updates a DNS entry. Normal response codes: 200 -Error response codes: unauthorized(401), forbidden(403), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), gone(410), +notImplemented(501) Request ------- @@ -163,7 +166,7 @@ Request - domain: domain - name: name -**Example Create Or Update Dns Entry: JSON request** +**Example Create Or Update DNS Entry: JSON request** .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-req.json :language: javascript @@ -171,12 +174,12 @@ Request Response -------- -**Example Create Or Update Dns Entry: JSON response** +**Example Create Or Update DNS Entry: JSON response** .. literalinclude:: ../../doc/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-resp.json :language: javascript -Delete Dns Entry +Delete DNS Entry ================ .. rest_method:: DELETE /os-floating-ip-dns/{domain}/entries/{name} @@ -185,8 +188,8 @@ Deletes a DNS entry. Normal response codes: 202 -Error response codes: unauthorized(401), forbidden(403), -itemNotFound(404), notImplemented(501) +Error response codes: unauthorized(401), forbidden(403), itemNotFound(404), +gone(410), notImplemented(501) Request ------- diff --git a/nova/api/openstack/compute/floating_ip_dns.py b/nova/api/openstack/compute/floating_ip_dns.py index d214e193c038..1c4321b5f6b3 100644 --- a/nova/api/openstack/compute/floating_ip_dns.py +++ b/nova/api/openstack/compute/floating_ip_dns.py @@ -12,242 +12,38 @@ # License for the specific language governing permissions and limitations # under the License. -from oslo_utils import netutils -from six.moves import urllib -import webob +from webob import exc -from nova.api.openstack.api_version_request \ - import MAX_PROXY_API_SUPPORT_VERSION -from nova.api.openstack import common -from nova.api.openstack.compute.schemas import floating_ip_dns from nova.api.openstack import wsgi -from nova.api import validation -from nova import exception -from nova.i18n import _ -from nova import network -from nova.policies import floating_ip_dns as fid_policies - - -def _translate_dns_entry_view(dns_entry): - result = {} - result['ip'] = dns_entry.get('ip') - result['id'] = dns_entry.get('id') - result['type'] = dns_entry.get('type') - result['domain'] = dns_entry.get('domain') - result['name'] = dns_entry.get('name') - return {'dns_entry': result} - - -def _translate_dns_entries_view(dns_entries): - return {'dns_entries': [_translate_dns_entry_view(entry)['dns_entry'] - for entry in dns_entries]} - - -def _translate_domain_entry_view(domain_entry): - result = {} - result['domain'] = domain_entry.get('domain') - result['scope'] = domain_entry.get('scope') - result['project'] = domain_entry.get('project') - result['availability_zone'] = domain_entry.get('availability_zone') - return {'domain_entry': result} - - -def _translate_domain_entries_view(domain_entries): - return {'domain_entries': - [_translate_domain_entry_view(entry)['domain_entry'] - for entry in domain_entries]} - - -def _unquote_domain(domain): - """Unquoting function for receiving a domain name in a URL. - - Domain names tend to have .'s in them. Urllib doesn't quote dots, - but Routes tends to choke on them, so we need an extra level of - by-hand quoting here. - """ - return urllib.parse.unquote(domain).replace('%2E', '.') - - -def _create_dns_entry(ip, name, domain): - return {'ip': ip, 'name': name, 'domain': domain} - - -def _create_domain_entry(domain, scope=None, project=None, av_zone=None): - return {'domain': domain, 'scope': scope, 'project': project, - 'availability_zone': av_zone} class FloatingIPDNSDomainController(wsgi.Controller): """DNS domain controller for OpenStack API.""" - def __init__(self): - super(FloatingIPDNSDomainController, self).__init__() - self.network_api = network.API() - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors(501) + @wsgi.expected_errors(410) def index(self, req): - """Return a list of available DNS domains.""" - context = req.environ['nova.context'] - context.can(fid_policies.BASE_POLICY_NAME) + raise exc.HTTPGone() - try: - domains = self.network_api.get_dns_domains(context) - except NotImplementedError: - common.raise_feature_not_supported() - - domainlist = [_create_domain_entry(domain['domain'], - domain.get('scope'), - domain.get('project'), - domain.get('availability_zone')) - for domain in domains] - - return _translate_domain_entries_view(domainlist) - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((400, 501)) - @validation.schema(floating_ip_dns.domain_entry_update) + @wsgi.expected_errors(410) def update(self, req, id, body): - """Add or modify domain entry.""" - context = req.environ['nova.context'] - context.can(fid_policies.POLICY_ROOT % "domain:update") - fqdomain = _unquote_domain(id) - entry = body['domain_entry'] - scope = entry['scope'] - project = entry.get('project', None) - av_zone = entry.get('availability_zone', None) + raise exc.HTTPGone() - if scope == 'private' and project: - msg = _("you can not pass project if the scope is private") - raise webob.exc.HTTPBadRequest(explanation=msg) - if scope == 'public' and av_zone: - msg = _("you can not pass av_zone if the scope is public") - raise webob.exc.HTTPBadRequest(explanation=msg) - - if scope == 'private': - create_dns_domain = self.network_api.create_private_dns_domain - area_name, area = 'availability_zone', av_zone - else: - create_dns_domain = self.network_api.create_public_dns_domain - area_name, area = 'project', project - - try: - create_dns_domain(context, fqdomain, area) - except NotImplementedError: - common.raise_feature_not_supported() - - return _translate_domain_entry_view({'domain': fqdomain, - 'scope': scope, - area_name: area}) - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((404, 501)) - @wsgi.response(202) + @wsgi.expected_errors(410) def delete(self, req, id): - """Delete the domain identified by id.""" - context = req.environ['nova.context'] - context.can(fid_policies.POLICY_ROOT % "domain:delete") - domain = _unquote_domain(id) - - # Delete the whole domain - try: - self.network_api.delete_dns_domain(context, domain) - except NotImplementedError: - common.raise_feature_not_supported() - except exception.NotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.format_message()) + raise exc.HTTPGone() class FloatingIPDNSEntryController(wsgi.Controller): """DNS Entry controller for OpenStack API.""" - def __init__(self): - super(FloatingIPDNSEntryController, self).__init__() - self.network_api = network.API() - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((404, 501)) + @wsgi.expected_errors(410) def show(self, req, domain_id, id): - """Return the DNS entry that corresponds to domain_id and id.""" - context = req.environ['nova.context'] - context.can(fid_policies.BASE_POLICY_NAME) - domain = _unquote_domain(domain_id) + raise exc.HTTPGone() - floating_ip = None - # Check whether id is a valid ipv4/ipv6 address. - if netutils.is_valid_ip(id): - floating_ip = id - - try: - if floating_ip: - entries = self.network_api.get_dns_entries_by_address(context, - floating_ip, - domain) - else: - entries = self.network_api.get_dns_entries_by_name(context, - id, - domain) - except NotImplementedError: - common.raise_feature_not_supported() - - if not entries: - explanation = _("DNS entries not found.") - raise webob.exc.HTTPNotFound(explanation=explanation) - - if floating_ip: - entrylist = [_create_dns_entry(floating_ip, entry, domain) - for entry in entries] - dns_entries = _translate_dns_entries_view(entrylist) - return wsgi.ResponseObject(dns_entries) - - entry = _create_dns_entry(entries[0], id, domain) - return _translate_dns_entry_view(entry) - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors(501) - @validation.schema(floating_ip_dns.dns_entry_update) + @wsgi.expected_errors(410) def update(self, req, domain_id, id, body): - """Add or modify dns entry.""" - context = req.environ['nova.context'] - context.can(fid_policies.BASE_POLICY_NAME) - domain = _unquote_domain(domain_id) - name = id - entry = body['dns_entry'] - address = entry['ip'] - dns_type = entry['dns_type'] + raise exc.HTTPGone() - try: - entries = self.network_api.get_dns_entries_by_name(context, - name, domain) - if not entries: - # create! - self.network_api.add_dns_entry(context, address, name, - dns_type, domain) - else: - # modify! - self.network_api.modify_dns_entry(context, name, - address, domain) - except NotImplementedError: - common.raise_feature_not_supported() - - return _translate_dns_entry_view({'ip': address, - 'name': name, - 'type': dns_type, - 'domain': domain}) - - @wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION) - @wsgi.expected_errors((404, 501)) - @wsgi.response(202) + @wsgi.expected_errors(410) def delete(self, req, domain_id, id): - """Delete the entry identified by req and id.""" - context = req.environ['nova.context'] - context.can(fid_policies.BASE_POLICY_NAME) - domain = _unquote_domain(domain_id) - name = id - - try: - self.network_api.delete_dns_entry(context, name, domain) - except NotImplementedError: - common.raise_feature_not_supported() - except exception.NotFound as e: - raise webob.exc.HTTPNotFound(explanation=e.format_message()) + raise exc.HTTPGone() diff --git a/nova/api/openstack/compute/schemas/floating_ip_dns.py b/nova/api/openstack/compute/schemas/floating_ip_dns.py deleted file mode 100644 index 3859143886a6..000000000000 --- a/nova/api/openstack/compute/schemas/floating_ip_dns.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2014 IBM Corporation. All rights reserved. -# -# 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 nova.api.validation import parameter_types - - -domain_entry_update = { - 'type': 'object', - 'properties': { - 'domain_entry': { - 'type': 'object', - 'properties': { - 'scope': { - 'type': 'string', - 'enum': ['public', 'private'], - }, - 'project': parameter_types.project_id, - 'availability_zone': parameter_types.name, - }, - 'required': ['scope'], - 'maxProperties': 2, - 'additionalProperties': False, - }, - }, - 'required': ['domain_entry'], - 'additionalProperties': False, -} - - -dns_entry_update = { - 'type': 'object', - 'properties': { - 'dns_entry': { - 'type': 'object', - 'properties': { - 'ip': parameter_types.ip_address, - 'dns_type': { - 'type': 'string', - 'enum': ['a', 'A'], - }, - }, - 'required': ['ip', 'dns_type'], - 'additionalProperties': False, - }, - }, - 'required': ['dns_entry'], - 'additionalProperties': False, -} diff --git a/nova/policies/__init__.py b/nova/policies/__init__.py index 56fea01dd62f..bd7b04dbcc8c 100644 --- a/nova/policies/__init__.py +++ b/nova/policies/__init__.py @@ -41,7 +41,6 @@ from nova.policies import flavor_extra_specs from nova.policies import flavor_manage from nova.policies import flavor_rxtx from nova.policies import flavors -from nova.policies import floating_ip_dns from nova.policies import floating_ip_pools from nova.policies import floating_ips from nova.policies import hide_server_addresses @@ -115,7 +114,6 @@ def list_rules(): flavor_manage.list_rules(), flavor_rxtx.list_rules(), flavors.list_rules(), - floating_ip_dns.list_rules(), floating_ip_pools.list_rules(), floating_ips.list_rules(), hide_server_addresses.list_rules(), diff --git a/nova/policies/floating_ip_dns.py b/nova/policies/floating_ip_dns.py deleted file mode 100644 index fc4b0e78c022..000000000000 --- a/nova/policies/floating_ip_dns.py +++ /dev/null @@ -1,78 +0,0 @@ -# Copyright 2016 Cloudbase Solutions Srl -# All Rights Reserved. -# -# 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 oslo_policy import policy - -from nova.policies import base - - -BASE_POLICY_NAME = 'os_compute_api:os-floating-ip-dns' -POLICY_ROOT = 'os_compute_api:os-floating-ip-dns:%s' - - -floating_ip_dns_policies = [ - policy.DocumentedRuleDefault( - BASE_POLICY_NAME, - base.RULE_ADMIN_OR_OWNER, - """List registered DNS domains, and CRUD actions on domain names. - -Note this only works with nova-network and this API is deprecated.""", - [ - { - 'method': 'GET', - 'path': '/os-floating-ip-dns' - }, - { - 'method': 'GET', - 'path': '/os-floating-ip-dns/{domain}/entries/{ip}' - }, - { - 'method': 'GET', - 'path': '/os-floating-ip-dns/{domain}/entries/{name}' - }, - { - 'method': 'PUT', - 'path': '/os-floating-ip-dns/{domain}/entries/{name}' - }, - { - 'method': 'DELETE', - 'path': '/os-floating-ip-dns/{domain}/entries/{name}' - }, - ]), - policy.DocumentedRuleDefault( - POLICY_ROOT % 'domain:update', - base.RULE_ADMIN_API, - "Create or update a DNS domain.", - [ - { - 'method': 'PUT', - 'path': '/os-floating-ip-dns/{domain}' - } - ]), - policy.DocumentedRuleDefault( - POLICY_ROOT % 'domain:delete', - base.RULE_ADMIN_API, - "Delete a DNS domain.", - [ - { - 'method': 'DELETE', - 'path': '/os-floating-ip-dns/{domain}' - } - ]), -] - - -def list_rules(): - return floating_ip_dns_policies diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-req.json.tpl deleted file mode 100644 index 000c5e123188..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-req.json.tpl +++ /dev/null @@ -1,6 +0,0 @@ -{ - "dns_entry": { - "ip": "%(ip)s", - "dns_type": "%(dns_type)s" - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-resp.json.tpl deleted file mode 100644 index 3ec0743ba714..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-entry-resp.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dns_entry": { - "domain": "%(domain)s", - "id": null, - "ip": "%(ip)s", - "name": "%(name)s", - "type": "%(dns_type)s" - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-req.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-req.json.tpl deleted file mode 100644 index f6685f5d3ff7..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-req.json.tpl +++ /dev/null @@ -1,6 +0,0 @@ -{ - "domain_entry": { - "scope": "%(scope)s", - "project": "%(project)s" - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-resp.json.tpl deleted file mode 100644 index a14d395d23fe..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-create-or-update-resp.json.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{ - "domain_entry": { - "availability_zone": null, - "domain": "%(domain)s", - "project": "%(project)s", - "scope": "%(scope)s" - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-get-resp.json.tpl deleted file mode 100644 index 8edd0603f7eb..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-get-resp.json.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{ - "dns_entry": { - "domain": "%(domain)s", - "id": null, - "ip": "%(ip)s", - "name": "%(name)s", - "type": null - } -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-list-resp.json.tpl deleted file mode 100644 index 831cda7b55df..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-entry-list-resp.json.tpl +++ /dev/null @@ -1,11 +0,0 @@ -{ - "dns_entries": [ - { - "domain": "%(domain)s", - "id": null, - "ip": "%(ip)s", - "name": "%(name)s", - "type": null - } - ] -} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-list-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-list-resp.json.tpl deleted file mode 100644 index a6055cfecca1..000000000000 --- a/nova/tests/functional/api_sample_tests/api_samples/os-floating-ip-dns/floating-ip-dns-list-resp.json.tpl +++ /dev/null @@ -1,10 +0,0 @@ -{ - "domain_entries": [ - { - "availability_zone": null, - "domain": "%(domain)s", - "project": "%(project)s", - "scope": "%(scope)s" - } - ] -} diff --git a/nova/tests/functional/api_sample_tests/test_floating_ip_dns.py b/nova/tests/functional/api_sample_tests/test_floating_ip_dns.py index 273b7f3a6c0b..acdbcd1b5317 100644 --- a/nova/tests/functional/api_sample_tests/test_floating_ip_dns.py +++ b/nova/tests/functional/api_sample_tests/test_floating_ip_dns.py @@ -12,81 +12,59 @@ # License for the specific language governing permissions and limitations # under the License. +from nova.tests.functional.api import client as api_client from nova.tests.functional.api_sample_tests import api_sample_base class FloatingIpDNSTest(api_sample_base.ApiSampleTestBaseV21): ADMIN_API = True - sample_dir = "os-floating-ip-dns" - - domain = 'domain1.example.org' - name = 'instance1' - scope = 'public' - project = 'project1' - dns_type = 'A' - ip = '192.168.1.1' - - def _create_or_update(self): - subs = {'project': self.project, - 'scope': self.scope} - response = self._do_put('os-floating-ip-dns/%s' % self.domain, - 'floating-ip-dns-create-or-update-req', subs) - subs.update({'domain': self.domain}) - self._verify_response('floating-ip-dns-create-or-update-resp', subs, - response, 200) - - def _create_or_update_entry(self): - subs = {'ip': self.ip, 'dns_type': self.dns_type} - response = self._do_put('os-floating-ip-dns/%s/entries/%s' - % (self.domain, self.name), - 'floating-ip-dns-create-or-update-entry-req', - subs) - subs.update({'name': self.name, 'domain': self.domain}) - self._verify_response('floating-ip-dns-create-or-update-entry-resp', - subs, response, 200) def test_floating_ip_dns_list(self): - self._create_or_update() - response = self._do_get('os-floating-ip-dns') - subs = {'domain': self.domain, - 'project': self.project, - 'scope': self.scope} - self._verify_response('floating-ip-dns-list-resp', subs, - response, 200) + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, + 'os-floating-ip-dns') + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_create_or_update(self): - self._create_or_update() + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_put, + 'os-floating-ip-dns/domain1.example.org', + {'project': 'project1', + 'scope': 'public'}) + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_delete(self): - self._create_or_update() - response = self._do_delete('os-floating-ip-dns/%s' % self.domain) - self.assertEqual(202, response.status_code) + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_delete, + 'os-floating-ip-dns/domain1.example.org') + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_create_or_update_entry(self): - self._create_or_update_entry() + url = 'os-floating-ip-dns/domain1.example.org/entries/instance1' + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_put, + url, + {'ip': '192.168.1.1', + 'dns_type': 'A'}) + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_entry_get(self): - self._create_or_update_entry() - response = self._do_get('os-floating-ip-dns/%s/entries/%s' - % (self.domain, self.name)) - subs = {'domain': self.domain, - 'ip': self.ip, - 'name': self.name} - self._verify_response('floating-ip-dns-entry-get-resp', subs, - response, 200) + url = 'os-floating-ip-dns/domain1.example.org/entries/instance1' + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, + url) + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_entry_delete(self): - self._create_or_update_entry() - response = self._do_delete('os-floating-ip-dns/%s/entries/%s' - % (self.domain, self.name)) - self.assertEqual(202, response.status_code) + url = 'os-floating-ip-dns/domain1.example.org/entries/instance1' + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_delete, + url) + self.assertEqual(410, ex.response.status_code) def test_floating_ip_dns_entry_list(self): - self._create_or_update_entry() - response = self._do_get('os-floating-ip-dns/%s/entries/%s' - % (self.domain, self.ip)) - subs = {'domain': self.domain, - 'ip': self.ip, - 'name': self.name} - self._verify_response('floating-ip-dns-entry-list-resp', subs, - response, 200) + url = 'os-floating-ip-dns/domain1.example.org/entries/192.168.1.1' + ex = self.assertRaises(api_client.OpenStackApiException, + self.api.api_get, + url) + self.assertEqual(410, ex.response.status_code) diff --git a/nova/tests/unit/api/openstack/compute/test_floating_ip_dns.py b/nova/tests/unit/api/openstack/compute/test_floating_ip_dns.py deleted file mode 100644 index 275e14b8a4ea..000000000000 --- a/nova/tests/unit/api/openstack/compute/test_floating_ip_dns.py +++ /dev/null @@ -1,453 +0,0 @@ -# Copyright 2011 Andrew Bogott for the Wikimedia Foundation -# All Rights Reserved. -# Copyright 2013 Red Hat, Inc. -# -# 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. - -import mock -from six.moves import urllib -import webob - -from nova.api.openstack.compute import floating_ip_dns \ - as fipdns_v21 -from nova import context -from nova.db import api as db -from nova import exception -from nova import network -from nova import test -from nova.tests.unit.api.openstack import fakes - - -name = "arbitraryname" -name2 = "anotherarbitraryname" - -test_ipv4_address = '10.0.0.66' -test_ipv4_address2 = '10.0.0.67' - -test_ipv6_address = 'fe80:0:0:0:0:0:a00:42' - -domain = "example.org" -domain2 = "example.net" -floating_ip_id = '1' - - -def _quote_domain(domain): - """Domain names tend to have .'s in them. Urllib doesn't quote dots, - but Routes tends to choke on them, so we need an extra level of - by-hand quoting here. This function needs to duplicate the one in - python-novaclient/novaclient/v1_1/floating_ip_dns.py - """ - return urllib.parse.quote(domain.replace('.', '%2E')) - - -def network_api_get_floating_ip(self, context, id): - return {'id': floating_ip_id, 'address': test_ipv4_address, - 'fixed_ip': None} - - -def network_get_dns_domains(self, context): - return [{'domain': 'example.org', 'scope': 'public'}, - {'domain': 'example.com', 'scope': 'public', - 'project': 'project1'}, - {'domain': 'private.example.com', 'scope': 'private', - 'availability_zone': 'avzone'}] - - -def network_get_dns_entries_by_address(self, context, address, domain): - return [name, name2] - - -def network_get_dns_entries_by_name(self, context, address, domain): - return [test_ipv4_address] - - -def network_add_dns_entry(self, context, address, name, dns_type, domain): - return {'dns_entry': {'ip': test_ipv4_address, - 'name': name, - 'type': dns_type, - 'domain': domain}} - - -def network_modify_dns_entry(self, context, address, name, domain): - return {'dns_entry': {'name': name, - 'ip': address, - 'domain': domain}} - - -def network_create_private_dns_domain(self, context, domain, avail_zone): - pass - - -def network_create_public_dns_domain(self, context, domain, project): - pass - - -class FloatingIpDNSTestV21(test.TestCase): - floating_ip_dns = fipdns_v21 - - def _create_floating_ip(self): - """Create a floating ip object.""" - host = "fake_host" - db.floating_ip_create(self.context, - {'address': test_ipv4_address, - 'host': host}) - db.floating_ip_create(self.context, - {'address': test_ipv6_address, - 'host': host}) - - def _delete_floating_ip(self): - db.floating_ip_destroy(self.context, test_ipv4_address) - db.floating_ip_destroy(self.context, test_ipv6_address) - - def _check_status(self, expected_status, res, controller_method): - self.assertEqual(expected_status, controller_method.wsgi_code) - - def _bad_request(self): - return webob.exc.HTTPBadRequest - - def setUp(self): - super(FloatingIpDNSTestV21, self).setUp() - # None of these APIs are implemented for Neutron. - self.flags(use_neutron=False) - self.stub_out("nova.network.api.API.get_dns_domains", - network_get_dns_domains) - self.stub_out("nova.network.api.API.get_dns_entries_by_address", - network_get_dns_entries_by_address) - self.stub_out("nova.network.api.API.get_dns_entries_by_name", - network_get_dns_entries_by_name) - self.stub_out("nova.network.api.API.get_floating_ip", - network_api_get_floating_ip) - self.stub_out("nova.network.api.API.add_dns_entry", - network_add_dns_entry) - self.stub_out("nova.network.api.API.modify_dns_entry", - network_modify_dns_entry) - self.stub_out("nova.network.api.API.create_public_dns_domain", - network_create_public_dns_domain) - self.stub_out("nova.network.api.API.create_private_dns_domain", - network_create_private_dns_domain) - - self.context = context.get_admin_context() - - self._create_floating_ip() - temp = self.floating_ip_dns.FloatingIPDNSDomainController() - self.domain_controller = temp - self.entry_controller = self.floating_ip_dns.\ - FloatingIPDNSEntryController() - self.admin_req = fakes.HTTPRequest.blank('', use_admin_context=True) - self.req = fakes.HTTPRequest.blank('') - - def tearDown(self): - self._delete_floating_ip() - super(FloatingIpDNSTestV21, self).tearDown() - - def test_dns_domains_list(self): - res_dict = self.domain_controller.index(self.req) - entries = res_dict['domain_entries'] - self.assertTrue(entries) - self.assertEqual(entries[0]['domain'], "example.org") - self.assertFalse(entries[0]['project']) - self.assertFalse(entries[0]['availability_zone']) - self.assertEqual(entries[1]['domain'], "example.com") - self.assertEqual(entries[1]['project'], "project1") - self.assertFalse(entries[1]['availability_zone']) - self.assertEqual(entries[2]['domain'], "private.example.com") - self.assertFalse(entries[2]['project']) - self.assertEqual(entries[2]['availability_zone'], "avzone") - - def _test_get_dns_entries_by_address(self, address): - - entries = self.entry_controller.show(self.req, _quote_domain(domain), - address) - entries = entries.obj - self.assertEqual(len(entries['dns_entries']), 2) - self.assertEqual(entries['dns_entries'][0]['name'], - name) - self.assertEqual(entries['dns_entries'][1]['name'], - name2) - self.assertEqual(entries['dns_entries'][0]['domain'], - domain) - - def test_get_dns_entries_by_ipv4_address(self): - self._test_get_dns_entries_by_address(test_ipv4_address) - - def test_get_dns_entries_by_ipv6_address(self): - self._test_get_dns_entries_by_address(test_ipv6_address) - - def test_get_dns_entries_by_name(self): - entry = self.entry_controller.show(self.req, _quote_domain(domain), - name) - - self.assertEqual(entry['dns_entry']['ip'], - test_ipv4_address) - self.assertEqual(entry['dns_entry']['domain'], - domain) - - @mock.patch.object(network.api.API, "get_dns_entries_by_name", - side_effect=webob.exc.HTTPNotFound()) - def test_dns_entries_not_found(self, mock_get_entries): - self.assertRaises(webob.exc.HTTPNotFound, - self.entry_controller.show, - self.req, _quote_domain(domain), 'nonexistent') - self.assertTrue(mock_get_entries.called) - - def test_create_entry(self): - body = {'dns_entry': - {'ip': test_ipv4_address, - 'dns_type': 'A'}} - entry = self.entry_controller.update(self.req, _quote_domain(domain), - name, body=body) - self.assertEqual(entry['dns_entry']['ip'], test_ipv4_address) - - def test_create_domain(self): - self._test_create_domain(self.req) - - def _test_create_domain(self, req): - body = {'domain_entry': - {'scope': 'private', - 'project': 'testproject'}} - self.assertRaises(self._bad_request(), - self.domain_controller.update, req, - _quote_domain(domain), body=body) - - body = {'domain_entry': - {'scope': 'public', - 'availability_zone': 'zone1'}} - self.assertRaises(self._bad_request(), - self.domain_controller.update, req, - _quote_domain(domain), body=body) - - body = {'domain_entry': - {'scope': 'public', - 'project': 'testproject'}} - entry = self.domain_controller.update(req, - _quote_domain(domain), body=body) - self.assertEqual(entry['domain_entry']['domain'], domain) - self.assertEqual(entry['domain_entry']['scope'], 'public') - self.assertEqual(entry['domain_entry']['project'], 'testproject') - - body = {'domain_entry': - {'scope': 'private', - 'availability_zone': 'zone1'}} - entry = self.domain_controller.update(req, - _quote_domain(domain), body=body) - self.assertEqual(entry['domain_entry']['domain'], domain) - self.assertEqual(entry['domain_entry']['scope'], 'private') - self.assertEqual(entry['domain_entry']['availability_zone'], 'zone1') - - @mock.patch.object(network.api.API, "delete_dns_entry") - def test_delete_entry(self, mock_del_entry): - delete = self.entry_controller.delete - res = delete(self.req, _quote_domain(domain), name) - - self._check_status(202, res, delete) - mock_del_entry.assert_called_once_with(mock.ANY, name, domain) - - @mock.patch.object(network.api.API, "delete_dns_entry", - side_effect=exception.NotFound) - def test_delete_entry_notfound(self, mock_del_entry): - self.assertRaises(webob.exc.HTTPNotFound, - self.entry_controller.delete, self.req, _quote_domain(domain), - name) - self.assertTrue(mock_del_entry.called) - - def test_delete_domain(self): - self._test_delete_domain(self.req) - - @mock.patch.object(network.api.API, "delete_dns_domain") - def _test_delete_domain(self, req, mock_del_dom): - delete = self.domain_controller.delete - res = delete(req, _quote_domain(domain)) - - self._check_status(202, res, delete) - mock_del_dom.assert_called_once_with(mock.ANY, domain) - - def test_delete_domain_notfound(self): - self._test_delete_domain_notfound(self.req) - - @mock.patch.object(network.api.API, "delete_dns_domain", - side_effect=exception.NotFound) - def _test_delete_domain_notfound(self, req, mock_del_dom): - self.assertRaises( - webob.exc.HTTPNotFound, self.domain_controller.delete, - req, _quote_domain(domain)) - self.assertTrue(mock_del_dom.called) - - def test_modify(self): - body = {'dns_entry': - {'ip': test_ipv4_address2, - 'dns_type': 'A'}} - entry = self.entry_controller.update(self.req, domain, name, body=body) - - self.assertEqual(entry['dns_entry']['ip'], test_ipv4_address2) - - def test_not_implemented_dns_entry_update(self): - body = {'dns_entry': - {'ip': test_ipv4_address, - 'dns_type': 'A'}} - with mock.patch.object(network.api.API, 'modify_dns_entry', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.entry_controller.update, self.req, - _quote_domain(domain), name, body=body) - - def test_not_implemented_dns_entry_show(self): - with mock.patch.object(network.api.API, 'get_dns_entries_by_name', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.entry_controller.show, - self.req, _quote_domain(domain), name) - - def test_not_implemented_delete_entry(self): - with mock.patch.object(network.api.API, 'delete_dns_entry', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.entry_controller.delete, self.req, - _quote_domain(domain), name) - - def test_not_implemented_delete_domain(self): - with mock.patch.object(network.api.API, 'delete_dns_domain', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.domain_controller.delete, self.admin_req, - _quote_domain(domain)) - - def test_not_implemented_create_domain(self): - body = {'domain_entry': - {'scope': 'private', - 'availability_zone': 'zone1'}} - with mock.patch.object(network.api.API, 'create_private_dns_domain', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.domain_controller.update, self.admin_req, - _quote_domain(domain), body=body) - - def test_not_implemented_dns_domains_list(self): - with mock.patch.object(network.api.API, 'get_dns_domains', - side_effect=NotImplementedError()): - self.assertRaises(webob.exc.HTTPNotImplemented, - self.domain_controller.index, self.req) - - -class FloatingIPDNSDomainPolicyEnforcementV21(test.NoDBTestCase): - - def setUp(self): - super(FloatingIPDNSDomainPolicyEnforcementV21, self).setUp() - self.controller = fipdns_v21.FloatingIPDNSDomainController() - self.rule_name = "os_compute_api:os-floating-ip-dns" - self.policy.set_rules({self.rule_name: "project:non_fake"}) - self.req = fakes.HTTPRequest.blank('') - - def test_get_floating_ip_dns_policy_failed(self): - rule_name = "os_compute_api:os-floating-ip-dns" - self.policy.set_rules({rule_name: "project:non_fake"}) - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.index, self.req) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - - def test_update_floating_ip_dns_policy_failed(self): - rule_name = "os_compute_api:os-floating-ip-dns:domain:update" - self.policy.set_rules({rule_name: "project:non_fake"}) - body = {'domain_entry': - {'scope': 'public', - 'project': 'testproject'}} - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.update, self.req, _quote_domain(domain), body=body) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - - def test_delete_floating_ip_dns_policy_failed(self): - rule_name = "os_compute_api:os-floating-ip-dns:domain:delete" - self.policy.set_rules({rule_name: "project:non_fake"}) - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.delete, self.req, _quote_domain(domain)) - self.assertEqual( - "Policy doesn't allow %s to be performed." % rule_name, - exc.format_message()) - - -class FloatingIPDNSEntryPolicyEnforcementV21(test.NoDBTestCase): - - def setUp(self): - super(FloatingIPDNSEntryPolicyEnforcementV21, self).setUp() - self.controller = fipdns_v21.FloatingIPDNSEntryController() - self.rule_name = "os_compute_api:os-floating-ip-dns" - self.policy.set_rules({self.rule_name: "project:non_fake"}) - self.req = fakes.HTTPRequest.blank('') - - def test_show_floating_ip_dns_entry_policy_failed(self): - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.show, self.req, - _quote_domain(domain), test_ipv4_address) - self.assertEqual( - "Policy doesn't allow %s to be performed." % self.rule_name, - exc.format_message()) - - def test_update_floating_ip_dns_policy_failed(self): - body = {'dns_entry': - {'ip': test_ipv4_address, - 'dns_type': 'A'}} - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.update, self.req, _quote_domain(domain), - name, body=body) - self.assertEqual( - "Policy doesn't allow %s to be performed." % self.rule_name, - exc.format_message()) - - def test_delete_floating_ip_dns_policy_failed(self): - exc = self.assertRaises( - exception.PolicyNotAuthorized, - self.controller.delete, self.req, _quote_domain(domain), name) - self.assertEqual( - "Policy doesn't allow %s to be performed." % self.rule_name, - exc.format_message()) - - -class FloatingIpDNSDomainDeprecationTest(test.NoDBTestCase): - - def setUp(self): - super(FloatingIpDNSDomainDeprecationTest, self).setUp() - self.controller = fipdns_v21.FloatingIPDNSDomainController() - self.req = fakes.HTTPRequest.blank('', version='2.36') - - def test_all_apis_return_not_found(self): - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.index, self.req) - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.update, self.req, fakes.FAKE_UUID, {}) - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.delete, self.req, fakes.FAKE_UUID) - - -class FloatingIpDNSEntryDeprecationTest(test.NoDBTestCase): - - def setUp(self): - super(FloatingIpDNSEntryDeprecationTest, self).setUp() - self.controller = fipdns_v21.FloatingIPDNSEntryController() - self.req = fakes.HTTPRequest.blank('', version='2.36') - - def test_all_apis_return_not_found(self): - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.show, self.req, fakes.FAKE_UUID, fakes.FAKE_UUID) - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.update, self.req, fakes.FAKE_UUID, fakes.FAKE_UUID, - {}) - self.assertRaises(exception.VersionNotFoundForAPIMethod, - self.controller.delete, self.req, fakes.FAKE_UUID, fakes.FAKE_UUID) diff --git a/nova/tests/unit/fake_policy.py b/nova/tests/unit/fake_policy.py index 6c00b1dc31fe..587903cf6d7d 100644 --- a/nova/tests/unit/fake_policy.py +++ b/nova/tests/unit/fake_policy.py @@ -46,9 +46,6 @@ policy_data = """ "os_compute_api:os-flavor-manage": "", "os_compute_api:os-flavor-manage:create": "", "os_compute_api:os-flavor-manage:delete": "", - "os_compute_api:os-floating-ip-dns": "", - "os_compute_api:os-floating-ip-dns:domain:update": "", - "os_compute_api:os-floating-ip-dns:domain:delete": "", "os_compute_api:os-floating-ip-pools": "", "os_compute_api:os-floating-ips": "", "os_compute_api:os-instance-actions": "", diff --git a/nova/tests/unit/test_policy.py b/nova/tests/unit/test_policy.py index 367aec8637d5..a5afc02bbaee 100644 --- a/nova/tests/unit/test_policy.py +++ b/nova/tests/unit/test_policy.py @@ -311,8 +311,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase): "os_compute_api:os-flavor-manage:create", "os_compute_api:os-flavor-manage:update", "os_compute_api:os-flavor-manage:delete", -"os_compute_api:os-floating-ip-dns:domain:delete", -"os_compute_api:os-floating-ip-dns:domain:update", "os_compute_api:os-hosts", "os_compute_api:os-hypervisors", "os_compute_api:os-instance-actions:events", @@ -408,7 +406,6 @@ class RealRolePolicyTestCase(test.NoDBTestCase): "os_compute_api:flavors", "os_compute_api:os-flavor-extra-specs:index", "os_compute_api:os-flavor-extra-specs:show", -"os_compute_api:os-floating-ip-dns", "os_compute_api:os-floating-ip-pools", "os_compute_api:os-floating-ips", "os_compute_api:image-size", diff --git a/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml index ab9b881b785d..58166e9baa65 100644 --- a/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml +++ b/releasenotes/notes/bp-remove-nova-network-api-removals-931ad60364f6f2a8.yaml @@ -16,6 +16,13 @@ upgrade: * ``GET /os-floating-ips-bulk/{host_name}`` * ``POST /os-floating-ips-bulk`` * ``PUT /os-floating-ips-bulk/delete`` + * ``GET /os-floating-ip-dns`` + * ``PUT /os-floating-ip-dns/{domain}`` + * ``DELETE /os-floating-ip-dns/{domain}`` + * ``GET /os-floating-ip-dns/{domain}/entries/{ip}`` + * ``GET /os-floating-ip-dns/{domain}/entries/{name}`` + * ``PUT /os-floating-ip-dns/{domain}/entries/{name}`` + * ``DELETE /os-floating-ip-dns/{domain}/entries/{name}`` In addition, the following configuration options have been removed.