summaryrefslogtreecommitdiffstats
path: root/saltstack-adapter
diff options
context:
space:
mode:
Diffstat (limited to 'saltstack-adapter')
-rw-r--r--saltstack-adapter/.pydevproject5
-rw-r--r--saltstack-adapter/README.md137
-rw-r--r--saltstack-adapter/pom.xml199
-rw-r--r--saltstack-adapter/saltstack-adapter-installer/pom.xml165
-rw-r--r--saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml61
-rw-r--r--saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml50
-rw-r--r--saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh42
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/.gitignore25
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/pom.xml120
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java59
-rwxr-xr-xsaltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java32
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java172
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java446
-rwxr-xr-xsaltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java192
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java217
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java93
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java89
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java412
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java102
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java100
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java93
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java37
-rwxr-xr-xsaltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml42
-rwxr-xr-xsaltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml42
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties43
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java184
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java1051
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java310
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java76
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls2
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties102
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test30
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json29
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json35
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json30
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls30
-rw-r--r--saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt30
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json203
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml50
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json350
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml112
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json399
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml129
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json203
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml51
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json214
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml52
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json372
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml112
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json214
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml48
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json372
-rw-r--r--saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml112
53 files changed, 7877 insertions, 0 deletions
diff --git a/saltstack-adapter/.pydevproject b/saltstack-adapter/.pydevproject
new file mode 100644
index 000000000..d001f0aea
--- /dev/null
+++ b/saltstack-adapter/.pydevproject
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python interpreter</pydev_property>
+</pydev_project>
diff --git a/saltstack-adapter/README.md b/saltstack-adapter/README.md
new file mode 100644
index 000000000..9c00457b3
--- /dev/null
+++ b/saltstack-adapter/README.md
@@ -0,0 +1,137 @@
+This source repository contains the code for the CCSDK plugins.
+
+To compile this code:
+
+1. Make sure your local Maven settings file ($HOME/.m2/settings.xml) contains references to the ONAP repositories and OpenDaylight repositories. See example-settings.xml for an example.
+
+2. To compile, run "mvn clean install".
+
+
+***SaltStack Adaptor:*** CCSDK SLI ADAPTORS to support SaltStack server:
+
+***Connection from CCSDK SLI ADAPTOR Adaptor to SaltStack server:***
+
+Create an Adaptor to communicate with the SaltStack server:
+1) SaltStack server doesn’t expose any REST API unlike Chef.
+2) SSH based communication with the SaltStack server, one command at a time (preferred). This will mean that SaltStack server should have it’s SSH enabled.
+3) Create a REST-wrap around SaltStack server like is done for Ansible server.
+
+***SSH based communication:***
+1) Adaptor can execute commands on the Salt Master and bring back the result and put to the context memory for DG based analysis. (https://docs.saltstack.com/en/latest/ref/modules/all/index.html#all-salt-modules).
+2) This can be useful for several reasons, for instance it might be useful to know the interfaces in the minions before executing certain network config based commands. This can simple be done by running, 'salt '*' network.interfaces' on server.
+3) SaltStack Server, Output module support: The json-out outputter can be used to display the return data in JSON format. So the DG can put this onto context memory for execution. https://docs.saltstack.com/en/latest/ref/output/all/index.html#all-salt-output
+4) Since the command execution on server might take time, a thread can be spawn to make a single SSH command execution in a SYNC manner. The thread executes the command and brings back the result and puts to the context memory for DG’s access.
+5) For some specific executions operations like configure and upgrade, each configuration execution on the server will be handled by 2 or more SSH command execution. (1 for sending configuration and another for verifying the result). This will give the DGs and Saltstack adaptor with more control on the SaltStack server.
+
+***SaltState (SLS) file for execution on the SaltStack server:***
+ The desired SLS file can be executed by one of the following three ways:
+1) The SLS file for VNF configuration can be assumed to be already on the server, similar to Ansible. In this case, no addition requirements are necessary. We would already know the name of SLS file to execute so the configuration is performed on the VNF.
+2) SLS file creation using DG: Create a DG to parse the configuration and create an SLS file using adaptors such as FileRecorder. Then this SLS file can be passed to the adaptor, so the adaptor can send the configuration to server. The adaptor can also send a SLS file to the Saltstack server and then run the command to execute it.
+3) Third option is for the configuration SLS file that is to be sent to the VNF after instantiation is attached at the design time. This SLS formula- SaltStack file can be picked up and stored in the DB, as part of UEB listener. This can then be sent to adaptor using DGs.
+
+***Requirements and benefits of the chosen SSH method:***
+1) The SaltStack server should have it’s SSH enabled.
+2) Via ssh user account we should have the access to run saltstack command.
+3) Such execution method will give the DGs and adaptor with more refined control on the SaltStack server.
+==================================================================================================================
+
+
+***Defining Saltstack server properties:*** Can be done with 2 different methods.
+1) Saltstack server details are found in the property file named saltstack-adapter.properties. Param has to be given with following types.
+ "org.onap.appc.adapter.saltstack.clientType"; -> Supported types are (BASIC || SSH_CERT || BOTH).
+ "org.onap.appc.adapter.saltstack.host"; -> Saltstack server's host name IP address.
+ "org.onap.appc.adapter.saltstack.port"; -> Saltstack server's port to make SSH connection to.
+ "org.onap.appc.adapter.saltstack.userName"; -> Saltstack server's SSH UserName.
+ "org.onap.appc.adapter.saltstack.userPasswd"; -> Saltstack server's SSH Password.
+ "org.onap.appc.adapter.saltstack.sshKey"; -> Saltstack server's SSH KEY file location.
+2) All the server related details can also be passed as param to the adaptor from the Directed Graphs. Param has to be given with following types.
+ "HostName"; -> Saltstack server's host name IP address.
+ "Port"; -> Saltstack server's port to make SSH connection to.
+ "Password"; -> Saltstack server's SSH UserName.
+ "User"; -> Saltstack server's SSH Password.
+ "withRetry"; -> Specify 'true' if you wanna connect to server with retry.
+ Note: SSH_CERT based Auth is not supported in this method.
+
+***Using Saltstack Adaptor Commands and params to pass in: reqExecCommand API:***
+
+Method to execute a single command on SaltState server and execute a SLS file located on the server. The command entered should request the output in JSON format, this can be done by appending json-out outputter as specified in https://docs.saltstack.com/en/latest/ref/output/all/salt.output.json_out.html#module-salt.output.json_out and https://docs.saltstack.com/en/2017.7/ref/cli/salt-call.html
+The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix.
+If Id is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId.
+1) Execute a single command on SaltState server : Example command will look like:
+1.1) Command to test if all VNFC are running: "salt '*' test.ping --out=json --static"
+1.2) To check Network interfaces on your minions: "salt '*' network.interfaces --out=json --static"
+1.3) Restart Minion service after upgrade process: "salt minion1 service.restart salt-minion --out=json --static"
+Note: If using --out=json, you will probably want --static as well. Without the static option, you will get a separate JSON string per minion which makes JSON output invalid as a whole. This is due to using an iterative outputter. So if you want to feed it to a JSON parser, use --static as well.
+
+This "reqExecCommand" method gives the Operator/Directed Graphs to execute commands in a fine-tuned manner, which also means the operator/DG-creator should know what to expect as output as a result of command execution (for both success/failure case).
+By this way using DGs, the operator can check for success/failure of the executed comment.
+If the output is not in JSON format, then the adaptor still tries to convert it into properties, in addition, params that will hold the command execution result for DG access are (note: this is just to check if the command was executed successfully on the server, this doesn't check the status of the command on saltstack server):
+Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be always be 250, means command execution was success but the result of the execution is unknown and is to be checked from ctx using DGs)
+Message at: org.onap.appc.adapter.saltstack.message
+Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id
+To check the status of the command configuration on saltstack server: the user should exactly know what to look for in the context
+so the user can identify if the configuration execution on the saltstack server succeded or not.
+here for instance, in 1.1) the user should check if $reqId.<minion-name> is set to true in the context memory using DGs.
+
+2) Execute a SLS file located on the server : Example command will look like:
+Knowing the saltstack server has vim.sls file located at "/srv/salt" directory then user can execute the following commands:
+1.1) Command to run the vim.sls file on saltstack server: Cmd = "salt '*' state.apply vim --out=json --static"
+1.2) Command to run the nettools.sls file on saltstack server: Cmd = "cd /srv/salt/; salt '*' state.apply <sls-file-name> --out=json --static"
+Important thing to note: If the reqExecCommand is used to execute sls file then along with following,
+ "HostName"; -> Saltstack server's host name IP address.
+ "Port"; -> Saltstack server's port to make SSH connection to.
+ "Password"; -> Saltstack server's SSH UserName.
+ "User"; -> Saltstack server's SSH Password.
+the param should contain,
+ "SlsExec"; -> this variable should be set to true.
+ "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds).
+
+In this case, params that will hold the command execution result for DG access in Key:
+Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful)
+Message at: org.onap.appc.adapter.saltstack.message
+Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id
+The result code here will be the execution of configuration SLS file on the server.
+NOTE: It would be better to use reqExecSLS, where you will only have to specify SLS file name on server to execute it.
+
+
+***Using Saltstack Adaptor Commands and params to pass in: reqExecSLS API:***
+
+Method to execute a single sls on SaltState server (Where the SLS file already located on the server). The command entered will only be the SLS file name and the output will be in JSON format automatically.
+The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix.
+If request Id (Id) is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId.
+1) Execute a single command on SaltState server : Example command will look like:
+ In the context set the "SlsName" to "test.sls"
+ In the context set the "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds).
+ In the context set the "NodeList" to "minion1" //to the minions or VNFCs you want to apply the SLS file to.
+ "NodeList" can be empty or set to "*" is the SLS has to be applied to all the minions or VNFCs.
+ In the context set the "FileParameters: A JSON dictionary where keys are filenames and values are contents of files. The Saltstack Server will utilize this feature to generate files with keys as filenames and values as content. This attribute can be used to generate files that a SSL file may require as part of execution (Optional).
+ In the context set the "EnvParameters: A JSON dictionary which should list key value pairs to be passed to the Salstack command to run SLS. These values would correspond to instance specific parameters that a playbook may need to execute an action.
+
+In this case, params that will hold the command execution result for DG access in Key:
+Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful)
+Message at: org.onap.appc.adapter.saltstack.message
+Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id
+The result code here will be the execution of configuration SLS file on the server.
+
+***Using Saltstack Adaptor Commands and params to pass in: reqExecSLSFile API:***
+
+Method to execute a single sls on SaltState server (Where the SLS file in the adaptor). The command entered will only be the SLS file location on the APPC/ODL container and the output from server will be in JSON format automatically.
+The response from Saltstack comes in json format and it is automatically put to context for DGs access, with a certain request-ID as prefix.
+If request Id (Id) is not passed as part of input param, then a random Id will be generated and put to properties in "org.onap.appc.adapter.saltstack.Id" field. All the output message from the execution will be appended with reqId.
+1) Execute a single command on SaltState server : Example command will look like:
+ In the context set the "SlsFile" to "/path/to/test.sls" //mention the path of the SLS file in ODL container.
+ In the context set the "Timeout"; -> set large timeout if your SLS file will take large time to finish executing (in Seconds).
+ In the context set the "NodeList" to "minion1" //to the minions or VNFCs you want to apply the SLS file to.
+ "NodeList" can be empty or set to 'minion*' (pattern matching) or set to "*" is the SLS has to be applied to all the minions or VNFCs.
+ In the context set the "FileParameters: A JSON dictionary where keys are filenames and values are contents of files. The Saltstack Server will utilize this feature to generate files with keys as filenames and values as content. This attribute can be used to generate files that a SSL file may require as part of execution (Optional).
+ In the context set the "EnvParameters: A JSON dictionary which should list key value pairs to be passed to the Salstack command to run SLS. These values would correspond to instance specific parameters that a playbook may need to execute an action.
+
+In this case, params that will hold the command execution result for DG access in Key:
+Result code at: org.onap.appc.adapter.saltstack.result.code (On success: This will be 200, this means the command was executed successfully and also configuration change made using the SLS file was also successful)
+Message at: org.onap.appc.adapter.saltstack.message
+Both user inputted/auto generated req Id at: org.onap.appc.adapter.saltstack.Id
+The result code here will be the execution of configuration SLS file on the server.
+
+Control the state system on the minion: by specifying Env Params (pillars) and Files.
+
+https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.state.html \ No newline at end of file
diff --git a/saltstack-adapter/pom.xml b/saltstack-adapter/pom.xml
new file mode 100644
index 000000000..de8a87b05
--- /dev/null
+++ b/saltstack-adapter/pom.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ ================================================================================
+
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>2.1.0</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+ <artifactId>saltstack-adaptor</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>ccsdk-sli-adaptors :: saltstack-adapter</name>
+ <description>Abstractions to interact with Saltstack server via REST
+ </description>
+
+ <modules>
+ <module>saltstack-adapter-provider</module>
+ <module>saltstack-adapter-installer</module>
+ </modules>
+
+ <dependencyManagement>
+ <dependencies>
+
+ <dependency>
+ <groupId>org.onap.appc</groupId>
+ <artifactId>saltstack-adapter-features</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.appc</groupId>
+ <artifactId>saltstack-adapter-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+
+
+ </dependencies>
+
+
+ </dependencyManagement>
+
+ <pluginRepositories>
+ <!-- Black Duck plugin dependencies -->
+ <pluginRepository>
+ <id>JCenter</id>
+ <name>JCenter Repository</name>
+ <url>http://jcenter.bintray.com</url>
+ </pluginRepository>
+
+ </pluginRepositories>
+
+ <build>
+ <plugins>
+
+ <!-- Black duck plugin Not required for regular builds
+ <plugin> <groupId>com.blackducksoftware.integration</groupId> <artifactId>hub-maven-plugin</artifactId>
+ <version>1.4.0</version> <inherited>false</inherited> <configuration> <hubProjectName>${project.name}</hubProjectName>
+ <outputDirectory>${project.basedir}</outputDirectory> <deployHubBdio>false</deployHubBdio>
+ </configuration> <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>create-bdio-file</id>
+ <phase>package</phase>
+ <goals>
+ <goal>createHubOutput</goal>
+ </goals>
+ </execution>
+ </executions>
+
+ </plugin>
+ -->
+
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <additionalDependencies>
+ <additionalDependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>${slf4j.version}</version>
+ </additionalDependency>
+ <additionalDependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4</artifactId>
+ <version>${antlr.version}</version>
+ </additionalDependency>
+ <additionalDependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr4-runtime</artifactId>
+ <version>4.3</version>
+ </additionalDependency>
+ </additionalDependencies>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>javadoc-no-fork</report>
+ <report>test-javadoc-no-fork</report>
+ </reports>
+ </reportSet>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ <report>test-aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jxr-plugin</artifactId>
+ <version>2.3</version>
+ <reportSets>
+ <reportSet>
+ <id>aggregate</id>
+ <reports>
+ <report>aggregate</report>
+ <report>test-aggregate</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changelog-plugin</artifactId>
+ <version>2.3</version>
+ <reportSets>
+ <reportSet>
+ <id>dual-report</id>
+ <configuration>
+ <type>range</type>
+ <range>30</range>
+ </configuration>
+ <reports>
+ <report>changelog</report>
+ <report>file-activity</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>taglist-maven-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ </plugins>
+
+ </reporting>
+</project>
diff --git a/saltstack-adapter/saltstack-adapter-installer/pom.xml b/saltstack-adapter/saltstack-adapter-installer/pom.xml
new file mode 100644
index 000000000..67e30fa02
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-installer/pom.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ ================================================================================
+
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>2.1.0</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+ <artifactId>saltstack-adapter-installer</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <name>ccsdk-sli-adaptors :: saltstack-adapter :: ${project.artifactId}
+ </name>
+
+ <properties>
+ <application.name>ccsdk-saltstack-adapter</application.name>
+ <features.boot>${application.name}</features.boot>
+ <features.repositories>
+ mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features
+ </features.repositories>
+ <include.transitive.dependencies>false</include.transitive.dependencies>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+ <artifactId>saltstack-adapter-provider</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>maven-repo-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>true</appendAssemblyId>
+ <attach>true</attach>
+ <finalName>
+ stage/${application.name}-${project.version}
+ </finalName>
+ <descriptors>
+ <descriptor>
+ src/assembly/assemble_mvnrepo_zip.xml
+ </descriptor>
+ </descriptors>
+ <appendAssemblyId>true</appendAssemblyId>
+ </configuration>
+ </execution>
+ <execution>
+ <id>installer-zip</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>true</attach>
+ <finalName>${application.name}-${project.version}
+ </finalName>
+ <descriptors>
+ <descriptor>
+ src/assembly/assemble_installer_zip.xml
+ </descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-dependencies</id>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <phase>prepare-package</phase>
+ <configuration>
+ <transitive>false</transitive>
+ <outputDirectory>
+ ${project.build.directory}/assembly/system
+ </outputDirectory>
+ <overWriteReleases>false</overWriteReleases>
+ <overWriteSnapshots>true</overWriteSnapshots>
+ <overWriteIfNewer>true</overWriteIfNewer>
+ <useRepositoryLayout>true</useRepositoryLayout>
+ <addParentPoms>false</addParentPoms>
+ <copyPom>false</copyPom>
+ <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds>
+ <scope>provided</scope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy-version</id>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <!-- here the phase you need -->
+ <phase>validate</phase>
+ <configuration>
+ <outputDirectory>${basedir}/target/stage
+ </outputDirectory>
+ <resources>
+ <resource>
+ <directory>src/main/resources/scripts
+ </directory>
+ <includes>
+ <include>install-feature.sh</include>
+ </includes>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml
new file mode 100644
index 000000000..d307e4f30
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_installer_zip.xml
@@ -0,0 +1,61 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ ================================================================================
+
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>adapter</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>755</fileMode>
+ <includes>
+ <include>*.sh</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>target/stage/</directory>
+ <outputDirectory>${application.name}</outputDirectory>
+ <fileMode>644</fileMode>
+ <excludes>
+ <exclude>*.sh</exclude>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+
+</assembly>
diff --git a/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644
index 000000000..1b1bf0b6b
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-installer/src/assembly/assemble_mvnrepo_zip.xml
@@ -0,0 +1,50 @@
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ ================================================================================
+
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <id>repo</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+
+ <!-- we want "system" and related files right at the root level
+ as this file is suppose to be unzip on top of a karaf
+ distro. -->
+ <includeBaseDirectory>false</includeBaseDirectory>
+
+ <fileSets>
+ <fileSet>
+ <directory>target/assembly/</directory>
+ <outputDirectory>.</outputDirectory>
+ <excludes>
+ </excludes>
+ </fileSet>
+ </fileSets>
+
+</assembly>
diff --git a/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh b/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh
new file mode 100644
index 000000000..38782cabb
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-installer/src/main/resources/scripts/install-feature.sh
@@ -0,0 +1,42 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2018 Samsung Electronics. All rights reserved.
+# ================================================================================
+#
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file 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=========================================================
+###
+
+#!/bin/bash
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+ unzip -n -d ${ODL_HOME} ${REPOZIP}
+else
+ echo "ERROR : repo zip ($REPOZIP) not found"
+ exit 1
+fi
+
+${ODL_KARAF_CLIENT} feature:repo-add ${features.repositories}
+${ODL_KARAF_CLIENT} feature:install ${features.boot}
diff --git a/saltstack-adapter/saltstack-adapter-provider/.gitignore b/saltstack-adapter/saltstack-adapter-provider/.gitignore
new file mode 100644
index 000000000..4e1ad823a
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/.gitignore
@@ -0,0 +1,25 @@
+# ============LICENSE_START==========================================
+# ONAP : CCSDK
+# ===================================================================
+# Copyright (C) 2017-2018 Samsung Electronics. 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============================================
+/bin/
+/target/
+/target-ide/
+/.settings/
diff --git a/saltstack-adapter/saltstack-adapter-provider/pom.xml b/saltstack-adapter/saltstack-adapter-provider/pom.xml
new file mode 100644
index 000000000..4b6868179
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/pom.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ============LICENSE_START=======================================================
+ ONAP : CCSDK ================================================================================
+ Copyright (C) 2017-2018 Samsung Electronics. All rights reserved.
+ ================================================================================
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ use this file 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========================================================= -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onap.ccsdk.parent</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>2.1.0</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+ <artifactId>saltstack-adapter-provider</artifactId>
+ <version>1.1.1-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>ccsdk-sli-adaptors :: saltstack-adapter :: ${project.artifactId}
+ </name>
+
+ <properties>
+ <ccsdk.sli.adaptors.version>${project.version}</ccsdk.sli.adaptors.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-core-artifacts</artifactId>
+ <version>${ccsdk.sli.core.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>com.att.eelf</groupId>
+ <artifactId>eelf-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+
+ <!-- Needed to run SSH -->
+ <!-- VERSION CONFLICT !!!!! -->
+ <!-- OpenDaylight Fluorine comes with version 1.7.0 installed, which is not compatible -->
+ <!-- Code must be updated to use version 1.7.0 before this can be safely installed -->
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-core</artifactId>
+ <version>1.7.0</version>
+ </dependency>
+
+ <!-- Needed to run test cases -->
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.jettison</groupId>
+ <artifactId>jettison</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-common</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.ccsdk.sli.core</groupId>
+ <artifactId>sli-provider</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
+
+ </dependencies>
+</project>
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java
new file mode 100644
index 000000000..346910a39
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapter.java
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack;
+
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+
+import java.util.Map;
+
+/**
+ * This interface defines the operations that the Saltstack adapter exposes.
+ */
+public interface SaltstackAdapter extends SvcLogicJavaPlugin {
+ /**
+ * Returns the symbolic name of the adapter
+ *
+ * @return The adapter name
+ */
+ String getAdapterName();
+
+ /* Method to post a single command request for execution on SaltState server
+ * The response from Saltstack comes in json format and it is automatically put
+ * to context for DGs access, with a certain prefix*/
+ void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+
+ /* Method for execution of saltstack SLS command on SaltState server
+ * The response from Saltstack comes in json format and it is automatically put
+ * to context for DGs access, with a certain prefix*/
+ void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+
+ /* When SLS file is created/available then this Method can be used to post
+ * the file to saltstack server and execute the SLS file on SaltState server
+ * The response from Saltstack comes in json format and it is automatically put
+ * to context for DGs access, with a certain prefix*/
+ void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java
new file mode 100755
index 000000000..a6b707afc
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/SaltstackAdapterPropertiesProvider.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack;
+
+import java.util.Properties;
+
+public interface SaltstackAdapterPropertiesProvider {
+
+ public Properties getProperties();
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java
new file mode 100644
index 000000000..48469fdd5
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/ConnectionBuilder.java
@@ -0,0 +1,172 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.impl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SshException;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * Returns a custom SSH client
+ * - based on options
+ * - can create one with ssl using an X509 certificate that does NOT have a known CA
+ * - create one which trusts ALL SSL certificates
+ * - return default sshclient (which only trusts known CAs from default cacerts file for process) this is the default
+ * option
+ **/
+public class ConnectionBuilder {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ConnectionBuilder.class);
+ SshConnection sshConnection;
+
+ /**
+ * Constructor that initializes an ssh client based on username and password
+ **/
+ public ConnectionBuilder(String host, String port, String userName, String userPasswd) {
+ sshConnection = new SshConnection(host, Integer.parseInt(port), userName, userPasswd);
+ }
+
+ /**
+ * Constructor that initializes an ssh client based on ssh certificate
+ * This is still not supported in 1.3.0 version
+ **/
+ public ConnectionBuilder(String host, String port, String certFile) {
+ sshConnection = new SshConnection(host, Integer.parseInt(port), certFile);
+ }
+
+
+ /**
+ * 1. Connect to SSH server.
+ * 2. Exec remote command over SSH. Return command execution status.
+ * Command output is written to out or err stream.
+ *
+ * @param cmd Commands to execute
+ * @return command execution status
+ */
+ public SaltstackResult connectNExecute(String cmd, long execTimeout) throws IOException {
+ return connectNExecute(cmd, false, execTimeout);
+ }
+
+ /**
+ * 1. Connect to SSH server with retry enabled.
+ * 2. Exec remote command over SSH. Return command execution status.
+ * Command output is written to out or err stream.
+ *
+ * @param cmd Commands to execute
+ * @param withRetry make a SSH connection with default retry.
+ * @return command execution status
+ */
+ public SaltstackResult connectNExecute(String cmd, boolean withRetry, long execTimeout)
+ throws IOException {
+
+ SaltstackResult result = new SaltstackResult();
+ ByteArrayOutputStream out = null;
+ ByteArrayOutputStream errs = null;
+ if (execTimeout >= 0) {
+ sshConnection.setExecTimeout(execTimeout);
+ }
+
+ try {
+ if (withRetry) {
+ sshConnection.connectWithRetry();
+ } else {
+ sshConnection.connect();
+ }
+ out = new ByteArrayOutputStream();
+ errs = new ByteArrayOutputStream();
+ int resultCode = sshConnection.execCommand(cmd, out, errs);
+ sshConnection.disconnect();
+ if (resultCode != 0) {
+ return sortExitStatus(resultCode, errs.toString(), cmd);
+ }
+ result.setStatusCode(SaltstackResultCodes.SUCCESS.getValue());
+ result.setStatusMessage("Success");
+ result.setOutputMessage(out);
+ } catch (SshException io) {
+ if (io.toString().equalsIgnoreCase("Authentication failed")) {
+ logger.error(io.toString());
+ result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue());
+ result.setStatusMessage(io.toString());
+ return result;
+ }
+ logger.error("Caught Exception", io);
+ result.setStatusCode(SaltstackResultCodes.SSH_EXCEPTION.getValue());
+ result.setStatusMessage(io.getMessage());
+ } catch (Exception io) {
+ logger.error("Caught Exception", io);
+ result.setStatusCode(SaltstackResultCodes.SSH_EXCEPTION.getValue());
+ result.setStatusMessage(io.getMessage());
+ } finally {
+ if (out != null) {
+ out.close();
+ }
+ if (errs != null) {
+ errs.close();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Print Reasonable error messages based on SSH Exit status code
+ * */
+ public SaltstackResult sortExitStatus(int exitStatus, String errMess, String cmd) {
+ SaltstackResult result = new SaltstackResult();
+ if (exitStatus == 255 || exitStatus == 1) {
+ String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ + "]. Exit Code " + exitStatus + " and Error message : " +
+ "Malformed configuration. " + errMess;
+ logger.error(errMessage);
+ result.setStatusCode(SaltstackResultCodes.INVALID_COMMAND.getValue());
+ result.setStatusMessage(errMessage);
+ } else if (exitStatus == 5 || exitStatus == 65) {
+ String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ + "]. Exit Code " + exitStatus + " and Error message : " +
+ "Host not allowed to connect. " + errMess;
+ logger.error(errMessage);
+ result.setStatusCode(SaltstackResultCodes.USER_UNAUTHORIZED.getValue());
+ result.setStatusMessage(errMessage);
+ } else if (exitStatus == 67 || exitStatus == 73) {
+ String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ + "]. Exit Code " + exitStatus + " and Error message : " +
+ "Key exchange failed. " + errMess;
+ logger.error(errMessage);
+ result.setStatusCode(SaltstackResultCodes.CERTIFICATE_ERROR.getValue());
+ result.setStatusMessage(errMessage);
+ } else {
+ String errMessage = "Error executing command [" + cmd + "] over SSH [" + sshConnection.toString()
+ + "]. Exit Code " + exitStatus + " and Error message : " + errMess;
+ logger.error(errMessage);
+ result.setStatusCode(SaltstackResultCodes.UNKNOWN_EXCEPTION.getValue());
+ result.setStatusMessage(errMessage);
+ }
+ return result;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java
new file mode 100644
index 000000000..34321ea59
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterImpl.java
@@ -0,0 +1,446 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.impl;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter;
+import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackMessageParser;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResultCodes;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackServerEmulator;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * This class implements the {@link SaltstackAdapter} interface. This interface defines the behaviors
+ * that our service provides.
+ */
+public class SaltstackAdapterImpl implements SaltstackAdapter {
+
+ /**
+ * The constant for the status code for a failed outcome
+ */
+ @SuppressWarnings("nls")
+ public static final String OUTCOME_FAILURE = "failure";
+ /**
+ * The constant for the status code for a successful outcome
+ */
+ @SuppressWarnings("nls")
+ public static final String OUTCOME_SUCCESS = "success";
+ public static final String CONNECTION_RETRY = "withRetry";
+ private static final String APPC_EXCEPTION_CAUGHT = "APPCException caught";
+ /**
+ * Adapter Name
+ */
+ private static final String ADAPTER_NAME = "Saltstack Adapter";
+ private static final String RESULT_CODE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.result.code";
+ private static final String MESSAGE_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.message";
+ private static final String ID_ATTRIBUTE_NAME = "org.onap.appc.adapter.saltstack.Id";
+ private static final String CLIENT_TYPE_PROPERTY_NAME = "org.onap.appc.adapter.saltstack.clientType";
+ private static final String SS_SERVER_HOSTNAME = "org.onap.appc.adapter.saltstack.host";
+ private static final String SS_SERVER_PORT = "org.onap.appc.adapter.saltstack.port";
+ private static final String SS_SERVER_USERNAME = "org.onap.appc.adapter.saltstack.userName";
+ private static final String SS_SERVER_PASSWD = "org.onap.appc.adapter.saltstack.userPasswd";
+ private static final String SS_SERVER_SSH_KEY = "org.onap.appc.adapter.saltstack.sshKey";
+
+ private static final String COMMAND_IN_JSON_OUT = " --out=json --static ";
+ private static final String COMMAND_CHANGE_DEFAULT_DIR = " cd /srv/salt/ ;";
+
+ /**
+ * The logger to be used
+ */
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackAdapterImpl.class);
+ /**
+ * Connection object
+ **/
+ private ConnectionBuilder sshClient;
+
+ /**
+ * Saltstack API Message Handlers
+ **/
+ private SaltstackMessageParser messageProcessor;
+
+ /**
+ * indicator whether in test mode
+ **/
+ private boolean testMode = false;
+
+ /**
+ * server emulator object to be used if in test mode
+ **/
+ private SaltstackServerEmulator testServer;
+
+ /**
+ * This default constructor is used as a work around because the activator wasn't getting called
+ */
+ public SaltstackAdapterImpl() throws SvcLogicException {
+ initialize(new SaltstackAdapterPropertiesProviderImpl());
+ }
+
+ public SaltstackAdapterImpl(SaltstackAdapterPropertiesProvider propProvider) throws SvcLogicException {
+ initialize(propProvider);
+ }
+
+ /**
+ * Used for jUnit test and testing interface
+ */
+ public SaltstackAdapterImpl(boolean mode) {
+ testMode = mode;
+ testServer = new SaltstackServerEmulator();
+ messageProcessor = new SaltstackMessageParser();
+ }
+
+ /**
+ * Returns the symbolic name of the adapter
+ *
+ * @return The adapter name
+ * @see SaltstackAdapter#getAdapterName()
+ */
+ @Override
+ public String getAdapterName() {
+ return ADAPTER_NAME;
+ }
+
+ /**
+ * Method posts info to Context memory in case of an error and throws a
+ * SvcLogicException causing SLI to register this as a failure
+ */
+ @SuppressWarnings("static-method")
+ private void doFailure(SvcLogicContext svcLogic, int code, String message) throws SvcLogicException {
+ logger.error(APPC_EXCEPTION_CAUGHT, message);
+ svcLogic.setStatus(OUTCOME_FAILURE);
+ svcLogic.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(code));
+ svcLogic.setAttribute(MESSAGE_ATTRIBUTE_NAME, message);
+ throw new SvcLogicException("Saltstack Adapter Error = " + message);
+ }
+
+ /**
+ * initialize the Saltstack adapter based on default and over-ride configuration data
+ */
+ private void initialize(SaltstackAdapterPropertiesProvider propProvider) throws SvcLogicException {
+
+
+ Properties props = propProvider.getProperties();
+
+ // Create the message processor instance
+ messageProcessor = new SaltstackMessageParser();
+
+ // Create the ssh client instance
+ // type of client is extracted from the property file parameter
+ // org.onap.appc.adapter.saltstack.clientType
+ // It can be :
+ // 1. BASIC. SSH Connection using username and password
+ // 2. SSH_CERT (trust only those whose certificates have been stored in the SSH KEY file)
+ // 3. DEFAULT SSH Connection without any authentication
+
+ try {
+ String clientType = props.getProperty(CLIENT_TYPE_PROPERTY_NAME);
+ logger.info("Saltstack ssh client type set to " + clientType);
+
+ if ("BASIC".equalsIgnoreCase(clientType)) {
+ logger.info("Creating ssh client connection");
+ // set path to keystore file
+ String sshHost = props.getProperty(SS_SERVER_HOSTNAME);
+ String sshPort = reqServerPort(props);
+ String sshUserName = props.getProperty(SS_SERVER_USERNAME);
+ String sshPassword = props.getProperty(SS_SERVER_PASSWD);
+ sshClient = new ConnectionBuilder(sshHost, sshPort, sshUserName, sshPassword);
+ } else if ("SSH_CERT".equalsIgnoreCase(clientType)) {
+ // set path to keystore file
+ String sshKey = props.getProperty(SS_SERVER_SSH_KEY);
+ String sshHost = props.getProperty(SS_SERVER_HOSTNAME);
+ String sshPort = reqServerPort(props);
+ logger.info("Creating ssh client with ssh KEY from " + sshKey);
+ sshClient = new ConnectionBuilder(sshHost, sshPort, sshKey);
+ } else {
+ logger.info("No saltstack-adapter.properties defined so reading from DG props");
+ sshClient = null;
+ }
+ } catch (NumberFormatException e) {
+ logger.error("Error Initializing Saltstack Adapter due to Unknown Exception", e);
+ throw new SvcLogicException("Saltstack Adapter Property file parsing Error = port in property file has to be an integer.");
+ } catch (Exception e) {
+ logger.error("Error Initializing Saltstack Adapter due to Exception", e);
+ throw new SvcLogicException("Saltstack Adapter Property file parsing Error = " + e.getMessage());
+ }
+ logger.info("Initialized Saltstack Adapter");
+ }
+
+ private String reqServerPort(Properties props) {
+ // use default port if null
+ if (props.getProperty(SS_SERVER_PORT) == null) {
+ return "22";
+ }
+ return props.getProperty(SS_SERVER_PORT);
+ }
+
+ private void setSSHClient(Map<String, String> params) throws SvcLogicException {
+ if (sshClient == null) {
+ logger.info("saltstack-adapter.properties not defined so reading saltstack host and " +
+ "auth details from DG's parameters");
+ String sshHost = messageProcessor.reqHostNameResult(params);
+ String sshPort = messageProcessor.reqPortResult(params);
+ String sshUserName = messageProcessor.reqUserNameResult(params);
+ String sshPassword = messageProcessor.reqPasswordResult(params);
+ logger.info("Creating ssh client with BASIC Auth");
+ if (!testMode) {
+ sshClient = new ConnectionBuilder(sshHost, sshPort, sshUserName, sshPassword);
+ }
+ }
+ }
+
+ private String parseEnvParam(JSONObject envParams) {
+ StringBuilder envParamBuilder = new StringBuilder();
+ if (envParams != null) {
+ for (Object key : envParams.keySet()) {
+ if (envParamBuilder.length() > 0) {
+ envParamBuilder.append(", ");
+ }
+ envParamBuilder.append(key + "=" + envParams.get((String) key));
+ logger.info("EnvParameters : " + envParamBuilder);
+ }
+ }
+ return envParamBuilder.toString();
+ }
+
+ private String parseFileParam(JSONObject fileParams) {
+ StringBuilder fileParamBuilder = new StringBuilder();
+ if (fileParams != null) {
+ for (Object key : fileParams.keySet()) {
+ fileParamBuilder.append("echo -e \"" + fileParams.get((String) key) + "\" > /srv/salt/" + key).append("; ");
+ logger.info("FileParameters : " + fileParamBuilder);
+ }
+ }
+ return fileParamBuilder.toString();
+ }
+
+ private String putToCommands(SvcLogicContext ctx, String slsFileName,
+ String applyTo, JSONObject envParams, JSONObject fileParams) throws SvcLogicException {
+
+ StringBuilder constructedCommand = new StringBuilder();
+ try {
+ File file = new File(slsFileName);
+ String slsFile = file.getName();
+ if (!slsFile.substring(slsFile.lastIndexOf("."),
+ slsFile.length()).equalsIgnoreCase(".sls")) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input file " +
+ "is not of type .sls");
+ }
+ try(InputStream in = new FileInputStream(file)){
+ byte[] data = new byte[(int) file.length()];
+ in.read(data);
+ String str = new String(data, "UTF-8");
+ String slsWithoutExtn = stripExtension(slsFile);
+ constructedCommand.append(parseFileParam(fileParams)).append("echo -e \"").append(str).append("\" > /srv/salt/").
+ append(slsFile).append("; ").append(COMMAND_CHANGE_DEFAULT_DIR).append(" salt '").
+ append(applyTo).append("' state.apply ").append(slsWithoutExtn).append(" ").append(parseEnvParam(envParams)).append(COMMAND_IN_JSON_OUT);
+ }
+ logger.info("Command to be executed on server : " + constructedCommand.toString());
+
+ } catch (FileNotFoundException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " +
+ "not found in path : " + slsFileName + ". " + e.getMessage());
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input SLS file " +
+ "error in path : " + slsFileName + ". " + e.getMessage());
+ } catch (StringIndexOutOfBoundsException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(), "Input file " +
+ "is not of type .sls");
+ }
+ return constructedCommand.toString();
+ }
+
+ private String stripExtension(String str) {
+ if (str == null) {
+ return null;
+ }
+ int pos = str.lastIndexOf(".");
+ if (pos == -1) {
+ return str;
+ }
+ return str.substring(0, pos);
+ }
+
+ private String putToCommands(String slsName, String applyTo, JSONObject envParams, JSONObject fileParams) {
+
+ StringBuilder constructedCommand = new StringBuilder();
+
+ constructedCommand.append(parseFileParam(fileParams)).append(COMMAND_CHANGE_DEFAULT_DIR).append(" salt '").append(applyTo)
+ .append("' state.apply ").append(slsName).append(" ").append(parseEnvParam(envParams)).append(COMMAND_IN_JSON_OUT);
+
+ logger.info("Command to be executed on server : " + constructedCommand.toString());
+ return constructedCommand.toString();
+ }
+
+ private void checkResponseStatus(SaltstackResult testResult, SvcLogicContext ctx, String reqID, boolean slsExec)
+ throws SvcLogicException {
+
+ // Check status of test request returned by Agent
+ if (testResult.getStatusCode() != SaltstackResultCodes.FINAL_SUCCESS.getValue()) {
+ ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID);
+ doFailure(ctx, testResult.getStatusCode(), "Request for execution of command failed. Reason = " + testResult.getStatusMessage());
+ } else {
+ logger.info(String.format("Execution of request : successful."));
+ ctx.setAttribute(RESULT_CODE_ATTRIBUTE_NAME, Integer.toString(testResult.getStatusCode()));
+ ctx.setAttribute(MESSAGE_ATTRIBUTE_NAME, OUTCOME_SUCCESS);
+ ctx.setAttribute(ID_ATTRIBUTE_NAME, reqID);
+ }
+ }
+
+ // Public Method to post single command request to execute saltState. Posts the following back
+ // to Svc context memory
+ // org.onap.appc.adapter.saltstack.req.code : 100 if successful
+ // org.onap.appc.adapter.saltstack.req.messge : any message
+ // org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
+ @Override
+ public void reqExecCommand(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+ String reqID;
+ boolean slsExec;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ try {
+ reqID = messageProcessor.reqId(params);
+ String commandToExecute = messageProcessor.reqCmd(params);
+ slsExec = messageProcessor.reqIsSLSExec(params);
+ long execTimeout = messageProcessor.reqExecTimeout(params);
+ testResult = execCommand(ctx, params, commandToExecute, execTimeout);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, slsExec);
+ checkResponseStatus(testResult, ctx, reqID, slsExec);
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(),
+ "IOException in file stream : " + e.getMessage());
+ }
+ }
+
+ /**
+ * Public Method to post SLS command request to execute saltState on server. Posts the following back
+ * to Svc context memory
+ * <p>
+ * org.onap.appc.adapter.saltstack.req.code : 200 if successful
+ * org.onap.appc.adapter.saltstack.req.messge : any message
+ * org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
+ */
+ @Override
+ public void reqExecSLS(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+ String reqID;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ try {
+ reqID = messageProcessor.reqId(params);
+ String slsName = messageProcessor.reqSlsName(params);
+ String applyTo = messageProcessor.reqApplyToDevices(params);
+ long execTimeout = messageProcessor.reqExecTimeout(params);
+ JSONObject envParams = messageProcessor.reqEnvParameters(params);
+ JSONObject fileParams = messageProcessor.reqFileParameters(params);
+
+ String commandToExecute = putToCommands(slsName, applyTo, envParams, fileParams);
+ testResult = execCommand(ctx, params, commandToExecute, execTimeout);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true);
+ checkResponseStatus(testResult, ctx, reqID, true);
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(),
+ "IOException in file stream : " + e.getMessage());
+ } catch (JSONException e) {
+ doFailure(ctx, SaltstackResultCodes.INVALID_COMMAND.getValue(), e.getMessage());
+ }
+ }
+
+ /**
+ * Public Method to post SLS file request to execute saltState. Posts the following back
+ * to Svc context memory
+ * <p>
+ * org.onap.appc.adapter.saltstack.req.code : 100 if successful
+ * org.onap.appc.adapter.saltstack.req.messge : any message
+ * org.onap.appc.adapter.saltstack.req.Id : a unique uuid to reference the request
+ */
+ @Override
+ public void reqExecSLSFile(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+ String reqID;
+ SaltstackResult testResult;
+ setSSHClient(params);
+ try {
+ reqID = messageProcessor.reqId(params);
+ String slsFile = messageProcessor.reqSlsFile(params);
+ String applyTo = messageProcessor.reqApplyToDevices(params);
+ long execTimeout = messageProcessor.reqExecTimeout(params);
+ JSONObject envParams = messageProcessor.reqEnvParameters(params);
+ JSONObject fileParams = messageProcessor.reqFileParameters(params);
+
+ String commandToExecute = putToCommands(ctx, slsFile, applyTo, envParams, fileParams);
+ testResult = execCommand(ctx, params, commandToExecute, execTimeout);
+ testResult = messageProcessor.parseResponse(ctx, reqID, testResult, true);
+ checkResponseStatus(testResult, ctx, reqID, true);
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(),
+ "IOException in file stream : " + e.getMessage());
+ }
+ }
+
+ public SaltstackResult execCommand(SvcLogicContext ctx, Map<String, String> params, String commandToExecute,
+ long execTimeout)
+ throws SvcLogicException {
+
+ //convert execTimeout to Milliseconds
+ execTimeout = execTimeout * 1000;
+ SaltstackResult testResult = new SaltstackResult();
+ try {
+ if (params.get(CONNECTION_RETRY) == null) {
+ if (!testMode) {
+ testResult = sshClient.connectNExecute(commandToExecute, execTimeout);
+ } else {
+ testResult = testServer.mockReqExec(params);
+ }
+ } else if (params.get(CONNECTION_RETRY).equalsIgnoreCase("true")) {
+ if (!testMode) {
+ testResult = sshClient.connectNExecute(commandToExecute, true, execTimeout);
+ } else {
+ testResult = testServer.mockReqExec(params);
+ }
+ } else {
+ if (!testMode) {
+ testResult = sshClient.connectNExecute(commandToExecute, execTimeout);
+ } else {
+ testResult = testServer.mockReqExec(params);
+ }
+ }
+ } catch (IOException e) {
+ doFailure(ctx, SaltstackResultCodes.IO_EXCEPTION.getValue(),
+ "IOException in file stream : " + e.getMessage());
+ }
+ return testResult;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java
new file mode 100755
index 000000000..8f0d9857a
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SaltstackAdapterPropertiesProviderImpl.java
@@ -0,0 +1,192 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.impl;
+
+import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider;
+import org.onap.ccsdk.sli.core.sli.ConfigurationException;
+import org.onap.ccsdk.sli.core.utils.JREFileResolver;
+import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver;
+import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.CoreDefaultFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Vector;
+
+/**
+ * Responsible for determining the properties file to use and instantiating the
+ * <code>SqlResource</code> Service. The priority for properties file
+ * resolution is as follows:
+ * <p>
+ * <ol>
+ * <li>A directory identified by the system environment variable
+ * <code>SDNC_CONFIG_DIR</code></li>
+ * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li>
+ * <li>A directory identified by the JRE argument
+ * <code>sql-resource.properties</code></li>
+ * <li>A <code>sql-resource.properties</code> file located in the karaf root
+ * directory</li>
+ * </ol>
+ */
+public class SaltstackAdapterPropertiesProviderImpl implements SaltstackAdapterPropertiesProvider {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SaltstackAdapterPropertiesProviderImpl.class);
+
+ /**
+ * The name of the properties file for database configuration
+ */
+ private static final String SALTSTACKADAPTER_PROP_FILE_NAME = "saltstack-adapter.properties";
+
+ /**
+ * A prioritized list of strategies for resolving sql-resource properties files.
+ */
+ private Vector<PropertiesFileResolver> saltstackAdapterPropertiesFileResolvers = new Vector<>();
+
+ /**
+ * The configuration properties for the db connection.
+ */
+ private Properties properties;
+
+ /**
+ * Set up the prioritized list of strategies for resolving dblib properties
+ * files.
+ */
+ public SaltstackAdapterPropertiesProviderImpl() {
+ saltstackAdapterPropertiesFileResolvers
+ .add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable"));
+ saltstackAdapterPropertiesFileResolvers.add(new CoreDefaultFileResolver("Using property file (2) from default directory"));
+
+ saltstackAdapterPropertiesFileResolvers.add(
+ new JREFileResolver("Using property file (3) from JRE argument", SaltstackAdapterPropertiesProviderImpl.class));
+ saltstackAdapterPropertiesFileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this));
+
+ // determines properties file as according to the priority described in the
+ // class header comment
+ final File propertiesFile = determinePropertiesFile(this);
+ if (propertiesFile != null) {
+ try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) {
+ properties = new Properties();
+ properties.load(fileInputStream);
+ } catch (final IOException e) {
+ LOG.error("Failed to load properties for file: {}", propertiesFile.toString(),
+ new ConfigurationException("Failed to load properties for file: " + propertiesFile.toString(),
+ e));
+ }
+ } else {
+ // Try to read properties as resource
+
+ InputStream propStr = getClass().getResourceAsStream("/" + SALTSTACKADAPTER_PROP_FILE_NAME);
+ if (propStr != null) {
+ properties = new Properties();
+ try {
+ properties.load(propStr);
+ propStr.close();
+ } catch (IOException e) {
+ properties = null;
+ }
+ }
+
+ }
+
+ if (properties == null) {
+ reportFailure("Missing configuration properties resource(3)", new ConfigurationException(
+ "Missing configuration properties resource(3): " + SALTSTACKADAPTER_PROP_FILE_NAME));
+
+ LOG.info("Defaulting org.onap.appc.adapter.saltstack.clientType to NONE");
+
+ properties = new Properties();
+ properties.setProperty("org.onap.appc.adapter.saltstack.clientType", "NONE");
+ }
+ }
+
+ /**
+ * Reports the method chosen for properties resolution to the
+ * <code>Logger</code>.
+ *
+ * @param message Some user friendly message
+ * @param fileOptional The file location of the chosen properties file
+ * @return the file location of the chosen properties file
+ */
+ private static File reportSuccess(final String message, final Optional<File> fileOptional) {
+ if (fileOptional.isPresent()) {
+ final File file = fileOptional.get();
+ LOG.info("{} {}", message, file.getPath());
+ return file;
+ }
+ return null;
+ }
+
+ /**
+ * Reports fatal errors. This is the case in which no properties file could be
+ * found.
+ *
+ * @param message An appropriate fatal error message
+ * @param configurationException An exception describing what went wrong during resolution
+ */
+ private static void reportFailure(final String message, final ConfigurationException configurationException) {
+
+ LOG.error("{}", message, configurationException);
+ }
+
+ /**
+ * Extract svclogic config properties.
+ *
+ * @return the svclogic config properties
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
+ /**
+ * Determines the sql-resource properties file to use based on the following priority:
+ * <ol>
+ * <li>A directory identified by the system environment variable
+ * <code>SDNC_CONFIG_DIR</code></li>
+ * <li>The default directory <code>DEFAULT_DBLIB_PROP_DIR</code></li>
+ * <li>A directory identified by the JRE argument
+ * <code>sql-resource.properties</code></li>
+ * <li>A <code>sql-resource.properties</code> file located in the karaf root
+ * directory</li>
+ * </ol>
+ */
+ File determinePropertiesFile(final SaltstackAdapterPropertiesProviderImpl resourceProvider) {
+
+ for (final PropertiesFileResolver sliPropertiesFileResolver : saltstackAdapterPropertiesFileResolvers) {
+ final Optional<File> fileOptional = sliPropertiesFileResolver.resolveFile(SALTSTACKADAPTER_PROP_FILE_NAME);
+ if (fileOptional.isPresent()) {
+ return reportSuccess(sliPropertiesFileResolver.getSuccessfulResolutionMessage(), fileOptional);
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java
new file mode 100644
index 000000000..25d2d8402
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/SshConnection.java
@@ -0,0 +1,217 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.impl;
+
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.KeyPair;
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.channel.ChannelExec;
+import org.apache.sshd.client.future.AuthFuture;
+import org.apache.sshd.client.future.OpenFuture;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.Constants;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SshException;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+/**
+ * Implementation of SshConnection interface based on Apache MINA SSHD library.
+ */
+class SshConnection {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getApplicationLogger();
+
+ private static final long AUTH_TIMEOUT = 60000;
+ private static final long EXEC_TIMEOUT = 120000;
+ private String host;
+ private int port;
+ private String username;
+ private String password;
+ private long timeout = EXEC_TIMEOUT;
+ private String keyFile;
+ private SshClient sshClient;
+ private ClientSession clientSession;
+
+ public SshConnection(String host, int port, String username, String password, String keyFile) {
+ this.host = host;
+ this.port = port;
+ this.username = username;
+ this.password = password;
+ this.keyFile = keyFile;
+ }
+
+ public SshConnection(String host, int port, String username, String password) {
+ this(host, port, username, password, null);
+ }
+
+ public SshConnection(String host, int port, String keyFile) {
+ this(host, port, null, null, keyFile);
+ }
+
+ public void connect() {
+ sshClient = SshClient.setUpDefaultClient();
+ sshClient.start();
+ try {
+ clientSession =
+ sshClient.connect(username, host, port).getSession();
+ if (password != null) {
+ clientSession.addPasswordIdentity(password);
+ } else if (keyFile != null) {
+ Path keyFilePath = Paths.get(keyFile);
+ KeyPairProvider keyPairProvider = new FileKeyPairProvider(keyFilePath);
+ KeyPair keyPair = keyPairProvider.loadKeys().iterator().next();
+ clientSession.addPublicKeyIdentity(keyPair);
+ }
+ AuthFuture authFuture = clientSession.auth();
+ authFuture.await(AUTH_TIMEOUT);
+ if (!authFuture.isSuccess()) {
+ throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port
+ + "]. Authentication failed.");
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new SshException("Error establishing ssh connection to [" + username + "@" + host + ":" + port + "].",
+ e);
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("SSH: connected to [" + toString() + "]");
+ }
+ }
+
+ public void connectWithRetry() {
+ int retryCount;
+ int retryDelay;
+ int retriesLeft;
+ retryCount = Constants.DEFAULT_CONNECTION_RETRY_COUNT;
+ retryDelay = Constants.DEFAULT_CONNECTION_RETRY_DELAY;
+ retriesLeft = retryCount + 1;
+ do {
+ try {
+ this.connect();
+ break;
+ } catch (RuntimeException e) {
+ if (retriesLeft > 1) {
+ logger.debug("SSH Connection failed. Waiting for change in server's state.");
+ waitForConnection(retryDelay);
+ retriesLeft--;
+ logger.debug("Retrying SSH connection. Attempt [" + Integer.toString(retryCount - retriesLeft + 1)
+ + "] out of [" + retryCount + "]");
+ } else {
+ throw e;
+ }
+ }
+ } while (retriesLeft > 0);
+ }
+
+ public void disconnect() {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("SSH: disconnecting from [" + toString() + "]");
+ }
+ clientSession.close(false);
+ } finally {
+ if (sshClient != null) {
+ sshClient.stop();
+ }
+ }
+ }
+
+ public void setExecTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ public int execCommand(String cmd, OutputStream out, OutputStream err) {
+ return execCommand(cmd, out, err, false);
+ }
+
+ public int execCommandWithPty(String cmd, OutputStream out) {
+ return execCommand(cmd, out, out, true);
+ }
+
+ private int execCommand(String cmd, OutputStream out, OutputStream err, boolean usePty) {
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("SSH: executing command");
+ }
+ ChannelExec client = clientSession.createExecChannel(cmd);
+ client.setUsePty(usePty); // use pseudo-tty?
+ client.setOut(out);
+ client.setErr(err);
+ OpenFuture openFuture = client.open();
+ int exitStatus;
+ try {
+ client.wait(timeout);
+ openFuture.verify();
+ Integer exitStatusI = client.getExitStatus();
+ if (exitStatusI == null) {
+ throw new SshException("Error executing command [" + cmd + "] over SSH [" + username + "@" + host
+ + ":" + port + "]. Operation timed out.");
+ }
+ exitStatus = exitStatusI;
+ } finally {
+ client.close(false);
+ }
+ return exitStatus;
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e1) {
+ throw new SshException(
+ "Error executing command [" + cmd + "] over SSH [" + username + "@" + host + ":" + port + "]", e1);
+ }
+ }
+
+ private void waitForConnection(int retryDelay) {
+ long time = retryDelay * 1000L;
+ long future = System.currentTimeMillis() + time;
+ if (time != 0) {
+ while (System.currentTimeMillis() < future && time > 0) {
+ try {
+ Thread.sleep(time);
+ } catch (InterruptedException e) {
+ /*
+ * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that
+ * case, the thread is resumed before the delay time has actually expired, so re-calculate the
+ * amount of delay time needed and reenter the sleep until we get to the future time.
+ */
+ time = future - System.currentTimeMillis();
+ }
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ String address = host;
+ if (username != null) {
+ address = username + '@' + address + ':' + port;
+ }
+ return address;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java
new file mode 100644
index 000000000..a1826c4e1
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/Constants.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+public class Constants {
+ public static final String NETCONF_SCHEMA = "sdnctl";
+ public static final String SDNCTL_SCHEMA = "sdnctl";
+ public static final String DEVICE_AUTHENTICATION_TABLE_NAME = "DEVICE_AUTHENTICATION";
+ public static final String CONFIGFILES_TABLE_NAME = "CONFIGFILES";
+ public static final String DEVICE_INTERFACE_LOG_TABLE_NAME = "DEVICE_INTERFACE_LOG";
+ public static final String FILE_CONTENT_TABLE_FIELD_NAME = "FILE_CONTENT";
+ public static final String FILE_NAME_TABLE_FIELD_NAME = "FILE_NAME";
+ public static final String USER_NAME_TABLE_FIELD_NAME = "USER_NAME";
+ public static final String PASSWORD_TABLE_FIELD_NAME = "PASSWORD";
+ public static final String PORT_NUMBER_TABLE_FIELD_NAME = "PORT_NUMBER";
+ public static final String VNF_TYPE_TABLE_FIELD_NAME = "VNF_TYPE";
+ public static final String SERVICE_INSTANCE_ID_FIELD_NAME = "SERVICE_INSTANCE_ID";
+ public static final String REQUEST_ID_FIELD_NAME = "REQUEST_ID";
+ public static final String CREATION_DATE_FIELD_NAME = "CREATION_DATE";
+ public static final String LOG_FIELD_NAME = "LOG";
+ public static final String SDC_ARTIFACTS_TABLE_NAME = "ASDC_ARTIFACTS";
+ public static final String PAYLOAD = "payload";
+ public static final String CONNECTION_RETRY_DELAY = "org.onap.appc.ssh.connection.retry.delay";
+ public static final String CONNECTION_RETRY_COUNT = "org.onap.appc.ssh.connection.retry.count";
+ public static final int DEFAULT_CONNECTION_RETRY_DELAY = 60;
+ public static final int DEFAULT_CONNECTION_RETRY_COUNT = 5;
+ public static final int DEFAULT_SSH_COMMAND_RETRY_COUNT = 3;
+ public static final int DEFAULT_CHECKACTIVE_RETRY_COUNT = 3;
+ public static final int DEFAULT_CHECKACTIVE_RETRY_DELAY = 30;
+ public static final int DEFAULT_STOP_RETRY_COUNT = 3;
+ public static final int DEFAULT_STOP_RETRY_DELAY = 30;
+ public static final String PARAM_IN_CONNECTION_DETAILS = "connection-details";
+ public static final String PARAM_IN_NODE_NAME = "node-name";
+ public static final String PARAM_IN_NODE_STATUS = "node-status";
+ public static final String PARAM_IN_VM_URL = "vm-url";
+ public static final String SKIP_EXECUTION_INSTALLER_BIN_FILE = "Skip-execution-installer-bin-file";
+ public static final String SKIP_DEPLOY = "Skip-deploy";
+ public static final String UPGRADE_VERSION = "upgrade-version";
+ public static final String STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh | grep -o UP | wc -l";
+ public static final String VNFC_STATE_COMMAND = "/opt/jnetx/skyfall-scp/asp-state.sh";
+ public static final String RESTART_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh --restart -f --nodes";
+ public static final String START_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-start.sh -f --nodes";
+ public static final String STOP_NODE_COMMAND = "/opt/jnetx/skyfall-scp/asp-stop.sh -f --nodes";
+ public static final int STATE_COMMAND_RESULT = 18;
+ public static final String FE_STATE_TRUE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o TRUE | wc -l";
+ public static final int FE_STATE_TRUE_TEST_RESULT = 22;
+ public static final String FE_STATE_FALSE_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o FALSE | wc -l";
+ public static final int FE_STATE_FALSE_TEST_RESULT = 2;
+ public static final String FE_OPERATIONAL_TEST_COMMAND = "ssh -t -q fe1 /opt/omni/bin/swmml -e display-platform-status | grep -o 'NOT FULLY OPERATIONAL' | wc -l";
+ public static final int FE_OPERATIONAL_TEST_RESULT = 2;
+ public static final String SMP_CHECK_ACTIVE_STATE_COMMAND = "cat skyfall-scp/runtime/SCP_SMP_*/smp/log/system.log| grep SSS | tail -1";
+ public static final String SMP_STATE_ACTIVE = "SMP is active";
+ public static final String SMP_STATE_INACTIVE = "SMP is not active";
+ public static final String RSYNC_COMMAND = "yes n | /opt/jnetx/skyfall-scp/asp-rsync.sh --check | grep -o 'is active' | wc -l";
+ public static final int RSYNC_COMMAND_RESULT = 9;
+ public static final String PARAM_IN_TIMEOUT = "timeout";
+ public static final String PARAM_IN_FILE_URL = "source-file-url";
+ public static final String DOWNLOAD_COMMAND = "wget -N %s";
+ public static final String[] VM_NAMES = new String[]{"fe1", "fe2", "be1", "be2", "be3", "be4", "be5", "smp1", "smp2"};
+ public static final String DEFAULT_DISK_SPACE = "10240000";
+ public static final String DF_COMMAND_TEMPLATE = "ssh %s df | grep vda1 | grep -v grep | tr -s ' '|cut -d ' ' -f4";
+ public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message";
+ public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message";
+ public static final String CONNECTION_DETAILS_FIELD_NAME = "connection-details";
+ public static final String VNF_HOST_IP_ADDRESS_FIELD_NAME = "vnf-host-ip-address";
+ public static final String VNF_HOST_IP2_ADDRESS_FIELD_NAME = "vnf-host-ip2-address";
+ public static final String DG_ERROR_FIELD_NAME = "org.openecom.appc.dg.error";
+
+ private Constants() {
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java
new file mode 100644
index 000000000..3eb353a17
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/JsonParser.java
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public final class JsonParser {
+
+ private static final Logger log = LoggerFactory.getLogger(JsonParser.class);
+
+ private JsonParser() {
+ // Preventing instantiation of the same.
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, String> convertToProperties(String s)
+ throws JSONException {
+
+ checkNotNull(s, "Input should not be null.");
+
+ JSONObject json = new JSONObject(s);
+ Map<String, Object> wm = new HashMap<>();
+ Iterator<String> ii = json.keys();
+ while (ii.hasNext()) {
+ String key1 = ii.next();
+ wm.put(key1, json.get(key1));
+ }
+
+ Map<String, String> mm = new HashMap<>();
+
+ while (!wm.isEmpty())
+ for (String key : new ArrayList<>(wm.keySet())) {
+ Object o = wm.get(key);
+ wm.remove(key);
+
+ if (o instanceof Boolean || o instanceof Number || o instanceof String) {
+ mm.put(key, o.toString());
+
+ log.info("Added property: {} : {}", key, o.toString());
+ } else if (o instanceof JSONObject) {
+ JSONObject jo = (JSONObject) o;
+ Iterator<String> i = jo.keys();
+ while (i.hasNext()) {
+ String key1 = i.next();
+ wm.put(key + "." + key1, jo.get(key1));
+ }
+ } else if (o instanceof JSONArray) {
+ JSONArray ja = (JSONArray) o;
+ mm.put(key + "_length", String.valueOf(ja.length()));
+
+ log.info("Added property: {}_length: {}", key, String.valueOf(ja.length()));
+
+ for (int i = 0; i < ja.length(); i++)
+ wm.put(key + '[' + i + ']', ja.get(i));
+ }
+ }
+ return mm;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java
new file mode 100644
index 000000000..3bb401ad4
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackMessageParser.java
@@ -0,0 +1,412 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2017-2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+/**
+ * This module implements the APP-C/Saltstack Server interface
+ * based on the REST API specifications
+ */
+
+import com.google.common.base.Strings;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Class that validates and constructs requests sent/received from
+ * Saltstack Server
+ */
+public class SaltstackMessageParser {
+
+ private static final String SS_AGENT_HOSTNAME_KEY = "HostName";
+ private static final String SS_AGENT_PORT_KEY = "Port";
+ private static final String PASS_KEY = "Password";
+ private static final String USER_KEY = "User";
+ private static final String CMD_EXEC = "Cmd"; //cmd
+ private static final String IS_SLS_EXEC = "SlsExec"; //slsExec
+ private static final String SS_REQ_ID = "Id";
+ private static final String SLS_FILE_LOCATION = "SlsFile"; //slsFile
+ private static final String SLS_NAME = "SlsName"; //slsName
+ private static final String MINION_TO_APPLY = "NodeList"; //applyTo
+ private static final String EXEC_TIMEOUT_TO_APPLY = "Timeout"; //execTimeout
+ private static final String FILE_PARAMETERS_OPT_KEY = "FileParameters";
+ private static final String ENV_PARAMETERS_OPT_KEY = "EnvParameters";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SaltstackMessageParser.class);
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate PORT number.
+ */
+ public String reqPortResult(Map<String, String> params) throws SvcLogicException {
+ // use default port if null
+ if (params.get(SS_AGENT_PORT_KEY) == null) {
+ return "22";
+ }
+ return params.get(SS_AGENT_PORT_KEY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate HOST name.
+ */
+ public String reqHostNameResult(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, SS_AGENT_HOSTNAME_KEY);
+ return params.get(SS_AGENT_HOSTNAME_KEY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate request ID.
+ */
+ public String reqId(Map<String, String> params) {
+
+ if (params.get(SaltstackMessageParser.SS_REQ_ID) == null) {
+ return UUID.randomUUID().toString();
+ } else if (params.get(SaltstackMessageParser.SS_REQ_ID).equalsIgnoreCase("")) {
+ return UUID.randomUUID().toString();
+ }
+ return params.get(SaltstackMessageParser.SS_REQ_ID);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate command to execute.
+ */
+ public String reqCmd(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, CMD_EXEC);
+ return params.get(SaltstackMessageParser.CMD_EXEC);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate SLS file location to execute.
+ */
+ public String reqSlsFile(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, SLS_FILE_LOCATION);
+ return params.get(SaltstackMessageParser.SLS_FILE_LOCATION);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate SLS file location to execute.
+ */
+ public String reqSlsName(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, SLS_NAME);
+ String slsName = params.get(SaltstackMessageParser.SLS_NAME);
+ try {
+ if (slsName.substring(slsName.lastIndexOf("."), slsName.length()).equalsIgnoreCase(".sls")) {
+ return stripExtension(slsName);
+ }
+ } catch (StringIndexOutOfBoundsException e) {
+ return slsName;
+ }
+ return slsName;
+ }
+
+ private String stripExtension(String str) {
+ if (str == null) {
+ return null;
+ }
+ int pos = str.lastIndexOf(".");
+ if (pos == -1) {
+ return str;
+ }
+ return str.substring(0, pos);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate minions/vnfc to execute the SLS file.
+ */
+ public String reqApplyToDevices(Map<String, String> params) {
+
+ if (params.get(SaltstackMessageParser.MINION_TO_APPLY) == null) {
+ return "*";
+ } else if (params.get(SaltstackMessageParser.MINION_TO_APPLY).equalsIgnoreCase("")) {
+ return "*";
+ }
+ return params.get(SaltstackMessageParser.MINION_TO_APPLY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate minions/vnfc to execute the SLS file.
+ */
+ public long reqExecTimeout(Map<String, String> params) {
+
+ if (params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY) == null) {
+ return -1;
+ } else if (params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY).equalsIgnoreCase("")) {
+ return -1;
+ }
+ return Long.parseLong(params.get(SaltstackMessageParser.EXEC_TIMEOUT_TO_APPLY));
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate EnvParameters to execute the SLS file.
+ */
+ public JSONObject reqEnvParameters(Map<String, String> params) throws JSONException {
+
+ JSONObject jsonPayload = new JSONObject();
+ final String[] optionalTestParam = {SaltstackMessageParser.ENV_PARAMETERS_OPT_KEY};
+ parseParam(params, optionalTestParam, jsonPayload);
+
+ return (JSONObject) jsonPayload.remove(SaltstackMessageParser.ENV_PARAMETERS_OPT_KEY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate EnvParameters to execute the SLS file.
+ */
+ public JSONObject reqFileParameters(Map<String, String> params) throws JSONException {
+
+ JSONObject jsonPayload = new JSONObject();
+ final String[] optionalTestParam = {SaltstackMessageParser.FILE_PARAMETERS_OPT_KEY};
+ parseParam(params, optionalTestParam, jsonPayload);
+
+ return (JSONObject) jsonPayload.remove(SaltstackMessageParser.FILE_PARAMETERS_OPT_KEY);
+ }
+
+ private void parseParam(Map<String, String> params, String[] optionalTestParams, JSONObject jsonPayload)
+ throws JSONException {
+
+ Set<String> optionalParamsSet = new HashSet<>();
+ Collections.addAll(optionalParamsSet, optionalTestParams);
+
+ //@formatter:off
+ params.entrySet()
+ .stream()
+ .filter(entry -> optionalParamsSet.contains(entry.getKey()))
+ .filter(entry -> !Strings.isNullOrEmpty(entry.getValue()))
+ .forEach(entry -> parseParam(entry, jsonPayload));
+ //@formatter:on
+ }
+
+ private void parseParam(Map.Entry<String, String> params, JSONObject jsonPayload)
+ throws JSONException {
+ String key = params.getKey();
+ String payload = params.getValue();
+
+ switch (key) {
+ case ENV_PARAMETERS_OPT_KEY:
+ JSONObject paramsJson = new JSONObject(payload);
+ jsonPayload.put(key, paramsJson);
+ break;
+
+ case FILE_PARAMETERS_OPT_KEY:
+ jsonPayload.put(key, getFilePayload(payload));
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * Return payload with escaped newlines
+ */
+ private JSONObject getFilePayload(String payload) {
+ String formattedPayload = payload.replace("\n", "\\n").replace("\r", "\\r");
+ return new JSONObject(formattedPayload);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate IsSLSExec true or false.
+ */
+ public boolean reqIsSLSExec(Map<String, String> params) throws SvcLogicException {
+
+ final String[] mandatoryTestParams = {CMD_EXEC, IS_SLS_EXEC};
+
+ for (String key : mandatoryTestParams) {
+ throwIfMissingMandatoryParam(params, key);
+ }
+
+ return params.get(SaltstackMessageParser.IS_SLS_EXEC).equalsIgnoreCase("true");
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate Saltstack server login user name.
+ */
+ public String reqUserNameResult(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, USER_KEY);
+ return params.get(USER_KEY);
+ }
+
+ /**
+ * Method that validates that the Map has enough information
+ * to query Saltstack server for a result. If so, it returns
+ * the appropriate Saltstack server login password.
+ */
+ public String reqPasswordResult(Map<String, String> params) throws SvcLogicException {
+
+ throwIfMissingMandatoryParam(params, PASS_KEY);
+ return params.get(PASS_KEY);
+ }
+
+ /**
+ * This method parses response from the Saltstack Server when we do a post
+ * and returns an SaltstackResult object.
+ */
+ public SaltstackResult parseResponse(SvcLogicContext ctx, String pfx,
+ SaltstackResult saltstackResult, boolean slsExec) throws IOException {
+ int code = saltstackResult.getStatusCode();
+ boolean executionStatus = true;
+ boolean retCodeFound = false;
+ if (code != SaltstackResultCodes.SUCCESS.getValue()) {
+ return saltstackResult;
+ }
+ ByteArrayOutputStream outStream = saltstackResult.getOutputMessage();
+ String outMessage = outStream.toString();
+ try {
+ Map<String, String> mm = JsonParser.convertToProperties(outMessage);
+ if (mm != null) {
+ for (Map.Entry<String, String> entry : mm.entrySet()) {
+ if (entry.getKey().contains("retcode")) {
+ retCodeFound = true;
+ if (!entry.getValue().equalsIgnoreCase("0")) {
+ executionStatus = false;
+ }
+ }
+ ctx.setAttribute(pfx + "." + entry.getKey(), entry.getValue());
+ LOGGER.info("+++ " + pfx + "." + entry.getKey() + ": [" + entry.getValue() + "]");
+ }
+ }
+ } catch (org.codehaus.jettison.json.JSONException e) {
+ if (slsExec) {
+ return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE.getValue(), "error parsing response file"
+ + " : Output has to be in JSON format");
+ }
+ LOGGER.info("Output not in JSON format");
+ return putToProperties(ctx, pfx, saltstackResult);
+ } catch (Exception e) {
+ return new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "error parsing response file"
+ + " : " + e.getMessage());
+ } finally {
+ if (outStream != null) {
+ outStream.close();
+ }
+ }
+ if (slsExec) {
+ if (!retCodeFound) {
+ if (outMessage != null && !outMessage.equalsIgnoreCase("")) {
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ outMessage);
+ }
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ "error in executing configuration at the server, check your command input");
+ }
+ if (!executionStatus) {
+ if (outMessage != null && !outMessage.equalsIgnoreCase("")) {
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ outMessage);
+ }
+ return new SaltstackResult(SaltstackResultCodes.COMMAND_EXEC_FAILED_STATUS.getValue(),
+ "error in executing configuration at the server, check your command input");
+ }
+ }
+ saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue());
+ return saltstackResult;
+ }
+
+ public SaltstackResult putToProperties(SvcLogicContext ctx, String pfx,
+ SaltstackResult saltstackResult) throws IOException {
+
+ ByteArrayOutputStream buffer = saltstackResult.getOutputMessage();
+ InputStream inputStream = null;
+ try {
+ byte[] bytes = buffer.toByteArray();
+ Properties prop = new Properties();
+ inputStream = new ByteArrayInputStream(bytes);
+ prop.load(inputStream);
+ ctx.setAttribute(pfx + "completeResult", prop.toString());
+ for (Object key : prop.keySet()) {
+ String name = (String) key;
+ String value = prop.getProperty(name);
+ if (value != null && value.trim().length() > 0) {
+ ctx.setAttribute(pfx + "." + name, value.trim());
+ LOGGER.info("+++ " + pfx + "." + name + ": [" + value + "]");
+ }
+ }
+ } catch (Exception e) {
+ saltstackResult = new SaltstackResult(SaltstackResultCodes.INVALID_RESPONSE_FILE.getValue(), "Error parsing response file." +
+ " Error = " + e.getMessage());
+ } finally {
+ if (buffer != null && inputStream != null) {
+ buffer.close();
+ inputStream.close();
+ }
+ }
+ saltstackResult.setStatusCode(SaltstackResultCodes.FINAL_SUCCESS.getValue());
+ return saltstackResult;
+ }
+
+ private void throwIfMissingMandatoryParam(Map<String, String> params, String key) throws SvcLogicException {
+ if (!params.containsKey(key)) {
+ throw new SvcLogicException(String.format(
+ "Saltstack: Mandatory SaltstackAdapter key %s not found in parameters provided by calling agent !",
+ key));
+ }
+ if (Strings.isNullOrEmpty(params.get(key))) {
+ throw new SvcLogicException(String.format(
+ "Saltstack: Mandatory SaltstackAdapter key %s not found in parameters provided by calling agent !",
+ key));
+ }
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java
new file mode 100644
index 000000000..727cfe314
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResult.java
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Simple class to store code and message returned by POST/GET to an Saltstack Server
+ */
+public class SaltstackResult {
+
+ private static final String EMPTY_VALUE = "UNKNOWN";
+
+ private int statusCode;
+ private String statusMessage;
+ private String results;
+ private ByteArrayOutputStream out;
+ private int sshExitStatus;
+
+ public SaltstackResult() {
+ this(-1, EMPTY_VALUE, EMPTY_VALUE, -1);
+ }
+
+ public SaltstackResult(int code, String message) {
+ this(code, message, EMPTY_VALUE, -1);
+ }
+
+ public SaltstackResult(int code, String message, String result, int sshCode) {
+ statusCode = code;
+ statusMessage = message;
+ results = result;
+ sshExitStatus = sshCode;
+ }
+
+ void set(int code, String message, String results) {
+ this.statusCode = code;
+ this.statusMessage = message;
+ this.results = results;
+ }
+
+ public ByteArrayOutputStream getOutputMessage() {
+ return out;
+ }
+
+ public void setOutputMessage(ByteArrayOutputStream out) {
+ this.out = out;
+ }
+
+ public int getStatusCode() {
+ return this.statusCode;
+ }
+
+ public void setStatusCode(int code) {
+ this.statusCode = code;
+ }
+
+ public String getStatusMessage() {
+ return this.statusMessage;
+ }
+
+ public void setStatusMessage(String message) {
+ this.statusMessage = message;
+ }
+
+ public String getResults() {
+ return this.results;
+ }
+
+ public void setResults(String results) {
+ this.results = results;
+ }
+
+ public int getSshExitStatus() {
+ return sshExitStatus;
+ }
+
+ public void setSshExitStatus(int sshExitStatus) {
+ this.sshExitStatus = sshExitStatus;
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java
new file mode 100644
index 000000000..932554983
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackResultCodes.java
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * enum of the various codes that APP-C uses to resolve different
+ * status of response from Saltstack Server
+ **/
+
+public enum SaltstackResultCodes {
+
+ // @formatter:off
+ SUCCESS(400),
+ KEYSTORE_EXCEPTION(622),
+ CERTIFICATE_ERROR(610),
+ IO_EXCEPTION(611),
+ HOST_UNKNOWN(625),
+ USER_UNAUTHORIZED(613),
+ UNKNOWN_EXCEPTION(699),
+ OPERATION_TIMEOUT(659),
+ SSL_EXCEPTION(697),
+ SSH_EXCEPTION(695),
+ INVALID_COMMAND(698),
+ INVALID_RESPONSE(601),
+ INVALID_RESPONSE_FILE(600),
+ PENDING(100),
+ REJECTED(101),
+ FINAL_SUCCESS(200),
+ CHECK_CTX_FOR_CMD_SUCCESS(250),
+ COMMAND_EXEC_FAILED_STATUS(670),
+ REQ_FAILURE(401),
+ MESSAGE(1),
+ CODE(0),
+ INITRESPONSE(0),
+ FINALRESPONSE(1);
+ // @formatter:on
+
+ private final Set<Integer> initCodes = new HashSet<>(Arrays.asList(100, 101));
+ private final Set<Integer> finalCodes = new HashSet<>(Arrays.asList(200, 500));
+ private final ArrayList<Set<Integer>> codeSets = new ArrayList<>(Arrays.asList(initCodes, finalCodes));
+ private final Set<String> messageSet = new HashSet<>(Arrays.asList("PENDING", "FINISHED", "TERMINATED"));
+ private final int value;
+
+ SaltstackResultCodes(int value) {
+ this.value = value;
+ }
+
+ ;
+
+ public int getValue() {
+ return value;
+ }
+
+ public boolean checkValidCode(int type, int code) {
+ return codeSets.get(type).contains(code);
+ }
+
+ public String getValidCodes(int type) {
+ StringBuilder sb = new StringBuilder("[ ");
+ codeSets.get(type).stream().forEach(s -> sb.append(s).append(","));
+ return sb.append("]").toString();
+ }
+
+ public boolean checkValidMessage(String message) {
+ return messageSet.contains(message);
+ }
+
+ public String getValidMessages() {
+ StringBuilder sb = new StringBuilder("[ ");
+ messageSet.stream().forEach(s -> sb.append(s).append(","));
+ return sb.append("]").toString();
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java
new file mode 100644
index 000000000..78976562b
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SaltstackServerEmulator.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+
+
+/*
+ * Class to emulate responses from the Saltstack Server that is compliant with the APP-C Saltstack Server
+ * Interface. Used for jUnit tests to verify code is working. In tests it can be used
+ * as a replacement for methods from ConnectionBuilder class
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+
+public class SaltstackServerEmulator {
+
+ private static final String SALTSTATE_FILE_NAME = "fileName";
+ private final EELFLogger logger = EELFManager.getInstance().getLogger(SaltstackServerEmulator.class);
+
+ /**
+ * Method that emulates the response from an Saltstack Server
+ * when presented with a request to execute a saltState
+ * Returns an saltstack object result. The response code is always the ssh code 200 (i.e connection successful)
+ * payload is json string as would be sent back by Saltstack Server
+ **/
+ public SaltstackResult mockReqExec(Map<String, String> params) {
+ SaltstackResult result = new SaltstackResult();
+
+ try {
+ if (params.get("Test") == "fail") {
+ result = rejectRequest(result, "Mocked: Fail");
+ } else {
+ String fileName = params.get(SALTSTATE_FILE_NAME);
+ if (fileName == null) {
+ throw new FileNotFoundException("No response file found");
+ }
+ result = acceptRequest(result, fileName);
+ }
+ } catch (Exception e) {
+ logger.error("Exception caught", e);
+ rejectRequest(result, e.getMessage());
+ }
+ return result;
+ }
+
+ private SaltstackResult rejectRequest(SaltstackResult result, String Message) {
+ result.setStatusCode(SaltstackResultCodes.REJECTED.getValue());
+ result.setStatusMessage("Rejected");
+ return result;
+ }
+
+ private SaltstackResult acceptRequest(SaltstackResult result, String fileName) throws IOException {
+ result.setStatusCode(SaltstackResultCodes.SUCCESS.getValue());
+ result.setStatusMessage("Success");
+ Path path = Paths.get(fileName);
+ byte[] data = Files.readAllBytes(path);
+ ByteArrayOutputStream byteOut = new ByteArrayOutputStream(data.length);
+ byteOut.write(data, 0, data.length);
+ result.setOutputMessage(byteOut);
+ return result;
+ }
+} \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java
new file mode 100644
index 000000000..037a1e891
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/java/org/onap/ccsdk/sli/adaptors/saltstack/model/SshException.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.saltstack.model;
+
+public class SshException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ public SshException(String message) {
+ super(message);
+ }
+
+ public SshException(String message, Throwable cause) {
+ super(message, cause);
+ }
+} \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml
new file mode 100755
index 000000000..e360f8184
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/OSGI-INF/blueprint/saltstack-adapter-blueprint.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2017 - 2018 Samsung Electronics. All rights
+ reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<blueprint xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <bean id="propProvider"
+ class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterPropertiesProviderImpl"/>
+
+ <bean id="saltstackAdapterInstance"
+ class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl">
+ <argument ref="propProvider"/>
+ </bean>
+
+ <service ref="saltstackAdapterInstance">
+ <interfaces>
+ <value>org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter
+ </value>
+ </interfaces>
+ </service>
+
+</blueprint>
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml
new file mode 100755
index 000000000..e360f8184
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/org/opendaylight/blueprint/saltstack-adapter-blueprint.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : CCSDK
+ ================================================================================
+ Copyright (C) 2017 - 2018 Samsung Electronics. All rights
+ reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file 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=========================================================
+ -->
+
+<blueprint xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <bean id="propProvider"
+ class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterPropertiesProviderImpl"/>
+
+ <bean id="saltstackAdapterInstance"
+ class="org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl">
+ <argument ref="propProvider"/>
+ </bean>
+
+ <service ref="saltstackAdapterInstance">
+ <interfaces>
+ <value>org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapter
+ </value>
+ </interfaces>
+ </service>
+
+</blueprint>
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties
new file mode 100644
index 000000000..1755f7adf
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/main/resources/saltstack-adapter.properties
@@ -0,0 +1,43 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# Copyright (C) 2018 Samsung Electronics. All rights reserved.
+# ================================================================================
+#
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file 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=========================================================
+###
+#
+# Default properties for the APP-C TestService Adapter
+#
+# -------------------------------------------------------------------------------------------------
+#
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=${user.home},/opt/opendaylight/current/properties
+appc.application.name=APPC
+#
+# Define the message resource bundle name to be loaded
+org.onap.appc.resources=org.onap/appc/i18n/MessageResources
+#
+# The name of the adapter.
+org.onap.appc.provider.adaptor.name=org.onap.appc.appc_saltstack_adapter
+# Default truststore path and password
+org.onap.appc.adapter.saltstack.trustStore=/opt/opendaylight/tls-client/mykeystore.js
+org.onap.appc.adapter.saltstack.trustStore.trustPasswd=changeit
+org.onap.appc.adapter.saltstack.clientType=TRUST_ALL
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java
new file mode 100644
index 000000000..71fcf3454
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestConnectionBuilder.java
@@ -0,0 +1,184 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.adapter.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.saltstack.impl.ConnectionBuilder;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.SaltstackResult;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class TestConnectionBuilder {
+
+ private ConnectionBuilder connBuilder;
+ private Map<String, String> params;
+
+
+ @Before
+ public void setup() throws IllegalArgumentException {
+ String HostName = "test";
+ String Port = "10";
+ String User = "test";
+ String Password = "test";
+ connBuilder = new ConnectionBuilder(HostName, Port, User, Password);
+
+ params = new HashMap<>();
+ params.put("AgentUrl", "https://192.168.1.1");
+ params.put("User", "test");
+ params.put("Password", "test");
+ }
+
+ @After
+ public void tearDown() {
+ connBuilder = null;
+ params = null;
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus255() {
+
+ int exitStatus = 255;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(698, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus1() {
+
+ int exitStatus = 1;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(698, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus67() {
+
+ int exitStatus = 67;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(610, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus73() {
+
+ int exitStatus = 73;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(610, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus5() {
+
+ int exitStatus = 5;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus65() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus67613() {
+
+ int exitStatus = 5;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatus65613() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatusUnknown() {
+
+ int exitStatus = 5121;
+ String errFilePath = "src/test/resources/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(699, status);
+ }
+
+ @Test
+ public void reqExecCommand_exitStatusNoFile() {
+
+ int exitStatus = 65;
+ String errFilePath = "src/test/resource/test.json";
+ String command = "test";
+
+ SaltstackResult result = connBuilder.sortExitStatus(exitStatus, errFilePath, command);
+ int status = result.getStatusCode();
+ assertEquals(613, status);
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java
new file mode 100644
index 000000000..22e8c2082
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterImpl.java
@@ -0,0 +1,1051 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.adapter.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+public class TestSaltstackAdapterImpl {
+
+ private SaltstackAdapterImpl adapter;
+ private String TestId;
+ private boolean testMode = true;
+ private Map<String, String> params;
+ private SvcLogicContext svcContext;
+
+
+ @Before
+ public void setup() throws IllegalArgumentException {
+ testMode = true;
+ svcContext = new SvcLogicContext();
+ adapter = new SaltstackAdapterImpl(testMode);
+
+ params = new HashMap<>();
+ params.put("AgentUrl", "https://192.168.1.1");
+ params.put("User", "test");
+ params.put("Password", "test");
+ }
+
+ @After
+ public void tearDown() {
+ testMode = false;
+ adapter = null;
+ params = null;
+ svcContext = null;
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetUserFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("Password", "test");
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetHostFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetPortFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetPasswordFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetMandatoryFailed() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("Test", "fail");
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("101", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_NoResponseFile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
+ fail(e.getMessage() + " Unknown exception encountered ");
+ }
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_NoResponseFileWithRetry() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("withRetry", "true");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
+ fail(e.getMessage() + " Unknown exception encountered ");
+ }
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_NoResponseFileWithRetryZero() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("withRetry", "0");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
+ fail(e.getMessage() + " Unknown exception encountered ");
+ }
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_NoResponseFileWithNoRetry() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("withRetry", "false");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
+ fail(e.getMessage() + " Unknown exception encountered ");
+ }
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailure() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "test");
+ params.put("Test", "fail");
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("400", status);
+ } catch (NullPointerException e) {
+ fail(e.getMessage() + " Unknown exception encountered ");
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessNoSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessExecSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "true");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailExecSLS() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "true");
+
+ adapter.reqExecCommand(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileTxt() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.txt");
+ params.put("Id", "txt");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "txt");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileNoExtension() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test");
+ params.put("Id", "txt");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "txt");
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileInvalidJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-invalid.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_shouldSetFailFileInvalidFile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecCommand(params, svcContext);
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileJsonNoReqID() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("fileName", "src/test/resources/test.json");
+ params.put("Cmd", "test");
+ params.put("SlsExec", "false");
+
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ }
+
+ @Test
+ public void reqExecSLSFile_shouldSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_NoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test-none.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_NoExtn() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test-none");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_NoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithMinionSetNotSLSType() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLSFile_WithMinionSetSuccessSls() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithMinionNoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test-none.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLSFile_WithAllMinionSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("NodeList", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithAllMinionNoSLSfile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test-none.json");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLSFile_WithAllMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsFile", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "*");
+
+ adapter.reqExecSLSFile(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+
+ @Test
+ public void reqExecSLS_shouldSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLS_shouldSetNoExtn() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLS_NoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+
+ adapter.reqExecSLS(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+
+ @Test
+ public void reqExecSLS_WithMinionSetSuccessSls() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test/resources/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLS_WithMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "minion1");
+
+ adapter.reqExecSLS(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+ @Test
+ public void reqExecSLS_WithAllMinionSetSuccessJson() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test/resources/test.sls");
+ params.put("fileName", "src/test/resources/test-sls.json");
+ params.put("Id", "test1");
+ params.put("Cmd", "test");
+ params.put("NodeList", "*");
+
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ }
+
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecSLS_WithAllMinionNoResponsefile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "test");
+ params.put("Port", "10");
+ params.put("User", "test");
+ params.put("Password", "test");
+ params.put("Test", "success");
+ params.put("SlsName", "src/test/resources/test.json");
+ params.put("fileName", "src/test/resources/test-none.json");
+ params.put("Id", "test1");
+ params.put("NodeList", "*");
+
+ adapter.reqExecSLS(params, svcContext);
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals(TestId, "test1");
+ }
+
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessReal() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "127.0.0.1");
+ params.put("Port", "22");
+ params.put("User", "sdn");
+ params.put("Password", "foo");
+ params.put("Id", "test1");
+ params.put("Cmd", "ls -l");
+ params.put("SlsExec", "false");
+ params.put("Timeout", "120");
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if local ssh is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessRealSLSCommand() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("Cmd", "salt '*' test.ping --out=json --static");
+ params.put("SlsExec", "false");
+ params.put("Timeout", "120");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ TestId = svcContext.getAttribute("test1.minion1");
+ assertEquals(TestId, "true");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessRealCommand() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("Cmd", "cd /srv/salt/; salt '*' state.apply vim --out=json --static");
+ params.put("SlsExec", "true");
+ params.put("Timeout", "120");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecCommand(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessRealSSL() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("SlsName", "vim");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessEnvParam() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("SlsName", "vim");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("EnvParameters", "{\"exclude\": bar*}");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessFileParam() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("SlsName", "vim");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("EnvParameters", "{\"exclude\": \"bar,baz\"}");
+ params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessPillarParam() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("SlsName", "vim");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("EnvParameters", "{\"exclude\": \"bar,baz\", \"pillar\":\"'{\\\"foo\\\": \\\"bar\\\"}'\"}");
+ params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessMultiFileParam() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("SlsName", "vim");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("EnvParameters", "{\"exclude\": bar*}");
+ params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\" , \"config-tep.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLS(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessSSLFile() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("SlsFile", "src/test/resources/config.sls");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+
+ @Test
+ public void reqExecCommand_shouldSetSuccessSSLFileMultiFileParam() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+
+ params.put("HostName", "<IP>");
+ params.put("Port", "2222");
+ params.put("User", "root");
+ params.put("Password", "vagrant");
+ params.put("Id", "test1");
+ params.put("Timeout", "120");
+ params.put("NodeList", "minion1");
+ params.put("SlsFile", "src/test/resources/config.sls");
+ params.put("EnvParameters", "{\"exclude\": bar, \"pillar\":\"'{\\\"foo\\\": \\\"bar\\\"}'\"}");
+ params.put("FileParameters", "{\"config.txt\":\"db_ip=10.1.1.1, sip_timer=10000\" , \"config-tep.txt\":\"db_ip=10.1.1.1, sip_timer=10000\"}");
+
+ adapter = new SaltstackAdapterImpl();
+ try {
+ adapter.reqExecSLSFile(params, svcContext);
+ String status = svcContext.getAttribute("org.onap.appc.adapter.saltstack.result.code");
+ TestId = svcContext.getAttribute("org.onap.appc.adapter.saltstack.Id");
+ assertEquals("200", status);
+ assertEquals(TestId, "test1");
+ } catch (Exception e) {
+ //if saltstack ssh IP is not enabled
+ System.out.print(e.getMessage());
+ }
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java
new file mode 100644
index 000000000..88acc1919
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/impl/TestSaltstackAdapterPropertiesProviderImpl.java
@@ -0,0 +1,310 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights reserved.
+ * ================================================================================
+ *
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.adapter.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.saltstack.SaltstackAdapterPropertiesProvider;
+import org.onap.ccsdk.sli.adaptors.saltstack.impl.SaltstackAdapterImpl;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestSaltstackAdapterPropertiesProviderImpl {
+
+ private SaltstackAdapterImpl adapter;
+ private Properties params;
+
+
+ @Before
+ public void setup() throws IllegalArgumentException {
+ params = new Properties();
+ }
+
+ @After
+ public void tearDown() {
+ adapter = null;
+ params = null;
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesBasicPortNull() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC");
+ params.put("User", "test");
+ params.put("Password", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_setPropertiesBasicPortString() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "test");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesBasicSuccess() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "BASIC");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "10");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(adapter);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesSSH_CERTPortNull() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT");
+ params.put("User", "test");
+ params.put("Password", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test(expected = SvcLogicException.class)
+ public void reqExecCommand_setPropertiesSSH_CERTPortString() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "test");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesSSH_CERTSuccess() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "SSH_CERT");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "10");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesBOTHPortNull() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "BOTH");
+ params.put("User", "test");
+ params.put("Password", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesBOTHSuccess() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "BOTH");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "10");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesNonePortNull() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "NONE");
+ params.put("User", "test");
+ params.put("Password", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesNonePortString() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "NONE");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "test");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesNoneSuccess() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.clientType", "NONE");
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "10");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+
+ @Test
+ public void reqExecCommand_setPropertiesElsePortNull() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("User", "test");
+ params.put("Password", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesElsePortString() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "test");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ assertNotNull(propProvider);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesElseSuccess() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ params.put("org.onap.appc.adapter.saltstack.host", "test");
+ params.put("org.onap.appc.adapter.saltstack.port", "10");
+ params.put("org.onap.appc.adapter.saltstack.userName", "test");
+ params.put("org.onap.appc.adapter.saltstack.userPasswd", "test");
+ params.put("org.onap.appc.adapter.saltstack.sshKey", "test");
+ SaltstackAdapterPropertiesProvider propProvider = new SaltstackAdapterPropertiesProvider() {
+ @Override
+ public Properties getProperties() {
+ return params;
+ }
+ };
+ adapter = new SaltstackAdapterImpl(propProvider);
+ String adaptorName = adapter.getAdapterName();
+ assertEquals("Saltstack Adapter", adaptorName);
+ }
+
+ @Test
+ public void reqExecCommand_setPropertiesDefault() throws SvcLogicException,
+ IllegalStateException, IllegalArgumentException {
+ adapter = new SaltstackAdapterImpl();
+ assertNotNull(adapter);
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java
new file mode 100644
index 000000000..d4eafc1a0
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/java/org/onap/ccsdk/adapter/model/TestJsonParser.java
@@ -0,0 +1,76 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : CCSDK
+ * ================================================================================
+ * Copyright (C) 2018 Samsung Electronics. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file 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=========================================================
+ */
+
+package org.onap.ccsdk.adapter.model;
+
+import org.codehaus.jettison.json.JSONException;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.saltstack.model.JsonParser;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import static org.junit.Assert.assertNotNull;
+
+public class TestJsonParser {
+
+ private static final Logger log = LoggerFactory.getLogger(TestJsonParser.class);
+
+ @Test
+ public void test() throws SvcLogicException, IOException, JSONException {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(ClassLoader.getSystemResourceAsStream("test.json"))
+ );
+ StringBuilder b = new StringBuilder();
+ String line;
+ while ((line = in.readLine()) != null)
+ b.append(line).append('\n');
+
+ Map<String, String> mm = JsonParser.convertToProperties(b.toString());
+
+ logProperties(mm);
+
+ in.close();
+ assertNotNull(mm);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNullString() throws SvcLogicException, JSONException {
+ JsonParser.convertToProperties(null);
+ }
+
+ private void logProperties(Map<String, String> mm) {
+ List<String> ll = new ArrayList<>();
+ for (Object o : mm.keySet())
+ ll.add((String) o);
+ Collections.sort(ll);
+ log.info("Properties:");
+ for (String name : ll)
+ log.info("--- {}: {}", name, mm.get(name));
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls
new file mode 100644
index 000000000..aff05939b
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/config.sls
@@ -0,0 +1,2 @@
+vim:
+ pkg.installed
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties
new file mode 100644
index 000000000..e5650e853
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/org/onap/ccsdk/default.properties
@@ -0,0 +1,102 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : CCSDK
+# ================================================================================
+# Copyright (C) 2018 Samsung Electronics. All rights reserved.
+# ================================================================================
+#
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file 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=========================================================
+###
+#
+# Default properties for the APP-C Provider Adapter
+#
+# -------------------------------------------------------------------------------------------------
+#
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded
+# to supply configuration options
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
+appc.application.name=APPC
+#
+# Define the message resource bundle name to be loaded
+org.onap.appc.resources=org/onap/appc/i18n/MessageResources
+#
+# The name of the adapter.
+org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adapter
+#
+# Set up the logging environment
+#
+org.onap.appc.logging.file=org/onap/appc/logback.xml
+org.onap.appc.logging.path=${user.home};etc;../etc
+org.onap.appc.logger=org.onap.appc
+org.onap.appc.security.logger=org.onap.appc.security
+#
+# The minimum and maximum provider/tenant context pool sizes. Min=1 means that as soon
+# as the provider/tenant is referenced a Context is opened and added to the pool. Max=0
+# means that the upper bound on the pool is unbounded.
+org.onap.appc.provider.min.pool=1
+org.onap.appc.provider.max.pool=0
+#
+# The following properties are used to configure the retry logic for connection to the
+# IaaS provider(s). The retry delay property is the amount of time, in seconds, the
+# application waits between retry attempts. The retry limit is the number of retries
+# that are allowed before the request is failed.
+org.onap.appc.provider.retry.delay=30
+org.onap.appc.provider.retry.limit=10
+#
+# The trusted hosts list for SSL access when a certificate is not provided.
+#
+provider.trusted.hosts=*
+#
+# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc).
+# If the server does not change state to a valid state within the alloted time, the operation
+# fails.
+org.onap.appc.server.state.change.timeout=300
+#
+# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider
+# to refresh the status of a resource we are waiting on.
+#
+org.onap.appc.openstack.poll.interval=20
+#
+# The connection information to connect to the provider we are using. These properties
+# are "structured" properties, in that the name is a compound name, where the nodes
+# of the name can be ordered (1, 2, 3, ...). All of the properties with the same ordinal
+# position are defining the same entity. For example, provider1.type and provider1.name
+# are defining the same provider, whereas provider2.name and provider2.type are defining
+# the values for a different provider. Any number of providers can be defined in this
+# way.
+#
+# Don't change these 2 right now since they are hard coded in the DG
+#provider1.type=appc
+#provider1.name=appc
+#These you can change
+#provider1.identity=appc
+#provider1.tenant1.name=appc
+#provider1.tenant1.userid=appc
+#provider1.tenant1.password=appc
+# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens
+test.expected-regions=1
+test.expected-endpoints=1
+#Your OpenStack IP
+#test.ip=192.168.1.2
+# Your OpenStack Platform's Keystone Port (default is 5000)
+#test.port=5000
+#test.tenantid=abcde12345fghijk6789lmnopq123rst
+#test.vmid=abc12345-1234-5678-890a-abcdefg12345
+# Port 8774 below is default port for OpenStack's Nova API Service
+#test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345
+
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test
new file mode 100644
index 000000000..dec578bd9
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test
@@ -0,0 +1,30 @@
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P
+service-configuration-notification-input.ack-final-indicator = Y
+service-configuration-notification-input.response-code = 0
+service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup.
+service-configuration-notification-input.service-information.service-instance-id = TEST7
+service-configuration-notification-input.service-information.service-type = AVPN
+service-configuration-notification-input.svc-request-id = TEST7
+service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI
+service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G
+service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000
+service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps
+service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX
+service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N
+service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q
+service-data.avpn-ip-port-information.clli = LONDENEH
+service-data.avpn-ip-port-information.contracted-port-speed = 10000
+service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps
+service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33
+service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0
+service-data.service-information.service-instance-id = ICORESITE-2751508
+service-data.service-information.service-type = AVPN
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json
new file mode 100644
index 000000000..d16bfccdf
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-invalid.json
@@ -0,0 +1,29 @@
+"equipment-data": [
+{
+"server-count": "4",
+"max-server-speed": "1600000",
+"number-primary-servers": "2",
+"equipment-id": "Server1",
+"server-model": "Unknown",
+"server-id": "Server1",
+"test-node": {
+"test-inner-node": "Test-Value"
+}
+}
+],
+"resource-state": {
+"threshold-value": "1600000",
+"last-added": "1605000",
+"used": "1605000",
+"limit-value": "1920000"
+},
+"resource-rule": {
+"endpoint-position": "VCE-Cust",
+"soft-limit-expression": "0.6 * max-server-speed * number-primary-servers",
+"resource-name": "Bandwidth",
+"service-model": "DUMMY",
+"hard-limit-expression": "max-server-speed * number-primary-servers",
+"equipment-level": "Server"
+},
+"message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity."
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json
new file mode 100644
index 000000000..bc1c10c8d
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test-sls.json
@@ -0,0 +1,35 @@
+{
+ "minion1": {
+ "retcode": 0,
+ "pkg_|-install_network_packages_|-install_network_packages_|-installed": {
+ "comment": "The following packages were installed/updated: lftp\nThe following packages were already installed: rsync, curl",
+ "name": "install_network_packages",
+ "start_time": "08:47:16.061765",
+ "result": true,
+ "duration": 11086.334,
+ "__run_num__": 0,
+ "__sls__": "nettools",
+ "changes": {
+ "lftp": {
+ "new": "4.6.3a-1build2",
+ "old": ""
+ }
+ },
+ "__id__": "install_network_packages"
+ }
+ },
+ "minion2": {
+ "retcode": 0,
+ "pkg_|-install_network_packages_|-install_network_packages_|-installed": {
+ "comment": "All specified packages are already installed",
+ "name": "curl",
+ "start_time": "08:47:16.152099",
+ "result": true,
+ "duration": 426.493,
+ "__run_num__": 0,
+ "__sls__": "nettools",
+ "changes": {},
+ "__id__": "install_network_packages"
+ }
+ }
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json
new file mode 100644
index 000000000..81131d6f4
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.json
@@ -0,0 +1,30 @@
+{
+ "equipment-data": [
+ {
+ "server-count": "4",
+ "max-server-speed": "1600000",
+ "number-primary-servers": "2",
+ "equipment-id": "Server1",
+ "server-model": "Unknown",
+ "server-id": "Server1",
+ "test-node": {
+ "test-inner-node": "Test-Value"
+ }
+ }
+ ],
+ "resource-state": {
+ "threshold-value": "1600000",
+ "last-added": "1605000",
+ "used": "1605000",
+ "limit-value": "1920000"
+ },
+ "resource-rule": {
+ "endpoint-position": "VCE-Cust",
+ "soft-limit-expression": "0.6 * max-server-speed * number-primary-servers",
+ "resource-name": "Bandwidth",
+ "service-model": "DUMMY",
+ "hard-limit-expression": "max-server-speed * number-primary-servers",
+ "equipment-level": "Server"
+ },
+ "message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity."
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls
new file mode 100644
index 000000000..cd76486aa
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.sls
@@ -0,0 +1,30 @@
+{
+ "equipment-data": [
+ {
+ "server-count": "4",
+ "max-server-speed": "1600000",
+ "number-primary-servers": "2",
+ "equipment-id": "Server1",
+ "server-model": "Unknown",
+ "server-id": "Server1",
+ "test-node" : {
+ "test-inner-node" : "Test-Value"
+ }
+ }
+ ],
+ "resource-state": {
+ "threshold-value": "1600000",
+ "last-added": "1605000",
+ "used": "1605000",
+ "limit-value": "1920000"
+ },
+ "resource-rule": {
+ "endpoint-position": "VCE-Cust",
+ "soft-limit-expression": "0.6 * max-server-speed * number-primary-servers",
+ "resource-name": "Bandwidth",
+ "service-model": "DUMMY",
+ "hard-limit-expression": "max-server-speed * number-primary-servers",
+ "equipment-level": "Server"
+ },
+ "message": "The provisioned access bandwidth is at or exceeds 50% of the total server capacity."
+}
diff --git a/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt
new file mode 100644
index 000000000..dec578bd9
--- /dev/null
+++ b/saltstack-adapter/saltstack-adapter-provider/src/test/resources/test.txt
@@ -0,0 +1,30 @@
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos2v-queueing-code = P
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-egress-class-queueing-policing-codes.cos3-queueing-code = W
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos2v-queueing = QueueLimit
+operational-data.avpn-ip-port-information.port-level-cos.queueing.pe-per-class-queueing-behaviors.cos3-queueing = WRED
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos2v-shaping = Enable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-behaviors.cos3-shaping = Disable
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2-shaping-code = W
+operational-data.avpn-ip-port-information.port-level-cos.shaping.pe-egress-per-class-shaping-codes.cos2v-shaping-code = P
+service-configuration-notification-input.ack-final-indicator = Y
+service-configuration-notification-input.response-code = 0
+service-configuration-notification-input.response-message = Plc Activation Failed: Device gblond2005me6 Sync-from Failed. Please check device IP address and NCS setup.
+service-configuration-notification-input.service-information.service-instance-id = TEST7
+service-configuration-notification-input.service-information.service-type = AVPN
+service-configuration-notification-input.svc-request-id = TEST7
+service-data.avpn-ip-port-information.avpn-access-information.access-circuit-id = DHEC.54831.170.ATI
+service-data.avpn-ip-port-information.avpn-access-information.access-interface = _1G
+service-data.avpn-ip-port-information.avpn-access-information.access-speed = 10000
+service-data.avpn-ip-port-information.avpn-access-information.access-speed-units = Kbps
+service-data.avpn-ip-port-information.avpn-access-information.l1-customer-handoff = _1000BASELX
+service-data.avpn-ip-port-information.avpn-access-information.managed-ce = N
+service-data.avpn-ip-port-information.avpn-access-information.vlan-tag-control = _1Q
+service-data.avpn-ip-port-information.clli = LONDENEH
+service-data.avpn-ip-port-information.contracted-port-speed = 10000
+service-data.avpn-ip-port-information.contracted-port-speed-units = Kbps
+service-data.avpn-ip-port-information.endpoint-information.bundle-id = 33
+service-data.avpn-ip-port-information.endpoint-information.interface-string = ae0
+service-data.service-information.service-instance-id = ICORESITE-2751508
+service-data.service-information.service-type = AVPN
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json
new file mode 100644
index 000000000..562c24ad3
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.json
@@ -0,0 +1,203 @@
+[
+ {
+ "id": "d86e7ee4.ee3f1",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exe-nonSLS' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 492,
+ "y": 216,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "38662e01.1d3c22"
+ ]
+ ]
+ },
+ {
+ "id": "9997883e.ec9028",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 283,
+ "y": 289,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "d86e7ee4.ee3f1"
+ ]
+ ]
+ },
+ {
+ "id": "d40bf650.8338e8",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1007,
+ "y": 373,
+ "z": "5945fc3c.78efc4",
+ "wires": []
+ },
+ {
+ "id": "38662e01.1d3c22",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='cd /srv/salt; ls -l'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 700,
+ "y": 212,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "7b75e382.6344dc",
+ "6f108926.d7baf8"
+ ]
+ ]
+ },
+ {
+ "id": "24fb9f79.a6c6c",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 486,
+ "y": 372,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "c526c44.c850738",
+ "9c394980.2a56a8"
+ ]
+ ]
+ },
+ {
+ "id": "c526c44.c850738",
+ "type": "other",
+ "name": "outcome",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 675,
+ "y": 371,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "d40bf650.8338e8"
+ ]
+ ]
+ },
+ {
+ "id": "7b75e382.6344dc",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 951,
+ "y": 210,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "d40bf650.8338e8"
+ ]
+ ]
+ },
+ {
+ "id": "6f108926.d7baf8",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 298,
+ "y": 378,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "24fb9f79.a6c6c"
+ ]
+ ]
+ },
+ {
+ "id": "9c394980.2a56a8",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 667,
+ "y": 460,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "1f81a3db.54cd1c"
+ ]
+ ]
+ },
+ {
+ "id": "1f81a3db.54cd1c",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 887,
+ "y": 460,
+ "z": "5945fc3c.78efc4",
+ "wires": []
+ },
+ {
+ "id": "fcad80f8.ba2d9",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 261,
+ "y": 189,
+ "z": "5945fc3c.78efc4",
+ "wires": [
+ [
+ "9997883e.ec9028"
+ ]
+ ]
+ },
+ {
+ "id": "b86e624d.49f0f",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 630,
+ "y": 75,
+ "z": "5945fc3c.78efc4",
+ "wires": []
+ },
+ {
+ "id": "83c0578d.061f98",
+ "type": "comment",
+ "name": "request-method = reqExecCommand, req-action = \"execute a single non SLS command\"",
+ "info": "",
+ "comments": "",
+ "x": 650,
+ "y": 155,
+ "z": "5945fc3c.78efc4",
+ "wires": []
+ },
+ {
+ "id": "f104feb6.558f7",
+ "type": "comment",
+ "name": "Assumptions for this DG",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ",
+ "comments": "",
+ "x": 627,
+ "y": 115,
+ "z": "5945fc3c.78efc4",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml
new file mode 100644
index 000000000..6fbbe5b1f
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exe-nonSLS.xml
@@ -0,0 +1,50 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exe-nonSLS' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd' value='cd /srv/salt; ls -l'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json
new file mode 100644
index 000000000..7f427674b
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.json
@@ -0,0 +1,350 @@
+[
+ {
+ "id": "d0ad0305.352fc",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exec-SLSFile' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 552,
+ "y": 183,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "65cc87e2.a95188"
+ ]
+ ]
+ },
+ {
+ "id": "22aefec.e8c7902",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 343,
+ "y": 261,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "d0ad0305.352fc"
+ ]
+ ]
+ },
+ {
+ "id": "31587001.4259e",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1262,
+ "y": 365,
+ "z": "b84dc629.83cd08",
+ "wires": []
+ },
+ {
+ "id": "65cc87e2.a95188",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt &apos;*&apos; test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 761,
+ "y": 185,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "f9bf6ee7.cf954",
+ "7b51c357.a852cc"
+ ]
+ ]
+ },
+ {
+ "id": "42fa1258.aa570c",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 544,
+ "y": 345,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "a7cf236a.84c03",
+ "c45d597b.20b4c8"
+ ]
+ ]
+ },
+ {
+ "id": "a7cf236a.84c03",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 735,
+ "y": 343,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "31587001.4259e"
+ ]
+ ]
+ },
+ {
+ "id": "f9bf6ee7.cf954",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1011,
+ "y": 182,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "31587001.4259e"
+ ]
+ ]
+ },
+ {
+ "id": "7b51c357.a852cc",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 366,
+ "y": 343,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "42fa1258.aa570c"
+ ]
+ ]
+ },
+ {
+ "id": "c45d597b.20b4c8",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 351,
+ "y": 459,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "30d5f0f7.0e3c8"
+ ]
+ ]
+ },
+ {
+ "id": "2856792.c401a86",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1042,
+ "y": 656,
+ "z": "b84dc629.83cd08",
+ "wires": []
+ },
+ {
+ "id": "6c359fdc.3b566",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 321,
+ "y": 161,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "22aefec.e8c7902"
+ ]
+ ]
+ },
+ {
+ "id": "b5342c59.29f74",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 693,
+ "y": 44,
+ "z": "b84dc629.83cd08",
+ "wires": []
+ },
+ {
+ "id": "19202194.8ff55e",
+ "type": "comment",
+ "name": "request-method = reqExecCommand, req-action = \"execute multiple SLS commands\"",
+ "info": "Here we basically test if minion1 is active by pinging to it, then install vim package to it. \n",
+ "comments": "",
+ "x": 711,
+ "y": 127,
+ "z": "b84dc629.83cd08",
+ "wires": []
+ },
+ {
+ "id": "a2ebc17e.fa03a",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 396,
+ "y": 661,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "c9345fbb.d6d19"
+ ]
+ ]
+ },
+ {
+ "id": "770411a5.18825",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='Cmd' value='cd /srv/salt/; salt &apos;minion1&apos; state.apply vim --out=json --static'/>\n <parameter name='SlsExec' value='true'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 773,
+ "y": 548,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "e09a3e12.87428",
+ "a2ebc17e.fa03a"
+ ]
+ ]
+ },
+ {
+ "id": "e09a3e12.87428",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 991,
+ "y": 554,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "31587001.4259e"
+ ]
+ ]
+ },
+ {
+ "id": "c9345fbb.d6d19",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 578,
+ "y": 658,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "485e453d.36c75c",
+ "f1adcf2a.2c456"
+ ]
+ ]
+ },
+ {
+ "id": "485e453d.36c75c",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 783,
+ "y": 732,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "31587001.4259e"
+ ]
+ ]
+ },
+ {
+ "id": "f1adcf2a.2c456",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 776,
+ "y": 658,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "2856792.c401a86"
+ ]
+ ]
+ },
+ {
+ "id": "30d5f0f7.0e3c8",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$test1.minion1`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 523,
+ "y": 459,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "15e9ff68.9812a1",
+ "17d9d7e.4d9a928"
+ ]
+ ]
+ },
+ {
+ "id": "17d9d7e.4d9a928",
+ "type": "other",
+ "name": "outcome",
+ "xml": "<outcome value='true'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 593,
+ "y": 550,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "770411a5.18825"
+ ]
+ ]
+ },
+ {
+ "id": "15e9ff68.9812a1",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 717,
+ "y": 459,
+ "z": "b84dc629.83cd08",
+ "wires": [
+ [
+ "31587001.4259e"
+ ]
+ ]
+ },
+ {
+ "id": "b764890c.ed0018",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "1) Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. \n2) We assume that sls file called vim.sls is already present in the path /srv/salt on the server.",
+ "comments": "",
+ "x": 693,
+ "y": 86,
+ "z": "b84dc629.83cd08",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml
new file mode 100644
index 000000000..fc63bbd7b
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-SLSFile.xml
@@ -0,0 +1,112 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLSFile' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt &apos;*&apos; test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='Cmd'
+ value='cd /srv/salt/; salt &apos;minion1&apos; state.apply vim --out=json --static'/>
+ <parameter name='SlsExec' value='true'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ </switch>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json
new file mode 100644
index 000000000..d7cfef01e
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.json
@@ -0,0 +1,399 @@
+[
+ {
+ "id": "65f5c0d6.9c4ce",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exec-multi-sls' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 615,
+ "y": 273,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "c332cb01.51a3e8"
+ ]
+ ]
+ },
+ {
+ "id": "bf71bd6e.1be5b",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 406,
+ "y": 351,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "65f5c0d6.9c4ce"
+ ]
+ ]
+ },
+ {
+ "id": "40ce8a6.5f7d174",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1325,
+ "y": 455,
+ "z": "6df02477.0463cc",
+ "wires": []
+ },
+ {
+ "id": "c332cb01.51a3e8",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt &apos;*&apos; test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 824,
+ "y": 275,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "5b387684.e51be8",
+ "4bb6b32e.adfc2c"
+ ]
+ ]
+ },
+ {
+ "id": "16dfbd4f.b6da73",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 607,
+ "y": 435,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "24d22f52.ef59a",
+ "ac765880.a6c548"
+ ]
+ ]
+ },
+ {
+ "id": "24d22f52.ef59a",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 798,
+ "y": 433,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "5b387684.e51be8",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1074,
+ "y": 272,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "4bb6b32e.adfc2c",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 429,
+ "y": 433,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "16dfbd4f.b6da73"
+ ]
+ ]
+ },
+ {
+ "id": "ac765880.a6c548",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 414,
+ "y": 549,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "2dda30fc.8747"
+ ]
+ ]
+ },
+ {
+ "id": "e45accfe.91615",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1345,
+ "y": 757,
+ "z": "6df02477.0463cc",
+ "wires": []
+ },
+ {
+ "id": "11a891ad.55bc1e",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 384,
+ "y": 251,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "bf71bd6e.1be5b"
+ ]
+ ]
+ },
+ {
+ "id": "a56383b.496c48",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 756,
+ "y": 134,
+ "z": "6df02477.0463cc",
+ "wires": []
+ },
+ {
+ "id": "cfda30b5.5e166",
+ "type": "comment",
+ "name": "request-method = reqExecCommand, req-action = \"execute multiple SLS commands\"",
+ "info": "Here we basically test if minion1 is active by pinging to it, then install vim package to it. \n",
+ "comments": "",
+ "x": 773,
+ "y": 217,
+ "z": "6df02477.0463cc",
+ "wires": []
+ },
+ {
+ "id": "a8efb922.f23ce8",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 459,
+ "y": 751,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "3ff32215.20cd0e"
+ ]
+ ]
+ },
+ {
+ "id": "df0c0907.d17838",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='Cmd' value='salt &apos;minion1&apos; pkg.install vim --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 836,
+ "y": 638,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "1e5bbe2e.9cbb82",
+ "a8efb922.f23ce8"
+ ]
+ ]
+ },
+ {
+ "id": "1e5bbe2e.9cbb82",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1054,
+ "y": 644,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "3ff32215.20cd0e",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 647,
+ "y": 745,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "8e2c712b.784b4",
+ "3d74cfe5.d41f5"
+ ]
+ ]
+ },
+ {
+ "id": "8e2c712b.784b4",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 830,
+ "y": 823,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "3d74cfe5.d41f5",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 829,
+ "y": 758,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "8313564b.004798"
+ ]
+ ]
+ },
+ {
+ "id": "2dda30fc.8747",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$test1.minion1`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 586,
+ "y": 549,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "e0133af5.2ca028",
+ "7f28f521.cf47cc"
+ ]
+ ]
+ },
+ {
+ "id": "7f28f521.cf47cc",
+ "type": "other",
+ "name": "outcome",
+ "xml": "<outcome value='true'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 656,
+ "y": 640,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "df0c0907.d17838"
+ ]
+ ]
+ },
+ {
+ "id": "e0133af5.2ca028",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 780,
+ "y": 549,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "8313564b.004798",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$test2.minion1.retcode`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 986,
+ "y": 752,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "13d18d2d.71fbf3",
+ "2e940add.522a36"
+ ]
+ ]
+ },
+ {
+ "id": "13d18d2d.71fbf3",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1165,
+ "y": 825,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "40ce8a6.5f7d174"
+ ]
+ ]
+ },
+ {
+ "id": "2e940add.522a36",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='0'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1156,
+ "y": 754,
+ "z": "6df02477.0463cc",
+ "wires": [
+ [
+ "e45accfe.91615"
+ ]
+ ]
+ },
+ {
+ "id": "6d6678d2.6a9bd8",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ",
+ "comments": "",
+ "x": 756,
+ "y": 173,
+ "z": "6df02477.0463cc",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml
new file mode 100644
index 000000000..cc36b1ca7
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-multi-sls.xml
@@ -0,0 +1,129 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-multi-sls' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt &apos;*&apos; test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='Cmd'
+ value='salt &apos;minion1&apos; pkg.install vim --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test2.minion1.retcode`">
+ <outcome value='0'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter
+ name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ </switch>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json
new file mode 100644
index 000000000..4be0db3dd
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.json
@@ -0,0 +1,203 @@
+[
+ {
+ "id": "bd0f1105.ff214",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exec-single-SLSComm' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 526,
+ "y": 238,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "f4e59dd0.ee45f"
+ ]
+ ]
+ },
+ {
+ "id": "26f2a2b8.90f58e",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 317,
+ "y": 316,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "bd0f1105.ff214"
+ ]
+ ]
+ },
+ {
+ "id": "55a7736.2789e8c",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1064,
+ "y": 453,
+ "z": "c053ae12.4067b",
+ "wires": []
+ },
+ {
+ "id": "f4e59dd0.ee45f",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt &apos;*&apos; test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 735,
+ "y": 240,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "93fca622.05ad58",
+ "7ce4a659.44c828"
+ ]
+ ]
+ },
+ {
+ "id": "2ceb37d9.a8ba18",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 522,
+ "y": 398,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "cd89356c.279678",
+ "781026e2.01d498"
+ ]
+ ]
+ },
+ {
+ "id": "cd89356c.279678",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 708,
+ "y": 456,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "55a7736.2789e8c"
+ ]
+ ]
+ },
+ {
+ "id": "93fca622.05ad58",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 985,
+ "y": 237,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "55a7736.2789e8c"
+ ]
+ ]
+ },
+ {
+ "id": "7ce4a659.44c828",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 332,
+ "y": 405,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "2ceb37d9.a8ba18"
+ ]
+ ]
+ },
+ {
+ "id": "781026e2.01d498",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 711,
+ "y": 398,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "ce510062.8dcc7"
+ ]
+ ]
+ },
+ {
+ "id": "ce510062.8dcc7",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 893,
+ "y": 399,
+ "z": "c053ae12.4067b",
+ "wires": []
+ },
+ {
+ "id": "593bd7fb.675368",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 295,
+ "y": 216,
+ "z": "c053ae12.4067b",
+ "wires": [
+ [
+ "26f2a2b8.90f58e"
+ ]
+ ]
+ },
+ {
+ "id": "901c8408.5fecb8",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 673,
+ "y": 103,
+ "z": "c053ae12.4067b",
+ "wires": []
+ },
+ {
+ "id": "cc449713.a1be88",
+ "type": "comment",
+ "name": "request-method = reqExecCommand, req-action = \"execute a single SLS command\"",
+ "info": "Here we just ping to all the minions, and we dont even check if the minions are active. ",
+ "comments": "",
+ "x": 684,
+ "y": 188,
+ "z": "c053ae12.4067b",
+ "wires": []
+ },
+ {
+ "id": "c07fa80e.7f3ac8",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controlls minion1 and minion2. ",
+ "comments": "",
+ "x": 676,
+ "y": 144,
+ "z": "c053ae12.4067b",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml
new file mode 100644
index 000000000..bd9aea771
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecCommand/APPC_saltstack-adapter-1.0-exec-single-SLSComm.xml
@@ -0,0 +1,51 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-single-SLSComm' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt &apos;*&apos; test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json
new file mode 100644
index 000000000..7fe88f063
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.json
@@ -0,0 +1,214 @@
+[
+ {
+ "id": "80b83851.e527b8",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 676,
+ "y": 277,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "83c8d47e.cb9c98"
+ ]
+ ]
+ },
+ {
+ "id": "41231c44.5d1324",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 453,
+ "y": 276,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "80b83851.e527b8"
+ ]
+ ]
+ },
+ {
+ "id": "1f4a794d.fb3be7",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1055,
+ "y": 369,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ },
+ {
+ "id": "5a85036.5a9e2fc",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 284,
+ "y": 275,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "41231c44.5d1324"
+ ]
+ ]
+ },
+ {
+ "id": "b38fc61c.a23438",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 661,
+ "y": 154,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ },
+ {
+ "id": "6a821d83.4070e4",
+ "type": "comment",
+ "name": "request-method = reqExecSLS, req-action = \"execute SLS\"",
+ "info": "This would be the ideal adaptor the orchestrator DG will call, this just takes in SlsName.",
+ "comments": "",
+ "x": 672,
+ "y": 239,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ },
+ {
+ "id": "ba16960c.36bad8",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ",
+ "comments": "",
+ "x": 664,
+ "y": 195,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ },
+ {
+ "id": "83c8d47e.cb9c98",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsName' value='test-file.sls'/>\n <parameter name='NodeList' value='`$NodeList`'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n <parameter name='FileParameters' value='`$FileParameters`'/>\n <parameter name='EnvParameters' value='`$EnvParameters`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 366,
+ "y": 406,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "b83f5a23.33f938",
+ "3354190.eb450e8"
+ ]
+ ]
+ },
+ {
+ "id": "b83f5a23.33f938",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 559,
+ "y": 367,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "efc02e73.0cf1d"
+ ]
+ ]
+ },
+ {
+ "id": "3354190.eb450e8",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 557,
+ "y": 439,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "88b53985.e42758"
+ ]
+ ]
+ },
+ {
+ "id": "88b53985.e42758",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 709,
+ "y": 427,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "195a294e.61efb7",
+ "bc1bfd78.146bc"
+ ]
+ ]
+ },
+ {
+ "id": "bc1bfd78.146bc",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 872,
+ "y": 373,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "1f4a794d.fb3be7"
+ ]
+ ]
+ },
+ {
+ "id": "195a294e.61efb7",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 869,
+ "y": 442,
+ "z": "1f6661d7.1ebd2e",
+ "wires": [
+ [
+ "81ddc2e0.dce24"
+ ]
+ ]
+ },
+ {
+ "id": "efc02e73.0cf1d",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 719,
+ "y": 351,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ },
+ {
+ "id": "81ddc2e0.dce24",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1039,
+ "y": 439,
+ "z": "1f6661d7.1ebd2e",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml
new file mode 100644
index 000000000..23ec7856b
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0 IDEAL.xml
@@ -0,0 +1,52 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsName' value='test-file.sls'/>
+ <parameter name='NodeList' value='`$NodeList`'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <parameter name='FileParameters' value='`$FileParameters`'/>
+ <parameter name='EnvParameters' value='`$EnvParameters`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json
new file mode 100644
index 000000000..b276f3815
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.json
@@ -0,0 +1,372 @@
+[
+ {
+ "id": "edb39979.b1ccd8",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exec-SLS-NodeList' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 476,
+ "y": 245,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "95c9ba42.6e4aa8"
+ ]
+ ]
+ },
+ {
+ "id": "a16ea11e.f8d1c",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 267,
+ "y": 323,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "edb39979.b1ccd8"
+ ]
+ ]
+ },
+ {
+ "id": "1591f92e.029ca7",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1191,
+ "y": 315,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "95c9ba42.6e4aa8",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt &apos;*&apos; test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 684,
+ "y": 251,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "cd0c458a.2430b8",
+ "69e531e3.4efc3"
+ ]
+ ]
+ },
+ {
+ "id": "38b44d70.9c85d2",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 472,
+ "y": 405,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "505df598.069b9c",
+ "5d7292e.22ec06c"
+ ]
+ ]
+ },
+ {
+ "id": "505df598.069b9c",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 658,
+ "y": 463,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "1591f92e.029ca7"
+ ]
+ ]
+ },
+ {
+ "id": "cd0c458a.2430b8",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 935,
+ "y": 244,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "1591f92e.029ca7"
+ ]
+ ]
+ },
+ {
+ "id": "69e531e3.4efc3",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 282,
+ "y": 412,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "38b44d70.9c85d2"
+ ]
+ ]
+ },
+ {
+ "id": "5d7292e.22ec06c",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 661,
+ "y": 405,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "c9df0cea.f2361"
+ ]
+ ]
+ },
+ {
+ "id": "e4f7eb59.0abb58",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1079,
+ "y": 564,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "8e586da4.570f1",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 245,
+ "y": 223,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "a16ea11e.f8d1c"
+ ]
+ ]
+ },
+ {
+ "id": "71387074.137c1",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 623,
+ "y": 110,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "c5e8c62d.021758",
+ "type": "comment",
+ "name": "request-method = reqExecSLS, req-action = \"execute SLS\"",
+ "info": "Here we basically test if minion1 is active by pinging to it, then respective sls file is executed on to it. \n",
+ "comments": "",
+ "x": 634,
+ "y": 195,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "1805797.a241487",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ",
+ "comments": "",
+ "x": 626,
+ "y": 151,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "c9df0cea.f2361",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$test1.minion1`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 825,
+ "y": 405,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "d83d6024.2454d",
+ "f4d70bbc.f0bc38"
+ ]
+ ]
+ },
+ {
+ "id": "d83d6024.2454d",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 991,
+ "y": 459,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "1591f92e.029ca7"
+ ]
+ ]
+ },
+ {
+ "id": "f4d70bbc.f0bc38",
+ "type": "other",
+ "name": "outcome",
+ "xml": "<outcome value='true'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 994,
+ "y": 401,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "e86d9995.b65c58"
+ ]
+ ]
+ },
+ {
+ "id": "e86d9995.b65c58",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsName' value='test-file.sls'/>\n <parameter name='NodeList' value='minion1'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 398,
+ "y": 593,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "89ff1c2a.08f52",
+ "e20c4c85.43d3c"
+ ]
+ ]
+ },
+ {
+ "id": "89ff1c2a.08f52",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 583,
+ "y": 562,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "6032e33e.5b044c"
+ ]
+ ]
+ },
+ {
+ "id": "e20c4c85.43d3c",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 581,
+ "y": 634,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "8bb4c177.499c8"
+ ]
+ ]
+ },
+ {
+ "id": "8bb4c177.499c8",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 733,
+ "y": 622,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "905334fe.934d68",
+ "9c217c10.9d539"
+ ]
+ ]
+ },
+ {
+ "id": "9c217c10.9d539",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 896,
+ "y": 568,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "e4f7eb59.0abb58"
+ ]
+ ]
+ },
+ {
+ "id": "905334fe.934d68",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 893,
+ "y": 637,
+ "z": "671ca899.284f68",
+ "wires": [
+ [
+ "7026a88c.5bffd8"
+ ]
+ ]
+ },
+ {
+ "id": "6032e33e.5b044c",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 735,
+ "y": 559,
+ "z": "671ca899.284f68",
+ "wires": []
+ },
+ {
+ "id": "7026a88c.5bffd8",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1054,
+ "y": 637,
+ "z": "671ca899.284f68",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml
new file mode 100644
index 000000000..cc4538cac
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLS/APPC_saltstack-adapter-1.0-exec-SLS-applyTo.xml
@@ -0,0 +1,112 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLS-NodeList' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt &apos;*&apos; test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsName'
+ value='test-file.sls'/>
+ <parameter name='NodeList' value='minion1'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json
new file mode 100644
index 000000000..b20e7e8da
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.json
@@ -0,0 +1,214 @@
+[
+ {
+ "id": "3228200a.5dc1a",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-SLSFILE' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 679,
+ "y": 282,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "50b2729f.712eac"
+ ]
+ ]
+ },
+ {
+ "id": "9fb54163.4fb28",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 456,
+ "y": 281,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "3228200a.5dc1a"
+ ]
+ ]
+ },
+ {
+ "id": "49109fbc.a7a14",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1058,
+ "y": 374,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ },
+ {
+ "id": "d030a396.56232",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 287,
+ "y": 280,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "9fb54163.4fb28"
+ ]
+ ]
+ },
+ {
+ "id": "281900c4.fd3e8",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 664,
+ "y": 159,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ },
+ {
+ "id": "431a69db.2d2c58",
+ "type": "comment",
+ "name": "request-method = reqExecSLS, req-action = \"execute SLS\"",
+ "info": "This would be the ideal adaptor the orchestrator DG will call, this just takes in SlsName.",
+ "comments": "",
+ "x": 675,
+ "y": 244,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ },
+ {
+ "id": "4202e1ce.09495",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ",
+ "comments": "",
+ "x": 667,
+ "y": 200,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ },
+ {
+ "id": "50b2729f.712eac",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsFile' value='file/location/test-file.sls'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 369,
+ "y": 411,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "71746570.35f0dc",
+ "3e4f7a4a.ae0dc6"
+ ]
+ ]
+ },
+ {
+ "id": "71746570.35f0dc",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 562,
+ "y": 372,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "e59a1a81.112a08"
+ ]
+ ]
+ },
+ {
+ "id": "3e4f7a4a.ae0dc6",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 560,
+ "y": 444,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "59e320fa.12908"
+ ]
+ ]
+ },
+ {
+ "id": "59e320fa.12908",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 712,
+ "y": 432,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "f81ed07.2135c3",
+ "eb55b5a9.f0d2f8"
+ ]
+ ]
+ },
+ {
+ "id": "eb55b5a9.f0d2f8",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 875,
+ "y": 378,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "49109fbc.a7a14"
+ ]
+ ]
+ },
+ {
+ "id": "f81ed07.2135c3",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 872,
+ "y": 447,
+ "z": "6d4f912d.f07bc",
+ "wires": [
+ [
+ "6549631f.8e516c"
+ ]
+ ]
+ },
+ {
+ "id": "e59a1a81.112a08",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 722,
+ "y": 356,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ },
+ {
+ "id": "6549631f.8e516c",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1042,
+ "y": 444,
+ "z": "6d4f912d.f07bc",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml
new file mode 100644
index 000000000..2c5e600fc
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-SLSFILE.xml
@@ -0,0 +1,48 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-SLSFILE' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsFile' value='file/location/test-file.sls'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json
new file mode 100644
index 000000000..264950d5e
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.json
@@ -0,0 +1,372 @@
+[
+ {
+ "id": "9a6bf94f.d969f8",
+ "type": "method",
+ "name": "saltstack-adapter-1.0",
+ "xml": "<method rpc='saltstack-adapter-1.0-exec-SLSFile-SlsName' mode='sync'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 498,
+ "y": 240,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "138ad7ed.403248"
+ ]
+ ]
+ },
+ {
+ "id": "4bb87049.3f546",
+ "type": "service-logic",
+ "name": "APPC 2.0.1",
+ "module": "APPC",
+ "version": "2.0.1",
+ "comments": "",
+ "xml": "<service-logic xmlns='http://www.onap.org/sdnc/svclogic' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd' module='APPC' version='2.0.1'>",
+ "outputs": 1,
+ "x": 289,
+ "y": 318,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "9a6bf94f.d969f8"
+ ]
+ ]
+ },
+ {
+ "id": "6c593992.106038",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1202,
+ "y": 280,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "138ad7ed.403248",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test1'/>\n <parameter name='Cmd' value='salt &apos;*&apos; test.ping --out=json --static'/>\n <parameter name='SlsExec' value='false'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 706,
+ "y": 246,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "167273ed.f0577c",
+ "954a34ea.701368"
+ ]
+ ]
+ },
+ {
+ "id": "d5841e65.537ba",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 494,
+ "y": 400,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "ede42371.2f52b",
+ "d306d7a0.c830e8"
+ ]
+ ]
+ },
+ {
+ "id": "ede42371.2f52b",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 680,
+ "y": 458,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "6c593992.106038"
+ ]
+ ]
+ },
+ {
+ "id": "167273ed.f0577c",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 957,
+ "y": 239,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "6c593992.106038"
+ ]
+ ]
+ },
+ {
+ "id": "954a34ea.701368",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 304,
+ "y": 407,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "d5841e65.537ba"
+ ]
+ ]
+ },
+ {
+ "id": "d306d7a0.c830e8",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 683,
+ "y": 400,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "5b12ba31.94b3b4"
+ ]
+ ]
+ },
+ {
+ "id": "9ef7fcc3.69279",
+ "type": "returnSuccess",
+ "name": "return success",
+ "xml": "<return status='success'>\n<parameter name='output.status.code' value='`$org.openecomp.appc.adapter.saltstack.result.code`' />\n<parameter name='output.status.message' value='`$org.openecomp.appc.adapter.saltstack.message`'/>\n<parameter name='output.status.results' value = '`$org.openecomp.appc.adapter.saltstack.results`'/>\n",
+ "comments": "",
+ "x": 1101,
+ "y": 559,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "7803eeaf.1e31d",
+ "type": "dgstart",
+ "name": "DGSTART",
+ "outputs": 1,
+ "x": 267,
+ "y": 218,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "4bb87049.3f546"
+ ]
+ ]
+ },
+ {
+ "id": "9c6f1e7c.2a3d9",
+ "type": "comment",
+ "name": "SaltStack Adaptor DG",
+ "info": "",
+ "comments": "",
+ "x": 645,
+ "y": 105,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "93ea02a5.4e792",
+ "type": "comment",
+ "name": "request-method = reqExecSLS, req-action = \"execute SLS FILE\"",
+ "info": "Here we basically test if minion1 is active by pinging to it, then respective sls file is executed on to it. \n",
+ "comments": "",
+ "x": 656,
+ "y": 190,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "243edbf.f35fc24",
+ "type": "comment",
+ "name": "Assumptions for this DG (example-server)",
+ "info": "Here we assume, the saltstack server is the example-vagrant based server. Where, the master saltstact controllers minion1 and minion2. ",
+ "comments": "",
+ "x": 648,
+ "y": 146,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "5b12ba31.94b3b4",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$test1.minion1`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 847,
+ "y": 400,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "9bf0915.96f217",
+ "f6e533d.95d99d"
+ ]
+ ]
+ },
+ {
+ "id": "9bf0915.96f217",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1013,
+ "y": 454,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "6c593992.106038"
+ ]
+ ]
+ },
+ {
+ "id": "f6e533d.95d99d",
+ "type": "other",
+ "name": "outcome",
+ "xml": "<outcome value='true'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 1016,
+ "y": 396,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "eb57ba41.1d7328"
+ ]
+ ]
+ },
+ {
+ "id": "eb57ba41.1d7328",
+ "type": "execute",
+ "name": "execute",
+ "xml": "<execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter' method='reqExecCommand' >\n <parameter name='HostName' value='`$AgentUrl`'/>\n <parameter name='Port' value='`$Port`'/>\n <parameter name='User' value='`$User`'/>\n <parameter name='Password' value='`$Password`'/>\n <parameter name='Id' value='test2'/>\n <parameter name='SlsFile' value='file/location/test.sls'/>\n <parameter name='NodeList' value='minion1'/>\n <parameter name='Timeout' value='`$Timeout`'/>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 420,
+ "y": 588,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "892a8f1d.7d77f",
+ "74be8a6e.975f24"
+ ]
+ ]
+ },
+ {
+ "id": "892a8f1d.7d77f",
+ "type": "failure",
+ "name": "failure",
+ "xml": "<outcome value='failure'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 605,
+ "y": 557,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "8c091fe.c6cbfe"
+ ]
+ ]
+ },
+ {
+ "id": "74be8a6e.975f24",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 603,
+ "y": 629,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "3875d695.fd37ca"
+ ]
+ ]
+ },
+ {
+ "id": "3875d695.fd37ca",
+ "type": "switchNode",
+ "name": "switch",
+ "xml": "<switch test=\"`$org.onap.appc.adapter.saltstack.result.code`\">\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 755,
+ "y": 617,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "2e60af80.ea3a6",
+ "24ed6dd2.6624c2"
+ ]
+ ]
+ },
+ {
+ "id": "24ed6dd2.6624c2",
+ "type": "success",
+ "name": "success",
+ "xml": "<outcome value='200'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 918,
+ "y": 563,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "9ef7fcc3.69279"
+ ]
+ ]
+ },
+ {
+ "id": "2e60af80.ea3a6",
+ "type": "other",
+ "name": "other",
+ "xml": "<outcome value='Other'>\n",
+ "comments": "",
+ "outputs": 1,
+ "x": 915,
+ "y": 632,
+ "z": "723548c7.652d78",
+ "wires": [
+ [
+ "2e4414a7.ba6d4c"
+ ]
+ ]
+ },
+ {
+ "id": "8c091fe.c6cbfe",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 757,
+ "y": 554,
+ "z": "723548c7.652d78",
+ "wires": []
+ },
+ {
+ "id": "2e4414a7.ba6d4c",
+ "type": "returnFailure",
+ "name": "return failure",
+ "xml": "<return status='failure'>\n<parameter name='error-code' value='200' />\n<parameter name='error-message' value='`$org.openecomp.appc.adapter.saltstack.message`' />\n<parameter name='output.status.results' value='`$org.openecomp.appc.adapter.saltstack.results`' />\n",
+ "comments": "",
+ "x": 1076,
+ "y": 632,
+ "z": "723548c7.652d78",
+ "wires": []
+ }
+] \ No newline at end of file
diff --git a/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml
new file mode 100644
index 000000000..16c573add
--- /dev/null
+++ b/saltstack-adapter/saltstack-directed-graphs-sample/reqExecSLSFile/APPC_saltstack-adapter-1.0-exec-SLSFile-applyTo.xml
@@ -0,0 +1,112 @@
+<service-logic xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+ xmlns='http://www.onap.org/sdnc/svclogic'
+ xsi:schemaLocation='http://www.onap.org/sdnc/svclogic ./svclogic.xsd'
+ module='APPC' version='2.0.1'>
+ <method rpc='saltstack-adapter-1.0-exec-SLSFile-NodeList' mode='sync'>
+ <execute plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName' value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password' value='`$Password`'/>
+ <parameter name='Id' value='test1'/>
+ <parameter name='Cmd'
+ value='salt &apos;*&apos; test.ping --out=json --static'/>
+ <parameter name='SlsExec' value='false'/>
+ <parameter name='Timeout' value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <switch test="`$test1.minion1`">
+ <outcome value='true'>
+ <execute
+ plugin='org.openecomp.appc.adapter.saltstack.SaltstackAdapter'
+ method='reqExecCommand'>
+ <parameter name='HostName'
+ value='`$AgentUrl`'/>
+ <parameter name='Port' value='`$Port`'/>
+ <parameter name='User' value='`$User`'/>
+ <parameter name='Password'
+ value='`$Password`'/>
+ <parameter name='Id' value='test2'/>
+ <parameter name='SlsFile'
+ value='file/location/test.sls'/>
+ <parameter name='NodeList' value='minion1'/>
+ <parameter name='Timeout'
+ value='`$Timeout`'/>
+ <outcome value='failure'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <switch test="`$org.onap.appc.adapter.saltstack.result.code`">
+ <outcome value='200'>
+ <return status='success'>
+ <parameter
+ name='output.status.code'
+ value='`$org.openecomp.appc.adapter.saltstack.result.code`'/>
+ <parameter
+ name='output.status.message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code'
+ value='200'/>
+ <parameter
+ name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter
+ name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ <outcome value='Other'>
+ <return status='failure'>
+ <parameter name='error-code' value='200'/>
+ <parameter name='error-message'
+ value='`$org.openecomp.appc.adapter.saltstack.message`'/>
+ <parameter name='output.status.results'
+ value='`$org.openecomp.appc.adapter.saltstack.results`'/>
+ </return>
+ </outcome>
+ </switch>
+ </outcome>
+ </execute>
+ </method>
+</service-logic> \ No newline at end of file