Support openstack controller node status check feature
Change-Id: I285b977ae32dd6d140aca7f25b00962db77b1054
diff --git a/apps/openstacknode/api/BUCK b/apps/openstacknode/api/BUCK
index 1099c27..4f335f3 100644
--- a/apps/openstacknode/api/BUCK
+++ b/apps/openstacknode/api/BUCK
@@ -1,3 +1,5 @@
+include_defs('//apps/openstacknetworking/openstack4j.bucklet')
+
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:org.apache.karaf.shell.console',
@@ -15,5 +17,7 @@
osgi_jar_with_tests (
deps = COMPILE_DEPS,
- test_deps = TEST_DEPS
+ test_deps = TEST_DEPS,
+
+ import_packages = INCLUDE_PACKAGES + ',' + EXCLUDE_PACKAGES + ',' + ALL_PACKAGES,
)
diff --git a/apps/openstacknode/api/pom.xml b/apps/openstacknode/api/pom.xml
index cd9bbca..a08e109 100644
--- a/apps/openstacknode/api/pom.xml
+++ b/apps/openstacknode/api/pom.xml
@@ -35,5 +35,32 @@
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.pacesys</groupId>
+ <artifactId>openstack4j-core</artifactId>
+ <version>${openstack4j.version}</version>
+ </dependency>
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-SymbolicName>
+ ${project.groupId}.${project.artifactId}
+ </Bundle-SymbolicName>
+ <Import-Package>
+ !org.openstack4j.*,
+ *
+ </Import-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/apps/openstacknode/app/BUCK b/apps/openstacknode/app/BUCK
index 4612f6a..a80ba98 100644
--- a/apps/openstacknode/app/BUCK
+++ b/apps/openstacknode/app/BUCK
@@ -1,3 +1,5 @@
+include_defs('//apps/openstacknode/openstack4j.bucklet')
+
COMPILE_DEPS = [
'//lib:CORE_DEPS',
'//lib:JACKSON',
@@ -10,6 +12,14 @@
'//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
'//core/store/serializers:onos-core-serializers',
'//apps/openstacknode/api:onos-apps-openstacknode-api',
+ '//lib:openstack4j-core',
+ '//lib:openstack4j-http-connector',
+ '//lib:openstack4j-httpclient',
+ '//lib:json-patch',
+ '//lib:jackson-coreutils',
+ '//lib:btf',
+ '//lib:msg-simple',
+ '//lib:snakeyaml',
]
TEST_DEPS = [
@@ -28,5 +38,9 @@
api_version = '1.0',
api_description = 'REST API for OpenStack Node',
api_package = 'org.onosproject.openstacknode.web',
+
+ # dependency embedding
+ import_packages = INCLUDE_PACKAGES + ',' + EXCLUDE_PACKAGES + ',' + ALL_PACKAGES,
+ bundle_classpath = get_openstack4j_deps_path() + get_jackson_deps_path()
)
diff --git a/apps/openstacknode/app/pom.xml b/apps/openstacknode/app/pom.xml
index 5d2ff79..401824f 100644
--- a/apps/openstacknode/app/pom.xml
+++ b/apps/openstacknode/app/pom.xml
@@ -132,6 +132,47 @@
</dependency>
<dependency>
+ <groupId>org.pacesys</groupId>
+ <artifactId>openstack4j-core</artifactId>
+ <version>${openstack4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.pacesys.openstack4j.connectors</groupId>
+ <artifactId>openstack4j-http-connector</artifactId>
+ <version>${openstack4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.pacesys.openstack4j.connectors</groupId>
+ <artifactId>openstack4j-httpclient</artifactId>
+ <version>${openstack4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.fge</groupId>
+ <artifactId>json-patch</artifactId>
+ <version>${json-patch.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.fge</groupId>
+ <artifactId>jackson-coreutils</artifactId>
+ <version>${jackson-coreutils.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.fge</groupId>
+ <artifactId>btf</artifactId>
+ <version>${btf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.github.fge</groupId>
+ <artifactId>msg-simple</artifactId>
+ <version>${msg-simple.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <version>${snakeyaml.version}</version>
+ </dependency>
+
+ <dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<scope>test</scope>
@@ -184,6 +225,28 @@
<build>
<plugins>
<plugin>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>generate-scr-srcdescriptor</id>
+ <goals>
+ <goal>scr</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <supportedProjectTypes>
+ <supportedProjectType>bundle</supportedProjectType>
+ <supportedProjectType>war</supportedProjectType>
+ </supportedProjectTypes>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
@@ -197,13 +260,26 @@
<Bundle-SymbolicName>
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
+ <Web-ContextPath>${web.context}</Web-ContextPath>
<Import-Package>
+ !org.apache.http.*,
+ !com.fasterxml.jackson.dataformat.*,
+ !javax.annotation,
*,org.glassfish.jersey.servlet
</Import-Package>
- <Web-ContextPath>${web.context}</Web-ContextPath>
+ <Embed-Dependency>
+ openstack4j-core,
+ openstack4j-http-connector,
+ openstack4j-httpclient,
+ json-patch,
+ jackson-coreutils,
+ btf,
+ msg-simple,
+ snakeyaml
+ </Embed-Dependency>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
-</project>
+</project>
\ No newline at end of file
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNode.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNode.java
index 73c8e1b..e6592b0 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNode.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNode.java
@@ -398,9 +398,6 @@
}
} else {
checkArgument(endPoint != null, NOT_NULL_MSG, "endpoint URL");
-
- // we force controller node to have COMPLETE state for now
- state = NodeState.COMPLETE;
}
if (type == NodeType.GATEWAY && uplinkPort == null) {
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
index 6064267..ba7e8ec 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DefaultOpenstackNodeHandler.java
@@ -60,6 +60,7 @@
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.onosproject.openstacknode.api.OpenstackPhyInterface;
import org.onosproject.ovsdb.controller.OvsdbController;
+import org.openstack4j.api.OSClient;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -80,8 +81,11 @@
import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
import static org.onosproject.openstacknode.api.NodeState.DEVICE_CREATED;
import static org.onosproject.openstacknode.api.NodeState.INCOMPLETE;
+import static org.onosproject.openstacknode.api.NodeState.INIT;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
import static org.onosproject.openstacknode.api.OpenstackNodeService.APP_ID;
+import static org.onosproject.openstacknode.util.OpenstackNodeUtil.getConnectedClient;
import static org.onosproject.openstacknode.util.OpenstackNodeUtil.isOvsdbConnected;
import static org.slf4j.LoggerFactory.getLogger;
@@ -422,11 +426,39 @@
* @param osNode openstack node
*/
private void bootstrapNode(OpenstackNode osNode) {
- if (isCurrentStateDone(osNode)) {
- setState(osNode, osNode.state().nextState());
+ if (osNode.type() == CONTROLLER) {
+ if (osNode.state() == INIT && checkEndpoint(osNode)) {
+ setState(osNode, COMPLETE);
+ }
} else {
- log.trace("Processing {} state for {}", osNode.state(), osNode.hostname());
- osNode.state().process(this, osNode);
+ if (isCurrentStateDone(osNode)) {
+ setState(osNode, osNode.state().nextState());
+ } else {
+ log.trace("Processing {} state for {}", osNode.state(), osNode.hostname());
+ osNode.state().process(this, osNode);
+ }
+ }
+ }
+
+ /**
+ * Checks the validity of the given endpoint.
+ *
+ * @param osNode gateway node
+ * @return validity result
+ */
+ private boolean checkEndpoint(OpenstackNode osNode) {
+ if (osNode == null) {
+ log.warn("Keystone auth info has not been configured. " +
+ "Please specify auth info via network-cfg.json.");
+ return false;
+ }
+
+ OSClient client = getConnectedClient(osNode);
+
+ if (client == null) {
+ return false;
+ } else {
+ return client.getSupportedServices().size() != 0;
}
}
@@ -442,7 +474,8 @@
NodeId leader = leadershipService.getLeader(appId.name());
return Objects.equals(localNode, leader) &&
event.subject().type() == Device.Type.CONTROLLER &&
- osNodeService.node(event.subject().id()) != null;
+ osNodeService.node(event.subject().id()) != null &&
+ osNodeService.node(event.subject().id()).type() != CONTROLLER;
}
@Override
@@ -483,7 +516,8 @@
NodeId leader = leadershipService.getLeader(appId.name());
return Objects.equals(localNode, leader) &&
event.subject().type() == Device.Type.SWITCH &&
- osNodeService.node(event.subject().id()) != null;
+ osNodeService.node(event.subject().id()) != null &&
+ osNodeService.node(event.subject().id()).type() != CONTROLLER;
}
@Override
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DistributedOpenstackNodeStore.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DistributedOpenstackNodeStore.java
index be49135..4b40775 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DistributedOpenstackNodeStore.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/impl/DistributedOpenstackNodeStore.java
@@ -166,23 +166,6 @@
@Override
public void event(MapEvent<String, OpenstackNode> event) {
- OpenstackNode node;
-
- if (event.type() == INSERT || event.type() == UPDATE) {
- node = event.newValue().value();
- } else {
- node = event.oldValue().value();
- }
-
- // we do not notify the controller node related event
- // controller node event should be handled in different way
- if (node.type() == CONTROLLER) {
- // TODO: need to find a way to check the controller node availability
- log.info("node {} is detected", node.hostname());
-
- return;
- }
-
switch (event.type()) {
case INSERT:
log.debug("OpenStack node created {}", event.newValue());
@@ -198,6 +181,13 @@
OPENSTACK_NODE_UPDATED,
event.newValue().value()
));
+
+ // if the event is about controller node, we will not
+ // process COMPLETE and INCOMPLETE state
+ if (isControllerNode(event)) {
+ return;
+ }
+
if (event.newValue().value().state() == COMPLETE) {
notifyDelegate(new OpenstackNodeEvent(
OPENSTACK_NODE_COMPLETE,
@@ -223,5 +213,25 @@
break;
}
}
+
+ /**
+ * Checks the openstack node whether a controller node or not with
+ * the given MapEvent.
+ *
+ * @param event map event
+ * @return controller node indicator flag
+ */
+ private boolean isControllerNode(MapEvent<String, OpenstackNode> event) {
+
+ OpenstackNode node;
+
+ if (event.type() == INSERT || event.type() == UPDATE) {
+ node = event.newValue().value();
+ } else {
+ node = event.oldValue().value();
+ }
+
+ return node.type() == CONTROLLER;
+ }
}
}
diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
index 79526e6..8e1de52 100644
--- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
+++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/util/OpenstackNodeUtil.java
@@ -16,21 +16,44 @@
package org.onosproject.openstacknode.util;
import org.onosproject.net.device.DeviceService;
+import org.onosproject.openstacknode.api.OpenstackAuth;
+import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.ovsdb.controller.OvsdbClientService;
import org.onosproject.ovsdb.controller.OvsdbController;
import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.api.client.IOSClientBuilder;
+import org.openstack4j.api.exceptions.AuthenticationException;
+import org.openstack4j.api.types.Facing;
+import org.openstack4j.core.transport.Config;
+import org.openstack4j.model.common.Identifier;
+import org.openstack4j.openstack.OSFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.X509Certificate;
+
/**
* An utility that used in openstack node app.
*/
public final class OpenstackNodeUtil {
protected static final Logger log = LoggerFactory.getLogger(OpenstackNodeUtil.class);
+ // keystone endpoint related variables
+ private static final String DOMAIN_DEFAULT = "default";
+ private static final String KEYSTONE_V2 = "v2.0";
+ private static final String KEYSTONE_V3 = "v3";
+ private static final String IDENTITY_PATH = "identity/";
+ private static final String SSL_TYPE = "SSL";
+
/**
- * Prevents object instantiation from external.
+ * Prevents object installation from external.
*/
private OpenstackNodeUtil() {
}
@@ -55,4 +78,147 @@
client != null &&
client.isConnected();
}
+
+ /**
+ * Obtains a connected openstack client.
+ *
+ * @param osNode openstack node
+ * @return a connected openstack client
+ */
+ public static OSClient getConnectedClient(OpenstackNode osNode) {
+ OpenstackAuth auth = osNode.authentication();
+ String endpoint = buildEndpoint(osNode);
+ Perspective perspective = auth.perspective();
+
+ Config config = getSslConfig();
+
+ try {
+ if (endpoint.contains(KEYSTONE_V2)) {
+ IOSClientBuilder.V2 builder = OSFactory.builderV2()
+ .endpoint(endpoint)
+ .tenantName(auth.project())
+ .credentials(auth.username(), auth.password())
+ .withConfig(config);
+
+ if (perspective != null) {
+ builder.perspective(getFacing(perspective));
+ }
+
+ return builder.authenticate();
+ } else if (endpoint.contains(KEYSTONE_V3)) {
+
+ Identifier project = Identifier.byName(auth.project());
+ Identifier domain = Identifier.byName(DOMAIN_DEFAULT);
+
+ IOSClientBuilder.V3 builder = OSFactory.builderV3()
+ .endpoint(endpoint)
+ .credentials(auth.username(), auth.password(), domain)
+ .scopeToProject(project, domain)
+ .withConfig(config);
+
+ if (perspective != null) {
+ builder.perspective(getFacing(perspective));
+ }
+
+ return builder.authenticate();
+ } else {
+ log.warn("Unrecognized keystone version type");
+ return null;
+ }
+ } catch (AuthenticationException e) {
+ log.error("Authentication failed due to {}", e.toString());
+ return null;
+ }
+ }
+
+ /**
+ * Builds up and a complete endpoint URL from gateway node.
+ *
+ * @param node gateway node
+ * @return a complete endpoint URL
+ */
+ private static String buildEndpoint(OpenstackNode node) {
+
+ OpenstackAuth auth = node.authentication();
+
+ StringBuilder endpointSb = new StringBuilder();
+ endpointSb.append(auth.protocol().name().toLowerCase());
+ endpointSb.append("://");
+ endpointSb.append(node.endPoint());
+ endpointSb.append(":");
+ endpointSb.append(auth.port());
+ endpointSb.append("/");
+
+ // in case the version is v3, we need to append identity path into endpoint
+ if (auth.version().equals(KEYSTONE_V3)) {
+ endpointSb.append(IDENTITY_PATH);
+ }
+
+ endpointSb.append(auth.version());
+ return endpointSb.toString();
+ }
+
+ /**
+ * Obtains the SSL config without verifying the certification.
+ *
+ * @return SSL config
+ */
+ private static Config getSslConfig() {
+ // we bypass the SSL certification verification for now
+ // TODO: verify server side SSL using a given certification
+ Config config = Config.newConfig().withSSLVerificationDisabled();
+
+ TrustManager[] trustAllCerts = new TrustManager[]{
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public void checkClientTrusted(X509Certificate[] certs,
+ String authType) {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs,
+ String authType) {
+ }
+ }
+ };
+
+ HostnameVerifier allHostsValid = (hostname, session) -> true;
+
+ try {
+ SSLContext sc = SSLContext.getInstance(SSL_TYPE);
+ sc.init(null, trustAllCerts,
+ new java.security.SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
+
+ config.withSSLContext(sc);
+ } catch (Exception e) {
+ log.error("Failed to access OpenStack service due to {}", e.toString());
+ return null;
+ }
+
+ return config;
+ }
+
+ /**
+ * Obtains the facing object with given openstack perspective.
+ *
+ * @param perspective keystone perspective
+ * @return facing object
+ */
+ private static Facing getFacing(Perspective perspective) {
+
+ switch (perspective) {
+ case PUBLIC:
+ return Facing.PUBLIC;
+ case ADMIN:
+ return Facing.ADMIN;
+ case INTERNAL:
+ return Facing.INTERNAL;
+ default:
+ return null;
+ }
+ }
}
diff --git a/apps/openstacknode/app/src/main/resources/deps/btf-1.2.jar b/apps/openstacknode/app/src/main/resources/deps/btf-1.2.jar
new file mode 100644
index 0000000..bbeee88
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/btf-1.2.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/jackson-coreutils-1.6.jar b/apps/openstacknode/app/src/main/resources/deps/jackson-coreutils-1.6.jar
new file mode 100644
index 0000000..ee7b43d
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/jackson-coreutils-1.6.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/json-patch-1.9.jar b/apps/openstacknode/app/src/main/resources/deps/json-patch-1.9.jar
new file mode 100644
index 0000000..36569b6
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/json-patch-1.9.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/msg-simple-1.1.jar b/apps/openstacknode/app/src/main/resources/deps/msg-simple-1.1.jar
new file mode 100644
index 0000000..db74210
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/msg-simple-1.1.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/openstack4j-core-3.1.0.jar b/apps/openstacknode/app/src/main/resources/deps/openstack4j-core-3.1.0.jar
new file mode 100644
index 0000000..c03203f
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/openstack4j-core-3.1.0.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/openstack4j-http-connector-3.1.0.jar b/apps/openstacknode/app/src/main/resources/deps/openstack4j-http-connector-3.1.0.jar
new file mode 100644
index 0000000..cbe8476
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/openstack4j-http-connector-3.1.0.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/openstack4j-httpclient-3.1.0.jar b/apps/openstacknode/app/src/main/resources/deps/openstack4j-httpclient-3.1.0.jar
new file mode 100644
index 0000000..964b15a
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/openstack4j-httpclient-3.1.0.jar
Binary files differ
diff --git a/apps/openstacknode/app/src/main/resources/deps/snakeyaml-1.15.jar b/apps/openstacknode/app/src/main/resources/deps/snakeyaml-1.15.jar
new file mode 100644
index 0000000..34084e3
--- /dev/null
+++ b/apps/openstacknode/app/src/main/resources/deps/snakeyaml-1.15.jar
Binary files differ
diff --git a/apps/openstacknode/openstack4j.bucklet b/apps/openstacknode/openstack4j.bucklet
new file mode 100644
index 0000000..6de5d52
--- /dev/null
+++ b/apps/openstacknode/openstack4j.bucklet
@@ -0,0 +1,41 @@
+INCLUDE_PACKAGES = 'com.google.common.net,com.google.common.io,com.fasterxml.jackson.annotation'
+EXCLUDE_PACKAGES = '!org.openstack4j,!org.openstack4j.*'
+ALL_PACKAGES = '*'
+
+def get_openstack4j_deps_path():
+
+ WEB_INF_PATH = 'WEB-INF/classes/deps/'
+ OPENSTACK4J_DEPS = [
+ 'openstack4j-core',
+ 'openstack4j-http-connector',
+ 'openstack4j-httpclient',
+ ]
+ OPENSTACK4J_VER = '3.1.0'
+
+ openstack_deps_path = ''
+
+ for dep in OPENSTACK4J_DEPS:
+ name = dep + '-' + OPENSTACK4J_VER + '.jar'
+ path = WEB_INF_PATH + name
+ openstack_deps_path = openstack_deps_path + path + ','
+
+ return openstack_deps_path
+
+def get_jackson_deps_path():
+
+ WEB_INF_PATH = 'WEB-INF/classes/deps/'
+ JACKSON_DEPS_WITH_VER = [
+ 'json-patch-1.9.jar',
+ 'jackson-coreutils-1.6.jar',
+ 'msg-simple-1.1.jar',
+ 'btf-1.2.jar',
+ 'snakeyaml-1.15.jar'
+ ]
+
+ jackson_deps_path = ''
+
+ for dep in JACKSON_DEPS_WITH_VER:
+ path = WEB_INF_PATH + dep
+ jackson_deps_path = jackson_deps_path + path + ','
+
+ return jackson_deps_path
\ No newline at end of file
diff --git a/apps/openstacknode/pom.xml b/apps/openstacknode/pom.xml
index 379bd79..86b8962 100644
--- a/apps/openstacknode/pom.xml
+++ b/apps/openstacknode/pom.xml
@@ -30,6 +30,15 @@
<description>SONA Openstack Node Bootstrap Application</description>
+ <properties>
+ <openstack4j.version>3.1.0</openstack4j.version>
+ <json-patch.version>1.9</json-patch.version>
+ <jackson-coreutils.version>1.6</jackson-coreutils.version>
+ <btf.version>1.2</btf.version>
+ <msg-simple.version>1.1</msg-simple.version>
+ <snakeyaml.version>1.15</snakeyaml.version>
+ </properties>
+
<modules>
<module>api</module>
<module>app</module>