Support PATCH partial updates
Change-Id: I4bb34bccc0c95e985ab10190fc11ed21d0664be8
(cherry picked from commit e93309ff86
)
This commit is contained in:
parent
b4cd5825be
commit
1cbb8d815c
|
@ -29,7 +29,7 @@ class TestPolicyApi(nsxlib_testcase.NsxClientTestCase):
|
||||||
|
|
||||||
super(TestPolicyApi, self).setUp()
|
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
|
url = BASE_POLICY_URI + url
|
||||||
return super(TestPolicyApi, self).assert_json_call(
|
return super(TestPolicyApi, self).assert_json_call(
|
||||||
method, client, url, data=data)
|
method, client, url, data=data, headers=headers)
|
||||||
|
|
|
@ -852,7 +852,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
name=vs_name,
|
|
||||||
rules=[lb_rule])
|
rules=[lb_rule])
|
||||||
self.assert_called_with_def(update_call, expected_def)
|
self.assert_called_with_def(update_call, expected_def)
|
||||||
|
|
||||||
|
@ -880,7 +879,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
name=vs_name,
|
|
||||||
rules=[lb_rule,
|
rules=[lb_rule,
|
||||||
{'display_name': 'xx'},
|
{'display_name': 'xx'},
|
||||||
{'display_name': 'yy'}])
|
{'display_name': 'yy'}])
|
||||||
|
@ -908,7 +906,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
name=vs_name,
|
|
||||||
rules=[{'display_name': 'xx'},
|
rules=[{'display_name': 'xx'},
|
||||||
{'display_name': 'yy'},
|
{'display_name': 'yy'},
|
||||||
lb_rule])
|
lb_rule])
|
||||||
|
@ -937,7 +934,7 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
rule_match_strategy, rule_phase)
|
rule_match_strategy, rule_phase)
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id, name=vs_name,
|
virtual_server_id=vs_obj_id,
|
||||||
rules=[{'display_name': 'xx'},
|
rules=[{'display_name': 'xx'},
|
||||||
{'display_name': 'yy'},
|
{'display_name': 'yy'},
|
||||||
lb_rule])
|
lb_rule])
|
||||||
|
@ -965,7 +962,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
rule_match_strategy, rule_phase)
|
rule_match_strategy, rule_phase)
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
name=vs_name,
|
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
rules=[{'display_name': 'xx'},
|
rules=[{'display_name': 'xx'},
|
||||||
lb_rule,
|
lb_rule,
|
||||||
|
@ -983,7 +979,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
self.resourceApi.update_lb_rule(vs_obj_id, 'xx', actions='22')
|
self.resourceApi.update_lb_rule(vs_obj_id, 'xx', actions='22')
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
name=vs_name,
|
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
rules=[{'display_name': 'xx', 'actions': '22'},
|
rules=[{'display_name': 'xx', 'actions': '22'},
|
||||||
{'display_name': 'yy'}])
|
{'display_name': 'yy'}])
|
||||||
|
@ -1002,7 +997,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
name=vs_name,
|
|
||||||
rules=[{'display_name': 'yy'},
|
rules=[{'display_name': 'yy'},
|
||||||
{'display_name': 'xx', 'actions': '22'}])
|
{'display_name': 'xx', 'actions': '22'}])
|
||||||
self.assert_called_with_def(update_call, expected_def)
|
self.assert_called_with_def(update_call, expected_def)
|
||||||
|
@ -1018,7 +1012,6 @@ class TestPolicyLBVirtualServer(test_resources.NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = lb_defs.LBVirtualServerDef(
|
expected_def = lb_defs.LBVirtualServerDef(
|
||||||
virtual_server_id=vs_obj_id,
|
virtual_server_id=vs_obj_id,
|
||||||
name=vs_name,
|
|
||||||
rules=[{'display_name': 'yy'}])
|
rules=[{'display_name': 'yy'}])
|
||||||
self.assert_called_with_def(update_call, expected_def)
|
self.assert_called_with_def(update_call, expected_def)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import mock
|
||||||
|
|
||||||
from vmware_nsxlib.tests.unit.v3 import nsxlib_testcase
|
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.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 exceptions as nsxlib_exc
|
||||||
from vmware_nsxlib.v3 import nsx_constants
|
from vmware_nsxlib.v3 import nsx_constants
|
||||||
from vmware_nsxlib.v3 import policy
|
from vmware_nsxlib.v3 import policy
|
||||||
|
@ -39,7 +40,7 @@ class NsxPolicyLibTestCase(policy_testcase.TestPolicyApi):
|
||||||
# Mock the nsx-lib for the passthrough api
|
# Mock the nsx-lib for the passthrough api
|
||||||
# TODO(annak): move version forward with backend releases
|
# TODO(annak): move version forward with backend releases
|
||||||
with mock.patch("vmware_nsxlib.v3.NsxLib") as mock_lib:
|
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_lib = policy.NsxPolicyLib(nsxlib_config)
|
||||||
|
|
||||||
self.policy_api = self.policy_lib.policy_api
|
self.policy_api = self.policy_lib.policy_api
|
||||||
|
@ -216,7 +217,8 @@ class TestPolicyDomain(NsxPolicyLibTestCase):
|
||||||
|
|
||||||
self.assert_json_call('PATCH', self.client,
|
self.assert_json_call('PATCH', self.client,
|
||||||
'%s/domains/%s' % (TEST_TENANT, domain_id),
|
'%s/domains/%s' % (TEST_TENANT, domain_id),
|
||||||
data=expected_body)
|
data=expected_body,
|
||||||
|
headers=test_client.PARTIAL_UPDATE_HEADERS)
|
||||||
|
|
||||||
|
|
||||||
class TestPolicyGroup(NsxPolicyLibTestCase):
|
class TestPolicyGroup(NsxPolicyLibTestCase):
|
||||||
|
@ -595,7 +597,8 @@ class TestPolicyGroup(NsxPolicyLibTestCase):
|
||||||
'%s/domains/%s/groups/%s' % (TEST_TENANT,
|
'%s/domains/%s/groups/%s' % (TEST_TENANT,
|
||||||
domain_id,
|
domain_id,
|
||||||
group_id),
|
group_id),
|
||||||
data=expected_body)
|
data=expected_body,
|
||||||
|
headers=test_client.PARTIAL_UPDATE_HEADERS)
|
||||||
|
|
||||||
def test_get_realized(self):
|
def test_get_realized(self):
|
||||||
domain_id = 'd1'
|
domain_id = 'd1'
|
||||||
|
@ -2385,6 +2388,7 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
|
||||||
def setUp(self, *args, **kwargs):
|
def setUp(self, *args, **kwargs):
|
||||||
super(TestPolicyTier1, self).setUp(*args, **kwargs)
|
super(TestPolicyTier1, self).setUp(*args, **kwargs)
|
||||||
self.resourceApi = self.policy_lib.tier1
|
self.resourceApi = self.policy_lib.tier1
|
||||||
|
self.partial_updates = True
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
name = 'test'
|
name = 'test'
|
||||||
|
@ -2551,9 +2555,10 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = core_defs.Tier1Def(
|
expected_def = core_defs.Tier1Def(
|
||||||
tier1_id=obj_id,
|
tier1_id=obj_id,
|
||||||
name=rtr_name,
|
|
||||||
route_advertisement=new_adv,
|
route_advertisement=new_adv,
|
||||||
tenant=TEST_TENANT)
|
tenant=TEST_TENANT)
|
||||||
|
if not self.partial_updates:
|
||||||
|
expected_def.attrs['name'] = rtr_name
|
||||||
|
|
||||||
self.assert_called_with_def(
|
self.assert_called_with_def(
|
||||||
update_call, expected_def)
|
update_call, expected_def)
|
||||||
|
@ -2583,10 +2588,11 @@ class TestPolicyTier1(NsxPolicyLibTestCase):
|
||||||
|
|
||||||
expected_def = core_defs.Tier1Def(
|
expected_def = core_defs.Tier1Def(
|
||||||
tier1_id=obj_id,
|
tier1_id=obj_id,
|
||||||
name=rtr_name,
|
|
||||||
route_advertisement=new_adv,
|
route_advertisement=new_adv,
|
||||||
tier0=tier0,
|
tier0=tier0,
|
||||||
tenant=TEST_TENANT)
|
tenant=TEST_TENANT)
|
||||||
|
if not self.partial_updates:
|
||||||
|
expected_def.attrs['name'] = rtr_name
|
||||||
|
|
||||||
self.assert_called_with_def(
|
self.assert_called_with_def(
|
||||||
update_call, expected_def)
|
update_call, expected_def)
|
||||||
|
@ -2902,6 +2908,8 @@ class TestPolicyTier1NoPassthrough(TestPolicyTier1):
|
||||||
def setUp(self, *args, **kwargs):
|
def setUp(self, *args, **kwargs):
|
||||||
super(TestPolicyTier1NoPassthrough, self).setUp(
|
super(TestPolicyTier1NoPassthrough, self).setUp(
|
||||||
allow_passthrough=False)
|
allow_passthrough=False)
|
||||||
|
# No passthrough also means no partial updates
|
||||||
|
self.partial_updates = False
|
||||||
|
|
||||||
def test_update_transport_zone(self):
|
def test_update_transport_zone(self):
|
||||||
# Will not work without passthrough api
|
# Will not work without passthrough api
|
||||||
|
|
|
@ -39,6 +39,13 @@ JSON_DFT_ACCEPT_HEADERS = {
|
||||||
'Cookie': 'JSESSIONID=%s;' % nsxlib_testcase.JSESSIONID
|
'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):
|
def _headers(**kwargs):
|
||||||
headers = copy.copy(DFT_ACCEPT_HEADERS)
|
headers = copy.copy(DFT_ACCEPT_HEADERS)
|
||||||
|
|
|
@ -156,11 +156,10 @@ class NsxPolicyLib(lib.NsxLibBase):
|
||||||
if (feature == nsx_constants.FEATURE_ENS_WITH_QOS):
|
if (feature == nsx_constants.FEATURE_ENS_WITH_QOS):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# TODO(asarfaty): Uncomment this once partial updates are supported
|
if (version.LooseVersion(self.get_version()) >=
|
||||||
# if (version.LooseVersion(self.get_version()) >=
|
version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
|
||||||
# version.LooseVersion(nsx_constants.NSX_VERSION_3_0_0)):
|
if feature == nsx_constants.FEATURE_PARTIAL_UPDATES:
|
||||||
# if feature == nsx_constants.FEATURE_PARTIAL_UPDATES:
|
return True
|
||||||
# return True
|
|
||||||
|
|
||||||
return (feature == nsx_constants.FEATURE_NSX_POLICY)
|
return (feature == nsx_constants.FEATURE_NSX_POLICY)
|
||||||
|
|
||||||
|
|
|
@ -1764,7 +1764,7 @@ class NsxPolicyApi(object):
|
||||||
def partial_updates_supported(self):
|
def partial_updates_supported(self):
|
||||||
return self.partial_updates
|
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.
|
"""Create or update a policy object.
|
||||||
|
|
||||||
This api will update an existing object, or create a new one if it
|
This api will update an existing object, or create a new one if it
|
||||||
|
@ -1776,7 +1776,10 @@ class NsxPolicyApi(object):
|
||||||
self.cache.remove(path)
|
self.cache.remove(path)
|
||||||
body = resource_def.get_obj_dict()
|
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):
|
def create_with_parent(self, parent_def, resource_def):
|
||||||
path = parent_def.get_resource_path()
|
path = parent_def.get_resource_path()
|
||||||
|
|
|
@ -147,14 +147,16 @@ class NsxPolicyResourceBase(object):
|
||||||
|
|
||||||
if self.policy_api.partial_updates_supported():
|
if self.policy_api.partial_updates_supported():
|
||||||
policy_def = self._init_def(**kwargs)
|
policy_def = self._init_def(**kwargs)
|
||||||
|
partial_updates = True
|
||||||
else:
|
else:
|
||||||
policy_def = self._get_and_update_def(**kwargs)
|
policy_def = self._get_and_update_def(**kwargs)
|
||||||
|
partial_updates = False
|
||||||
|
|
||||||
if policy_def.bodyless():
|
if policy_def.bodyless():
|
||||||
# Nothing to update - only keys provided in kwargs
|
# Nothing to update - only keys provided in kwargs
|
||||||
return
|
return
|
||||||
|
self.policy_api.create_or_update(
|
||||||
self.policy_api.create_or_update(policy_def)
|
policy_def, partial_updates=partial_updates)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _init_obj_uuid(obj_uuid):
|
def _init_obj_uuid(obj_uuid):
|
||||||
|
@ -994,8 +996,7 @@ class NsxPolicyTier1Api(NsxPolicyResourceBase):
|
||||||
self.update(tier1_id,
|
self.update(tier1_id,
|
||||||
route_advertisement=route_adv,
|
route_advertisement=route_adv,
|
||||||
tier0=tier0,
|
tier0=tier0,
|
||||||
tenant=tenant,
|
tenant=tenant)
|
||||||
current_body=tier1_dict)
|
|
||||||
|
|
||||||
def add_advertisement_rule(
|
def add_advertisement_rule(
|
||||||
self, tier1_id, name, action=None, prefix_operator=None,
|
self, tier1_id, name, action=None, prefix_operator=None,
|
||||||
|
|
Loading…
Reference in New Issue