Kessel Asset Inventory APIs
This document does not supersede any information in the API specification. This is meant to help explain why the API works the way that it does. In other words, think of the API specification as the API “syntax” documentation and this as the API “semantics” documentation.
Notes:
- This document talks about the ability to have multiple Reporters for the same resource type. This is to help explain some of the structure. However, this will not be supported initially. Support for multiple reporters of the same resource type will be added at a future release.
- At the time of this writing, a GET method is not defined for Asset Inventory
Reporting a New Resource to Asset Inventory
Section titled “Reporting a New Resource to Asset Inventory”A management service creates, modifies or deletes a managed resource in its local inventory. To aid in the integration of the Red Hat Hybrid Cloud Management solution, they will report all of these operations to the Kessel via the Asset Inventory APIs. With the Asset Inventory APIs, these services are referenced as Reporters.
When a new resource is created in the Reporter’s private inventory, the Reporter will issue a POST to Kessel. The endpoint is structured as follows: /api/inventory/{api-version}/resources/{resource-type}
.
An example would be: /api/inventory/v1beta1/resources/k8s-clusters
.
The Request Body
Section titled “The Request Body”The request body is the resource type. This top level json object is comprised of 3 objects: metadata, reporter_data and resource_data, i.e.
{ "resource_type":{ "metadata":{}, "reporter_data":{}, "resource_data":{} }}
Required data is marked with an asterisk (*).
Metadata
Section titled “Metadata”This object represents the attributes that are common for all resources, no matter the type. The information that a reporter provides for this object is:
- org_id*
- workspace_id
- labels
Most of the metadata is generated by the Asset Inventory service, i.e.
- id - this is the GUID for the resource instance
- resource_type - this is derived from the top level object of the request body.
- created_at
- updated_at
- deleted_at
Reporter_data
Section titled “Reporter_data”This object represents data that is specific to the reporter who called the Asset Inventory API in order to report on this resource. The information that a reporter provides for this object is:
- reporter_type*
- reporter_version
- local_resource_id*
- console_href
- api_href
Similar to the metadata, some of this information is created by the Asset Inventory service, i.e.
- reporter_instance_id - created from attributes in the authentication token
The reporter_type and reporter_version, along with the system generated reporter_instance_id, help to identify the reporter.
The local_resource_id is the identification of the resource within the Reporter’s domain.
The two hrefs are used if a consumer of an event (or query) from Asset Inventory and they wanted to consume additional domain-specific information about the resource. For example, ACM reports on a cluster. One could use an href to query into ACM to find out some health information of that cluster.
NOTE: These hrefs only provide how to access this information. One still has to have the appropriate credentials of the Reporter in order to access the data referenced by these URLs.
Multiple Reporters
Section titled “Multiple Reporters”The above talks about the reporter_data object from a request body perspective, i.e. what a single reporter passes in on an API call. In reality, there can be multiple reporters for the same resource instance. For example, ACM can report on the creation of a cluster. ACS can report on the security monitoring of a cluster.
Internally, the reporter_data is an array, keeping track of this information per reporter. On a query for a resource instance, i.e. GET method, the resultset would include the full array of reporters for this resource instance.
Resource_data
Section titled “Resource_data”This object represents data that is specific to the resource_type for this resource instance. For example, if the resource was of type k8sCluster, this would have attributes that are specific to a kube cluster. If this was a RHEL host, this would have attributes that were specific to a RHEL host.
This information is passed in from the Reporter. There are no attributes in which the Asset Inventory Service creates.
Resource Deduplication
Section titled “Resource Deduplication”Given that a resource can be reported by more than one Reporter, Asset Inventory needs to determine if the resource from one Reporter (data source) is the same as a resource from another Reporter (data source). Thus, there has to be defined comparison points in which the correlation algorithm leverages for this determination. The more comparison points, the better the deduplication results will be.
The comparison points are unique to each resource type. For example, for k8sClusters, the kube_vendor and the external_cluster_id will be used for correlation. A Reporter might report on a cluster with kube_vendor = OpenShift and external_cluster_id = 44028166-3196-4d96-8e60-b07249eb95d1. Given that the external_cluster_id is the openshift guid, any other Reporter that reports on this same OpenShift cluster would correlate with this guid.
From a Reporter’s perspective, the result of a valid POST will be a return code of 200, even if the resource was already reported from another Reporter. If there are more than one Reporter of the resource, an array of Reporters will be kept for this resource. Thus, on a query (GET), one can determine who all reported on the same resource.
Any subsequent POSTs or PUTs for a resource will update the attributes for that resource. In other words, the values for the attributes of the latest update will supersede previous values. For example, if Reporter-A POSTed a policy with an attribute of disabled=true and some time later Reporter-B POSTed the same policy but with the attribute of disabled=false, the current attribute for the resource in Asset Inventory would be disabled=false.
If the Reporter issued a POST for a resource in which it was the Reporter that created the resource prior, they would get a 405, i.e. Method Not Allowed. They would be expected to be issuing a PUT to update the resource in which they originally reported.
Resource Lifecycle
Section titled “Resource Lifecycle”The above talked about reporting data about a new resource to the Asset Inventory service. These resources can change and the metadata which is stored in Asset Inventory needs to reflect the current state of the resources. This can be anything from a label change, a workspace change or a resource-specific attribute change, e.g. cluster_status.
Reporters will send a PUT request to the Asset Inventory service, pointing to the URI of the specific resource to update with the data in the request body. When the API server receives the PUT request, it checks if the resource already exists. If the resource exists, then the API updates the resource with the data enclosed in the PUT request. If the resource doesn’t exist, then the API creates that resource with the data supplied.
Similarly, when a Management Domain service deletes the resource, or takes it out of management, the Reporting for that Management Domain will send a DELETE request to the Asset Inventory service pointing to the URI of the specific resource to delete.
Resource Identification
Section titled “Resource Identification”Typically in a RESTful api, the client will issue a POST and the service will return a REST ID for the newly created resource. This ID is then used for subsequent API calls, e.g. PUTs, DELETEs and GETs to reference this resource. This approach requires a Reporter to persist the ID; thus, increasing the cost of adoption/exploitation. Thus, as an alternative, a Reporter can use their existing knowledge in order to reference the resource. In order to get to a unique identifier which is an alias of the ID, we use the following:
- A Reporter has an identifier that is unique within their realm. This identifier is the local_reource_id.
- If you scope this id with the reporter_type, i.e. reporter_type:local_resource_id, you avoid collisions with other reporter types.
- However, there can be multiple instances of the same reporter type which could introduce collisions on this identifier. By introducing a unique identifier for the
Reporter instance, i.e. the reporter_instance_id, you now have a unique identifier, i.e. reporter_type:reporter_instance_id:local_resource_id.
Given the above, a reporter can use reporter_type:local_resource_id for PUTs and DELETEs. The Asset Inventory service will include the reporter_instance_id in order to map to the service’s unique ID. The reporter_instance_id will be loaded from the identity of the caller, it won’t be required as a separate input.
Reporting a New Relationship Between 2 Resources
Section titled “Reporting a New Relationship Between 2 Resources”In addition to maintaining metadata about managed resources, Asset Inventory maintains information about relationships between 2 managed resources. These relationships can have attributes associated with the relationship itself that are in addition to the attributes that are associated with either the subject or object resources in the relationship.
For example, there is a k8s-policy (foo) in Asset Inventory with its set of attributes. In addition, there is a k8s-cluster (bar) in Asset Inventory with its own set of attributes. One can create a relationship between foo and bar, including such attributes as status=compliant.
When a new resource relationship is created in the Reporter’s private inventory, the Reporter will issue a POST to Kessel. The endpoint are structured as follows:
/api/inventory/{api-version}/resource-relationships/{relationship-type}
where relationship-type is defined as “subject_relationship_object”.
An example would be: /api/inventory/v1beta1/resource-relationships/k8s-policy_is-propagated-to_k8s-cluster
The subject and object resources must both exist in Asset Inventory for the POST/PUT to be valid.
The Request Body
Section titled “The Request Body”The JSON for the resource-relationship is similar to resources, i.e.
{ "resource_relationship_type" : { "metadata": { }, "reporter_data": { }, "relationship_data": { } }}
Metadata
Section titled “Metadata”This object represents the attributes that are common for all resource relationships, no matter the type. The information that a reporter provides for this object is:
- org_id*
Most of the metadata is generated by the Asset Inventory service, i.e.
- id - this is the GUID for the relationship instance
- relationship_type - this is derived from the top level object of the request body.
- created_at
- updated_at
- deleted_at
Reporter_data
Section titled “Reporter_data”This object represents data that is specific to the reporter who called the Asset Inventory API in order to report on this relationship. The report_data differs in that there are no hrefs provided for the relationship. In addition, the Reporter must pass a local_resource_id for both the subject and the object resources in the relationship.
- reporter_type*
- reporter_version
- subject_local_resource_id*
- object_local_resource_id*
Similar to the metadata, some of this information is created by the Asset Inventory service, i.e.
- reporter_instance_id - created from attributes in the authentication token
Reporter_data
Section titled “Reporter_data”Multiple Reporters
Section titled “Multiple Reporters”The semantics of multiple reporters is the same as with resources.
Relationship_data
Section titled “Relationship_data”Similar to resources, the attributes defined by this object vary by the resource_relationship_type.
Relationship Lifecycle
Section titled “Relationship Lifecycle”The lifecycle for a resource_relationship is the same as with a resource itself. The main difference is that when one of the resources defined in a relationship, i.e. subject_resource or object_resource, is deleted, all relationships for that resource will be deleted as well.