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.

image1

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:

image0

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:

image0

Architecture

image3

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:

  1. Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the ONAP repositories and OpenDaylight repositories.
  2. git clone https://(LFID)@gerrit.onap.org/r/a/ccsdk/cds
  3. cd cds ; mvn clean install ; cd ..
  4. Open the cds-ui/client code for development

Functional Decomposition

image2

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:

image0

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.

image1

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.

image0

Source Primary DB 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
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.

Dbsystemcode
 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.

image1

Rest Source 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
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:

Resource Rest Authentication
token-auth:
1
2
3
4
5
6
7
8
9
{
   "dsl_definitions": {
     "dynamic-rest-source": {
       "type" : "token-auth",
       "url" : "http://localhost:32778",
       "token" : "<token>"
     }
   }
}
basic-auth:
 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>"
    }
   }
}
ssl-basic-auth:
 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.

image2

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
{
   "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.

complex Response code
 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

dt-netbox-ip code
 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.

create_netbox_ip_address code
{
 "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.

Setup local Helm

helm repo

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