diff --git a/octaviaclient/osc/v2/constants.py b/octaviaclient/osc/v2/constants.py index 11e2f8e..75dd2ae 100644 --- a/octaviaclient/osc/v2/constants.py +++ b/octaviaclient/osc/v2/constants.py @@ -33,6 +33,7 @@ LOAD_BALANCER_ROWS = ( 'vip_qos_policy_id', 'vip_subnet_id', 'vip_vnic_type', + 'vip_sg_ids', 'tags', 'additional_vips', ) diff --git a/octaviaclient/osc/v2/load_balancer.py b/octaviaclient/osc/v2/load_balancer.py index 2dde5f7..9ef4194 100644 --- a/octaviaclient/osc/v2/load_balancer.py +++ b/octaviaclient/osc/v2/load_balancer.py @@ -96,6 +96,13 @@ class CreateLoadBalancer(command.ShowOne): help="Expose an additional VIP on the load balancer. This " "parameter can be provided more than once." ) + parser.add_argument( + '--vip-sg-id', + metavar='', + action='append', + help="Set a Custom Security Group for VIP port. This " + "parameter can be provided more than once." + ) parser.add_argument( '--project', @@ -436,6 +443,13 @@ class SetLoadBalancer(command.Command): metavar='', help="Set QoS policy ID for VIP port. Unset with 'None'.", ) + parser.add_argument( + '--vip-sg-id', + metavar='', + action='append', + help="Set a Custom Security Group for VIP port. This " + "parameter can be provided more than once." + ) admin_group = parser.add_mutually_exclusive_group() admin_group.add_argument( @@ -508,6 +522,12 @@ class UnsetLoadBalancer(command.Command): action='store_true', help="Clear the load balancer QoS policy.", ) + parser.add_argument( + '--vip-sg-id', + dest='vip_sg_ids', + action='store_true', + help="Clear the Custom Security Groups.", + ) parser.add_argument( '--wait', action='store_true', diff --git a/octaviaclient/osc/v2/utils.py b/octaviaclient/osc/v2/utils.py index 07588aa..d376260 100644 --- a/octaviaclient/osc/v2/utils.py +++ b/octaviaclient/osc/v2/utils.py @@ -215,6 +215,16 @@ def handle_additional_vips(vips, client_manager): return additional_vips +def handle_vip_sg_ids(vip_sgs, client_manager): + vip_sg_ids = [] + for sg in vip_sgs: + sg_id = get_resource_id( + client_manager.neutronclient.list_security_groups, + 'security_groups', sg) + vip_sg_ids.append(sg_id) + return vip_sg_ids + + def get_loadbalancer_attrs(client_manager, parsed_args): attr_map = { 'name': ('name', str), @@ -271,6 +281,11 @@ def get_loadbalancer_attrs(client_manager, parsed_args): functools.partial( handle_additional_vips, client_manager=client_manager) ), + 'vip_sg_id': ( + 'vip_sg_ids', + functools.partial( + handle_vip_sg_ids, client_manager=client_manager), + ) } add_tags_attr_map(attr_map) diff --git a/octaviaclient/tests/unit/osc/v2/constants.py b/octaviaclient/tests/unit/osc/v2/constants.py index d2c05b9..ce010a0 100644 --- a/octaviaclient/tests/unit/osc/v2/constants.py +++ b/octaviaclient/tests/unit/osc/v2/constants.py @@ -107,6 +107,10 @@ LOADBALANCER_ATTRS = { "subnet_id": uuidutils.generate_uuid(dashed=True), "ip_address": "192.0.2.179" }], + "vip_sg_ids": [ + uuidutils.generate_uuid(dashed=True), + uuidutils.generate_uuid(dashed=True), + ], "tags": ["foo", "bar"] } diff --git a/octaviaclient/tests/unit/osc/v2/test_load_balancer.py b/octaviaclient/tests/unit/osc/v2/test_load_balancer.py index af64a99..64447ab 100644 --- a/octaviaclient/tests/unit/osc/v2/test_load_balancer.py +++ b/octaviaclient/tests/unit/osc/v2/test_load_balancer.py @@ -456,6 +456,35 @@ class TestLoadBalancerCreate(TestLoadBalancer): self.api_mock.load_balancer_create.assert_called_with( json={'loadbalancer': lb_info}) + @mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs') + def test_load_balancer_create_with_vip_sg_ids(self, mock_client): + vip_sg_ids = [ + uuidutils.generate_uuid(), + uuidutils.generate_uuid() + ] + lb_info = copy.deepcopy(self.lb_info) + lb_info.update({'vip_sg_ids': vip_sg_ids}) + mock_client.return_value = lb_info + + arglist = [ + '--name', self._lb.name, + '--vip-network-id', self._lb.vip_network_id, + '--project', self._lb.project_id, + '--vip-sg-id', vip_sg_ids[0], + '--vip-sg-id', vip_sg_ids[1], + ] + verifylist = [ + ('name', self._lb.name), + ('vip_network_id', self._lb.vip_network_id), + ('project', self._lb.project_id), + ('vip_sg_id', vip_sg_ids), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.load_balancer_create.assert_called_with( + json={'loadbalancer': lb_info}) + @mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs') def test_load_balancer_create_with_tags(self, mock_client): lb_info = copy.deepcopy(self.lb_info) @@ -679,6 +708,24 @@ class TestLoadBalancerSet(TestLoadBalancer): except Exception as e: self.fail("%s raised unexpectedly" % e) + @mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs') + def test_load_balancer_set_vip_sg_id(self, mock_attrs): + mock_attrs.return_value = { + 'loadbalancer_id': self._lb.id, + } + sg_id = uuidutils.generate_uuid() + arglist = [self._lb.id, '--vip-sg-id', sg_id] + verifylist = [ + ('loadbalancer', self._lb.id), + ('vip_sg_id', [sg_id]), + ] + + try: + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + except Exception as e: + self.fail("%s raised unexpectedly" % e) + class TestLoadBalancerStats(TestLoadBalancer): @@ -887,3 +934,26 @@ class TestLoadBalancerUnset(TestLoadBalancer): self.api_mock.load_balancer_set.assert_called_once_with( self._lb.id, json={'loadbalancer': {'tags': []}}) + + @mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs') + def test_load_balancer_unset_vip_sg_id(self, mock_attrs): + sg_id = uuidutils.generate_uuid() + mock_attrs.return_value = { + 'loadbalancer_id': self._lb.id, + 'vip_sg_ids': [sg_id] + } + arglist = [self._lb.id, '--vip-sg-id'] + verifylist = [ + ('loadbalancer', self._lb.id), + ('vip_sg_ids', True), + ] + + try: + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + except Exception as e: + self.fail("%s raised unexpectedly" % e) + + self.api_mock.load_balancer_set.assert_called_once_with( + self._lb.id, + json={'loadbalancer': {'vip_sg_ids': None}}) diff --git a/releasenotes/notes/add-vip-sg-id-22691a95cc8b3fc7.yaml b/releasenotes/notes/add-vip-sg-id-22691a95cc8b3fc7.yaml new file mode 100644 index 0000000..835e854 --- /dev/null +++ b/releasenotes/notes/add-vip-sg-id-22691a95cc8b3fc7.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Add support for setting Security Groups on VIP ports. ``--vip-sg-id + `` can be passed (it can be provided more than once) to + ``loadbalancer create`` and ``loadbalancer set``. A user can clear the + Security Groups of a VIP port by passing ``--vip-sg-id`` to ``loadbalancer + unset``.