Merge "Allow creating/showing LBs with Additional VIPs"
This commit is contained in:
commit
03083c3dab
|
@ -33,6 +33,7 @@ LOAD_BALANCER_ROWS = (
|
|||
'vip_qos_policy_id',
|
||||
'vip_subnet_id',
|
||||
'tags',
|
||||
'additional_vips',
|
||||
)
|
||||
|
||||
LOAD_BALANCER_COLUMNS = (
|
||||
|
|
|
@ -89,6 +89,13 @@ class CreateLoadBalancer(command.ShowOne):
|
|||
metavar='<vip_qos_policy_id>',
|
||||
help="Set QoS policy ID for VIP port. Unset with 'None'.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--additional-vip',
|
||||
metavar='subnet-id=<name-or-uuid>[,ip-address=<ip>]',
|
||||
action='append',
|
||||
help="Expose an additional VIP on the load balancer. This "
|
||||
"parameter can be provided more than once."
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--project',
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
# under the License.
|
||||
#
|
||||
|
||||
import functools
|
||||
import ipaddress
|
||||
|
||||
import munch
|
||||
from openstackclient.identity import common as identity_common
|
||||
from osc_lib import exceptions as osc_exc
|
||||
|
@ -181,6 +184,37 @@ def add_tags_attr_map(attr_map):
|
|||
attr_map.update(tags_attr_map)
|
||||
|
||||
|
||||
def validate_vip_dict(vip_dict, client_manager):
|
||||
# We have validation in two places -- _map_attrs checks sub-resources, and
|
||||
# later _check_attrs does further api-specific validation. We need both for
|
||||
# additional vips, so we may as well just do both here while we're at it.
|
||||
if 'subnet_id' not in vip_dict:
|
||||
raise osc_exc.CommandError(
|
||||
'Additional VIPs must include a subnet-id.')
|
||||
subnet_id = get_resource_id(client_manager.neutronclient.list_subnets,
|
||||
'subnets', vip_dict['subnet_id'])
|
||||
vip_dict['subnet_id'] = subnet_id
|
||||
if 'ip_address' in vip_dict:
|
||||
try:
|
||||
ipaddress.ip_address(vip_dict['ip_address'])
|
||||
except ValueError as e:
|
||||
raise osc_exc.CommandError(str(e))
|
||||
|
||||
|
||||
def handle_additional_vips(vips, client_manager):
|
||||
additional_vips = []
|
||||
for vip in vips:
|
||||
vip_dict = {}
|
||||
parts = vip.split(',')
|
||||
for part in parts:
|
||||
k, v = part.split('=')
|
||||
vip_dict[k.replace('-', '_')] = v
|
||||
validate_vip_dict(vip_dict, client_manager)
|
||||
additional_vips.append(vip_dict)
|
||||
|
||||
return additional_vips
|
||||
|
||||
|
||||
def get_loadbalancer_attrs(client_manager, parsed_args):
|
||||
attr_map = {
|
||||
'name': ('name', str),
|
||||
|
@ -231,6 +265,11 @@ def get_loadbalancer_attrs(client_manager, parsed_args):
|
|||
client_manager.load_balancer.flavor_list
|
||||
),
|
||||
'availability_zone': ('availability_zone', str),
|
||||
'additional_vip': (
|
||||
'additional_vips',
|
||||
functools.partial(
|
||||
handle_additional_vips, client_manager=client_manager)
|
||||
),
|
||||
}
|
||||
add_tags_attr_map(attr_map)
|
||||
|
||||
|
|
|
@ -97,6 +97,13 @@ LOADBALANCER_ATTRS = {
|
|||
"operating_status": "ONLINE",
|
||||
"provider": "octavia",
|
||||
"flavor_id": uuidutils.generate_uuid(dashed=True),
|
||||
"additional_vips": [{
|
||||
"subnet_id": uuidutils.generate_uuid(dashed=True),
|
||||
"ip_address": "192.0.2.156"
|
||||
}, {
|
||||
"subnet_id": uuidutils.generate_uuid(dashed=True),
|
||||
"ip_address": "192.0.2.179"
|
||||
}],
|
||||
"tags": ["foo", "bar"]
|
||||
}
|
||||
|
||||
|
|
|
@ -398,6 +398,39 @@ 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_additional_vips(self, mock_client):
|
||||
mock_client.return_value = self.lb_info
|
||||
|
||||
arglist = [
|
||||
'--name', self._lb.name,
|
||||
'--vip-subnet-id', self._lb.vip_subnet_id,
|
||||
'--project', self._lb.project_id,
|
||||
'--additional-vip', 'subnet-id={},ip-address={}'.format(
|
||||
self._lb.additional_vips[0]['subnet_id'],
|
||||
self._lb.additional_vips[0]['ip_address']),
|
||||
'--additional-vip', 'subnet-id={},ip-address={}'.format(
|
||||
self._lb.additional_vips[1]['subnet_id'],
|
||||
self._lb.additional_vips[1]['ip_address'])
|
||||
]
|
||||
verifylist = [
|
||||
('name', self._lb.name),
|
||||
('vip_subnet_id', self._lb.vip_subnet_id),
|
||||
('project', self._lb.project_id),
|
||||
('additional_vip', [
|
||||
'subnet-id={},ip-address={}'.format(
|
||||
self._lb.additional_vips[0]['subnet_id'],
|
||||
self._lb.additional_vips[0]['ip_address']),
|
||||
'subnet-id={},ip-address={}'.format(
|
||||
self._lb.additional_vips[1]['subnet_id'],
|
||||
self._lb.additional_vips[1]['ip_address'])])
|
||||
]
|
||||
|
||||
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': self.lb_info})
|
||||
|
||||
@mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs')
|
||||
def test_load_balancer_create_with_provider(self, mock_client):
|
||||
provider = 'foobar'
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
It is now possible to create a loadbalancer with more than one VIP by
|
||||
passing ``--additional-vip subnet-id=<name-or-uuid>[,ip-address=<ip>]`` to
|
||||
the create command.
|
||||
Additional VIPs will also appear in the ``show`` details of a loadbalancer.
|
Loading…
Reference in New Issue