Merge "Support inventory APIs"
This commit is contained in:
commit
0d173ec3f5
@ -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
|
||||
|
@ -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
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user