CONTROLLER DESIGN STUDIO (CDS)¶
Introduction¶
The system is designed to be self service, which means that users, not just programmers, can reconfigure the software system as needed to meet customer requirements. To accomplish this goal, the system is built around models that provide for real-time changes in how the system operates. Users merely need to change a model to change how a service operates. Self service is a completely new way of delivering services. It removes the dependence on code releases and the delays they cause and puts the control of services into the hands of the service providers. They can change a model and its parameters and create a new service without writing a single line of code. This makes SERVICE PROVIDER(S) more responsive to its customers and able to deliver products that more closely match the needs of its customers.
Architecture¶
- The Controller Design Studio is composed of two major components:
- The GUI (or frontend)
- The Run Time (or backend)
The GUI handles direct user input and allows for displaying both design time and run time activities. For design time, it allows for the creation of controller blueprint, from selecting the DGs to be included, to incorporating the artifact templates, to adding necessary components. For run time, it allows the user to direct the system to resolve the unresolved elements of the controller blueprint and download the resulting configuration into a VNF. At a more basic level, it allows for creation of data dictionaries, capabilities catalogs, and controller blueprint, the basic elements that are used to generate a configuration. The essential function of the Controller Design Studio is to create and populate a controller blueprint, create a configuration file from this Controller blueprint, and download this configuration file (configlet) to a VNF/PNF.
Modeling Concept¶
In Dublin release, the CDS community has contributed a framework to automate the resolution of resources for instantiation and any config provisioning operation, such as day0, day1 or day2 configuration.
The content of the CBA Package is driven from a catalog of reusable data dictionary, component and workflow, delivering a reusable and simplified self service experience.
TOSCA based JSON formatted model following standard: http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html
Most of the TOSCA modeled entity presented in the bellow documentation can be found here: https://github.com/onap/ccsdk-cds/tree/master/components/model-catalog/definition-type/starter-type
Tosca Model Reference:
Modeling Concept Links:¶
Controller Blueprints Studio Processor¶
The Controller Blueprint Archive is the overall service design, fully model-driven, intent based package needed for SELF SERVICE provisioning and configuration management automation.
The CBA is .zip file which is saved in Controller Blueprint Database.
Controller Blueprint Microservices:¶
Dynamic API¶
The nature of the API request and response is meant to be model driven and dynamic. They both share the same definition.
The actionName, under the actionIdentifiers refers to the name of a Workflow (see workflow)
The content of the payload is what is fully dynamic / model driven.
The first top level element will always be either $actionName-request for a request or $actionName-response for a response.
Then the content within this element is fully based on the workflow input and output.
Here is how the a generic request and response look like.
Blueprints Processor¶
Micro service to Manage Controller Blueprint Models, such as Resource Dictionary, Service Models, Velocity Templates etc, which will serve service for Controller Design Studio and Controller runtimes.
This microservice is used to deploy Controller Blueprint Archive file in Run time database. This also helps to test the Valid Blueprint.
Architecture:¶
Running Blueprints Processor Microservice Locally:¶
The purpose of this page is to show how to run the Blueprints Processor microservice locally, using the docker-compose.yaml file provided in the project.
Check out the CDS’ code:
Check out the latest code from Gerrit: https://gerrit.onap.org/r/#/admin/projects/ccsdk/cds
Build CDS locally: In the checked out directory, type
mvn clean install -DskipTests=true -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -Dadditionalparam=-Xdoclint:none
Create the needed Docker images:
The Blueprints Processor microservice project has a module, called distribution, that provides a docker-compose.yaml file that can be used to spin up Docker containers to run this microservice.
The first step is to create any custom image needed, by building the distribution module. From the CDS home directory (where the code was checked out), navigate to the module:
cd ms/blueprintsprocessor/distribution/
Build it using the Maven profile called Docker:
mvn clean install -Pdocker
Start Docker containers using docker-composer:¶
Navigate to the docker-compose file in the distribution module:
cd src/main/dc/
From there, start the containers:
docker-compose up -d
This will spin the Docker containers declared inside the docker-compose.yaml file in the background.
To verify the logs generated by docker-composer, type:
docker-compose logs -f
Testing the environment:¶
Point your browser to http://localhost:8000/api/v1/execution-service/ping (please note that the port is 8000, not 8080)
To authenticate, use login user id and password.
Expression¶
TOSCA provides for a set of functions to reference elements within the template or to retrieve runtime values.
Below is a list of supported expressions
get_input¶
The get_input function is used to retrieve the values of properties declared within the inputs section of a TOSCA Service Template.
get_property¶
The get_property function is used to retrieve property values between modelable entities defined in the same service template.
get_attribute¶
The get_attribute function is used to retrieve the values of named attributes declared by the referenced node or relationship template name.
get_operation_output¶
The get_operation_output function is used to retrieve the values of variables exposed / exported from an interface operation.
get_artifact¶
The get_artifact function is used to retrieve artifact location between modelable entities defined in the same service template.
Flexible Plug-in¶
Interaction with external systems is made plug-able, removing development cycle to support new endpoint.
Currently, REST or SQL external systems are supported.
An external system might be used by multiple resources, or by multiple scripts.
In order to share the external system information, TOSCA provides a way to create macros using dsl_definitions:
http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454160 http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.2/csd01/TOSCA-Simple-Profile-YAML-v1.2-csd01.html#_Toc494454173
Design tools¶
Controller Blueprint Archived Designer Tool(CBA)¶
Introduction¶
The Controller Blueprint Archived is the overall service design, fully model-driven, package needed to automate the resolution of resources for instantiation and any config provisioning operation, such as day0, day1 or day2 configuration.
The CBA is .zip file, comprised of the following folder structure, the files may vary:
Architecture¶
Installation¶
Building client html and js files¶
- FROM alpine:3.8 as builder
- RUN apk add –no-cache npm
- WORKDIR /opt/cds-ui/client/
- COPY client/package.json /opt/cds-ui/client/
- RUN npm install
- COPY client /opt/cds-ui/client/
- RUN npm run build
Building and creating server¶
- FROM alpine:3.8
- WORKDIR /opt/cds-ui/
- RUN apk add –no-cache npm
- COPY server/package.json /opt/cds-ui/
- RUN npm install
- COPY server /opt/cds-ui/
- COPY –from=builder /opt/cds-ui/server/public /opt/cds-ui/public
- RUN npm run build
- EXPOSE 3000
- CMD [ “npm”, “start” ]
Development¶
Pre-requiste¶
- Visual Studio code editor
- Git bash
- Node.js & npm
- loopback 4 cl
Steps¶
To compile CDS code:
- Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the ONAP repositories and OpenDaylight repositories.
- git clone https://(LFID)@gerrit.onap.org/r/a/ccsdk/cds
- cd cds ; mvn clean install ; cd ..
- Open the cds-ui/client code for development
Functional Decomposition¶
Resource Definition¶
Introduction:¶
A Resource definition models the how a specific resource can be resolved.
A resource is a variable/parameter in the context of the service. It can be anything, but it should not be confused with SDC or Openstack resources.
A Resource definition can have multiple sources to handle resolution in different ways. The main goal of Resource definition is to define re-usable entity that could be shared.
Creation of Resource definition is a standalone activity, separated from the blueprint design.
As part of modelling a Resource definition entry, the following generic information should be provided:
Below are properties that all the resource source have will have
The modeling does allow for data translation between external capability and CDS for both input and output key mapping.
Example:¶
vf-module-model-customization-uuid and vf-module-label are two data dictionaries. A SQL table, VF_MODULE_MODEL, exist to correlate them.
Here is how input-key-mapping, output-key-mapping and key-dependencies can be used:
Source Capability Code¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | {
"description": "This is Component Resource Source Node Type",
"version": "1.0.0",
"properties": {
"script-type": {
"required": true,
"type": "string",
"default": "kotlin",
"constraints": [
{
"valid_values": [
"kotlin",
"jython"
]
}
]
},
"script-class-reference": {
"description": "Capability reference name for internal and kotlin, for jython script file path",
"required": true,
"type": "string"
},
"instance-dependencies": {
"required": false,
"description": "Instance dependency Names to Inject to Kotlin / Jython Script.",
"type": "list",
"entry_schema": {
"type": "string"
}
},
"key-dependencies": {
"description": "Resource Resolution dependency dictionary names.",
"required": true,
"type": "list",
"entry_schema": {
"type": "string"
}
}
},
"derived_from": "tosca.nodes.ResourceSource"
}
|
Resource source:¶
Defines the contract to resolve a resource.
A resource source is modeled, following TOSCA node type definition and derives from the Resource source.
Also please click below for resource source available details
Resource Source¶
Input:¶
Expects the value to be provided as input to the request.
1 2 3 4 5 6 7 8 9 | {
"source-input" :
{
"description": "This is Input Resource Source Node Type",
"version": "1.0.0",
"properties": {},
"derived_from": "tosca.nodes.ResourceSource"
}
}
|
Default:¶
Expects the value to be defaulted in the model itself.
1 2 3 4 5 6 7 8 9 | {
"source-default" :
{
"description": "This is Default Resource Source Node Type",
"version": "1.0.0",
"properties": {},
"derived_from": "tosca.nodes.ResourceSource"
}
}
|
sql:¶
Expects the SQL query to be modeled; that SQL query can be parameterized, and the parameters be other resources resolved through other means. If that’s the case, this data dictionary definition will have to define key-dependencies along with input-key-mapping.
CDS is currently deployed along the side of SDNC, hence the primary database connection provided by the framework is to SDNC database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | {
"description": "This is Database Resource Source Node Type",
"version": "1.0.0",
"properties": {
"type": {
"required": true,
"type": "string",
"constraints": [
{
"valid_values": [
"SQL"
]
}
]
},
"endpoint-selector": {
"required": false,
"type": "string"
},
"query": {
"required": true,
"type": "string"
},
"input-key-mapping": {
"required": false,
"type": "map",
"entry_schema": {
"type": "string"
}
},
"output-key-mapping": {
"required": false,
"type": "map",
"entry_schema": {
"type": "string"
}
},
"key-dependencies": {
"required": true,
"type": "list",
"entry_schema": {
"type": "string"
}
}
},
"derived_from": "tosca.nodes.ResourceSource"
}
|
Connection to a specific database can be expressed through the endpoint-selector property, which refers to a macro defining the information about the database the connect to. Understand TOSCA Macro in the context of CDS.
1 2 3 4 5 6 7 8 9 10 | {
"dsl_definitions": {
"dynamic-db-source": {
"type": "maria-db",
"url": "jdbc:mysql://localhost:3306/sdnctl",
"username": "<username>",
"password": "<password>"
}
}
}
|
REST:¶
Expects the URI along with the VERB and the payload, if needed.
CDS is currently deployed along the side of SDNC, hence the default rest connection provided by the framework is to SDNC MDSAL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | {
"description": "This is Rest Resource Source Node Type",
"version": "1.0.0",
"properties": {
"type": {
"required": false,
"type": "string",
"default": "JSON",
"constraints": [
{
"valid_values": [
"JSON"
]
}
]
},
"verb": {
"required": false,
"type": "string",
"default": "GET",
"constraints": [
{
"valid_values": [
"GET", "POST", "DELETE", "PUT"
]
}
]
},
"payload": {
"required": false,
"type": "string",
"default": ""
},
"endpoint-selector": {
"required": false,
"type": "string"
},
"url-path": {
"required": true,
"type": "string"
},
"path": {
"required": true,
"type": "string"
},
"expression-type": {
"required": false,
"type": "string",
"default": "JSON_PATH",
"constraints": [
{
"valid_values": [
"JSON_PATH",
"JSON_POINTER"
]
}
]
},
"input-key-mapping": {
"required": false,
"type": "map",
"entry_schema": {
"type": "string"
}
},
"output-key-mapping": {
"required": false,
"type": "map",
"entry_schema": {
"type": "string"
}
},
"key-dependencies": {
"required": true,
"type": "list",
"entry_schema": {
"type": "string"
}
}
},
"derived_from": "tosca.nodes.ResourceSource"
}
|
Connection to a specific REST system can be expressed through the endpoint-selector property, which refers to a macro defining the information about the REST system the connect to. Understand TOSCA Macro in the context of CDS.
Few ways are available to authenticate to the REST system:
- token-auth
- basic-auth
- ssl-basic-auth
For source code of Authentication click below link:
1 2 3 4 5 6 7 8 9 | {
"dsl_definitions": {
"dynamic-rest-source": {
"type" : "token-auth",
"url" : "http://localhost:32778",
"token" : "<token>"
}
}
}
|
1 2 3 4 5 6 7 8 9 10 | {
"dsl_definitions": {
"dynamic-rest-source": {
"type" : "basic-auth",
"url" : "http://localhost:32778",
"username" : "<username>",
"password": "<password>"
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"dsl_definitions": {
"dynamic-rest-source": {
"type" : "ssl-basic-auth",
"url" : "http://localhost:32778",
"keyStoreInstance": "JKS or PKCS12",
"sslTrust": "trusture",
"sslTrustPassword": "<password>",
"sslKey": "keystore",
"sslKeyPassword": "<password>"
}
}
}
|
Capability:¶
Expects a script to be provided.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | {
"description": "This is Component Resource Source Node Type",
"version": "1.0.0",
"properties": {
"script-type": {
"required": true,
"type": "string",
"default": "kotlin",
"constraints": [
{
"valid_values": [
"kotlin",
"jython"
]
}
]
},
"script-class-reference": {
"description": "Capability reference name for internal and kotlin, for jython script file path",
"required": true,
"type": "string"
},
"key-dependencies": {
"description": "Resource Resolution dependency dictionary names.",
"required": true,
"type": "list",
"entry_schema": {
"type": "string"
}
}
},
"derived_from": "tosca.nodes.ResourceSource"
}
|
Complex Type:¶
Value will be resolved through REST., and output will be a complex type.
Modeling reference: Modeling Concepts#rest
In this example, we’re making a POST request to an IPAM system with no payload.
Some ingredients are required to perform the query, in this case, $prefixId. Hence It is provided as an input-key-mapping and defined as a key-dependencies. Please refer to the modeling guideline for more in depth understanding.
As part of this request, the expected response will be as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 | {
"id": 4,
"address": "192.168.10.2/32",
"vrf": null,
"tenant": null,
"status": 1,
"role": null,
"interface": null,
"description": "",
"nat_inside": null,
"created": "2018-08-30",
"last_updated": "2018-08-30T14:59:05.277820Z"
}
|
What is of interest is the address and id fields. For the process to return these two values, we need to create a custom data-type, as bellow
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | {
"version": "1.0.0",
"description": "This is Netbox IP Data Type",
"properties": {
"address": {
"required": true,
"type": "string"
},
"id": {
"required": true,
"type": "integer"
}
},
"derived_from": "tosca.datatypes.Root"
}
|
The type of the data dictionary will be dt-netbox-ip.
To tell the resolution framework what is of interest in the response, the output-key-mapping section is used. The process will map the output-key-mapping to the defined data-type.
{
"tags" : "oam-local-ipv4-address",
"name" : "create_netbox_ip",
"property" : {
"description" : "netbox ip",
"type" : "dt-netbox-ip"
},
"updated-by" : "adetalhouet",
"sources" : {
"config-data" : {
"type" : "source-rest",
"properties" : {
"type" : "JSON",
"verb" : "POST",
"endpoint-selector" : "ipam-1",
"url-path" : "/api/ipam/prefixes/$prefixId/available-ips/",
"path" : "",
"input-key-mapping" : {
"prefixId" : "prefix-id"
},
"output-key-mapping" : {
"address" : "address",
"id" : "id"
},
"key-dependencies" : [ "prefix-id" ]
}
}
}
}
Scripts¶
Library¶
- NetconfClient
In order to facilitate NETCONF interaction within scripts, a python NetconfClient binded to our Kotlin implementation is made available. This NetconfClient can be used when using the component-netconf-executor.
The client can be find here: https://github.com/onap/ccsdk-cds/blob/master/components/scripts/python/ccsdk_netconf/netconfclient.py
- ResolutionHelper
When executing a component executor script, designer might want to perform resource resolution along with template meshing directly from the script itself.
The helper can be found in below link: https://github.com/onap/ccsdk-apps/blob/master/components/scripts/python/ccsdk_netconf/common.py
User Guide¶
User Guide¶
Installation¶
ONAP is meant to be deployed within a Kubernetes environment. Hence, the de-facto way to deploy CDS is through Kubernetes.
ONAP also package Kubernetes manifest as Chart, using Helm.
Get the chart¶
Make sure to checkout the release to use, by replacing $release-tag in bellow command
git clone https://gerrit.onap.org/r/oom git checkout tags/$release-tag cd oom/kubernetes make cds
Install CDS¶
helm install –name cds cds
Result¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $ kubectl get all --selector=release=cds
NAME READY STATUS RESTARTS AGE
pod/cds-blueprints-processor-54f758d69f-p98c2 0/1 Running 1 2m
pod/cds-cds-6bd674dc77-4gtdf 1/1 Running 0 2m
pod/cds-cds-db-0 1/1 Running 0 2m
pod/cds-controller-blueprints-545bbf98cf-zwjfc 1/1 Running 0 2m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/blueprints-processor ClusterIP 10.43.139.9 <none> 8080/TCP,9111/TCP 2m
service/cds NodePort 10.43.254.69 <none> 3000:30397/TCP 2m
service/cds-db ClusterIP None <none> 3306/TCP 2m
service/controller-blueprints ClusterIP 10.43.207.152 <none> 8080/TCP 2m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/cds-blueprints-processor 1 1 1 0 2m
deployment.apps/cds-cds 1 1 1 1 2m
deployment.apps/cds-controller-blueprints 1 1 1 1 2m
NAME DESIRED CURRENT READY AGE
replicaset.apps/cds-blueprints-processor-54f758d69f 1 1 0 2m
replicaset.apps/cds-cds-6bd674dc77 1 1 1 2m
replicaset.apps/cds-controller-blueprints-545bbf98cf 1 1 1 2m
NAME DESIRED CURRENT AGE
statefulset.apps/cds-cds-db 1 1 2m
|
Running CDS UI:¶
Client:¶
Install Node.js and angularCLI. Refer https://angular.io/guide/quickstart npm install in the directory cds/cds-ui/client npm run build - to build UI module
Loopback Server:¶
npm install in the directory cds/cds-ui/server npm start should bring you the CDS UI page in your local machine with the link https://127.0.0.1:3000/
Design Time User Guide¶
Below are the requirements to enable automation for a service within ONAP.
For instantiation, the goal is to be able to automatically resolve all the HEAT/Helm variables, called cloud parameters.
For post-instantiation, the goal is to configure the VNF with initial configuration.
Prerequisite¶
- Gather the cloud parameters:
Instantiation:¶
Have the HEAT template along with the HEAT environment file (or) Have the Helm chart along with the Values.yaml file
(CDS supports, but whether SO → Multicloud support for Helm/K8S is different story)
Post-instantiation:¶
Have the configuration template to apply on the VNF.
- XML for NETCONF
- JSON / XML for RESTCONF
- not supported yet - CLI
- JSON for Ansible [not supported yet]
- Identify which template parameters are static and dynamic
- Create and fill-in the a table for all the dynamic values
While doing so, identify the resources using the same process to be resolved; for instance, if two IPs has to be resolved through the same IPAM, the process the resolve the IP is the same.
Services:¶
Resource Assignment¶
Component executor:¶
Workflow:¶
A workflow defines an overall action to be taken for the service; it can be composed of a set of sub-actions to execute. Currently, workflows are backed by Directed Graph engine.
A CBA can have as many workflow as needed.
Template:¶
A template is an artifact.
A template is parameterized and each parameter must be defined in a corresponding mapping file.
In order to know which mapping correlate to which template, the file name must start with an artifact-prefix, serving as identifier to the overall template + mapping.
The requirement is as follow:
${artifact-prefix}-template ${artifact-prefix}-mapping
A template can represent anything, such as device config, payload to interact with 3rd party systems, resource-accumulator template, etc…
Mapping:¶
Defines the contract of each resource to be resolved. Each placeholder in the template must have a corresponding mapping definition.
A mapping is comprised of:
- name
- required / optional
- type (support complex type)
- dictionary-name
- dictionary-source
Dependencies:¶
This allows to make sure given resources get resolved prior the resolution of the resources defining the dependency. The dictionary fields reference to a specific data dictionary.
Resource accumulator:¶
In order to resolve HEAT environment variables, resource accumulator templates are being in used for Dublin.
These templates are specific to the pre-instantiation scenario, and relies on GR-API within SDNC.
It is composed of the following sections:
resource-accumulator-resolved-data: defines all the resources that can be resolved directly from the context. It expresses a direct mapping between the name of the resource and its value.
capability-data: defines what capability to use to create a specific resource, along with the ingredients required to invoke the capability and the output mapping.
- Scripts
- Library
- NetconfClient
In order to facilitate NETCONF interaction within scripts, a python NetconfClient binded to our Kotlin implementation is made available. This NetconfClient can be used when using the netconf-component-executor.
The client can be find here: https://github.com/onap/ccsdk-apps/blob/master/components/scripts/python/ccsdk_netconf/netconfclient.py
Controller Design Studio Presentation¶
Details about CDS Architecture and Design detail, Please click the link.
CDS_Architecture_Design.pptx