Merge "Add widget for choosing an existing security group"
This commit is contained in:
commit
82824c3fef
|
@ -29,6 +29,7 @@ from horizon import exceptions
|
||||||
from horizon import forms as hz_forms
|
from horizon import forms as hz_forms
|
||||||
from horizon import messages
|
from horizon import messages
|
||||||
from openstack_dashboard.api import glance
|
from openstack_dashboard.api import glance
|
||||||
|
from openstack_dashboard.api import network
|
||||||
from openstack_dashboard.api import nova
|
from openstack_dashboard.api import nova
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_log import versionutils
|
from oslo_log import versionutils
|
||||||
|
@ -408,7 +409,7 @@ class FlavorChoiceField(ChoiceField):
|
||||||
|
|
||||||
|
|
||||||
class KeyPairChoiceField(DynamicChoiceField):
|
class KeyPairChoiceField(DynamicChoiceField):
|
||||||
" This widget allows to select keypair for VMs "
|
"""This widget allows to select keypair for VMs"""
|
||||||
@with_request
|
@with_request
|
||||||
def update(self, request, **kwargs):
|
def update(self, request, **kwargs):
|
||||||
self.choices = [('', _('No keypair'))]
|
self.choices = [('', _('No keypair'))]
|
||||||
|
@ -418,6 +419,20 @@ class KeyPairChoiceField(DynamicChoiceField):
|
||||||
self.choices.append((keypair.name, keypair.name))
|
self.choices.append((keypair.name, keypair.name))
|
||||||
|
|
||||||
|
|
||||||
|
class SecurityGroupChoiceField(DynamicChoiceField):
|
||||||
|
"""This widget allows to select a security group for VMs"""
|
||||||
|
@with_request
|
||||||
|
def update(self, request, **kwargs):
|
||||||
|
self.choices = [('', _('Application default security group'))]
|
||||||
|
# TODO(pbourke): remove sorted when supported natively in Horizon
|
||||||
|
# (https://bugs.launchpad.net/horizon/+bug/1692972)
|
||||||
|
for secgroup in sorted(
|
||||||
|
network.security_group_list(request),
|
||||||
|
key=lambda e: e.name_or_id):
|
||||||
|
if not secgroup.name_or_id.startswith('murano--'):
|
||||||
|
self.choices.append((secgroup.name_or_id, secgroup.name_or_id))
|
||||||
|
|
||||||
|
|
||||||
# NOTE(kzaitsev): for transform to work correctly on horizon SelectWidget
|
# NOTE(kzaitsev): for transform to work correctly on horizon SelectWidget
|
||||||
# Choice has to be non-string
|
# Choice has to be non-string
|
||||||
class Choice(object):
|
class Choice(object):
|
||||||
|
|
|
@ -50,7 +50,8 @@ TYPES.update({
|
||||||
'network': fields.NetworkChoiceField,
|
'network': fields.NetworkChoiceField,
|
||||||
'text': (fields.CharField, forms.Textarea),
|
'text': (fields.CharField, forms.Textarea),
|
||||||
'choice': fields.ChoiceField,
|
'choice': fields.ChoiceField,
|
||||||
'floatingip': fields.FloatingIpBooleanField
|
'floatingip': fields.FloatingIpBooleanField,
|
||||||
|
'securitygroup': fields.SecurityGroupChoiceField
|
||||||
})
|
})
|
||||||
|
|
||||||
KEYPAIR_IMPORT_URL = "horizon:project:key_pairs:import"
|
KEYPAIR_IMPORT_URL = "horizon:project:key_pairs:import"
|
||||||
|
|
|
@ -576,6 +576,31 @@ class TestKeyPairChoiceField(testtools.TestCase):
|
||||||
sorted(key_pair_choice_field.choices))
|
sorted(key_pair_choice_field.choices))
|
||||||
|
|
||||||
|
|
||||||
|
class TestSecurityGroupChoiceField(testtools.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestSecurityGroupChoiceField, self).setUp()
|
||||||
|
self.request = {'request': mock.Mock()}
|
||||||
|
self.addCleanup(mock.patch.stopall)
|
||||||
|
|
||||||
|
@mock.patch.object(fields, 'network')
|
||||||
|
def test_update(self, mock_network):
|
||||||
|
mock_network.security_group_list.return_value = [
|
||||||
|
mock.Mock(name_or_id='foo'),
|
||||||
|
mock.Mock(name_or_id='bar')
|
||||||
|
]
|
||||||
|
security_group_choice_field = fields.SecurityGroupChoiceField()
|
||||||
|
security_group_choice_field.choices = []
|
||||||
|
security_group_choice_field.update(self.request)
|
||||||
|
|
||||||
|
expected_choices = [
|
||||||
|
('', _('Application default security group')),
|
||||||
|
('foo', 'foo'), ('bar', 'bar')
|
||||||
|
]
|
||||||
|
self.assertEqual(sorted(expected_choices),
|
||||||
|
sorted(security_group_choice_field.choices))
|
||||||
|
|
||||||
|
|
||||||
class TestImageChoiceField(testtools.TestCase):
|
class TestImageChoiceField(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
Loading…
Reference in New Issue