diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py index 326fff5889..af9a457c1d 100644 --- a/openstack_dashboard/api/nova.py +++ b/openstack_dashboard/api/nova.py @@ -149,7 +149,7 @@ class SecurityGroup(APIResourceWrapper): def rules(self): """Wraps transmitted rule info in the novaclient rule class.""" if "_rules" not in self.__dict__: - manager = nova_rules.SecurityGroupRuleManager + manager = nova_rules.SecurityGroupRuleManager(None) self._rules = [nova_rules.SecurityGroupRule(manager, rule) for rule in self._apiresource.rules] return self.__dict__['_rules'] diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py index 51dedadd9c..cf20802546 100644 --- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py +++ b/openstack_dashboard/dashboards/project/access_and_security/security_groups/forms.py @@ -30,6 +30,7 @@ from horizon.utils.validators import validate_port_range from horizon.utils import fields from openstack_dashboard import api +from ..floating_ips.utils import get_int_or_uuid class CreateGroup(forms.SelfHandlingForm): @@ -58,7 +59,7 @@ class CreateGroup(forms.SelfHandlingForm): class AddRule(forms.SelfHandlingForm): - id = forms.IntegerField(widget=forms.HiddenInput()) + id = forms.CharField(widget=forms.HiddenInput()) ip_protocol = forms.ChoiceField(label=_('IP Protocol'), choices=[('tcp', _('TCP')), ('udp', _('UDP')), @@ -232,7 +233,7 @@ class AddRule(forms.SelfHandlingForm): try: rule = api.nova.security_group_rule_create( request, - data['id'], + get_int_or_uuid(data['id']), data['ip_protocol'], data['from_port'], data['to_port'], diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py index c3a5e8a677..7cd4f7a81f 100644 --- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py +++ b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tables.py @@ -22,6 +22,7 @@ from django.utils.translation import ugettext_lazy as _ from horizon import tables from openstack_dashboard import api +from ..floating_ips.utils import get_int_or_uuid LOG = logging.getLogger(__name__) @@ -59,7 +60,7 @@ class SecurityGroupsTable(tables.DataTable): description = tables.Column("description", verbose_name=_("Description")) def sanitize_id(self, obj_id): - return int(obj_id) + return get_int_or_uuid(obj_id) class Meta: name = "security_groups" @@ -109,7 +110,7 @@ class RulesTable(tables.DataTable): source = tables.Column(get_source, verbose_name=_("Source")) def sanitize_id(self, obj_id): - return int(obj_id) + return get_int_or_uuid(obj_id) def get_object_display(self, rule): return unicode(rule) diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py index 2bb6c52d5d..88b1a220ff 100644 --- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py +++ b/openstack_dashboard/dashboards/project/access_and_security/security_groups/tests.py @@ -106,7 +106,6 @@ class SecurityGroupsViewTests(test.TestCase): api.nova.security_group_get(IsA(http.HttpRequest), sec_group.id).AndReturn(sec_group) self.mox.ReplayAll() - res = self.client.get(self.detail_url) self.assertTemplateUsed(res, 'project/access_and_security/security_groups/detail.html') @@ -371,3 +370,27 @@ class SecurityGroupsViewTests(test.TestCase): self.assertEqual(strip_absolute_base(handled['location']), INDEX_URL) + + +class SecurityGroupsQuantumTests(SecurityGroupsViewTests): + def setUp(self): + super(SecurityGroupsQuantumTests, self).setUp() + + self._sec_groups_orig = self.security_groups + self.security_groups = self.security_groups_uuid + + self._sec_group_rules_orig = self.security_group_rules + self.security_group_rules = self.security_group_rules_uuid + + sec_group = self.security_groups.first() + self.detail_url = reverse('horizon:project:access_and_security:' + 'security_groups:detail', + args=[sec_group.id]) + self.edit_url = reverse('horizon:project:access_and_security:' + 'security_groups:add_rule', + args=[sec_group.id]) + + def tearDown(self): + self.security_groups = self._sec_groups_orig + self.security_group_rules = self._sec_group_rules_orig + super(SecurityGroupsQuantumTests, self).tearDown() diff --git a/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py b/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py index bc06b29c1a..bc1834a0ad 100644 --- a/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py +++ b/openstack_dashboard/dashboards/project/access_and_security/security_groups/views.py @@ -31,6 +31,7 @@ from horizon import forms from horizon import tables from openstack_dashboard import api +from ..floating_ips.utils import get_int_or_uuid from .forms import CreateGroup, AddRule from .tables import RulesTable @@ -43,7 +44,7 @@ class DetailView(tables.DataTableView): template_name = 'project/access_and_security/security_groups/detail.html' def get_data(self): - security_group_id = int(self.kwargs['security_group_id']) + security_group_id = get_int_or_uuid(self.kwargs['security_group_id']) try: self.object = api.nova.security_group_get(self.request, security_group_id) @@ -86,7 +87,7 @@ class AddRuleView(forms.ModalFormView): security_groups = [] for group in groups: - if group.id == int(self.kwargs['security_group_id']): + if group.id == get_int_or_uuid(self.kwargs['security_group_id']): security_groups.append((group.id, _("%s (current)") % group.name)) else: diff --git a/openstack_dashboard/dashboards/project/dashboard.py b/openstack_dashboard/dashboards/project/dashboard.py index 0ddbf0d28b..021fcd1728 100644 --- a/openstack_dashboard/dashboards/project/dashboard.py +++ b/openstack_dashboard/dashboards/project/dashboard.py @@ -26,11 +26,16 @@ class BasePanels(horizon.PanelGroup): 'instances', 'volumes', 'images_and_snapshots', - 'access_and_security', - 'networks', + 'access_and_security',) + + +class NetworkPanels(horizon.PanelGroup): + slug = "network" + name = _("Manage Network") + panels = ('networks', 'routers', - 'network_topology', - 'loadbalancers') + 'loadbalancers', + 'network_topology',) class ObjectStorePanels(horizon.PanelGroup): @@ -42,7 +47,7 @@ class ObjectStorePanels(horizon.PanelGroup): class Project(horizon.Dashboard): name = _("Project") slug = "project" - panels = (BasePanels, ObjectStorePanels) + panels = (BasePanels, NetworkPanels, ObjectStorePanels) default_panel = 'overview' supports_tenants = True diff --git a/openstack_dashboard/dashboards/project/loadbalancers/panel.py b/openstack_dashboard/dashboards/project/loadbalancers/panel.py index b59d34043d..e12676804c 100644 --- a/openstack_dashboard/dashboards/project/loadbalancers/panel.py +++ b/openstack_dashboard/dashboards/project/loadbalancers/panel.py @@ -11,6 +11,6 @@ class LoadBalancer(horizon.Panel): slug = "loadbalancers" permissions = ('openstack.services.network',) -if hasattr(settings, 'OPENSTACK_QUANTUM_NETWORK'): - if getattr(settings, 'OPENSTACK_QUANTUM_NETWORK')['enable_lb']: - dashboard.Project.register(LoadBalancer) + +if getattr(settings, 'OPENSTACK_QUANTUM_NETWORK', {}).get('enable_lb', False): + dashboard.Project.register(LoadBalancer) diff --git a/openstack_dashboard/local/local_settings.py.example b/openstack_dashboard/local/local_settings.py.example index 9202c6cb50..b7c5baf168 100644 --- a/openstack_dashboard/local/local_settings.py.example +++ b/openstack_dashboard/local/local_settings.py.example @@ -57,7 +57,7 @@ LOCAL_PATH = os.path.dirname(os.path.abspath(__file__)) # We recommend you use memcached for development; otherwise after every reload # of the django development server, you will have to login again. To use -# memcached set CACHES to something like +# memcached set CACHES to something like # CACHES = { # 'default': { # 'BACKEND' : 'django.core.cache.backends.memcached.MemcachedCache', @@ -119,7 +119,7 @@ OPENSTACK_HYPERVISOR_FEATURES = { # services provided by quantum. Currently only the load balancer service # is available. OPENSTACK_QUANTUM_NETWORK = { - 'enable_lb': True + 'enable_lb': False } # OPENSTACK_ENDPOINT_TYPE specifies the endpoint type to use for the endpoints diff --git a/openstack_dashboard/test/test_data/nova_data.py b/openstack_dashboard/test/test_data/nova_data.py index 9208bd8f71..c41d48fab9 100644 --- a/openstack_dashboard/test/test_data/nova_data.py +++ b/openstack_dashboard/test/test_data/nova_data.py @@ -141,7 +141,9 @@ def data(TEST): TEST.flavors = TestDataContainer() TEST.keypairs = TestDataContainer() TEST.security_groups = TestDataContainer() + TEST.security_groups_uuid = TestDataContainer() TEST.security_group_rules = TestDataContainer() + TEST.security_group_rules_uuid = TestDataContainer() TEST.volumes = TestDataContainer() TEST.quotas = TestDataContainer() TEST.quota_usages = TestDataContainer() @@ -229,64 +231,79 @@ def data(TEST): dict(name='keyName')) TEST.keypairs.add(keypair) - # Security Groups - sg_manager = sec_groups.SecurityGroupManager(None) - sec_group_1 = sec_groups.SecurityGroup(sg_manager, - {"rules": [], - "tenant_id": TEST.tenant.id, - "id": 1, - "name": u"default", - "description": u"default"}) - sec_group_2 = sec_groups.SecurityGroup(sg_manager, - {"rules": [], - "tenant_id": TEST.tenant.id, - "id": 2, - "name": u"other_group", - "description": u"Not default."}) - sec_group_3 = sec_groups.SecurityGroup(sg_manager, - {"rules": [], - "tenant_id": TEST.tenant.id, - "id": 3, - "name": u"another_group", - "description": u"Not default."}) + # Security Groups and Rules + def generate_security_groups(is_uuid=False): - rule = {'id': 1, - 'ip_protocol': u"tcp", - 'from_port': u"80", - 'to_port': u"80", - 'parent_group_id': 1, - 'ip_range': {'cidr': u"0.0.0.0/32"}} + def get_id(is_uuid): + global current_int_id + if is_uuid: + return str(uuid.uuid4()) + else: + get_id.current_int_id += 1 + return get_id.current_int_id - icmp_rule = {'id': 2, - 'ip_protocol': u"icmp", - 'from_port': u"9", - 'to_port': u"5", - 'parent_group_id': 1, - 'ip_range': {'cidr': u"0.0.0.0/32"}} + get_id.current_int_id = 0 - group_rule = {'id': 3, - 'ip_protocol': u"tcp", - 'from_port': u"80", - 'to_port': u"80", - 'parent_group_id': 1, - 'source_group_id': 1} + sg_manager = sec_groups.SecurityGroupManager(None) + rule_manager = rules.SecurityGroupRuleManager(None) - rule_obj = rules.SecurityGroupRule(rules.SecurityGroupRuleManager(None), - rule) - rule_obj2 = rules.SecurityGroupRule(rules.SecurityGroupRuleManager(None), - icmp_rule) - rule_obj3 = rules.SecurityGroupRule(rules.SecurityGroupRuleManager(None), - group_rule) + sec_group_1 = sec_groups.SecurityGroup(sg_manager, + {"rules": [], + "tenant_id": TEST.tenant.id, + "id": get_id(is_uuid), + "name": u"default", + "description": u"default"}) + sec_group_2 = sec_groups.SecurityGroup(sg_manager, + {"rules": [], + "tenant_id": TEST.tenant.id, + "id": get_id(is_uuid), + "name": u"other_group", + "description": u"NotDefault."}) + sec_group_3 = sec_groups.SecurityGroup(sg_manager, + {"rules": [], + "tenant_id": TEST.tenant.id, + "id": get_id(is_uuid), + "name": u"another_group", + "description": u"NotDefault."}) - TEST.security_group_rules.add(rule_obj) - TEST.security_group_rules.add(rule_obj2) - TEST.security_group_rules.add(rule_obj3) + rule = {'id': get_id(is_uuid), + 'ip_protocol': u"tcp", + 'from_port': u"80", + 'to_port': u"80", + 'parent_group_id': sec_group_1.id, + 'ip_range': {'cidr': u"0.0.0.0/32"}} - sec_group_1.rules = [rule_obj] - sec_group_2.rules = [rule_obj] - TEST.security_groups.add(sec_group_1, sec_group_2, sec_group_3) + icmp_rule = {'id': get_id(is_uuid), + 'ip_protocol': u"icmp", + 'from_port': u"9", + 'to_port': u"5", + 'parent_group_id': sec_group_1.id, + 'ip_range': {'cidr': u"0.0.0.0/32"}} - # Security Group Rules + group_rule = {'id': 3, + 'ip_protocol': u"tcp", + 'from_port': u"80", + 'to_port': u"80", + 'parent_group_id': sec_group_1.id, + 'source_group_id': sec_group_1.id} + + rule_obj = rules.SecurityGroupRule(rule_manager, rule) + rule_obj2 = rules.SecurityGroupRule(rule_manager, icmp_rule) + rule_obj3 = rules.SecurityGroupRule(rule_manager, group_rule) + + sec_group_1.rules = [rule_obj] + sec_group_2.rules = [rule_obj] + + return {"rules": [rule_obj, rule_obj2, rule_obj3], + "groups": [sec_group_1, sec_group_2, sec_group_3]} + + sg_data = generate_security_groups() + TEST.security_group_rules.add(*sg_data["rules"]) + TEST.security_groups.add(*sg_data["groups"]) + + sg_uuid_data = generate_security_groups(is_uuid=True) + TEST.security_group_rules_uuid.add(*sg_uuid_data["rules"]) + TEST.security_groups_uuid.add(*sg_uuid_data["groups"]) # Quota Sets quota_data = dict(metadata_items='1',