Support inventory APIs

For NCP, Inventory service exposes list, update and delete APIs.

Change-Id: Id312347c2e02c1ec3558031989da10aeafeaabcf
This commit is contained in:
vicky liu 2019-03-19 15:26:30 +08:00
parent 12a0b64171
commit 1957a48809
4 changed files with 142 additions and 0 deletions

View File

@ -2144,6 +2144,66 @@ class TestNsxlibClusterNodesConfigTestCase(BaseTestResource):
test_constants.FAKE_MANAGER_IP2], result)
class InventoryTestCase(BaseTestResource):
CONTAINER_CLUSTER = "k8s-cluster-1"
def setUp(self):
super(InventoryTestCase, self).setUp(resources.Inventory)
def test_get_resource(self):
mocked_resource = self.get_mocked_resource()
mocked_resource.get('ContainerCluster', self.CONTAINER_CLUSTER)
base_url = 'https://1.2.3.4/api/v1/fabric/container-clusters'
surfix = '/%s' % self.CONTAINER_CLUSTER
test_client.assert_json_call(
'get', mocked_resource,
base_url + surfix,
headers=self.default_headers())
def test_list_all(self):
mocked_resource = self.get_mocked_resource()
mocked_resource.list(
self.CONTAINER_CLUSTER,
'ContainerApplication')
base_url = 'https://1.2.3.4/api/v1/fabric/container-applications'
surfix = '?cluster-id=%s' % self.CONTAINER_CLUSTER
test_client.assert_json_call(
'get', mocked_resource,
base_url + surfix,
headers=self.default_headers())
def test_delete_resource(self, extra_params=None):
mocked_resource = self.get_mocked_resource()
mocked_resource.delete('ContainerCluster', self.CONTAINER_CLUSTER)
base_url = 'https://1.2.3.4/api/v1/fabric/container-clusters'
surfix = '/%s' % self.CONTAINER_CLUSTER
test_client.assert_json_call(
'delete', mocked_resource,
base_url + surfix,
headers=self.default_headers())
def test_update(self):
mocked_resource = self.get_mocked_resource()
body = {}
update_dict = {'external_id': '1234',
'resource_type': 'Application',
'name': 'service-1',
'labels': [{'key': 'key-1', 'value': 'value-1'}]}
mocked_resource.update(
self.CONTAINER_CLUSTER, [('CREATE', update_dict)])
item = {}
item["object_update_type"] = 'CREATE'
item["container_object"] = update_dict
body = {"container_inventory_objects": [item]}
base_url = 'https://1.2.3.4/api/v1/inventory/container/'
surfix = '%s?action=updates' % self.CONTAINER_CLUSTER
test_client.assert_json_call(
'post', mocked_resource,
base_url + surfix,
data=jsonutils.dumps(body, sort_keys=True),
headers=self.default_headers())
class DummyCachedResource(utils.NsxLibApiBase):
@property

View File

@ -163,6 +163,12 @@ class NsxLib(lib.NsxLibBase):
return node.get('export_type') is 'RESTRICTED'
def feature_supported(self, feature):
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_2_5_0)):
# features available since 2.5
if (feature == nsx_constants.FEATURE_CONTAINER_CLUSTER_INVENTORY):
return True
if (version.LooseVersion(self.get_version()) >=
version.LooseVersion(nsx_constants.NSX_VERSION_2_4_0)):
# Features available since 2.4

View File

@ -145,6 +145,7 @@ NSX_VERSION_2_1_0 = '2.1.0'
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_3_0_0 = '3.0.0'
# Features available depending on the NSX Manager backend version
@ -170,3 +171,6 @@ FEATURE_ENABLE_STANDBY_RELOCATION = 'Router Enable standby relocation'
# Features available depending on the Policy Manager backend version
FEATURE_NSX_POLICY = 'NSX Policy'
FEATURE_NSX_POLICY_NETWORKING = 'NSX Policy Networking'
# FEATURE available depending on Inventory service backend version
FEATURE_CONTAINER_CLUSTER_INVENTORY = 'Container Cluster Inventory'

View File

@ -705,3 +705,75 @@ class NsxlibClusterNodesConfig(utils.NsxLibApiBase):
manager_ips.append(list_addr['ip_address'])
return manager_ips
class Inventory(utils.NsxLibApiBase):
"""REST APIs to support inventory service."""
RESOURCES_PATH = {"ContainerCluster": "container-clusters",
"ContainerProject": "container-projects",
"ContainerApplication": "container-applications",
"ContainerApplicationInstance":
"container-application-instances",
"ContainerClusterNode": "container-cluster-nodes",
"ContainerNetworkPolicy": "container-network-policies",
"ContainerIngressPolicy": "container-ingress-policies"}
SEGMENT_URI = 'fabric'
SEGMENT_URI_FOR_UPDATE = 'inventory/container'
@property
def uri_segment(self):
# only serves for get, list and delete. For batch update,
# another base url is used. The reason is update API is internal.
return self.SEGMENT_URI
@property
def resource_type(self):
return 'Inventory'
def update(self, cluster_id, updates):
"""This method supports multiple updates in a batching way."""
items = []
for update_type, update_object in updates:
item = {}
item["object_update_type"] = update_type
item["container_object"] = update_object
items.append(item)
body = {"container_inventory_objects": items}
request_url = "%s/%s?action=updates" % (
self.SEGMENT_URI_FOR_UPDATE, cluster_id)
return self.client.url_post(request_url, body)
def get(self, resource_type, resource_id):
if not resource_type:
msg = "null resource type is not supported"
raise exceptions.ResourceNotFound(details=msg)
request_url = "%s/%s" % (
self.get_path(self._get_path_for_resource(resource_type)),
resource_id)
return self.client.url_get(request_url)
def list(self, cluster_id, resource_type):
if not resource_type:
msg = "null resource type is not supported"
raise exceptions.ResourceNotFound(details=msg)
request_url = "%s?cluster-id=%s" % (
self.get_path(self._get_path_for_resource(resource_type)),
cluster_id)
return self.client.url_get(request_url)
def delete(self, resource_type, resource_id):
if not resource_type:
msg = "null resource type is not supported"
raise exceptions.ResourceNotFound(details=msg)
request_url = "%s/%s" % (
self.get_path(self._get_path_for_resource(resource_type)),
resource_id)
return self.client.url_delete(request_url)
def _get_path_for_resource(self, resource_type):
path = self.RESOURCES_PATH.get(resource_type)
if not path:
msg = "backend resource %s is not supported" % resource_type
raise exceptions.ResourceNotFound(details=msg)
return path