Drop Nova floating IP dependency from dashboard
This commit drops Nova floating IP dependency from the dashboard implementation. * Use neutron policy for floating IP operations. * SimpleAssociateIP is supported only by Nova API, so the action was removed in this patch. Floating IP support in the nova API wrapper will be dropped in a separate patch. Partially implement blueprint drop-nova-network Change-Id: I1610fb9aa2212b3f34814fdb9894b715a5211d9c
This commit is contained in:
parent
f100793164
commit
8b6d3422e8
|
@ -20,6 +20,7 @@ import horizon
|
|||
class FloatingIps(horizon.Panel):
|
||||
name = _("Floating IPs")
|
||||
slug = 'floating_ips'
|
||||
permissions = ('openstack.services.network',)
|
||||
|
||||
@staticmethod
|
||||
def can_register():
|
||||
|
|
|
@ -58,11 +58,7 @@ class AllocateIP(tables.LinkAction):
|
|||
classes = [c for c in self.classes if c != "disabled"]
|
||||
self.classes = classes
|
||||
|
||||
if api.base.is_service_enabled(request, "network"):
|
||||
policy_rules = (("network", "create_floatingip"),)
|
||||
else:
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
|
||||
policy_rules = (("network", "create_floatingip"),)
|
||||
return policy.check(policy_rules, request)
|
||||
|
||||
|
||||
|
@ -90,11 +86,7 @@ class ReleaseIPs(tables.BatchAction):
|
|||
)
|
||||
|
||||
def allowed(self, request, fip=None):
|
||||
if api.base.is_service_enabled(request, "network"):
|
||||
policy_rules = (("network", "delete_floatingip"),)
|
||||
else:
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
|
||||
policy_rules = (("network", "delete_floatingip"),)
|
||||
return policy.check(policy_rules, request)
|
||||
|
||||
def action(self, request, obj_id):
|
||||
|
@ -109,11 +101,7 @@ class AssociateIP(tables.LinkAction):
|
|||
icon = "link"
|
||||
|
||||
def allowed(self, request, fip):
|
||||
if api.base.is_service_enabled(request, "network"):
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
else:
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
return not fip.port_id and policy.check(policy_rules, request)
|
||||
|
||||
def get_link_url(self, datum):
|
||||
|
@ -130,11 +118,7 @@ class DisassociateIP(tables.Action):
|
|||
action_type = "danger"
|
||||
|
||||
def allowed(self, request, fip):
|
||||
if api.base.is_service_enabled(request, "network"):
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
else:
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
return fip.port_id and policy.check(policy_rules, request)
|
||||
|
||||
def single(self, table, request, obj_id):
|
||||
|
@ -203,8 +187,6 @@ class FloatingIPsTable(tables.DataTable):
|
|||
super(FloatingIPsTable, self).__init__(
|
||||
request, data=data, needs_form_wrapper=needs_form_wrapper,
|
||||
**kwargs)
|
||||
if not api.base.is_service_enabled(request, 'network'):
|
||||
del self.columns['status']
|
||||
|
||||
def sanitize_id(self, obj_id):
|
||||
return filters.get_int_or_uuid(obj_id)
|
||||
|
|
|
@ -36,6 +36,21 @@ NAMESPACE = "horizon:project:floating_ips"
|
|||
|
||||
|
||||
class FloatingIpViewTests(test.TestCase):
|
||||
|
||||
# TODO(amotoki): [drop-nova-network] self.floating_ips (with integer
|
||||
# ID) is no longer needed. self.floating_ips_uuid should be renamed
|
||||
# self.floating_ips.
|
||||
# floating IP test data in nova_data.py needs to be dropped as well.
|
||||
|
||||
def setUp(self):
|
||||
super(FloatingIpViewTests, self).setUp()
|
||||
self._floating_ips_orig = self.floating_ips
|
||||
self.floating_ips = self.floating_ips_uuid
|
||||
|
||||
def tearDown(self):
|
||||
self.floating_ips = self._floating_ips_orig
|
||||
super(FloatingIpViewTests, self).tearDown()
|
||||
|
||||
@test.create_stubs({api.network: ('floating_ip_target_list',
|
||||
'tenant_floating_ip_list',)})
|
||||
def test_associate(self):
|
||||
|
@ -237,10 +252,6 @@ class FloatingIpViewTests(test.TestCase):
|
|||
quotas.tenant_quota_usages(
|
||||
IsA(http.HttpRequest)).MultipleTimes() \
|
||||
.AndReturn(quota_data)
|
||||
api.base.is_service_enabled(
|
||||
IsA(http.HttpRequest),
|
||||
'network').MultipleTimes() \
|
||||
.AndReturn(True)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
@ -279,10 +290,6 @@ class FloatingIpViewTests(test.TestCase):
|
|||
quotas.tenant_quota_usages(
|
||||
IsA(http.HttpRequest)).MultipleTimes() \
|
||||
.AndReturn(quota_data)
|
||||
api.base.is_service_enabled(
|
||||
IsA(http.HttpRequest),
|
||||
'network').MultipleTimes() \
|
||||
.AndReturn(True)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
@ -295,17 +302,6 @@ class FloatingIpViewTests(test.TestCase):
|
|||
self.assertEqual('Allocate IP To Project (Quota exceeded)',
|
||||
six.text_type(allocate_action.verbose_name))
|
||||
|
||||
|
||||
class FloatingIpNeutronViewTests(FloatingIpViewTests):
|
||||
def setUp(self):
|
||||
super(FloatingIpViewTests, self).setUp()
|
||||
self._floating_ips_orig = self.floating_ips
|
||||
self.floating_ips = self.floating_ips_uuid
|
||||
|
||||
def tearDown(self):
|
||||
self.floating_ips = self._floating_ips_orig
|
||||
super(FloatingIpViewTests, self).tearDown()
|
||||
|
||||
@test.create_stubs({api.nova: ('tenant_quota_get', 'flavor_list',
|
||||
'server_list'),
|
||||
api.network: ('floating_ip_pools_list',
|
||||
|
|
|
@ -35,7 +35,7 @@ class AssociateIPAction(workflows.Action):
|
|||
coerce=filters.get_int_or_uuid,
|
||||
empty_value=None,
|
||||
add_item_link=ALLOCATE_URL)
|
||||
instance_id = forms.ThemableChoiceField(label=_("Instance"))
|
||||
instance_id = forms.ThemableChoiceField(label=_("Port to be associated"))
|
||||
|
||||
class Meta(object):
|
||||
name = _("IP Address")
|
||||
|
@ -44,11 +44,6 @@ class AssociateIPAction(workflows.Action):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(AssociateIPAction, self).__init__(*args, **kwargs)
|
||||
if api.base.is_service_enabled(self.request, 'network'):
|
||||
label = _("Port to be associated")
|
||||
else:
|
||||
label = _("Instance to be associated")
|
||||
self.fields['instance_id'].label = label
|
||||
|
||||
# If AssociateIP is invoked from instance menu, instance_id parameter
|
||||
# is passed in URL. In Neutron based Floating IP implementation
|
||||
|
@ -101,6 +96,7 @@ class AssociateIPAction(workflows.Action):
|
|||
redirect=redirect)
|
||||
return targets
|
||||
|
||||
# TODO(amotoki): [drop-nova-network] Rename instance_id to port_id
|
||||
def populate_instance_id_choices(self, request, context):
|
||||
targets = self._get_target_list()
|
||||
|
||||
|
@ -111,19 +107,10 @@ class AssociateIPAction(workflows.Action):
|
|||
# Sort instances for easy browsing
|
||||
instances = sorted(instances, key=lambda x: x[1])
|
||||
|
||||
neutron_enabled = api.base.is_service_enabled(request, 'network')
|
||||
if instances:
|
||||
if neutron_enabled:
|
||||
label = _("Select a port")
|
||||
else:
|
||||
label = _("Select an instance")
|
||||
instances.insert(0, ("", label))
|
||||
instances.insert(0, ("", _("Select a port")))
|
||||
else:
|
||||
if neutron_enabled:
|
||||
label = _("No ports available")
|
||||
else:
|
||||
label = _("No instances available")
|
||||
instances = (("", label),)
|
||||
instances = (("", _("No ports available")),)
|
||||
return instances
|
||||
|
||||
|
||||
|
|
|
@ -626,11 +626,11 @@ class AssociateIP(policy.PolicyTargetMixin, tables.LinkAction):
|
|||
url = "horizon:project:floating_ips:associate"
|
||||
classes = ("ajax-modal",)
|
||||
icon = "link"
|
||||
# Nova doesn't support floating ip actions policy, update this
|
||||
# when bug #1610520 resloved
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if not api.base.is_service_enabled(request, 'network'):
|
||||
return False
|
||||
if not api.network.floating_ip_supported(request):
|
||||
return False
|
||||
if api.network.floating_ip_simple_associate_supported(request):
|
||||
|
@ -653,49 +653,20 @@ class AssociateIP(policy.PolicyTargetMixin, tables.LinkAction):
|
|||
return "?".join([base_url, params])
|
||||
|
||||
|
||||
class SimpleAssociateIP(policy.PolicyTargetMixin, tables.Action):
|
||||
name = "associate-simple"
|
||||
verbose_name = _("Associate Floating IP")
|
||||
icon = "link"
|
||||
# Nova doesn't support floating ip actions policy, update this
|
||||
# when bug #1610520 resloved
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if not api.network.floating_ip_simple_associate_supported(request):
|
||||
return False
|
||||
if instance.status == "ERROR":
|
||||
return False
|
||||
return not is_deleting(instance)
|
||||
|
||||
def single(self, table, request, instance_id):
|
||||
try:
|
||||
# target_id is port_id for Neutron and instance_id for Nova Network
|
||||
# (Neutron API wrapper returns a 'portid_fixedip' string)
|
||||
target_id = api.network.floating_ip_target_get_by_instance(
|
||||
request, instance_id).split('_')[0]
|
||||
|
||||
fip = api.network.tenant_floating_ip_allocate(request)
|
||||
api.network.floating_ip_associate(request, fip.id, target_id)
|
||||
messages.success(request,
|
||||
_("Successfully associated floating IP: %s")
|
||||
% fip.ip)
|
||||
except Exception:
|
||||
exceptions.handle(request,
|
||||
_("Unable to associate floating IP."))
|
||||
return shortcuts.redirect(request.get_full_path())
|
||||
|
||||
|
||||
# TODO(amotoki): [drop-nova-network] The current SimpleDisassociateIP
|
||||
# just disassociates the first found FIP. It looks better to have a form
|
||||
# which allows to choose which FIP should be disassociated.
|
||||
# HORIZON_CONFIG['simple_ip_management'] can be dropped then.
|
||||
class SimpleDisassociateIP(policy.PolicyTargetMixin, tables.Action):
|
||||
name = "disassociate"
|
||||
verbose_name = _("Disassociate Floating IP")
|
||||
classes = ("btn-disassociate",)
|
||||
# Nova doesn't support floating ip actions policy, update this
|
||||
# when bug #1610520 resloved
|
||||
policy_rules = (("compute", "os_compute_api:os-floating-ips"),)
|
||||
policy_rules = (("network", "update_floatingip"),)
|
||||
action_type = "danger"
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if not api.base.is_service_enabled(request, 'network'):
|
||||
return False
|
||||
if not api.network.floating_ip_supported(request):
|
||||
return False
|
||||
if not conf.HORIZON_CONFIG["simple_ip_management"]:
|
||||
|
@ -1278,7 +1249,7 @@ class InstancesTable(tables.DataTable):
|
|||
table_actions = launch_actions + (DeleteInstance,
|
||||
InstancesFilterAction)
|
||||
row_actions = (StartInstance, ConfirmResize, RevertResize,
|
||||
CreateSnapshot, SimpleAssociateIP, AssociateIP,
|
||||
CreateSnapshot, AssociateIP,
|
||||
SimpleDisassociateIP, AttachInterface,
|
||||
DetachInterface, EditInstance, AttachVolume,
|
||||
DetachVolume, UpdateMetadata, DecryptInstancePassword,
|
||||
|
|
|
@ -3537,40 +3537,6 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
|||
def test_select_default_keypair_if_only_one_glance_v1(self):
|
||||
self.test_select_default_keypair_if_only_one()
|
||||
|
||||
@helpers.create_stubs({api.network: ('floating_ip_target_get_by_instance',
|
||||
'tenant_floating_ip_allocate',
|
||||
'floating_ip_associate',
|
||||
'servers_update_addresses',),
|
||||
api.glance: ('image_list_detailed',),
|
||||
api.nova: ('server_list',
|
||||
'flavor_list')})
|
||||
def test_associate_floating_ip(self):
|
||||
servers = self.servers.list()
|
||||
server = servers[0]
|
||||
fip = self.q_floating_ips.first()
|
||||
|
||||
search_opts = {'marker': None, 'paginate': True}
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
|
||||
api.glance.image_list_detailed(IgnoreArg()) \
|
||||
.AndReturn((self.images.list(), False, False))
|
||||
api.network.floating_ip_target_get_by_instance(
|
||||
IsA(http.HttpRequest),
|
||||
server.id).AndReturn(server.id)
|
||||
api.network.tenant_floating_ip_allocate(
|
||||
IsA(http.HttpRequest)).AndReturn(fip)
|
||||
api.network.floating_ip_associate(
|
||||
IsA(http.HttpRequest), fip.id, server.id)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action': 'instances__associate-simple__%s' % server.id}
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@helpers.create_stubs({api.network: ('floating_ip_target_list_by_instance',
|
||||
'tenant_floating_ip_list',
|
||||
'floating_ip_disassociate',
|
||||
|
|
Loading…
Reference in New Issue