Support PATCH partial updates

Change-Id: I4bb34bccc0c95e985ab10190fc11ed21d0664be8
This commit is contained in:
Adit Sarfaty 2019-08-01 12:29:54 +03:00
parent 759fab944d
commit e93309ff86
7 changed files with 37 additions and 26 deletions

View File

@ -29,7 +29,7 @@ class TestPolicyApi(nsxlib_testcase.NsxClientTestCase):
super(TestPolicyApi, self).setUp()
def assert_json_call(self, method, client, url, data=None):
def assert_json_call(self, method, client, url, data=None, headers=None):
url = BASE_POLICY_URI + url
return super(TestPolicyApi, self).assert_json_call(
method, client, url, data=data)
method, client, url, data=data, headers=headers)

View File

@ -913,7 +913,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[lb_rule])
self.assert_called_with_def(update_call, expected_def)
@ -941,7 +940,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[lb_rule,
{'display_name': 'xx'},
{'display_name': 'yy'}])
@ -969,7 +967,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'},
lb_rule])
@ -998,7 +995,7 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id, name=vs_name,
virtual_server_id=vs_obj_id,
rules=[{'display_name': 'xx'},
{'display_name': 'yy'},
lb_rule])
@ -1026,7 +1023,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
rule_match_strategy, rule_phase)
expected_def = lb_defs.LBVirtualServerDef(
name=vs_name,
virtual_server_id=vs_obj_id,
rules=[{'display_name': 'xx'},
lb_rule,
@ -1044,7 +1040,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
self.resourceApi.update_lb_rule(vs_obj_id, 'xx', actions='22')
expected_def = lb_defs.LBVirtualServerDef(
name=vs_name,
virtual_server_id=vs_obj_id,
rules=[{'display_name': 'xx', 'actions': '22'},
{'display_name': 'yy'}])
@ -1063,7 +1058,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
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)
@ -1079,7 +1073,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
expected_def = lb_defs.LBVirtualServerDef(
virtual_server_id=vs_obj_id,
name=vs_name,
rules=[{'display_name': 'yy'}])
self.assert_called_with_def(update_call, expected_def)

View File

@ -18,6 +18,7 @@ import mock
from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase
from vmware_nsxlib.tests.unit.v3.policy import policy_testcase
from vmware_nsxlib.tests.unit.v3 import test_client
from vmware_nsxlib.v3 import exceptions as nsxlib_exc
from vmware_nsxlib.v3 import nsx_constants
from vmware_nsxlib.v3 import policy
@ -39,7 +40,7 @@ class NsxPolicyLibTestCase(policy_testcase.TestPolicyApi):
# Mock the nsx-lib for the passthrough api
# 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"
mock_lib.return_value.get_version.return_value = "3.0.0"
self.policy_lib = policy.NsxPolicyLib(nsxlib_config)
self.policy_api = self.policy_lib.policy_api
@ -216,7 +217,8 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
self.assert_json_call('PATCH', self.client,
'%s/domains/%s' % (TEST_TENANT, domain_id),
data=expected_body)
data=expected_body,
headers=test_client.PARTIAL_UPDATE_HEADERS)
class TestPolicyGroup(NsxPolicyLibTestCase):
@ -595,7 +597,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
'%s/domains/%s/groups/%s' % (TEST_TENANT,
domain_id,
group_id),
data=expected_body)
data=expected_body,
headers=test_client.PARTIAL_UPDATE_HEADERS)
def test_get_realized(self):
domain_id = 'd1'
@ -2407,6 +2410,7 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
def setUp(self, *args, **kwargs):
super(TestPolicyTier1, self).setUp(*args, **kwargs)
self.resourceApi = self.policy_lib.tier1
self.partial_updates = True
def test_create(self):
name = 'test'
@ -2575,9 +2579,10 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
expected_def = core_defs.Tier1Def(
tier1_id=obj_id,
name=rtr_name,
route_advertisement=new_adv,
tenant=TEST_TENANT)
if not self.partial_updates:
expected_def.attrs['name'] = rtr_name
self.assert_called_with_def(
update_call, expected_def)
@ -2607,10 +2612,11 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
expected_def = core_defs.Tier1Def(
tier1_id=obj_id,
name=rtr_name,
route_advertisement=new_adv,
tier0=tier0,
tenant=TEST_TENANT)
if not self.partial_updates:
expected_def.attrs['name'] = rtr_name
self.assert_called_with_def(
update_call, expected_def)
@ -3000,6 +3006,8 @@ class TestPolicyTier1NoPassthrough(TestPolicyTier1):
def setUp(self, *args, **kwargs):
super(TestPolicyTier1NoPassthrough, self).setUp(
allow_passthrough=False)
# No passthrough also means no partial updates
self.partial_updates = False
def test_update_transport_zone(self):
# Will not work without passthrough api

View File

@ -39,6 +39,13 @@ JSON_DFT_ACCEPT_HEADERS = {
'Cookie': 'JSESSIONID=%s;' % nsxlib_testcase.JSESSIONID
}
PARTIAL_UPDATE_HEADERS = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Cookie': 'JSESSIONID=%s;' % nsxlib_testcase.JSESSIONID,
'nsx-enable-partial-patch': 'true'
}
def _headers(**kwargs):
headers = copy.copy(DFT_ACCEPT_HEADERS)

View File

@ -161,11 +161,10 @@ class NsxPolicyLib(lib.NsxLibBase):
if (feature == nsx_constants.FEATURE_ENS_WITH_QOS):
return True
# TODO(asarfaty): Uncomment this once partial updates are supported
# if (version.LooseVersion(self.get_version()) >=
# version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
# if feature == nsx_constants.FEATURE_PARTIAL_UPDATES:
# return True
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
if feature == nsx_constants.FEATURE_PARTIAL_UPDATES:
return True
return (feature == nsx_constants.FEATURE_NSX_POLICY)

View File

@ -1852,7 +1852,7 @@ class NsxPolicyApi(object):
def partial_updates_supported(self):
return self.partial_updates
def create_or_update(self, resource_def):
def create_or_update(self, resource_def, partial_updates=False):
"""Create or update a policy object.
This api will update an existing object, or create a new one if it
@ -1864,7 +1864,10 @@ class NsxPolicyApi(object):
self.cache.remove(path)
body = resource_def.get_obj_dict()
self.client.patch(path, body)
headers = None
if partial_updates:
headers = {'nsx-enable-partial-patch': 'true'}
self.client.patch(path, body, headers=headers)
def create_with_parent(self, parent_def, resource_def):
path = parent_def.get_resource_path()

View File

@ -147,14 +147,16 @@ class NsxPolicyResourceBase(object):
if self.policy_api.partial_updates_supported():
policy_def = self._init_def(**kwargs)
partial_updates = True
else:
policy_def = self._get_and_update_def(**kwargs)
partial_updates = False
if policy_def.bodyless():
# Nothing to update - only keys provided in kwargs
return
self.policy_api.create_or_update(policy_def)
self.policy_api.create_or_update(
policy_def, partial_updates=partial_updates)
@staticmethod
def _init_obj_uuid(obj_uuid):
@ -969,8 +971,7 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase):
self.update(tier1_id,
route_advertisement=route_adv,
tier0=tier0,
tenant=tenant,
current_body=tier1_dict)
tenant=tenant)
def add_advertisement_rule(
self, tier1_id, name, action=None, prefix_operator=None,