Design Guidelines to create a new ODA Component
ODA Components are self-contained, independently deployable software modules that confirm to the TM Forum Open Digital Architecture.
The business drivers and conceptual model for ODA Components is described in IG1171 ODA Component Definition.
The ODA Component concept builds on top of open standards like Docker and Kubernetes, and adds Telco-domain knowledge and meta-data. The starting point for building an ODA component is containerized, micro-service software described in a kubernetes manifest YAML file. To turn this into an ODA Component we will:
Add meta-data to the Kubernetes manifest describing the Core Function, Notification/Reporting, Security Function and Management Function of the software component.
Add labels to all the standard Kubernetes resources to label them as belonging to the component.
Test the deployment of the Component in an operating platform that has the ODA Canvas installed (for example the TM FOrum Open-Digital Lab). See the Getting Started section to see how to install the ODA Canvas onto a kubernetes cluster environmnet.
Step 1: ODA-Component Metadata
This guide has been updated to conform to the v1beta2 component specification.
The ODA-Component metadata contains all the Telco-domain knowledge that makes the component a self-describing deployable software module. From IG1171 ODA Component Definition, this meta-data describes the Open-APIs, event data schemas as well as security and management & operations for the component.
The meta-data is defined using a Kubernetes CustomResourceDefinition. This allows us to extend the Kubernetes API with our custom-defined schema for Telco meta-data. The CustomResourceDefinition schema is in the github.com/tmforum-oda/oda-canvas-charts repository.
There is an example of the metadata for the productcatalog example component broken-down into sections below:
apiVersion: oda.tmforum.org/v1beta2
kind: component
metadata:
name: vodafone-productcatalog
labels:
oda.tmforum.org/componentName: vodafone-productcatalog
oda.tmforum.org/funtionalBlockName: CoreCommerce
This is the header information for the component, specifying the version of the CRD (Custom Resource Definition) that it is using, and providing a name and a label for the component and a label describing which functional block the component belongs to.
spec:
name: ProductCatalogManagement
functionalBlock: CoreCommerce
id: TMFC001
status: specified
version: 1.2.1
description: "Simple Product Catalog ODA-Component from Open-API reference implementation."
publicationDate: 2023-08-18
maintainers:
- name: Lester Thomas
email: lester.thomas@vodafone.com
owners:
- name: Lester Thomas
email: lester.thomas@vodafone.com
This next section starts the spec for the component.
The type allows us to specify that this is an implementation of a standard type of Component. If the type and version match one of the Golden Components then the Component CTK will test that the functional capability matches the requirements from that Golden Component. For a full list of all the standard ODA Components, see the ODA Component Directory
The description, maintainers and owners are self-descriptive.
coreFunction:
exposedAPIs:
- name: productcatalogmanagement
specification: https://raw.githubusercontent.com/tmforum-apis/TMF620_ProductCatalog/master/TMF620-ProductCatalog-v4.0.0.swagger.json
implementation: {{.Release.Name}}-prodcatapi
apitype: openapi
path: /{{.Release.Name}}-{{.Values.component.type}}/tmf-api/productCatalogManagement/v4
developerUI: /{{.Release.Name}}-{{.Values.component.type}}/tmf-api/productCatalogManagement/v4/docs
port: 8080
dependantAPIs:
- name: party
apitype: openapi
specification: https://open-api.tmforum.org/TMF632-Party-v4.0.0.swagger.json
publishedEvents:
- name: TMF620-productspecification
specification: https://open-api.tmforum.org/TMF620-Productcatalog-v4.0.0.swagger.json
hub: /{{.Release.Name}}-{{.Values.component.type}}/tmf-api/productspecification/hub
implementation: {{.Release.Name}}-prodspecevent
apitype: openapi
port: 80
subscribedEvents:
- name: TMF633-servicespecification
specification: https://open-api.tmforum.org/TMF633-Servicecatalog-v4.0.0.swagger.json
call-back: /{{.Release.Name}}-{{.Values.component.type}}/tmf-api/servicepecification/call-back
port: 80
implementation: {{.Release.Name}}-servicespecevent
apitype: openapi
filter: CatalogStateChangeEvent&status=active
The coreFunction describes the core purpose of the software component. It describes the list of APIs and/or events that the component exposes as well as the APIs and/or events that it is dependant on. The definitions within the publishedEvents and subscribedEvents are experimental at this point, and we will modify and enhance them as we build-out the ODA Canvas and assemble a representative set of ODA Components. The current definition has:
an
implementationwhich links to the Kubernetes service that implements the API or event, including theportwhere the http service is exposed.The
pathshows the API resource end-point, and can be used, for example, to automatically configure any API Gateway that is included as part of the Canvas. Note that thepathpoints to the root of the API (and you need to append the relevant path from the swagger document to get to an implemented API resource).The
specificationpoints to the swagger documentation for the API. The Component CTK (Compliance Test Kit) will look inside this swagger for thebasePathdetermine which Open-API CTK to execute for that API. ThebasePathis of format"/tmf-api/productCatalogManagement/v4/"which shows it is atmf-apiforproductCatalogManagementwith major version4. The swagger can be one of the TM Forum published swagger files (e.g. https://raw.githubusercontent.com/tmforum-rand/Open_API_And_Data_Model/v4.0-Sprint-2020-03/apis/TMF620_Product_Catalog/swaggers/TMF620-ProductCatalog-v4.1.0.swagger.json) or can be an extension (conforming to the TMF630 Design Guidelines).The
hubrepresents the path for configuring the destination for the events.The
call-backrepresents the path to the call-back end-point for these events.The
filterallows the component to define a filter to only subscribe to certain type of events.
managementFunction:
exposedAPIs:
- name: metrics
apitype: open-metrics
implementation: {{.Release.Name}}-{{.Values.component.name}}-sm
path: /{{.Release.Name}}-{{.Values.component.name}}/metrics
port: 4000
dependantAPIs: []
publishedEvents:
- name: TMF642-alarmmanagement
specification: https://open-api.tmforum.org/TMF642-alarmmanagement-v4.0.0.swagger.json
hub: /{{.Release.Name}}-{{.Values.component.type}}/tmf-api/alarmmanagement/hub
implementation: {{.Release.Name}}-alarmmgtevent
apitype: openapi
port: 80
subscribedEvents: []
securityFunction:
controllerRole: secConAdmin
exposedAPIs:
- name: partyrole
specification: https://raw.githubusercontent.com/tmforum-apis/TMF669_PartyRole/master/TMF669-PartyRole-v4.0.0.swagger.json
implementation: {{.Release.Name}}-partyroleapi
apitype: openapi
path: /{{.Release.Name}}-{{.Values.component.name}}/tmf-api/partyRoleManagement/v4
developerUI: /{{.Release.Name}}-{{.Values.component.name}}/tmf-api/partyRoleManagement/v4/docs
port: 8080
dependantAPIs: []
The managementFunction and securityFunction sections describe management and security APIs the component exposes that are part of its management or security (rather than part of its core business function). Examples of management APIs are for self-testing, raising operational alarms, or configuring the component itself. The security section provides meta-data on the security mechanisms used by the component, for example, exposing the roles the component requires to be configured in the Identity Management service. Again, the current definitions within these sections are experimental and we will modify and enhance them as we build-out the ODA Canvas and assemble a representative set of ODA Components. As of version v1alpha2 and later, the security definition should include a partyrole property that describes the TMF669 PartyRole Open-API that all components must support (future versions may support multiple mechanisms for components to expose the roles they support). As of version v1alpha3 and layer, the security definition must include a controllerRole property that gives the name of a pre-existing role in the component that the security controller can use to a) POST a listener URL to the component partyRole notification endpoint so that it can receive notifications of events against party roles and b) GET the partyrole endpoint to query roles in the component.
Step 2: Add labels to all the standard Kubernetes resources
By default, when you deploy a kubernetes manifest containing a number of different standard resources (Deployments, Pods, Services etc), they are deployed as independant resources with no reference to each-other. As part of the component standard, we add a label to every kubernetes resource to show that it belongs to a particular component.
In our productcatalog example component, if you look at the service definition below, it shows us adding the component label to this service.
apiVersion: v1
kind: Service
metadata:
name: productcatalog
labels:
app: productcatalog
oda.tmforum.org/componentName: vodafone-productcatalog
spec:
ports:
- port: 8080
targetPort: productcatalog
name: productcatalog
type: NodePort
selector:
app: productcatalog
When this component is deployed, the Component Operator will use this information to build a parent relationship between the running instances of the component. This also means that when we delete a component using the kubectl delete component <componentname> comand, the Kubernetes garbage-collection will also delete all the standard resources within the component.
The component operator will create a parent->child relationship with any labelled resources (services, deployments, persistentvolumeclaims, jobs, cronjobs, statefulsets, configmap, secret, serviceaccount, role, rolebinding) to make them part of the component (and help with things like cascading deletion)
We should not support certain resources:
ingress - A developer should express a components intent via APIs and not via ingress. The canvas should create any required ingress
pod, replicaset - a developer should use deployments (for stateless microservices) or statefulsets (for stateful microservices)
demonset - a component developer should have no need for creating a demonset
clusterrole, clusterrolebinding - a component developer should have no need for creating a clusterrole, clusterrolebinding they should be using role, rolebinding
This if you include these unsupported resources in a component specification, the component CTK will issue a warning.
Changes between versions
v1beta1 to v1beta2
There were a number of changes to align the security and management sections with the core - previously they described APIs in a slightly different structure.
v1beta2 adds some additional metadata for
functionalBlock,versionandstatus, so that the ODA Component Directory could be created entirely from the YAML definitions in the components. The components team is now publishing all their components (against the beta2 standard) here: https://github.com/tmforum-rand/TMForum-ODA-Ready-for-publication/tree/v1beta2/specifications Finally, we renamedsecuritytosecurityFunctionandmanagementtomanagementFunctionto align with thecoreFunctionsection.