Remove support for /os-floating-ip-dns REST API
Drop support for the os-floating-ip-dns API which has been deprecated since Newton: Idca478c566f9a7b5b30a3172453ce7c66d9fd8f0 This API now returns a 410 response for all routes. Unit tests are removed and the functional API sample tests are just asserting the 410 response now. The API sample docs are left intact since the API reference still builds from those and can be considered more or less branchless, so people looking at the API reference can apply it to older deployments of nova before os-floating-ip-dns was removed. The release note added for previous nova-network API removals is amended to note this additional change. Part of blueprint remove-nova-network Change-Id: I0c4b586292814b8483226aee315f41cbefc86a1e
This commit is contained in:
parent
823c4e840d
commit
db294b1e33
@ -60,7 +60,6 @@ the `API guide <http://developer.openstack.org/api-guide/compute/index.html>`_.
|
||||
.. 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
|
||||
|
@ -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
|
||||
-------
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
}
|
@ -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(),
|
||||
|
@ -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
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"dns_entry": {
|
||||
"ip": "%(ip)s",
|
||||
"dns_type": "%(dns_type)s"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"dns_entry": {
|
||||
"domain": "%(domain)s",
|
||||
"id": null,
|
||||
"ip": "%(ip)s",
|
||||
"name": "%(name)s",
|
||||
"type": "%(dns_type)s"
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"domain_entry": {
|
||||
"scope": "%(scope)s",
|
||||
"project": "%(project)s"
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"domain_entry": {
|
||||
"availability_zone": null,
|
||||
"domain": "%(domain)s",
|
||||
"project": "%(project)s",
|
||||
"scope": "%(scope)s"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"dns_entry": {
|
||||
"domain": "%(domain)s",
|
||||
"id": null,
|
||||
"ip": "%(ip)s",
|
||||
"name": "%(name)s",
|
||||
"type": null
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"dns_entries": [
|
||||
{
|
||||
"domain": "%(domain)s",
|
||||
"id": null,
|
||||
"ip": "%(ip)s",
|
||||
"name": "%(name)s",
|
||||
"type": null
|
||||
}
|
||||
]
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"domain_entries": [
|
||||
{
|
||||
"availability_zone": null,
|
||||
"domain": "%(domain)s",
|
||||
"project": "%(project)s",
|
||||
"scope": "%(scope)s"
|
||||
}
|
||||
]
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
@ -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": "",
|
||||
|
@ -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",
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user