diff --git a/horizon/api/quantum.py b/horizon/api/quantum.py index 457425732..bd792d702 100644 --- a/horizon/api/quantum.py +++ b/horizon/api/quantum.py @@ -50,7 +50,8 @@ class QuantumAPIDictWrapper(APIDictWrapper): class Network(QuantumAPIDictWrapper): """Wrapper for quantum Networks""" - _attrs = ['name', 'id', 'subnets', 'tenant_id', 'status', 'admin_state_up'] + _attrs = ['name', 'id', 'subnets', 'tenant_id', 'status', + 'admin_state_up', 'shared'] def __init__(self, apiresource): apiresource['admin_state'] = \ @@ -110,6 +111,27 @@ def network_list(request, **params): return [Network(n) for n in networks] +def network_list_for_tenant(request, tenant_id, **params): + """Return a network list available for the tenant. + The list contains networks owned by the tenant and public networks. + If requested_networks specified, it searches requested_networks only. + """ + LOG.debug("network_list_for_tenant(): tenant_id=%s, params=%s" + % (tenant_id, params)) + + # If a user has admin role, network list returned by Quantum API + # contains networks that do not belong to that tenant. + # So we need to specify tenant_id when calling network_list(). + networks = network_list(request, tenant_id=tenant_id, + shared=False, **params) + + # In the current Quantum API, there is no way to retrieve + # both owner networks and public networks in a single API call. + networks += network_list(request, shared=True, **params) + + return networks + + def network_get(request, network_id, **params): LOG.debug("network_get(): netid=%s, params=%s" % (network_id, params)) network = quantumclient(request).show_network(network_id, diff --git a/horizon/dashboards/nova/instances/tests.py b/horizon/dashboards/nova/instances/tests.py index c248b51bf..57bbe6065 100644 --- a/horizon/dashboards/nova/instances/tests.py +++ b/horizon/dashboards/nova/instances/tests.py @@ -608,8 +608,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.tenant_quota_usages(IsA(http.HttpRequest)) \ .AndReturn(quota_usages) api.nova.flavor_list(IsA(http.HttpRequest)) \ @@ -678,8 +682,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) api.nova.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) @@ -747,8 +755,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.flavor_list(IsA(http.HttpRequest)) \ .AndReturn(self.flavors.list()) api.nova.keypair_list(IsA(http.HttpRequest)) \ @@ -805,8 +817,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.tenant_quota_usages(IsA(http.HttpRequest)) \ .AndReturn(self.quota_usages.first()) api.nova.flavor_list(IsA(http.HttpRequest)) \ @@ -858,8 +874,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.volume_list(IgnoreArg()).AndReturn(self.volumes.list()) api.nova.server_create(IsA(http.HttpRequest), server.name, @@ -926,8 +946,12 @@ class InstanceTests(test.TestCase): 'status': 'active'}) \ .AndReturn([[], False]) api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + tenant_id=self.tenant.id, + shared=False) \ + .AndReturn(self.networks.list()[:1]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True) \ + .AndReturn(self.networks.list()[1:]) api.nova.volume_list(IsA(http.HttpRequest)) \ .AndReturn(self.volumes.list()) api.nova.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([]) diff --git a/horizon/dashboards/nova/instances/workflows.py b/horizon/dashboards/nova/instances/workflows.py index 09308f774..ef350eac8 100644 --- a/horizon/dashboards/nova/instances/workflows.py +++ b/horizon/dashboards/nova/instances/workflows.py @@ -421,12 +421,8 @@ class SetNetworkAction(workflows.Action): def populate_network_choices(self, request, context): try: - # If a user has admin role, network list returned by Quantum API - # contains networks that does not belong to that tenant. - # So we need to specify tenant_id when calling network_list(). tenant_id = self.request.user.tenant_id - networks = api.quantum.network_list(request, - tenant_id=tenant_id) + networks = api.quantum.network_list_for_tenant(request, tenant_id) for n in networks: n.set_id_as_name_if_empty() network_list = [(network.id, network.name) for network in networks] diff --git a/horizon/dashboards/nova/networks/forms.py b/horizon/dashboards/nova/networks/forms.py index 0ca479759..598ddd38e 100644 --- a/horizon/dashboards/nova/networks/forms.py +++ b/horizon/dashboards/nova/networks/forms.py @@ -43,7 +43,7 @@ class UpdateNetwork(forms.SelfHandlingForm): def handle(self, request, data): try: network = api.quantum.network_modify(request, data['network_id'], - name=data['name']) + name=data['name']) msg = _('Network %s was successfully updated.') % data['name'] LOG.debug(msg) messages.success(request, msg) diff --git a/horizon/dashboards/nova/networks/subnets/tables.py b/horizon/dashboards/nova/networks/subnets/tables.py index a32e5eef3..02b544fd1 100644 --- a/horizon/dashboards/nova/networks/subnets/tables.py +++ b/horizon/dashboards/nova/networks/subnets/tables.py @@ -16,7 +16,7 @@ import logging -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, reverse_lazy from django.utils.translation import ugettext_lazy as _ from horizon import api @@ -27,7 +27,19 @@ from horizon import tables LOG = logging.getLogger(__name__) -class DeleteSubnet(tables.DeleteAction): +class CheckNetworkEditable(object): + """Mixin class to determine the specified network is editable.""" + + def allowed(self, request, datum=None): + # Only administrator is allowed to create and manage subnets + # on shared networks. + network = self.table._get_network() + if network.shared: + return False + return True + + +class DeleteSubnet(CheckNetworkEditable, tables.DeleteAction): data_type_singular = _("Subnet") data_type_plural = _("Subnets") @@ -43,7 +55,7 @@ class DeleteSubnet(tables.DeleteAction): exceptions.handle(request, msg, redirect=redirect) -class CreateSubnet(tables.LinkAction): +class CreateSubnet(CheckNetworkEditable, tables.LinkAction): name = "create" verbose_name = _("Create Subnet") url = "horizon:nova:networks:addsubnet" @@ -54,7 +66,7 @@ class CreateSubnet(tables.LinkAction): return reverse(self.url, args=(network_id,)) -class UpdateSubnet(tables.LinkAction): +class UpdateSubnet(CheckNetworkEditable, tables.LinkAction): name = "update" verbose_name = _("Edit Subnet") url = "horizon:nova:networks:editsubnet" @@ -71,6 +83,20 @@ class SubnetsTable(tables.DataTable): cidr = tables.Column("cidr", verbose_name=_("Network Address")) ip_version = tables.Column("ipver_str", verbose_name=_("IP Version")) gateway_ip = tables.Column("gateway_ip", verbose_name=_("Gateway IP")) + failure_url = reverse_lazy('horizon:nova:networks:index') + + def _get_network(self): + if not hasattr(self, "_network"): + try: + network_id = self.kwargs['network_id'] + network = api.quantum.network_get(self.request, network_id) + network.set_id_as_name_if_empty(length=0) + except: + msg = _('Unable to retrieve details for network "%s".') \ + % (network_id) + exceptions.handle(self.request, msg, redirect=self.failure_url) + self._network = network + return self._network class Meta: name = "subnets" diff --git a/horizon/dashboards/nova/networks/tables.py b/horizon/dashboards/nova/networks/tables.py index d94ca0766..92ea02a60 100644 --- a/horizon/dashboards/nova/networks/tables.py +++ b/horizon/dashboards/nova/networks/tables.py @@ -17,6 +17,7 @@ import logging from django import template from django.core.urlresolvers import reverse +from django.template import defaultfilters as filters from django.utils.translation import ugettext_lazy as _ from horizon import api @@ -27,7 +28,17 @@ from horizon import tables LOG = logging.getLogger(__name__) -class DeleteNetwork(tables.DeleteAction): +class CheckNetworkEditable(object): + """Mixin class to determine the specified network is editable.""" + + def allowed(self, request, datum=None): + # Only administrator is allowed to create and manage shared networks. + if datum and datum.shared: + return False + return True + + +class DeleteNetwork(CheckNetworkEditable, tables.DeleteAction): data_type_singular = _("Network") data_type_plural = _("Networks") @@ -57,14 +68,14 @@ class CreateNetwork(tables.LinkAction): classes = ("ajax-modal", "btn-create") -class EditNetwork(tables.LinkAction): +class EditNetwork(CheckNetworkEditable, tables.LinkAction): name = "update" verbose_name = _("Edit Network") url = "horizon:nova:networks:update" classes = ("ajax-modal", "btn-edit") -class CreateSubnet(tables.LinkAction): +class CreateSubnet(CheckNetworkEditable, tables.LinkAction): name = "subnet" verbose_name = _("Add Subnet") url = "horizon:nova:networks:addsubnet" @@ -83,6 +94,8 @@ class NetworksTable(tables.DataTable): link='horizon:nova:networks:detail') subnets = tables.Column(get_subnets, verbose_name=_("Subnets Associated"),) + shared = tables.Column("shared", verbose_name=_("Shared"), + filters=(filters.yesno, filters.capfirst)) status = tables.Column("status", verbose_name=_("Status")) admin_state = tables.Column("admin_state", verbose_name=_("Admin State")) diff --git a/horizon/dashboards/nova/networks/templates/networks/_detail_overview.html b/horizon/dashboards/nova/networks/templates/networks/_detail_overview.html index a1d3d7ffc..b64341fb5 100644 --- a/horizon/dashboards/nova/networks/templates/networks/_detail_overview.html +++ b/horizon/dashboards/nova/networks/templates/networks/_detail_overview.html @@ -14,5 +14,7 @@
{{ network.status|default:"Unknown" }}
{% trans "Admin State" %}
{{ network.admin_state|default:"Unknown" }}
+
{% trans "Shared" %}
+
{{ network.shared|yesno|capfirst }}
diff --git a/horizon/dashboards/nova/networks/tests.py b/horizon/dashboards/nova/networks/tests.py index da15e9b24..40e17569a 100644 --- a/horizon/dashboards/nova/networks/tests.py +++ b/horizon/dashboards/nova/networks/tests.py @@ -34,9 +34,13 @@ INDEX_URL = reverse('horizon:nova:networks:index') class NetworkTests(test.TestCase): @test.create_stubs({api.quantum: ('network_list',)}) def test_index(self): - api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndReturn(self.networks.list()) + api.quantum.network_list( + IsA(http.HttpRequest), + tenant_id=self.tenant.id, + shared=False).AndReturn(self.networks.list()) + api.quantum.network_list( + IsA(http.HttpRequest), + shared=True).AndReturn([]) self.mox.ReplayAll() @@ -48,10 +52,10 @@ class NetworkTests(test.TestCase): @test.create_stubs({api.quantum: ('network_list',)}) def test_index_network_list_exception(self): - api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=self.tenant.id) \ - .AndRaise(self.exceptions.quantum) - + api.quantum.network_list( + IsA(http.HttpRequest), + tenant_id=self.tenant.id, + shared=False).AndRaise(self.exceptions.quantum) self.mox.ReplayAll() res = self.client.get(INDEX_URL) @@ -71,6 +75,8 @@ class NetworkTests(test.TestCase): .AndReturn([self.subnets.first()]) api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id)\ .AndReturn([self.ports.first()]) + api.quantum.network_get(IsA(http.HttpRequest), network_id)\ + .AndReturn(self.networks.first()) self.mox.ReplayAll() @@ -90,11 +96,6 @@ class NetworkTests(test.TestCase): network_id = self.networks.first().id api.quantum.network_get(IsA(http.HttpRequest), network_id)\ .AndRaise(self.exceptions.quantum) - api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network_id)\ - .AndReturn([self.subnets.first()]) - api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id)\ - .AndReturn([self.ports.first()]) - self.mox.ReplayAll() url = reverse('horizon:nova:networks:detail', args=[network_id]) @@ -114,6 +115,9 @@ class NetworkTests(test.TestCase): AndRaise(self.exceptions.quantum) api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id).\ AndReturn([self.ports.first()]) + # Called from SubnetTable + api.quantum.network_get(IsA(http.HttpRequest), network_id).\ + AndReturn(self.networks.first()) self.mox.ReplayAll() @@ -137,6 +141,9 @@ class NetworkTests(test.TestCase): AndReturn([self.subnets.first()]) api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id).\ AndRaise(self.exceptions.quantum) + # Called from SubnetTable + api.quantum.network_get(IsA(http.HttpRequest), network_id).\ + AndReturn(self.networks.first()) self.mox.ReplayAll() @@ -402,8 +409,12 @@ class NetworkTests(test.TestCase): def test_delete_network_no_subnet(self): network = self.networks.first() api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=network.tenant_id)\ + tenant_id=network.tenant_id, + shared=False)\ .AndReturn([network]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True)\ + .AndReturn([]) api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network.id)\ .AndReturn([]) api.quantum.network_delete(IsA(http.HttpRequest), network.id) @@ -423,8 +434,11 @@ class NetworkTests(test.TestCase): network = self.networks.first() subnet = self.subnets.first() api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=network.tenant_id)\ + tenant_id=network.tenant_id, + shared=False)\ .AndReturn([network]) + api.quantum.network_list(IsA(http.HttpRequest), shared=True)\ + .AndReturn([]) api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network.id)\ .AndReturn([subnet]) api.quantum.subnet_delete(IsA(http.HttpRequest), subnet.id) @@ -445,8 +459,12 @@ class NetworkTests(test.TestCase): network = self.networks.first() subnet = self.subnets.first() api.quantum.network_list(IsA(http.HttpRequest), - tenant_id=network.tenant_id)\ + tenant_id=network.tenant_id, + shared=False)\ .AndReturn([network]) + api.quantum.network_list(IsA(http.HttpRequest), + shared=True)\ + .AndReturn([]) api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network.id)\ .AndReturn([subnet]) api.quantum.subnet_delete(IsA(http.HttpRequest), subnet.id) @@ -686,6 +704,7 @@ class NetworkTests(test.TestCase): @test.create_stubs({api.quantum: ('subnet_delete', 'subnet_list', + 'network_get', 'port_list',)}) def test_subnet_delete(self): subnet = self.subnets.first() @@ -693,8 +712,13 @@ class NetworkTests(test.TestCase): api.quantum.subnet_delete(IsA(http.HttpRequest), subnet.id) api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network_id)\ .AndReturn([self.subnets.first()]) + api.quantum.network_get(IsA(http.HttpRequest), network_id)\ + .AndReturn(self.networks.first()) api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id)\ .AndReturn([self.ports.first()]) + # Called from SubnetTable + api.quantum.network_get(IsA(http.HttpRequest), network_id)\ + .AndReturn(self.networks.first()) self.mox.ReplayAll() formData = {'action': 'subnets__delete__%s' % subnet.id} @@ -706,16 +730,22 @@ class NetworkTests(test.TestCase): @test.create_stubs({api.quantum: ('subnet_delete', 'subnet_list', + 'network_get', 'port_list',)}) - def test_subnet_delete_exception(self): + def test_subnet_delete_excceeption(self): subnet = self.subnets.first() network_id = subnet.network_id api.quantum.subnet_delete(IsA(http.HttpRequest), subnet.id)\ .AndRaise(self.exceptions.quantum) api.quantum.subnet_list(IsA(http.HttpRequest), network_id=network_id)\ .AndReturn([self.subnets.first()]) + api.quantum.network_get(IsA(http.HttpRequest), network_id)\ + .AndReturn(self.networks.first()) api.quantum.port_list(IsA(http.HttpRequest), network_id=network_id)\ .AndReturn([self.ports.first()]) + # Called from SubnetTable + api.quantum.network_get(IsA(http.HttpRequest), network_id)\ + .AndReturn(self.networks.first()) self.mox.ReplayAll() formData = {'action': 'subnets__delete__%s' % subnet.id} diff --git a/horizon/dashboards/nova/networks/views.py b/horizon/dashboards/nova/networks/views.py index a6b02a94b..73d56a758 100644 --- a/horizon/dashboards/nova/networks/views.py +++ b/horizon/dashboards/nova/networks/views.py @@ -44,12 +44,9 @@ class IndexView(tables.DataTableView): def get_data(self): try: - # If a user has admin role, network list returned by Quantum API - # contains networks that does not belong to that tenant. - # So we need to specify tenant_id when calling network_list(). tenant_id = self.request.user.tenant_id - networks = api.quantum.network_list(self.request, - tenant_id=tenant_id) + networks = api.quantum.network_list_for_tenant(self.request, + tenant_id) except: networks = [] msg = _('Network list can not be retrieved.') @@ -104,9 +101,9 @@ class DetailView(tables.MultiTableView): def get_subnets_data(self): try: - network_id = self.kwargs['network_id'] + network = self._get_data() subnets = api.quantum.subnet_list(self.request, - network_id=network_id) + network_id=network.id) except: subnets = [] msg = _('Subnet list can not be retrieved.') diff --git a/horizon/dashboards/syspanel/networks/forms.py b/horizon/dashboards/syspanel/networks/forms.py index 88bff09cf..f6ed33687 100644 --- a/horizon/dashboards/syspanel/networks/forms.py +++ b/horizon/dashboards/syspanel/networks/forms.py @@ -24,8 +24,6 @@ from horizon import exceptions from horizon import forms from horizon import messages -from horizon.dashboards.nova.networks import forms as user_forms - LOG = logging.getLogger(__name__) @@ -35,6 +33,8 @@ class CreateNetwork(forms.SelfHandlingForm): label=_("Name"), required=False) tenant_id = forms.ChoiceField(label=_("Project")) + shared = forms.BooleanField(label=_("Shared"), + initial=False, required=False) @classmethod def _instantiate(cls, request, *args, **kwargs): @@ -52,7 +52,8 @@ class CreateNetwork(forms.SelfHandlingForm): try: network = api.quantum.network_create(request, name=data['name'], - tenant_id=data['tenant_id']) + tenant_id=data['tenant_id'], + shared=data['shared']) msg = _('Network %s was successfully created.') % data['name'] LOG.debug(msg) messages.success(request, msg) @@ -63,5 +64,26 @@ class CreateNetwork(forms.SelfHandlingForm): exceptions.handle(request, msg, redirect=redirect) -class UpdateNetwork(user_forms.UpdateNetwork): +class UpdateNetwork(forms.SelfHandlingForm): + name = forms.CharField(label=_("Name"), required=False) + tenant_id = forms.CharField(widget=forms.HiddenInput) + network_id = forms.CharField(label=_("ID"), + widget=forms.TextInput( + attrs={'readonly': 'readonly'})) + shared = forms.BooleanField(label=_("Shared"), required=False) failure_url = 'horizon:syspanel:networks:index' + + def handle(self, request, data): + try: + network = api.quantum.network_modify(request, data['network_id'], + name=data['name'], + shared=data['shared']) + msg = _('Network %s was successfully updated.') % data['name'] + LOG.debug(msg) + messages.success(request, msg) + return network + except: + msg = _('Failed to update network %s') % data['name'] + LOG.info(msg) + redirect = reverse(self.failure_url) + exceptions.handle(request, msg, redirect=redirect) diff --git a/horizon/dashboards/syspanel/networks/tables.py b/horizon/dashboards/syspanel/networks/tables.py index 77ba968a1..6d1ae5f80 100644 --- a/horizon/dashboards/syspanel/networks/tables.py +++ b/horizon/dashboards/syspanel/networks/tables.py @@ -17,6 +17,7 @@ import logging from django.core.urlresolvers import reverse +from django.template import defaultfilters as filters from django.utils.translation import ugettext_lazy as _ from horizon import api @@ -68,6 +69,8 @@ class NetworksTable(tables.DataTable): link='horizon:syspanel:networks:detail') subnets = tables.Column(get_subnets, verbose_name=_("Subnets Associated"),) + shared = tables.Column("shared", verbose_name=_("Shared"), + filters=(filters.yesno, filters.capfirst)) status = tables.Column("status", verbose_name=_("Status")) admin_state = tables.Column("admin_state", verbose_name=_("Admin State")) diff --git a/horizon/dashboards/syspanel/networks/tests.py b/horizon/dashboards/syspanel/networks/tests.py index 9bbc5fa3b..ecc845af6 100644 --- a/horizon/dashboards/syspanel/networks/tests.py +++ b/horizon/dashboards/syspanel/networks/tests.py @@ -167,12 +167,13 @@ class NetworkTests(test.BaseAdminViewTests): api.keystone.tenant_list(IsA(http.HttpRequest), admin=True)\ .AndReturn(tenants) api.quantum.network_create(IsA(http.HttpRequest), name=network.name, - tenant_id=tenant_id)\ + tenant_id=tenant_id, shared=True)\ .AndReturn(network) self.mox.ReplayAll() form_data = {'tenant_id': tenant_id, - 'name': network.name} + 'name': network.name, + 'shared': True} url = reverse('horizon:syspanel:networks:create') res = self.client.post(url, form_data) @@ -188,12 +189,13 @@ class NetworkTests(test.BaseAdminViewTests): api.keystone.tenant_list(IsA(http.HttpRequest), admin=True)\ .AndReturn(tenants) api.quantum.network_create(IsA(http.HttpRequest), name=network.name, - tenant_id=tenant_id)\ + tenant_id=tenant_id, shared=False)\ .AndRaise(self.exceptions.quantum) self.mox.ReplayAll() form_data = {'tenant_id': tenant_id, - 'name': network.name} + 'name': network.name, + 'shared': False} url = reverse('horizon:syspanel:networks:create') res = self.client.post(url, form_data) @@ -232,7 +234,7 @@ class NetworkTests(test.BaseAdminViewTests): def test_network_update_post(self): network = self.networks.first() api.quantum.network_modify(IsA(http.HttpRequest), network.id, - name=network.name)\ + name=network.name, shared=True)\ .AndReturn(network) api.quantum.network_get(IsA(http.HttpRequest), network.id)\ .AndReturn(network) @@ -240,7 +242,8 @@ class NetworkTests(test.BaseAdminViewTests): formData = {'network_id': network.id, 'name': network.name, - 'tenant_id': network.tenant_id} + 'tenant_id': network.tenant_id, + 'shared': True} url = reverse('horizon:syspanel:networks:update', args=[network.id]) res = self.client.post(url, formData) @@ -251,7 +254,7 @@ class NetworkTests(test.BaseAdminViewTests): def test_network_update_post_exception(self): network = self.networks.first() api.quantum.network_modify(IsA(http.HttpRequest), network.id, - name=network.name)\ + name=network.name, shared=False)\ .AndRaise(self.exceptions.quantum) api.quantum.network_get(IsA(http.HttpRequest), network.id)\ .AndReturn(network) @@ -259,7 +262,8 @@ class NetworkTests(test.BaseAdminViewTests): form_data = {'network_id': network.id, 'name': network.name, - 'tenant_id': network.tenant_id} + 'tenant_id': network.tenant_id, + 'shared': False} url = reverse('horizon:syspanel:networks:update', args=[network.id]) res = self.client.post(url, form_data) diff --git a/horizon/dashboards/syspanel/networks/views.py b/horizon/dashboards/syspanel/networks/views.py index 6d61d2e16..b9cb335b1 100644 --- a/horizon/dashboards/syspanel/networks/views.py +++ b/horizon/dashboards/syspanel/networks/views.py @@ -131,3 +131,10 @@ class UpdateView(user_views.UpdateView): form_class = UpdateNetwork template_name = 'syspanel/networks/update.html' success_url = reverse_lazy('horizon:syspanel:networks:index') + + def get_initial(self): + network = self._get_object() + return {'network_id': network['id'], + 'tenant_id': network['tenant_id'], + 'name': network['name'], + 'shared': network['shared']} diff --git a/horizon/tests/test_data/quantum_data.py b/horizon/tests/test_data/quantum_data.py index b229e274f..f20a82793 100644 --- a/horizon/tests/test_data/quantum_data.py +++ b/horizon/tests/test_data/quantum_data.py @@ -36,7 +36,8 @@ def data(TEST): 'name': 'net1', 'status': 'ACTIVE', 'subnets': ['e8abc972-eb0c-41f1-9edd-4bc6e3bcd8c9'], - 'tenant_id': '1'} + 'tenant_id': '1', + 'shared': False} subnet_dict = {'allocation_pools': [{'end': '10.0.0.254', 'start': '10.0.0.2'}], 'cidr': '10.0.0.0/24', @@ -75,7 +76,8 @@ def data(TEST): 'name': 'net2', 'status': 'ACTIVE', 'subnets': ['3f7c5d79-ee55-47b0-9213-8e669fb03009'], - 'tenant_id': '2'} + 'tenant_id': '2', + 'shared': True} subnet_dict = {'allocation_pools': [{'end': '172.16.88.254', 'start': '172.16.88.2'}], 'cidr': '172.16.88.0/24',