<div style="display: flex;flex-direction: row">
<div style="width: 30em;">
- <button class="btn-active" (click)="changeView()">{{viewText}}</button>
+ <button class="btn-active" (click)="changeView()" disabled>{{viewText}}</button>
</div>
<div style="width: 16em">
</div>
============LICENSE_END============================================
-->
<mat-radio-group>
- <mat-radio-button value="1" (click)="selected(1)">Upload Template file</mat-radio-button><br><br>
- <mat-radio-button value="2" (click)="selected(2)">Starter Template</mat-radio-button><br><br>
- <mat-radio-button value="3" (click)="selected(3)">Existing Model File</mat-radio-button>
-</mat-radio-group>
+ <mat-radio-button value="1" (click)="selected(1)">Upload Template file</mat-radio-button><br><br>
+ <!-- <mat-radio-button value="2" (click)="selected(2)">Starter Template</mat-radio-button><br><br>
+ <mat-radio-button value="3" (click)="selected(3)">Existing Model File</mat-radio-button> -->
+</mat-radio-group>
\ No newline at end of file
<form class="example-form" [formGroup]="myControl">
<mat-form-field class="example-full-width">
- <input type="text" [(ngModel)]="searchText" placeholder="Search Resources" matInput [matAutocomplete]="auto" formControlName="search_input">
+ <input #resourceSelect type="text" [(ngModel)]="searchText" placeholder="Search Resources" matInput [matAutocomplete]="auto" formControlName="search_input">
<button matSuffix mat-icon-button (click)="fetchResourceByName()"><mat-icon>search</mat-icon></button>
<mat-autocomplete #auto="matAutocomplete">
<mat-option (click)="selected(option)" *ngFor="let option of options | search : searchText" [value]="option.tags">
import { Component, OnInit, ViewChild, EventEmitter, Output } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import { ExsistingModelService } from '../exsisting-model.service';
+import { MatAutocompleteTrigger } from '@angular/material'
@Component({
selector: 'app-search-resource',
myControl: FormGroup;
@Output() resourcesData = new EventEmitter();
- options: any[] = [] ;
- // = ['One','One1', 'Two', 'Three'];
+ options: any[] = ['One','One1', 'Two', 'Three'];
+ // @ViewChild('resourceSelect') resourceSelect;
+ @ViewChild('resourceSelect', { read: MatAutocompleteTrigger }) resourceSelect: MatAutocompleteTrigger;
searchText: string = '';
constructor(private _formBuilder: FormBuilder,
console.log(data);
data.forEach(element => {
this.options.push(element)
- });
- // this.options = data.
+ });
+ this.resourceSelect.openPanel();
}, error=>{
window.alert('error' + error);
})
<app-resource-template-options (option)="selectedOption($event)"></app-resource-template-options>
<br>
<div>
- <button mat-button matStepperNext class="matStepNextBtn">Proceed</button>
+ <button mat-button matStepperNext class="matStepNextBtn" *ngIf="selectedValue == 1 || selectedValue == 3">Proceed</button>
</div>
</mat-step>
- <mat-step [stepControl]="step2FormGroup">
+ <mat-step [stepControl]="step2FormGroup" *ngIf="selectedValue == 1 || selectedValue == 3">
<ng-template matStepLabel>Browse or Search Resources</ng-template>
<app-upload-resource (fileData)=upload($event) *ngIf="selectedValue == 1"></app-upload-resource><br><br>
<app-existing-model *ngIf="selectedValue == 3"></app-existing-model>
*/-->
-<button (click) ="changeView()" class="toggle-view-btn">{{viewText}}</button>
+<button disabled style="opacity: 0.5;" (click) ="changeView()" class="toggle-view-btn">{{viewText}}</button>
<br><br>
<div *ngIf="designerMode">
<mat-card class="metadata-card">
<div class="btn">
<button mat-button matStepperPrevious>Back</button></div>
<div class="btn">
- <button mat-button matStepperNext type="submit" (click)="updateResourcesState()">Upload</button>
+ <button mat-button matStepperNext type="submit" (click)="saveToBackend()">Save</button>
</div>
background:#3f51b5;
margin-top: 10px;
position: absolute;
- border-radius: 1em;
+ border-radius: 4px;
}
.mat-card-title{
padding-top: 7px;
margin: 0 25px 25px 0;
display: inline-block;
vertical-align: top;
+ border-radius: 4px;
}
.toggle-view-btn{
color:white;
background:#3f51b5;
- border-radius: 1em;
+ border-radius: 4px;
margin-top: 10px;
padding:0.6em;
border: 1px solid #3f51b5;
import { JsonEditorComponent, JsonEditorOptions } from 'ang-jsoneditor';
import { Observable } from 'rxjs';
import { A11yModule } from '@angular/cdk/a11y';
+import { ResourceEditService } from './resource-edit.service';
@Component({
selector: 'app-resource-edit',
resources:IResources;
data:IResources;
rdState: Observable<IResourcesState>;
- designerMode: boolean = true;
- editorMode: boolean = false;
+ designerMode: boolean = false;
+ editorMode: boolean = true;
viewText: string = "Open in Editor Mode";
@ViewChild(JsonEditorComponent) editor: JsonEditorComponent;
options = new JsonEditorOptions();
- constructor(private store: Store<IAppState>) {
+ constructor(private store: Store<IAppState>, private resourceEditService: ResourceEditService) {
this.rdState = this.store.select('resources');
this.options.mode = 'text';
this.options.modes = [ 'text', 'tree', 'view'];
this.designerMode = true;
this.viewText = 'Open in Editor Mode'
}
- }
+ }
+
+ saveToBackend() {
+ this.resourceEditService.saveResource(this.data)
+ .subscribe(response=>{
+ window.alert("save success");
+ },
+ error=>{
+ window.alert('Error saving resources');
+ })
+ }
}
import { ResourceMetadataComponent } from './resource-metadata/resource-metadata.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { NgJsonEditorModule } from 'ang-jsoneditor';
+import { ResourceEditService } from './resource-edit.service';
@NgModule({
declarations: [ ResourceEditComponent,SourcesTemplateComponent,ResourceMetadataComponent ],
MatExpansionModule,MatToolbarModule,MatIconModule, MatButtonModule, MatSidenavModule, MatCheckboxModule, MatListModule, MatGridListModule, MatCardModule, MatMenuModule, MatTableModule, MatPaginatorModule, MatSortModule, MatInputModule, MatSelectModule, MatRadioModule, MatFormFieldModule, MatStepperModule,
NgJsonEditorModule
],
- exports: [ ResourceEditComponent,SharedModule ]
+ exports: [ ResourceEditComponent,SharedModule ],
+ providers: [ ResourceEditService ]
})
export class ResourceEditModule { }
--- /dev/null
+/*
+============LICENSE_START==========================================
+===================================================================
+Copyright (C) 2018-19 IBM Intellectual Property. All rights reserved.
+===================================================================
+
+Unless otherwise specified, all software contained herein is licensed
+under the Apache License, Version 2.0 (the License);
+you may not use this software except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+============LICENSE_END============================================
+*/
+
+
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable, observable } from 'rxjs';
+import { ApiService } from '../../../common/core/services/api.service';
+import { LoopbackConfig, ResourceDictionaryURLs } from '../../../common/constants/app-constants';
+
+@Injectable()
+export class ResourceEditService {
+ // blueprintUrl = '../../constants/blueprint.json';
+
+ constructor(private _http: HttpClient, private api: ApiService) {
+ }
+
+ saveResource(resource) {
+ return this.api.post(LoopbackConfig.url+ ResourceDictionaryURLs.saveResourceDictionary, resource);
+ }
+}
\ No newline at end of file
"constraints": [
{
"valid_values": [
- "ANSIBLE", "PYTHON"
+ "ansible_galaxy", "pip"
]
}
]
"description": "This is Remote Python Execution Component.",
"version": "1.0.0",
"attributes": {
- "execution-logs": {
- "required": true,
+ "prepare-environment-logs": {
+ "required": false,
+ "type": "string"
+ },
+ "execute-command-logs": {
+ "required": false,
"type": "string"
}
},
"required": false,
"type": "json"
},
+ "argument-properties": {
+ "description": "Argument Json Content or DSL Json reference.",
+ "required": false,
+ "type": "json"
+ },
"command": {
"description": "Command to execute.",
"required": true,
"file": "Definitions/policy_types.json"
}
],
+ "dsl_definitions": {
+ "execute-argument-properties": {
+ "input": {
+ "get_input": "input"
+ }
+ }
+ },
"topology_template": {
"workflows": {
"execute-remote-python": {
]
}
},
- "inputs": {},
+ "inputs": {
+ "input": {
+ "required": false,
+ "type": "string"
+ }
+ },
"outputs": {
- "logs": {
- "type": "json",
+ "prepare-environment-logs": {
+ "type": "string",
"value": {
"get_attribute": [
"execute-remote-python",
- "execution-logs"
+ "prepare-environment-logs"
+ ]
+ }
+ },
+ "execute-command-logs": {
+ "type": "string",
+ "value": {
+ "get_attribute": [
+ "execute-remote-python",
+ "execute-command-logs"
]
}
}
},
"inputs": {},
"outputs": {
- "logs": {
- "type": "json",
+ "prepare-environment-logs": {
+ "type": "string",
"value": {
"get_attribute": [
"execute-remote-ansible",
- "execution-logs"
+ "prepare-environment-logs"
+ ]
+ }
+ },
+ "execute-command-logs": {
+ "type": "string",
+ "value": {
+ "get_attribute": [
+ "execute-remote-ansible",
+ "execute-command-logs"
]
}
}
"operations": {
"process": {
"implementation": {
- "primary": "component-script",
- "dependencies": [
- "pyaml"
- ]
+ "primary": "component-script"
},
"inputs": {
- "command": "python SamplePython.py blah"
+ "command": "python SamplePython.py $input",
+ "packages": [
+ {
+ "type": "pip",
+ "package": [
+ "pyaml"
+ ]
+ }
+ ],
+ "argument-properties": "*execute-argument-properties"
}
}
}
"command": "ansible-playbook first.yaml",
"packages": [
{
- "type": "PYTHON",
+ "type": "pip",
"package": [
- "ansible"
+ "requirements.txt"
]
},
{
- "type": "ANSIBLE",
+ "type": "ansible_galaxy",
"package": [
"juniper.junos"
]
--- /dev/null
+ansible
\ No newline at end of file
"constraints": [
{
"valid_values": [
- "ANSIBLE",
- "PYTHON"
+ "ansible_galaxy",
+ "pip"
]
}
]
"description": "This is Remote Python Execution Component.",
"version": "1.0.0",
"attributes": {
- "execution-logs": {
- "required": true,
+ "prepare-environment-logs": {
+ "required": false,
+ "type": "string"
+ },
+ "execute-command-logs": {
+ "required": false,
"type": "string"
}
},
"required": false,
"type": "json"
},
+ "argument-properties": {
+ "description": "Argument Json Content or DSL Json reference.",
+ "required": false,
+ "type": "json"
+ },
"command": {
"description": "Command to execute.",
"required": true,
}
enum PackageType {
- PYTHON = 0;
- ANSIBLE = 1;
+ pip = 0;
+ ansible_galaxy = 1;
}
service CommandExecutorService {
Prerequisites:
https://developers.google.com/protocol-buffers/docs/downloads
- https://github.com/dropbox/mypy-protobuf
-
+ or
+ https://grpc.io/docs/quickstart/python.html
Command:
- protoc -I=. --python_out=. --mypy_out=. CommandExecutor.proto
-
-
-
+ protoc -I=. --python_out=. --grpc_python_out=. CommandExecutor.proto
+ or
+ python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. CommandExecutor.proto
3. cd cds ; mvn clean install ; cd ..
4. Open the cds-ui/client code for development
-Data Flow:
-==========
-|image1|
-
-.. |image1| image:: media/image1.jpg
- :width: 7.88889in
- :height: 4.43750in
Functional Decomposition:
=========================
:width: 7.88889in
:height: 4.43750in
-Controller design Studio Presentation:
-======================================
-
-Details about CDS Architecture and Design detail, Please click the link.
-:download:`CDS_Architecture_Design.pptx`
\ No newline at end of file
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+complex Response code
+=====================
+
+{
+ "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"
+}
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+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" : {
+ "primary-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" ]
+ }
+ }
+ }
+ }
\ No newline at end of file
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+dt-netbox-ip code
+=================
+
+{
+ "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"
+}
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 data dictionaries is a standalone activity, separated from the blueprint design.
+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:
:width: 7.88889in
:height: 4.43750in
-Bellow are properties that all the resource source have will have
+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.
Here is how input-key-mapping, output-key-mapping and key-dependencies can be used:
-vf-module-label Resource definition
-
-{
- "name" : "vf-module-label",
- "tags" : "vf-module-label",
- "updated-by" : "adetalhouet",
- "property" : {
- "description" : "vf-module-label",
- "type" : "string"
- },
- "sources" : {
- "primary-db" : {
- "type" : "source-primary-db",
- "properties" : {
- "type" : "SQL",
- "query" : "select sdnctl.VF_MODULE_MODEL.vf_module_label as vf_module_label from sdnctl.VF_MODULE_MODEL where sdnctl.VF_MODULE_MODEL.customization_uuid=:customizationid",
- "input-key-mapping" : {
- "customizationid" : "vf-module-model-customization-uuid"
- },
- "output-key-mapping" : {
- "vf-module-label" : "vf_module_label"
- },
- "key-dependencies" : [ "vf-module-model-customization-uuid" ]
- }
- }
- }
-}
+.. toctree::
+ :maxdepth: 1
+
+resourceDefintionCode
+
+
Resource source:
A resource source is modeled, following TOSCA_ node type definition and derives from the Resource_ source.
-Also please click below for detailed resource source details
+Also please click below for resource source available details
.. toctree::
:maxdepth: 1
resourcesource
.. _TOSCA: http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/csprd01/TOSCA-Simple-Profile-YAML-v1.0-csprd01.html#DEFN_ENTITY_NODE_TYPE
-.. _Resource_: https://wiki.onap.org/display/DW/Modeling+Concepts#ModelingConcepts-NodeResourceSource
\ No newline at end of file
+.. _Resource: https://wiki.onap.org/display/DW/Modeling+Concepts#ModelingConcepts-NodeResourceSource
\ No newline at end of file
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+Source Capability Code
+======================
+
+{
+ "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"
+}
|image0|
-.. |image0| image:: media/image0.jpg
+.. |image0| image:: image0.jpg
:width: 7.88889in
:height: 4.43750in
:maxdepth: 1
:glob:
- controllerBlueprintStudioProcessor
- bluePrintsProcessor
+ controllerBlueprintStudioProcessorMS
+ bluePrintsProcessorMS
Architecture:
=============
|image0|
-.. |image0| image:: media/CDS_architecture.jpg
+.. |image0| image:: CDS_architecture.jpg
:height: 4.43750in
:width: 7.88889in
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+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.
+
+Prerequisite
+============
+
+https://docs.onap.org/en/latest/guides/onap-developer/settingup/index.html
+
+Setup local Helm
+================
+
+helm repo
+
+* helm serve &
+* helm repo add local http://127.0.0.1:8879
+
+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
+======
+
+$ 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
\ No newline at end of file
--- /dev/null
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright (C) 2019 IBM.
+
+User guide
+----------
+
+.. toctree::
+ :maxdepth: 1
+
+ installation
+ designtime
+
import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ExecutionServiceConstant
import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.RemoteScriptExecutionService
-import org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
-import org.onap.ccsdk.cds.controllerblueprints.core.asJsonNode
+import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
import org.onap.ccsdk.cds.controllerblueprints.core.checkFileExists
import org.onap.ccsdk.cds.controllerblueprints.core.checkNotBlank
import org.onap.ccsdk.cds.controllerblueprints.core.data.OperationAssignment
import org.onap.ccsdk.cds.controllerblueprints.core.normalizedFile
+import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintVelocityTemplateService
import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.config.ConfigurableBeanFactory
companion object {
const val INPUT_ENDPOINT_SELECTOR = "endpoint-selector"
const val INPUT_DYNAMIC_PROPERTIES = "dynamic-properties"
+ const val INPUT_ARGUMENT_PROPERTIES = "argument-properties"
const val INPUT_COMMAND = "command"
const val INPUT_PACKAGES = "packages"
+
+ const val ATTRIBUTE_PREPARE_ENV_LOG = "prepare-environment-logs"
+ const val ATTRIBUTE_EXEC_CMD_LOG = "execute-command-logs"
}
override suspend fun processNB(executionRequest: ExecutionServiceInput) {
val endPointSelector = getOperationInput(INPUT_ENDPOINT_SELECTOR)
val dynamicProperties = getOperationInput(INPUT_DYNAMIC_PROPERTIES)
- val command = getOperationInput(INPUT_COMMAND).asText()
val packages = getOperationInput(INPUT_PACKAGES)
+ val argumentProperties = getOperationInput(INPUT_ARGUMENT_PROPERTIES)
- // TODO("Python execution command and Resolve some expressions with dynamic properties")
- val scriptCommand = command.replace(pythonScript.name, pythonScript.absolutePath)
-
-// val dependencies = operationAssignment.implementation?.dependencies
+ var command = getOperationInput(INPUT_COMMAND).asText()
+ command = command.replace(pythonScript.name, pythonScript.absolutePath)
+ val scriptCommand = BluePrintVelocityTemplateService.generateContent(command, json = JacksonUtils.getJson(argumentProperties))
try {
// Open GRPC Connection
remoteScriptExecutionService.init(endPointSelector.asText())
- var executionLogs = ""
-
// If packages are defined, then install in remote server
if (packages !is MissingNode && packages !is NullNode) {
val prepareEnvInput = PrepareRemoteEnvInput(requestId = processId,
packages = packages
)
val prepareEnvOutput = remoteScriptExecutionService.prepareEnv(prepareEnvInput)
- executionLogs = prepareEnvOutput.response
- setOutput(executionLogs)
+ setAttribute(ATTRIBUTE_PREPARE_ENV_LOG, prepareEnvOutput.response.asJsonPrimitive())
check(prepareEnvOutput.status == StatusType.SUCCESS) {
"failed to get prepare remote env response status for requestId(${prepareEnvInput.requestId})"
}
remoteIdentifier = RemoteIdentifier(blueprintName = blueprintName, blueprintVersion = blueprintVersion),
command = scriptCommand)
val remoteExecutionOutput = remoteScriptExecutionService.executeCommand(remoteExecutionInput)
- executionLogs += remoteExecutionOutput.response
- setOutput(executionLogs)
+ setAttribute(ATTRIBUTE_EXEC_CMD_LOG, remoteExecutionOutput.response.asJsonPrimitive())
check(remoteExecutionOutput.status == StatusType.SUCCESS) {
"failed to get prepare remote command response status for requestId(${remoteExecutionOutput.requestId})"
}
} catch (e: Exception) {
- log.error("", e)
+ log.error("Failed to process on remote executor", e)
} finally {
remoteScriptExecutionService.close()
}
}
- private fun setOutput(executionLogs: String) {
- bluePrintRuntimeService.setNodeTemplateAttributeValue(nodeTemplateName,
- "execution-logs", JacksonUtils.jsonNodeFromObject(executionLogs))
- }
-
override suspend fun recoverNB(runtimeException: RuntimeException, executionRequest: ExecutionServiceInput) {
bluePrintRuntimeService.getBluePrintError()
.addError("Failed in ComponentJythonExecutor : ${runtimeException.message}")
val pckage = Packages.newBuilder()
JsonFormat.parser().merge(it.toString(), pckage)
packageList.add(pckage.build())
- }
+ }
return PrepareEnvInput.newBuilder()
.setIdentifiers(this.remoteIdentifier!!.asGrpcData())
FROM python:3.6-slim
-ENV GRPC_PYTHON_VERSION 1.19.0
+ENV HTTP_PROXY ${HTTP_PROXY}
+ENV HTTPS_PROXY ${HTTPS_PROXY}
+
+ENV GRPC_PYTHON_VERSION 1.20.0
RUN python -m pip install --upgrade pip
RUN pip install grpcio==${GRPC_PYTHON_VERSION} grpcio-tools==${GRPC_PYTHON_VERSION}
RUN pip install virtualenv
import utils
import proto.CommandExecutor_pb2 as CommandExecutor_pb2
+REQUIREMENTS_TXT = "requirements.txt"
+
class CommandExecutorHandler():
return False
f = open(self.installed, "w+")
- if not self.install_packages(request, CommandExecutor_pb2.PYTHON, f, results):
+ if not self.install_packages(request, CommandExecutor_pb2.pip, f, results):
return False
f.write("\r\n")
results.append("\n")
- if not self.install_packages(request, CommandExecutor_pb2.ANSIBLE, f, results):
+ if not self.install_packages(request, CommandExecutor_pb2.ansible_galaxy, f, results):
return False
f.close()
else:
return True
def execute_command(self, request, results):
- if not self.activate_venv():
- return False
+ # if not self.activate_venv():
+ # return False
try:
results.append(os.popen(request.command).read())
for package in request.packages:
if package.type == type:
f.write("Installed %s packages:\r\n" % CommandExecutor_pb2.PackageType.Name(type))
- for python_package in package.package:
- f.write(" %s\r\n" % python_package)
- if package.type == CommandExecutor_pb2.PYTHON:
- success = self.install_python_packages(python_package, results)
+ for p in package.package:
+ f.write(" %s\r\n" % p)
+ if package.type == CommandExecutor_pb2.pip:
+ success = self.install_python_packages(p, results)
else:
- success = self.install_ansible_packages(python_package, results)
+ success = self.install_ansible_packages(p, results)
if not success:
f.close()
os.remove(self.installed)
def install_python_packages(self, package, results):
self.logger.info(
"{} - Install Python package({}) in Python Virtual Environment".format(self.blueprint_id, package))
- command = ["pip", "install", package]
+
+ if REQUIREMENTS_TXT == package:
+ command = ["pip", "install", "-r", self.venv_home + "/Environments/" + REQUIREMENTS_TXT]
+ else:
+ command = ["pip", "install", package]
env = dict(os.environ)
- env['https_proxy'] = os.environ['https_proxy']
+ if "https_proxy" in os.environ:
+ env['https_proxy'] = os.environ['https_proxy']
try:
results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode())
def install_ansible_packages(self, package, results):
self.logger.info(
"{} - Install Ansible Role package({}) in Python Virtual Environment".format(self.blueprint_id, package))
- command = ["ansible-galaxy", "install", package, "-p", "Scripts/ansible/roles"]
+ command = ["ansible-galaxy", "install", package, "-p", self.venv_home + "/Scripts/ansible/roles"]
env = dict(os.environ)
- # ansible galaxy uses https_proxy environment variable, but requires it to be set with http proxy value.
- env['https_proxy'] = os.environ['http_proxy']
+ if "http_proxy" in os.environ:
+ # ansible galaxy uses https_proxy environment variable, but requires it to be set with http proxy value.
+ env['https_proxy'] = os.environ['http_proxy']
try:
results.append(subprocess.run(command, check=True, stdout=PIPE, stderr=PIPE, env=env).stdout.decode())
package='org.onap.ccsdk.cds.controllerblueprints.command.api',
syntax='proto3',
serialized_options=_b('P\001'),
- serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd0\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12O\n\x08packages\x18\x04 \x03(\x0b\x32=.org.onap.ccsdk.cds.controllerblueprints.command.api.Packages\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x08Packages\x12N\n\x04type\x18\x01 \x01(\x0e\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType\x12\x0f\n\x07package\x18\x02 \x03(\t**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01*&\n\x0bPackageType\x12\n\n\x06PYTHON\x10\x00\x12\x0b\n\x07\x41NSIBLE\x10\x01\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3')
+ serialized_pb=_b('\n\x15\x43ommandExecutor.proto\x12\x33org.onap.ccsdk.cds.controllerblueprints.command.api\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n\x0e\x45xecutionInput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x15\n\rcorrelationId\x18\x02 \x01(\t\x12U\n\x0bidentifiers\x18\x03 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\t\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xd0\x02\n\x0fPrepareEnvInput\x12U\n\x0bidentifiers\x18\x01 \x01(\x0b\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.Identifiers\x12\x11\n\trequestId\x18\x02 \x01(\t\x12\x15\n\rcorrelationId\x18\x03 \x01(\t\x12O\n\x08packages\x18\x04 \x03(\x0b\x32=.org.onap.ccsdk.cds.controllerblueprints.command.api.Packages\x12\x0f\n\x07timeOut\x18\x05 \x01(\x05\x12+\n\nproperties\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12-\n\ttimestamp\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\">\n\x0bIdentifiers\x12\x15\n\rblueprintName\x18\x01 \x01(\t\x12\x18\n\x10\x62lueprintVersion\x18\x02 \x01(\t\"\xba\x01\n\x0f\x45xecutionOutput\x12\x11\n\trequestId\x18\x01 \x01(\t\x12\x10\n\x08response\x18\x02 \x01(\t\x12S\n\x06status\x18\x03 \x01(\x0e\x32\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ResponseStatus\x12-\n\ttimestamp\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x08Packages\x12N\n\x04type\x18\x01 \x01(\x0e\x32@.org.onap.ccsdk.cds.controllerblueprints.command.api.PackageType\x12\x0f\n\x07package\x18\x02 \x03(\t**\n\x0eResponseStatus\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01**\n\x0bPackageType\x12\x07\n\x03pip\x10\x00\x12\x12\n\x0e\x61nsible_galaxy\x10\x01\x32\xd1\x02\n\x16\x43ommandExecutorService\x12\x98\x01\n\nprepareEnv\x12\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.PrepareEnvInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutput\x12\x9b\x01\n\x0e\x65xecuteCommand\x12\x43.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionInput\x1a\x44.org.onap.ccsdk.cds.controllerblueprints.command.api.ExecutionOutputB\x02P\x01\x62\x06proto3')
,
dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,])
file=DESCRIPTOR,
values=[
_descriptor.EnumValueDescriptor(
- name='PYTHON', index=0, number=0,
+ name='pip', index=0, number=0,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
- name='ANSIBLE', index=1, number=1,
+ name='ansible_galaxy', index=1, number=1,
serialized_options=None,
type=None),
],
containing_type=None,
serialized_options=None,
serialized_start=1160,
- serialized_end=1198,
+ serialized_end=1202,
)
_sym_db.RegisterEnumDescriptor(_PACKAGETYPE)
PackageType = enum_type_wrapper.EnumTypeWrapper(_PACKAGETYPE)
SUCCESS = 0
FAILURE = 1
-PYTHON = 0
-ANSIBLE = 1
+pip = 0
+ansible_galaxy = 1
file=DESCRIPTOR,
index=0,
serialized_options=None,
- serialized_start=1201,
- serialized_end=1538,
+ serialized_start=1205,
+ serialized_end=1542,
methods=[
_descriptor.MethodDescriptor(
name='prepareEnv',