Generic solution for partial updates

Early versions of policy APIs do not support partial PATCH update
for most objects.
This change alters policy api to fetch a resource for update call,
and perform update based on existing object. This will only happen
for backend versions prior to 2.6.0

Change-Id: Ic9bc657d17a84121a32cd1645cc6cb03e49d241f
This commit is contained in:
Anna Khmelnitsky 2019-04-22 15:09:42 -07:00
parent cf6de6b6fe
commit e233fe2ea7
8 changed files with 210 additions and 380 deletions

View File

@ -110,8 +110,8 @@ class TestPolicyLBClientSSLProfileApi(test_resources.NsxPolicyLibTestCase):
obj_id = '111'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -142,8 +142,7 @@ class TestPolicyLBCookiePersistenceProfile(
cookie_path = 'path'
cookie_time = 'time'
persistence_shared = False
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name,
persistence_profile_id=obj_id,
@ -173,8 +172,7 @@ class TestPolicyLBCookiePersistenceProfile(
def test_create_without_id(self):
name = 'd1'
description = 'desc'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, description=description,
tenant=TEST_TENANT)
@ -241,8 +239,8 @@ class TestPolicyLBCookiePersistenceProfile(
cookie_path = 'path'
cookie_time = 'time'
persistence_shared = False
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -376,8 +374,9 @@ class TestPolicyLBSourceIpProfileApi(test_resources.NsxPolicyLibTestCase):
persistence_shared = False
purge = 'no purge'
timeout = 101
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -515,8 +514,8 @@ class TestPolicyLBApplicationProfile(test_resources.NsxPolicyLibTestCase):
obj_id = '111'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -542,8 +541,7 @@ class TestPolicyLBService(test_resources.NsxPolicyLibTestCase):
obj_id = '111'
size = 'SMALL'
connectivity_path = 'path'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name,
lb_service_id=obj_id,
@ -565,8 +563,7 @@ class TestPolicyLBService(test_resources.NsxPolicyLibTestCase):
def test_create_without_id(self):
name = 'd1'
description = 'desc'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, description=description,
tenant=TEST_TENANT)
@ -624,8 +621,8 @@ class TestPolicyLBService(test_resources.NsxPolicyLibTestCase):
description = 'new desc'
size = 'SMALL'
connectivity_path = 'path'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -730,49 +727,30 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
obj_id = '111'
name = 'new name'
description = 'new desc'
dummy_id = 'xxxx'
vs_name = 'name-name'
vs_ip_address = '1.1.1.1'
vs_ports = [80]
dummy_path = '/test/lb-app-profiles/' + dummy_id
with mock.patch.object(self.policy_api,
"create_or_update") as update_call, \
mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'application_profile_path': dummy_path}):
with self.mock_get(obj_id, vs_name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
tenant=TEST_TENANT)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=obj_id, name=name, ports=vs_ports,
description=description, ip_address=vs_ip_address,
tenant=TEST_TENANT, application_profile_id=dummy_id)
virtual_server_id=obj_id, name=name,
description=description,
tenant=TEST_TENANT)
self.assert_called_with_def(update_call, expected_def)
def test_add_lb_rule(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
rule_actions = 'test1'
rule_match_conditions = 'test2'
rule_name = 'dummy_rule'
rule_match_strategy = 'test3'
rule_phase = 'test4'
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name), \
self.mock_create_update() as update_call:
self.resourceApi.add_lb_rule(
vs_obj_id, actions=rule_actions, name=rule_name,
match_conditions=rule_match_conditions,
@ -782,32 +760,24 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports, rules=[lb_rule])
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[lb_rule])
self.assert_called_with_def(update_call, expected_def)
def test_add_lb_rule_first(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
rule_actions = 'test1'
rule_match_conditions = 'test2'
rule_name = 'dummy_rule'
rule_match_strategy = 'test3'
rule_phase = 'test4'
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx'}, {'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.add_lb_rule(
vs_obj_id, actions=rule_actions, name=rule_name,
match_conditions=rule_match_conditions,
@ -818,9 +788,8 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[lb_rule,
{'display_name': 'xx'},
{'display_name': 'yy'}])
@ -829,24 +798,15 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_add_lb_rule_last(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
rule_actions = 'test1'
rule_match_conditions = 'test2'
rule_name = 'dummy_rule'
rule_match_strategy = 'test3'
rule_phase = 'test4'
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx'}, {'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.add_lb_rule(
vs_obj_id, actions=rule_actions, name=rule_name,
match_conditions=rule_match_conditions,
@ -856,9 +816,8 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'},
lb_rule])
@ -867,24 +826,16 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_add_lb_rule_last_over(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
rule_actions = 'test1'
rule_match_conditions = 'test2'
rule_name = 'dummy_rule'
rule_match_strategy = 'test3'
rule_phase = 'test4'
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx'}, {'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.add_lb_rule(
vs_obj_id, actions=rule_actions, name=rule_name,
match_conditions=rule_match_conditions,
@ -896,8 +847,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'},
lb_rule])
@ -906,24 +855,15 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_add_lb_rule_mid(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
rule_actions = 'test1'
rule_match_conditions = 'test2'
rule_name = 'dummy_rule'
rule_match_strategy = 'test3'
rule_phase = 'test4'
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx'}, {'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.add_lb_rule(
vs_obj_id, actions=rule_actions, name=rule_name,
match_conditions=rule_match_conditions,
@ -934,9 +874,8 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
name=vs_name,
virtual_server_id=vs_obj_id,
rules=[{'display_name': 'xx'},
lb_rule,
{'display_name': 'yy'}])
@ -945,26 +884,16 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_update_lb_rule(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx', 'actions': '11'},
{'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(
vs_obj_id, vs_name,
rules=[{'display_name': 'xx', 'actions': '11'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.update_lb_rule(vs_obj_id, 'xx', actions='22')
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
name=vs_name,
virtual_server_id=vs_obj_id,
rules=[{'display_name': 'xx', 'actions': '22'},
{'display_name': 'yy'}])
self.assert_called_with_def(update_call, expected_def)
@ -972,27 +901,17 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_update_lb_rule_position(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx', 'actions': '11'},
{'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(
vs_obj_id, vs_name,
rules=[{'display_name': 'xx', 'actions': '11'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.update_lb_rule(vs_obj_id, 'xx', actions='22',
position=1)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[{'display_name': 'yy'},
{'display_name': 'xx', 'actions': '22'}])
self.assert_called_with_def(update_call, expected_def)
@ -1000,25 +919,15 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
def test_remove_lb_rule(self):
vs_obj_id = '111'
vs_name = 'name-name'
vs_ports = [80]
vs_ip_address = '1.1.1.1'
app_prof_id = 'xxxx'
app_prof_path = '/test/lb-app-profiles/' + app_prof_id
with mock.patch.object(
self.policy_api, "get", return_value={
'ip_address': vs_ip_address,
'ports': vs_ports,
'display_name': vs_name,
'rules': [{'display_name': 'xx'}, {'display_name': 'yy'}],
'application_profile_path': app_prof_path}), \
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(vs_obj_id, vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'}]), \
self.mock_create_update() as update_call:
self.resourceApi.remove_lb_rule(vs_obj_id, 'xx')
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
ip_address=vs_ip_address, application_profile_id=app_prof_id,
ports=vs_ports,
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[{'display_name': 'yy'}])
self.assert_called_with_def(update_call, expected_def)
@ -1236,8 +1145,9 @@ class TestPolicyLBMonitorProfileHttpApi(test_resources.NsxPolicyLibTestCase):
def test_update(self):
obj_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
tenant=TEST_TENANT)

View File

@ -37,8 +37,11 @@ class NsxPolicyLibTestCase(policy_testcase.TestPolicyApi):
allow_passthrough=kwargs.get('allow_passthrough', True))
# Mock the nsx-lib for the passthrough api
with mock.patch('vmware_nsxlib.v3.NsxLib'):
# TODO(annak): move version forward with backend releases
with mock.patch("vmware_nsxlib.v3.NsxLib") as mock_lib:
mock_lib.return_value.get_version.return_value = "2.5.0"
self.policy_lib = policy.NsxPolicyLib(nsxlib_config)
self.policy_api = self.policy_lib.policy_api
self.policy_api.client = self.client
@ -83,6 +86,19 @@ class NsxPolicyLibTestCase(policy_testcase.TestPolicyApi):
actual_dict = mock_api.call_args_list[call_num][0][0].body
self.assertEqual(expected_dict, actual_dict)
def mock_get(self, obj_id, obj_name, **kwargs):
obj_dict = {
'id': obj_id,
'display_name': obj_name,
'resource_type': self.resourceApi.entry_def.resource_type()}
if kwargs:
obj_dict.update(kwargs)
return mock.patch.object(self.policy_api, "get",
return_value=obj_dict)
def mock_create_update(self):
return mock.patch.object(self.policy_api, "create_or_update")
class TestPolicyDomain(NsxPolicyLibTestCase):
@ -94,8 +110,7 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
name = 'd1'
description = 'desc'
domain_id = '111'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name,
domain_id=domain_id,
@ -110,8 +125,7 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
def test_minimalistic_create(self):
name = 'test'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(name,
tenant=TEST_TENANT)
expected_def = core_defs.DomainDef(domain_id=mock.ANY,
@ -174,8 +188,8 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
domain_id = '111'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(domain_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(domain_id,
name=name,
description=description,
@ -188,19 +202,21 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
def test_unset(self):
domain_id = '111'
self.resourceApi.update(domain_id,
description=None,
tags=None,
tenant=TEST_TENANT)
with mock.patch.object(self.policy_api, "get",
return_value={'id': domain_id}):
self.resourceApi.update(domain_id,
description=None,
tags=None,
tenant=TEST_TENANT)
expected_body = {'id': domain_id,
'resource_type': 'Domain',
'description': None,
'tags': None}
expected_body = {'id': domain_id,
'resource_type': 'Domain',
'description': None,
'tags': None}
self.assert_json_call('PATCH', self.client,
'%s/domains/%s' % (TEST_TENANT, domain_id),
data=expected_body)
self.assert_json_call('PATCH', self.client,
'%s/domains/%s' % (TEST_TENANT, domain_id),
data=expected_body)
class TestPolicyGroup(NsxPolicyLibTestCase):
@ -496,8 +512,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
group_id = '222'
name = 'new name'
description = 'new desc'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(group_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(domain_id, group_id,
name=name,
description=description,
@ -563,22 +579,23 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
group_id = '222'
description = 'new'
self.resourceApi.update(domain_id,
group_id,
name=None,
description=description,
tenant=TEST_TENANT)
with self.mock_get(group_id, 'test'):
self.resourceApi.update(domain_id,
group_id,
name=None,
description=description,
tenant=TEST_TENANT)
expected_body = {'id': group_id,
'resource_type': 'Group',
'display_name': None,
'description': description}
expected_body = {'id': group_id,
'resource_type': 'Group',
'display_name': None,
'description': description}
self.assert_json_call('PATCH', self.client,
'%s/domains/%s/groups/%s' % (TEST_TENANT,
domain_id,
group_id),
data=expected_body)
self.assert_json_call('PATCH', self.client,
'%s/domains/%s/groups/%s' % (TEST_TENANT,
domain_id,
group_id),
data=expected_body)
def test_get_realized(self):
domain_id = 'd1'
@ -2228,8 +2245,8 @@ class TestPolicyDeploymentMap(NsxPolicyLibTestCase):
name = 'new name'
domain_id = 'domain2'
ep_id = 'ep2'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(domain_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
ep_id=ep_id,
@ -2449,9 +2466,8 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
obj_id = '111'
name = 'new name'
tier0 = 'tier0'
with mock.patch.object(self.policy_api, "get", return_value={}),\
mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name, tier0=tier0,
enable_standby_relocation=False,
@ -2513,12 +2529,8 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
def test_update_route_adv(self):
obj_id = '111'
rtr_name = 'rtr111'
ndra_profile_id = 'test'
ndra_profile_path = '/infra/ipv6-ndra-profiles/%s' % ndra_profile_id
get_result = {'id': obj_id,
'display_name': rtr_name,
'enable_standby_relocation': False,
'ipv6_profile_paths': [ndra_profile_path],
'route_advertisement_types': ['TIER1_NAT',
'TIER1_LB_VIP']}
with mock.patch.object(self.policy_api, "get",
@ -2538,9 +2550,7 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
expected_def = core_defs.Tier1Def(
tier1_id=obj_id,
name=rtr_name,
enable_standby_relocation=False,
route_advertisement=new_adv,
ipv6_ndra_profile_id=ndra_profile_id,
tenant=TEST_TENANT)
self.assert_called_with_def(
@ -2760,7 +2770,6 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
with mock.patch.object(self.policy_api,
"get",
return_value={'id': tier1_id,
'display_name': 'tier1name',
'resource_type': 'Tier1'}),\
mock.patch.object(self.policy_api,
'create_or_update') as api_call:
@ -2772,7 +2781,6 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
expected_def = core_defs.Tier1Def(
tier1_id=tier1_id,
name='tier1name',
route_advertisement_rules=[
core_defs.RouteAdvertisementRule(
rule_name,
@ -2789,7 +2797,6 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
rule_name = 'rule_name'
get_retval = {
'id': tier1_id,
'display_name': 'tier1name',
'route_advertisement_rules': [{'name': rule_name}]}
with mock.patch.object(self.policy_api,
"get",
@ -2801,7 +2808,6 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
expected_def = core_defs.Tier1Def(
tier1_id=tier1_id,
name='tier1name',
route_advertisement_rules=[],
tenant=TEST_TENANT)
@ -3135,8 +3141,8 @@ class TestPolicyTier0(NsxPolicyLibTestCase):
def test_update(self):
obj_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
tenant=TEST_TENANT)
@ -3268,8 +3274,8 @@ class TestPolicyTier1Segment(NsxPolicyLibTestCase):
tier1_id = '111'
segment_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(tier1_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(segment_id=segment_id,
tier1_id=tier1_id,
name=name,
@ -3348,8 +3354,9 @@ class TestPolicySegment(NsxPolicyLibTestCase):
def test_update(self):
segment_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(segment_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(segment_id,
name=name,
tenant=TEST_TENANT)
@ -3434,8 +3441,9 @@ class TestPolicyIpPool(NsxPolicyLibTestCase):
def test_update(self):
ip_pool_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(ip_pool_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(ip_pool_id,
name=name,
tenant=TEST_TENANT)
@ -3787,8 +3795,8 @@ class TestPolicySegmentProfileBase(NsxPolicyLibTestCase):
def test_update(self):
profile_id = '111'
name = 'new name'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(profile_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(profile_id,
name=name,
tenant=TEST_TENANT)
@ -3979,8 +3987,9 @@ class TestPolicySegmentSecProfilesBinding(NsxPolicyLibTestCase):
port_id = 'port1'
prf1 = '1'
prf2 = '2'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(segment_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(
segment_id=segment_id,
port_id=port_id,
@ -4082,8 +4091,8 @@ class TestPolicySegmentDiscoveryProfilesBinding(NsxPolicyLibTestCase):
port_id = 'port1'
prf1 = '1'
prf2 = '2'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(segment_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(
segment_id=segment_id,
port_id=port_id,
@ -4118,8 +4127,7 @@ class TestPolicySegmentQosProfilesBinding(NsxPolicyLibTestCase):
segment_id = 'seg1'
port_id = 'port1'
prf1 = '1'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, segment_id, port_id,
qos_profile_id=prf1,
@ -4181,8 +4189,8 @@ class TestPolicySegmentQosProfilesBinding(NsxPolicyLibTestCase):
segment_id = 'seg1'
port_id = 'port1'
prf1 = '1'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(segment_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(
segment_id=segment_id,
port_id=port_id,
@ -4220,8 +4228,7 @@ class TestPolicyTier1SegmentPort(NsxPolicyLibTestCase):
allocate_addresses = "BOTH"
tags = [{'scope': 'a', 'tag': 'b'}]
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, tier1_id, segment_id, description=description,
address_bindings=address_bindings,
@ -4291,8 +4298,7 @@ class TestPolicyDhcpRelayConfig(NsxPolicyLibTestCase):
description = 'desc'
server_addr = '1.1.1.1'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, description=description,
server_addresses=[server_addr],
@ -4348,8 +4354,7 @@ class TestPolicyCertificate(NsxPolicyLibTestCase):
private_key = 'private_key'
passphrase = 'passphrase'
key_algo = 'algo'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name,
certificate_id=obj_id,
@ -4376,8 +4381,7 @@ class TestPolicyCertificate(NsxPolicyLibTestCase):
name = 'd1'
description = 'desc'
pem_encoded = 'pem_encoded'
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
result = self.resourceApi.create_or_overwrite(
name, description=description,
tenant=TEST_TENANT,
@ -4437,8 +4441,8 @@ class TestPolicyCertificate(NsxPolicyLibTestCase):
private_key = 'private_key'
passphrase = '12'
key_algo = 'new_algo'
with mock.patch.object(self.policy_api,
"create_or_update") as update_call:
with self.mock_get(obj_id, name), \
self.mock_create_update() as update_call:
self.resourceApi.update(obj_id,
name=name,
description=description,
@ -4468,8 +4472,7 @@ class TestPolicyExcludeList(NsxPolicyLibTestCase):
def test_create_or_overwrite(self):
members = ["/infra/domains/default/groups/adit1"]
with mock.patch.object(self.policy_api,
"create_or_update") as api_call:
with self.mock_create_update() as api_call:
self.resourceApi.create_or_overwrite(
members=members, tenant=TEST_TENANT)
expected_def = core_defs.ExcludeListDef(

View File

@ -30,7 +30,9 @@ class TestPolicyTransaction(policy_testcase.TestPolicyApi):
nsxlib_config = nsxlib_testcase.get_default_nsxlib_config()
# Mock the nsx-lib for the passthrough api
with mock.patch('vmware_nsxlib.v3.NsxLib'):
with mock.patch('vmware_nsxlib.v3.NsxLib.get_version',
return_value='2.5.0'):
self.policy_lib = policy.NsxPolicyLib(nsxlib_config)
self.policy_api = self.policy_lib.policy_api
self.policy_api.client = self.client

View File

@ -146,6 +146,7 @@ NSX_VERSION_2_2_0 = '2.2.0'
NSX_VERSION_2_3_0 = '2.3.0'
NSX_VERSION_2_4_0 = '2.4.0'
NSX_VERSION_2_5_0 = '2.5.0'
NSX_VERSION_2_6_0 = '2.6.0'
NSX_VERSION_3_0_0 = '3.0.0'
# Features available depending on the NSX Manager backend version
@ -167,6 +168,7 @@ FEATURE_ENS_WITH_SEC = 'ENS with security'
FEATURE_ICMP_STRICT = 'Strict list of supported ICMP types and codes'
FEATURE_ROUTER_ALLOCATION_PROFILE = 'Router Allocation Profile'
FEATURE_ENABLE_STANDBY_RELOCATION = 'Router Enable standby relocation'
FEATURE_PARTIAL_UPDATES = 'Partial Update with PATCH'
# Features available depending on the Policy Manager backend version
FEATURE_NSX_POLICY = 'NSX Policy'

View File

@ -46,7 +46,12 @@ class NsxPolicyLib(lib.NsxLibBase):
self.nsx_api = v3.NsxLib(config)
else:
self.nsx_api = None
self.nsx_version = self.get_version()
if not self.feature_supported(nsx_constants.FEATURE_PARTIAL_UPDATES):
self.policy_api.disable_partial_updates()
args = (self.policy_api, self.nsx_api, self.nsx_version,
self.nsxlib_config)
@ -145,6 +150,11 @@ class NsxPolicyLib(lib.NsxLibBase):
if (feature == nsx_constants.FEATURE_NSX_POLICY_NETWORKING):
return True
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_2_6_0)):
if feature == nsx_constants.FEATURE_PARTIAL_UPDATES:
return True
return (feature == nsx_constants.FEATURE_NSX_POLICY)
def reinitialize_cluster(self, resource, event, trigger, payload=None):

View File

@ -274,8 +274,6 @@ class RouteAdvertisement(object):
# This initializes object based on list coming from backend
# f.e. [TIER1_NAT, TIER1_LB_SNAT]
# TODO(annak): for now platform does not return adv types
# check this when issue is fixed
for key, value in self.types.items():
self.attrs[key] = value in obj_dict
@ -370,7 +368,6 @@ class Tier1Def(RouterDef):
def get_obj_dict(self):
body = super(Tier1Def, self).get_obj_dict()
# TODO(annak): replace with provider path when provider is exposed
if self.has_attr('tier0'):
tier0 = self.get_attr('tier0')
tier0_path = None
@ -1759,6 +1756,13 @@ class NsxPolicyApi(object):
def __init__(self, client):
self.client = client
self.cache = utils.NsxLibCache(utils.DEFAULT_CACHE_AGE_SEC)
self.partial_updates = True
def disable_partial_updates(self):
self.partial_updates = False
def partial_updates_supported(self):
return self.partial_updates
def create_or_update(self, resource_def):
"""Create or update a policy object.
@ -1771,6 +1775,7 @@ class NsxPolicyApi(object):
if resource_def.resource_use_cache():
self.cache.remove(path)
body = resource_def.get_obj_dict()
self.client.patch(path, body)
def create_with_parent(self, parent_def, resource_def):
@ -1782,6 +1787,7 @@ class NsxPolicyApi(object):
else:
child_dict_key = resource_def.get_last_section_dict_key
body[child_dict_key] = [resource_def.get_obj_dict()]
self.client.patch(path, body)
def delete(self, resource_def):

View File

@ -145,7 +145,11 @@ class NsxPolicyResourceBase(object):
def _update(self, **kwargs):
"""Helper for update function - ignore attrs without explicit value"""
policy_def = self._init_def(**kwargs)
if self.policy_api.partial_updates_supported():
policy_def = self._init_def(**kwargs)
else:
policy_def = self._get_and_update_def(**kwargs)
if policy_def.bodyless():
# Nothing to update - only keys provided in kwargs
return
@ -894,31 +898,6 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase):
route_advertisement_rules=IGNORE,
tenant=constants.POLICY_INFRA_TENANT,
current_body=None):
# Note(asarfaty): L2/L3 PATCH APIs don't support partial updates yet
# TODO(asarfaty): Remove this when supported
if (name == IGNORE or enable_standby_relocation == IGNORE or
ipv6_ndra_profile_id == IGNORE or tags == IGNORE or
current_body):
if not current_body:
current_body = self.get(tier1_id, tenant=tenant)
if name == IGNORE:
name = current_body.get('display_name', IGNORE)
if enable_standby_relocation == IGNORE:
enable_standby_relocation = current_body.get(
'enable_standby_relocation', IGNORE)
if ipv6_ndra_profile_id == IGNORE:
ipv6_ndra_profile_id = self._get_ipv6_profile_from_dict(
current_body)
if route_advertisement_rules == IGNORE:
route_advertisement_rules = current_body.get(
'route_advertisement_rules', IGNORE)
if route_advertisement == IGNORE and current_body.get(
'route_advertisement_types'):
route_advertisement = self.entry_def.get_route_adv(
current_body)
if tags == IGNORE:
tags = current_body.get('tags', IGNORE)
self._update(tier1_id=tier1_id,
name=name,
@ -935,17 +914,6 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase):
tags=tags,
tenant=tenant)
# TODO(annak): remove this func when partial update is supported
def _get_ipv6_profile_from_dict(self, obj_dict):
ipv6_profiles = obj_dict.get('ipv6_profile_paths', [])
if not ipv6_profiles:
return IGNORE
for profile in ipv6_profiles:
tokens = profile.split('/')
if len(tokens) > 3 and tokens[2] == 'ipv6-ndra-profiles':
return tokens[3]
def update_route_advertisement(
self, tier1_id,
static_routes=None,
@ -1726,12 +1694,6 @@ class NsxPolicySegmentApi(NsxPolicyResourceBase):
dns_domain_name=IGNORE,
vlan_ids=IGNORE, tags=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
# Note(asarfaty): L2/L3 PATCH APIs don't support partial updates yet
# TODO(asarfaty): Remove this when supported
if name == IGNORE:
current_body = self.get(segment_id, tenant=tenant)
name = current_body.get('display_name', IGNORE)
self._update(segment_id=segment_id,
name=name,
description=description,

View File

@ -26,7 +26,6 @@ from vmware_nsxlib.v3.policy import constants
from vmware_nsxlib.v3.policy.core_resources import IGNORE
from vmware_nsxlib.v3.policy.core_resources import NsxPolicyResourceBase
from vmware_nsxlib.v3.policy import lb_defs
from vmware_nsxlib.v3.policy import utils as p_utils
LOG = logging.getLogger(__name__)
@ -427,36 +426,12 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
lb_pool_def = self.entry_def(tenant=tenant)
return self.policy_api.list(lb_pool_def)['results']
def _update_helper(
self, lb_pool_id, tenant, pool_data=None, **kwargs):
# TODO(kobis) method should be removed and replaced with a simple
# call to _update(), once the policy backend PATCH method works
# properly
if not pool_data:
pool_data = self.get(lb_pool_id, tenant)
if kwargs.get('active_monitor_paths', IGNORE) == IGNORE:
kwargs['active_monitor_paths'] = (
pool_data.get('active_monitor_paths'))
if kwargs.get('algorithm', IGNORE) == IGNORE:
kwargs['algorithm'] = pool_data.get('algorithm')
if kwargs.get('members', IGNORE) == IGNORE:
kwargs['members'] = pool_data.get('members')
for k in kwargs.keys():
if kwargs.get(k) == IGNORE and pool_data.get(k):
kwargs[k] = pool_data[k]
self._update(lb_pool_id=lb_pool_id, tenant=tenant, **kwargs)
def update(self, lb_pool_id, name=IGNORE, description=IGNORE,
tags=IGNORE, members=IGNORE, algorithm=IGNORE,
active_monitor_paths=IGNORE, member_group=IGNORE,
snat_translation=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
self._update_helper(
self._update(
lb_pool_id=lb_pool_id,
name=name,
description=description,
@ -475,7 +450,7 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
lb_pool = self.policy_api.get(lb_pool_def)
monitor_paths = lb_pool.get('active_monitor_paths', [])
monitor_paths.extend(active_monitor_paths)
self._update_helper(
self._update(
lb_pool_id, active_monitor_paths=monitor_paths, pool_data=lb_pool,
tenant=tenant)
@ -487,8 +462,8 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
monitor_paths = lb_pool.get('active_monitor_paths', [])
if monitor_path in monitor_paths:
monitor_paths.remove(monitor_path)
self._update_helper(lb_pool_id, active_monitor_paths=monitor_paths,
pool_data=lb_pool, tenant=tenant)
self._update(lb_pool_id, active_monitor_paths=monitor_paths,
pool_data=lb_pool, tenant=tenant)
def create_pool_member_and_add_to_pool(
self, lb_pool_id, ip_address, port=None,
@ -505,8 +480,8 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
lb_pool = self.policy_api.get(lb_pool_def)
lb_pool_members = lb_pool.get('members', [])
lb_pool_members.append(lb_pool_member)
self._update_helper(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
self._update(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
return lb_pool_member
def update_pool_member(
@ -529,8 +504,8 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
member_to_update[0]['admin_state'] = admin_state
if backup_member:
member_to_update[0]['backup_member'] = backup_member
self._update_helper(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
self._update(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
else:
ops = ('Updating member %(address)s:%(port)d failed, not found in '
'pool %(pool)s', {'address': ip_address,
@ -547,8 +522,8 @@ class NsxPolicyLoadBalancerPoolApi(NsxPolicyResourceBase):
lb_pool_members = lb_pool.get('members', [])
lb_pool_members = [x for x in lb_pool_members if (
x.get('ip_address') != ip_address and x.get('port') != str(port))]
self._update_helper(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
self.update(lb_pool_id, members=lb_pool_members,
pool_data=lb_pool, tenant=tenant)
def get_path(self, lb_pool_id,
tenant=constants.POLICY_INFRA_TENANT):
@ -689,49 +664,6 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
lbvs_def = self.entry_def(tenant=tenant)
return self.policy_api.list(lbvs_def)['results']
def _update_helper(
self, virtual_server_id, tenant, vs_data=None, **kwargs):
# TODO(kobis) method should be removed and replaced with a simple
# call to _update(), once the policy backend PATCH method works
# properly
if not vs_data:
vs_data = self.get(virtual_server_id, tenant)
if (kwargs.get('application_profile_id', IGNORE) == IGNORE and
vs_data.get('application_profile_path')):
kwargs['application_profile_id'] = p_utils.path_to_id(
vs_data['application_profile_path'])
if kwargs.get('ip_address', IGNORE) == IGNORE:
kwargs['ip_address'] = vs_data.get('ip_address')
if kwargs.get('ports', IGNORE) == IGNORE:
kwargs['ports'] = vs_data.get('ports')
if kwargs.get('name', IGNORE) == IGNORE:
kwargs['name'] = vs_data.get('display_name')
if (kwargs.get('description', IGNORE) == IGNORE and
vs_data.get('description')):
kwargs['description'] = vs_data.get('description')
if (kwargs.get('lb_service_id', IGNORE) == IGNORE and
vs_data.get('lb_service_path')):
kwargs['lb_service_id'] = p_utils.path_to_id(
vs_data['lb_service_path'])
for k in kwargs.keys():
if kwargs.get(k) == IGNORE and vs_data.get(k):
kwargs[k] = vs_data[k]
if (kwargs.get('tags', IGNORE) == IGNORE and
vs_data.get('tags')):
kwargs['tags'] = vs_data['tags']
self._update(
virtual_server_id=virtual_server_id,
tenant=tenant,
**kwargs)
def update(self, virtual_server_id, name=IGNORE, description=IGNORE,
rules=IGNORE, application_profile_id=IGNORE,
ip_address=IGNORE, lb_service_id=IGNORE,
@ -744,7 +676,7 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
max_concurrent_connections=IGNORE,
tags=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
self._update_helper(
self._update(
virtual_server_id=virtual_server_id,
name=name,
description=description,
@ -765,20 +697,20 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
def update_virtual_server_with_pool(
self, virtual_server_id, pool_id=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
return self._update_helper(
return self.update(
virtual_server_id, pool_id=pool_id, tenant=tenant)
def update_virtual_server_application_profile(
self, virtual_server_id, application_profile_id=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
return self._update_helper(
return self.update(
virtual_server_id, application_profile_id=application_profile_id,
tenant=tenant)
def update_virtual_server_persistence_profile(
self, virtual_server_id, lb_persistence_profile_id=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
return self._update_helper(
return self.update(
virtual_server_id,
lb_persistence_profile_id=lb_persistence_profile_id,
tenant=tenant)
@ -786,14 +718,14 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
def update_virtual_server_client_ssl_profile_binding(
self, virtual_server_id, client_ssl_profile_binding=IGNORE,
tenant=constants.POLICY_INFRA_TENANT):
return self._update_helper(
return self.update(
virtual_server_id,
client_ssl_profile_binding=client_ssl_profile_binding,
tenant=tenant)
def update_virtual_server_with_vip(self, virtual_server_id, vip,
tenant=constants.POLICY_INFRA_TENANT):
return self._update_helper(
return self.update(
virtual_server_id, ip_address=vip, tenant=tenant)
def build_client_ssl_profile_binding(self, default_certificate_path,
@ -818,7 +750,7 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
ssl_profile_path=ssl_profile_path,
client_auth_ca_paths=client_auth_ca_paths, client_auth=client_auth)
return self._update_helper(
return self.update(
virtual_server_id, client_ssl_profile_binding=client_ssl_def,
tenant=tenant)
@ -848,8 +780,9 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
tenant=tenant)
body = self.policy_api.get(lbvs_def)
lb_rules = self._add_rule_in_position(body, lb_rule, position)
return self._update_helper(virtual_server_id, vs_data=body,
rules=lb_rules, tenant=tenant)
return self._update(virtual_server_id=virtual_server_id,
vs_data=body,
rules=lb_rules, tenant=tenant)
def update_lb_rule(self, virtual_server_id, lb_rule_name,
actions=None, match_conditions=None,
@ -880,8 +813,9 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
# Insert new rule
lb_rules = self._add_rule_in_position(body, lb_rule, position)
return self._update_helper(
virtual_server_id, rules=lb_rules, vs_data=body, tenant=tenant)
return self._update(
virtual_server_id=virtual_server_id,
rules=lb_rules, vs_data=body, tenant=tenant)
def remove_lb_rule(self, virtual_server_id, lb_rule_name,
tenant=constants.POLICY_INFRA_TENANT):
@ -891,8 +825,9 @@ class NsxPolicyLoadBalancerVirtualServerAPI(NsxPolicyResourceBase):
lb_rules = body.get('rules', [])
lb_rules = [r for r in lb_rules if (r.get('display_name') !=
lb_rule_name)]
return self._update_helper(
virtual_server_id, vs_data=body, rules=lb_rules, tenant=tenant)
return self._update(
virtual_server_id=virtual_server_id, vs_data=body,
rules=lb_rules, tenant=tenant)
def get_path(self, virtual_server_id,
tenant=constants.POLICY_INFRA_TENANT):