Add DNS parameters to Floating IP panels
This adds support for the "DNS Domain" and "DNS Name" options to the panels for listing and allocation Floating IPs. These options are available as a Neutron extension, so we need to make them conditional based on the availability of that extension. Change-Id: Ife8e19aac44dccbdf11a6a6d4bb50cd3b7ed8d8e
This commit is contained in:
parent
94aea2fedd
commit
9e703aec2f
@ -492,7 +492,7 @@ class SecurityGroupManager(object):
|
||||
|
||||
class FloatingIp(base.APIDictWrapper):
|
||||
_attrs = ['id', 'ip', 'fixed_ip', 'port_id', 'instance_id',
|
||||
'instance_type', 'pool']
|
||||
'instance_type', 'pool', 'dns_domain', 'dns_name']
|
||||
|
||||
def __init__(self, fip):
|
||||
fip['ip'] = fip['floating_ip_address']
|
||||
@ -631,6 +631,10 @@ class FloatingIpManager(object):
|
||||
create_dict['floating_ip_address'] = params['floating_ip_address']
|
||||
if 'description' in params:
|
||||
create_dict['description'] = params['description']
|
||||
if 'dns_domain' in params:
|
||||
create_dict['dns_domain'] = params['dns_domain']
|
||||
if 'dns_name' in params:
|
||||
create_dict['dns_name'] = params['dns_name']
|
||||
fip = self.client.create_floatingip(
|
||||
{'floatingip': create_dict}).get('floatingip')
|
||||
self._set_instance_info(fip)
|
||||
|
@ -61,7 +61,13 @@ class FloatingIP(generic.View):
|
||||
:return: JSON representation of the new floating IP address
|
||||
"""
|
||||
pool = request.DATA['pool_id']
|
||||
result = api.neutron.tenant_floating_ip_allocate(request, pool)
|
||||
params = {}
|
||||
if 'dns_domain' in request.DATA:
|
||||
params['dns_domain'] = request.DATA['dns_domain']
|
||||
if 'dns_name' in request.DATA:
|
||||
params['dns_name'] = request.DATA['dns_name']
|
||||
result = api.neutron.tenant_floating_ip_allocate(request, pool,
|
||||
None, params)
|
||||
return result.to_dict()
|
||||
|
||||
@rest_utils.ajax(data_required=True)
|
||||
|
@ -27,7 +27,9 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
@test.create_mocks({
|
||||
api.nova: ['server_list'],
|
||||
api.keystone: ['tenant_list'],
|
||||
api.neutron: ['network_list', 'tenant_floating_ip_list']})
|
||||
api.neutron: ['network_list',
|
||||
'is_extension_supported',
|
||||
'tenant_floating_ip_list']})
|
||||
def test_index(self):
|
||||
# Use neutron test data
|
||||
fips = self.floating_ips.list()
|
||||
@ -37,6 +39,7 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
self.mock_server_list.return_value = [servers, False]
|
||||
self.mock_tenant_list.return_value = [tenants, False]
|
||||
self.mock_network_list.return_value = self.networks.list()
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
self.assertTemplateUsed(res, INDEX_TEMPLATE)
|
||||
@ -60,14 +63,19 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
params = {"router:external": True}
|
||||
self.mock_network_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), **params)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({
|
||||
api.neutron: ['tenant_floating_ip_get', 'network_get']})
|
||||
api.neutron: ['network_get',
|
||||
'is_extension_supported',
|
||||
'tenant_floating_ip_get']})
|
||||
def test_floating_ip_detail_get(self):
|
||||
fip = self.floating_ips.first()
|
||||
network = self.networks.first()
|
||||
self.mock_tenant_floating_ip_get.return_value = fip
|
||||
self.mock_network_get.return_value = network
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
res = self.client.get(reverse('horizon:admin:floating_ips:detail',
|
||||
args=[fip.id]))
|
||||
@ -78,6 +86,8 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
test.IsHttpRequest(), fip.id)
|
||||
self.mock_network_get.assert_called_once_with(
|
||||
test.IsHttpRequest(), fip.pool)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({api.neutron: ['tenant_floating_ip_get']})
|
||||
def test_floating_ip_detail_exception(self):
|
||||
@ -92,23 +102,31 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
self.mock_tenant_floating_ip_get.assert_called_once_with(
|
||||
test.IsHttpRequest(), fip.id)
|
||||
|
||||
@test.create_mocks({api.neutron: ['tenant_floating_ip_list']})
|
||||
@test.create_mocks({api.neutron: ['tenant_floating_ip_list',
|
||||
'is_extension_supported']})
|
||||
def test_index_no_floating_ips(self):
|
||||
self.mock_tenant_floating_ip_list.return_value = []
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
self.assertTemplateUsed(res, INDEX_TEMPLATE)
|
||||
self.mock_tenant_floating_ip_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), all_tenants=True)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({api.neutron: ['tenant_floating_ip_list']})
|
||||
@test.create_mocks({api.neutron: ['tenant_floating_ip_list',
|
||||
'is_extension_supported']})
|
||||
def test_index_error(self):
|
||||
self.mock_tenant_floating_ip_list.side_effect = self.exceptions.neutron
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
self.assertTemplateUsed(res, INDEX_TEMPLATE)
|
||||
self.mock_tenant_floating_ip_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), all_tenants=True)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({
|
||||
api.neutron: ['network_list'],
|
||||
@ -193,6 +211,7 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
@test.create_mocks({
|
||||
api.neutron: ['tenant_floating_ip_list',
|
||||
'floating_ip_disassociate',
|
||||
'is_extension_supported',
|
||||
'network_list'],
|
||||
api.nova: ['server_list'],
|
||||
api.keystone: ['tenant_list']})
|
||||
@ -207,6 +226,7 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
self.mock_tenant_list.return_value = [tenants, False]
|
||||
self.mock_network_list.return_value = self.networks.list()
|
||||
self.mock_floating_ip_disassociate.return_value = None
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
form_data = {
|
||||
"action":
|
||||
@ -226,9 +246,12 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
test.IsHttpRequest(), **params)
|
||||
self.mock_floating_ip_disassociate.assert_called_once_with(
|
||||
test.IsHttpRequest(), floating_ip.id)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({
|
||||
api.neutron: ['tenant_floating_ip_list',
|
||||
'is_extension_supported',
|
||||
'network_list'],
|
||||
api.nova: ['server_list'],
|
||||
api.keystone: ['tenant_list']})
|
||||
@ -242,6 +265,7 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
self.mock_server_list.return_value = [servers, False]
|
||||
self.mock_tenant_list.return_value = [tenants, False]
|
||||
self.mock_network_list.return_value = self.networks.list()
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
form_data = {
|
||||
"action":
|
||||
@ -259,9 +283,12 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
params = {"router:external": True}
|
||||
self.mock_network_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), **params)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({
|
||||
api.neutron: ['tenant_floating_ip_list',
|
||||
'is_extension_supported',
|
||||
'network_list'],
|
||||
api.nova: ['server_list'],
|
||||
api.keystone: ['tenant_list']})
|
||||
@ -274,6 +301,7 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
self.mock_server_list.return_value = [servers, False]
|
||||
self.mock_tenant_list.return_value = [tenants, False]
|
||||
self.mock_network_list.return_value = self.networks.list()
|
||||
self.mock_is_extension_supported.return_value = True
|
||||
|
||||
res = self.client.get(INDEX_URL)
|
||||
self.assertTemplateUsed(res, INDEX_TEMPLATE)
|
||||
@ -297,3 +325,5 @@ class AdminFloatingIpViewTest(test.BaseAdminViewTests):
|
||||
params = {"router:external": True}
|
||||
self.mock_network_list.assert_called_once_with(
|
||||
test.IsHttpRequest(), **params)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
@ -32,12 +32,25 @@ class FloatingIpAllocate(forms.SelfHandlingForm):
|
||||
description = forms.CharField(max_length=255,
|
||||
label=_("Description"),
|
||||
required=False)
|
||||
dns_domain = forms.CharField(max_length=255,
|
||||
label=_("DNS Domain"),
|
||||
required=False)
|
||||
dns_name = forms.CharField(max_length=255,
|
||||
label=_("DNS Name"),
|
||||
required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FloatingIpAllocate, self).__init__(*args, **kwargs)
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(FloatingIpAllocate, self).__init__(request, *args, **kwargs)
|
||||
floating_pool_list = kwargs.get('initial', {}).get('pool_list', [])
|
||||
self.fields['pool'].choices = floating_pool_list
|
||||
|
||||
dns_supported = api.neutron.is_extension_supported(
|
||||
request,
|
||||
"dns-integration")
|
||||
if not dns_supported:
|
||||
del self.fields["dns_name"]
|
||||
del self.fields["dns_domain"]
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
# Prevent allocating more IP than the quota allows
|
||||
@ -52,6 +65,10 @@ class FloatingIpAllocate(forms.SelfHandlingForm):
|
||||
param = {}
|
||||
if data['description']:
|
||||
param['description'] = data['description']
|
||||
if 'dns_domain' in data and data['dns_domain']:
|
||||
param['dns_domain'] = data['dns_domain']
|
||||
if 'dns_name' in data and data['dns_name']:
|
||||
param['dns_name'] = data['dns_name']
|
||||
fip = api.neutron.tenant_floating_ip_allocate(
|
||||
request,
|
||||
pool=data['pool'],
|
||||
|
@ -189,6 +189,10 @@ class FloatingIPsTable(tables.DataTable):
|
||||
attrs={'data-type': "ip"})
|
||||
description = tables.Column("description",
|
||||
verbose_name=_("Description"))
|
||||
dns_name = tables.Column("dns_name",
|
||||
verbose_name=_("DNS Name"))
|
||||
dns_domain = tables.Column("dns_domain",
|
||||
verbose_name=_("DNS Domain"))
|
||||
fixed_ip = tables.Column(get_instance_info,
|
||||
link=get_instance_link,
|
||||
verbose_name=_("Mapped Fixed IP Address"))
|
||||
@ -204,6 +208,12 @@ class FloatingIPsTable(tables.DataTable):
|
||||
super(FloatingIPsTable, self).__init__(
|
||||
request, data=data, needs_form_wrapper=needs_form_wrapper,
|
||||
**kwargs)
|
||||
dns_supported = api.neutron.is_extension_supported(
|
||||
request,
|
||||
"dns-integration")
|
||||
if not dns_supported:
|
||||
del self.columns["dns_name"]
|
||||
del self.columns["dns_domain"]
|
||||
|
||||
def sanitize_id(self, obj_id):
|
||||
return filters.get_int_or_uuid(obj_id)
|
||||
|
@ -214,10 +214,12 @@ class FloatingIpViewTests(test.TestCase):
|
||||
@test.create_mocks({api.nova: ('server_list',),
|
||||
api.neutron: ('floating_ip_disassociate',
|
||||
'floating_ip_pools_list',
|
||||
'is_extension_supported',
|
||||
'tenant_floating_ip_list')})
|
||||
def test_disassociate_post(self):
|
||||
floating_ip = self.floating_ips.first()
|
||||
|
||||
self.mock_is_extension_supported.return_value = False
|
||||
self.mock_server_list.return_value = [self.servers.list(), False]
|
||||
self.mock_tenant_floating_ip_list.return_value = \
|
||||
self.floating_ips.list()
|
||||
@ -237,14 +239,18 @@ class FloatingIpViewTests(test.TestCase):
|
||||
test.IsHttpRequest())
|
||||
self.mock_floating_ip_disassociate.assert_called_once_with(
|
||||
test.IsHttpRequest(), floating_ip.id)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({api.nova: ('server_list',),
|
||||
api.neutron: ('floating_ip_disassociate',
|
||||
'floating_ip_pools_list',
|
||||
'is_extension_supported',
|
||||
'tenant_floating_ip_list')})
|
||||
def test_disassociate_post_with_exception(self):
|
||||
floating_ip = self.floating_ips.first()
|
||||
|
||||
self.mock_is_extension_supported.return_value = False
|
||||
self.mock_server_list.return_value = [self.servers.list(), False]
|
||||
self.mock_tenant_floating_ip_list.return_value = \
|
||||
self.floating_ips.list()
|
||||
@ -263,8 +269,11 @@ class FloatingIpViewTests(test.TestCase):
|
||||
test.IsHttpRequest())
|
||||
self.mock_floating_ip_disassociate.assert_called_once_with(
|
||||
test.IsHttpRequest(), floating_ip.id)
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration')
|
||||
|
||||
@test.create_mocks({api.neutron: ('tenant_floating_ip_list',
|
||||
'is_extension_supported',
|
||||
'floating_ip_pools_list'),
|
||||
api.nova: ('server_list',),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
@ -273,6 +282,7 @@ class FloatingIpViewTests(test.TestCase):
|
||||
floating_pools = self.pools.list()
|
||||
quota_data = self.neutron_quota_usages.first()
|
||||
|
||||
self.mock_is_extension_supported.return_value = False
|
||||
self.mock_tenant_floating_ip_list.return_value = floating_ips
|
||||
self.mock_floating_ip_pools_list.return_value = floating_pools
|
||||
self.mock_server_list.return_value = [self.servers.list(), False]
|
||||
@ -299,8 +309,12 @@ class FloatingIpViewTests(test.TestCase):
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
self.mock_tenant_quota_usages, 3,
|
||||
mock.call(test.IsHttpRequest(), targets=('floatingip', )))
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration',
|
||||
)
|
||||
|
||||
@test.create_mocks({api.neutron: ('tenant_floating_ip_list',
|
||||
'is_extension_supported',
|
||||
'floating_ip_pools_list'),
|
||||
api.nova: ('server_list',),
|
||||
quotas: ('tenant_quota_usages',)})
|
||||
@ -310,6 +324,7 @@ class FloatingIpViewTests(test.TestCase):
|
||||
quota_data = self.neutron_quota_usages.first()
|
||||
quota_data['floatingip']['available'] = 0
|
||||
|
||||
self.mock_is_extension_supported.return_value = False
|
||||
self.mock_tenant_floating_ip_list.return_value = floating_ips
|
||||
self.mock_floating_ip_pools_list.return_value = floating_pools
|
||||
self.mock_server_list.return_value = [self.servers.list(), False]
|
||||
@ -333,6 +348,9 @@ class FloatingIpViewTests(test.TestCase):
|
||||
self.assert_mock_multiple_calls_with_same_arguments(
|
||||
self.mock_tenant_quota_usages, 3,
|
||||
mock.call(test.IsHttpRequest(), targets=('floatingip', )))
|
||||
self.mock_is_extension_supported.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'dns-integration',
|
||||
)
|
||||
|
||||
@test.create_mocks({api.neutron: ('floating_ip_pools_list',
|
||||
'tenant_floating_ip_list',
|
||||
@ -343,7 +361,7 @@ class FloatingIpViewTests(test.TestCase):
|
||||
@test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True})
|
||||
def test_correct_quotas_displayed(self):
|
||||
self.mock_is_service_enabled.return_value = True
|
||||
self.mock_is_extension_supported.side_effect = [True, False]
|
||||
self.mock_is_extension_supported.side_effect = [False, True, False]
|
||||
self.mock_is_router_enabled.return_value = True
|
||||
self.mock_tenant_quota_get.return_value = self.neutron_quotas.first()
|
||||
self.mock_tenant_floating_ip_list.return_value = \
|
||||
@ -357,8 +375,9 @@ class FloatingIpViewTests(test.TestCase):
|
||||
|
||||
self.mock_is_service_enabled.assert_called_once_with(
|
||||
test.IsHttpRequest(), 'network')
|
||||
self.assertEqual(2, self.mock_is_extension_supported.call_count)
|
||||
self.assertEqual(3, self.mock_is_extension_supported.call_count)
|
||||
self.mock_is_extension_supported.assert_has_calls([
|
||||
mock.call(test.IsHttpRequest(), 'dns-integration'),
|
||||
mock.call(test.IsHttpRequest(), 'quotas'),
|
||||
mock.call(test.IsHttpRequest(), 'quota_details'),
|
||||
])
|
||||
|
@ -75,7 +75,9 @@ class RestNetworkApiFloatingIpTests(test.TestCase):
|
||||
self.assertStatusCode(response, 200)
|
||||
self.assertEqual(response.json, fip.to_dict())
|
||||
self.mock_tenant_floating_ip_allocate.assert_called_once_with(request,
|
||||
'pool')
|
||||
'pool',
|
||||
None,
|
||||
{})
|
||||
|
||||
@test.create_mocks({api.neutron: ['floating_ip_associate']})
|
||||
def test_associate_floating_ip(self):
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Support has been added to set and display DNS attributes for Floating IPs
|
||||
(DNS Name and DNS Domain). These attributes are only available if Neutron
|
||||
has the `dns-integration` extension enabled.
|
Loading…
Reference in New Issue
Block a user