Daniel Park
Committed by Gerrit Code Review

[ONOS-3688] Implement application for Openstack Node bootstrap

- Using OVSDB connnection, it makes bridge and vxlan tunnel for Openstack Nodes.
- Reading nodes information from network config supported

Change-Id: I1c0483b146ace19cd77ac91141182ee9200a9432
1 +{
2 + "apps" : {
3 + "org.onosproject.openstacknode" : {
4 + "openstacknode" : {
5 + "nodes" : [
6 + {
7 + "hostname" : "compute-01",
8 + "ovsdbIp" : "192.168.56.112",
9 + "ovsdbPort" : "6640",
10 + "bridgeId" : "of:0000000000000001",
11 + "openstackNodeType" : "COMPUTENODE"
12 + },
13 + {
14 + "hostname" : "compute-02",
15 + "ovsdbIp" : "192.168.56.106",
16 + "ovsdbPort" : "6640",
17 + "bridgeId" : "of:0000000000000002",
18 + "openstackNodeType" : "COMPUTENODE"
19 + },
20 + {
21 + "hostname" : "network",
22 + "ovsdbIp" : "192.168.56.108",
23 + "ovsdbPort" : "6640",
24 + "bridgeId" : "of:0000000000000003",
25 + "openstackNodeType" : "GATEWAYNODE",
26 + "gatewayExternalInterfaceName" : "eth1",
27 + "gatewayExternalInterfaceMac" : "00:00:00:00:00:10"
28 + }
29 + ]
30 + }
31 + }
32 + }
33 +}
34 +
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2016 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<project xmlns="http://maven.apache.org/POM/4.0.0"
18 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20 + <modelVersion>4.0.0</modelVersion>
21 +
22 + <parent>
23 + <groupId>org.onosproject</groupId>
24 + <artifactId>onos-apps</artifactId>
25 + <version>1.5.0-SNAPSHOT</version>
26 + <relativePath>../pom.xml</relativePath>
27 + </parent>
28 +
29 + <artifactId>onos-app-openstacknode</artifactId>
30 + <packaging>bundle</packaging>
31 +
32 + <description>SONA Openstack Node Bootstrap Application</description>
33 +
34 +
35 + <properties>
36 + <onos.app.name>org.onosproject.openstacknode</onos.app.name>
37 + <onos.app.category>default</onos.app.category>
38 + <onos.app.url>http://onosproject.org</onos.app.url>
39 + <onos.app.readme>SONA Openstack Node Bootstrap Application</onos.app.readme>
40 + <onos.app.requires>
41 + org.onosproject.ovsdb
42 + </onos.app.requires>
43 + </properties>
44 +
45 + <dependencies>
46 + <dependency>
47 + <groupId>org.osgi</groupId>
48 + <artifactId>org.osgi.compendium</artifactId>
49 + </dependency>
50 + <dependency>
51 + <groupId>org.onosproject</groupId>
52 + <artifactId>onos-api</artifactId>
53 + </dependency>
54 + <dependency>
55 + <groupId>org.onosproject</groupId>
56 + <artifactId>onos-core-serializers</artifactId>
57 + <version>${project.version}</version>
58 + </dependency>
59 + <dependency>
60 + <groupId>org.onosproject</groupId>
61 + <artifactId>onos-ovsdb-api</artifactId>
62 + <version>${project.version}</version>
63 + </dependency>
64 + <dependency>
65 + <groupId>com.fasterxml.jackson.core</groupId>
66 + <artifactId>jackson-databind</artifactId>
67 + </dependency>
68 + <dependency>
69 + <groupId>com.fasterxml.jackson.core</groupId>
70 + <artifactId>jackson-annotations</artifactId>
71 + </dependency>
72 + </dependencies>
73 +</project>
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.openstacknode;
17 +
18 +/**
19 + * Entity capable of handling a subject connected and disconnected situation.
20 + */
21 +public interface ConnectionHandler<T> {
22 + /**
23 + * Processes the connected subject.
24 + *
25 + * @param subject subject
26 + */
27 + void connected(T subject);
28 +
29 + /**
30 + * Processes the disconnected subject.
31 + *
32 + * @param subject subject.
33 + */
34 + void disconnected(T subject);
35 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.openstacknode;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import org.onlab.packet.IpAddress;
20 +import org.onlab.packet.MacAddress;
21 +import org.onlab.packet.TpPort;
22 +import org.onosproject.net.DeviceId;
23 +
24 +import java.util.Comparator;
25 +import java.util.Objects;
26 +
27 +import static com.google.common.base.Preconditions.checkNotNull;
28 +
29 +/**
30 + * Representation of a compute/gateway node for OpenstackSwitching/Routing service.
31 + */
32 +public final class OpenstackNode {
33 +
34 + private final String hostName;
35 + private final IpAddress ovsdbIp;
36 + private final TpPort ovsdbPort;
37 + private final DeviceId bridgeId;
38 + private final OpenstackNodeService.OpenstackNodeType openstackNodeType;
39 + private final String gatewayExternalInterfaceName;
40 + private final MacAddress gatewayExternalInterfaceMac;
41 + private static final String OVSDB = "ovsdb:";
42 +
43 +
44 + public static final Comparator<OpenstackNode> OPENSTACK_NODE_COMPARATOR =
45 + (node1, node2) -> node1.hostName().compareTo(node2.hostName());
46 +
47 + /**
48 + * Creates a new node.
49 + *
50 + * @param hostName hostName
51 + * @param ovsdbIp OVSDB server IP address
52 + * @param ovsdbPort OVSDB server port number
53 + * @param bridgeId integration bridge identifier
54 + * @param openstackNodeType openstack node type
55 + * @param gatewayExternalInterfaceName gatewayExternalInterfaceName
56 + * @param gatewayExternalInterfaceMac gatewayExternalInterfaceMac
57 + */
58 + public OpenstackNode(String hostName, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId,
59 + OpenstackNodeService.OpenstackNodeType openstackNodeType,
60 + String gatewayExternalInterfaceName,
61 + MacAddress gatewayExternalInterfaceMac) {
62 + this.hostName = checkNotNull(hostName, "hostName cannot be null");
63 + this.ovsdbIp = checkNotNull(ovsdbIp, "ovsdbIp cannot be null");
64 + this.ovsdbPort = checkNotNull(ovsdbPort, "ovsdbPort cannot be null");
65 + this.bridgeId = checkNotNull(bridgeId, "bridgeId cannot be null");
66 + this.openstackNodeType = checkNotNull(openstackNodeType, "openstackNodeType cannot be null");
67 + this.gatewayExternalInterfaceName = gatewayExternalInterfaceName;
68 + this.gatewayExternalInterfaceMac = gatewayExternalInterfaceMac;
69 +
70 + if (openstackNodeType == OpenstackNodeService.OpenstackNodeType.GATEWAYNODE) {
71 + checkNotNull(gatewayExternalInterfaceName, "gatewayExternalInterfaceName cannot be null");
72 + checkNotNull(gatewayExternalInterfaceMac, "gatewayExternalInterfaceMac cannot be null");
73 + }
74 + }
75 +
76 + /**
77 + * Returns the OVSDB server IP address.
78 + *
79 + * @return ip address
80 + */
81 + public IpAddress ovsdbIp() {
82 + return this.ovsdbIp;
83 + }
84 +
85 + /**
86 + * Returns the OVSDB server port number.
87 + *
88 + * @return port number
89 + */
90 + public TpPort ovsdbPort() {
91 + return this.ovsdbPort;
92 + }
93 +
94 + /**
95 + * Returns the hostName.
96 + *
97 + * @return hostName
98 + */
99 + public String hostName() {
100 + return this.hostName;
101 + }
102 +
103 + /**
104 + * Returns the identifier of the integration bridge.
105 + *
106 + * @return device id
107 + */
108 + public DeviceId intBrId() {
109 + return this.bridgeId;
110 + }
111 +
112 + /**
113 + * Returns the identifier of the OVSDB device.
114 + *
115 + * @return device id
116 + */
117 + public DeviceId ovsdbId() {
118 + return DeviceId.deviceId(OVSDB.concat(this.ovsdbIp.toString()));
119 + }
120 +
121 + /**
122 + * Returns the openstack node type.
123 + *
124 + * @return openstack node type
125 + */
126 + public OpenstackNodeService.OpenstackNodeType openstackNodeType() {
127 + return this.openstackNodeType;
128 + }
129 +
130 + /**
131 + * Returns the gatewayExternalInterfaceName.
132 + *
133 + * @return gatewayExternalInterfaceName
134 + */
135 + public String gatewayExternalInterfaceName() {
136 + return this.gatewayExternalInterfaceName;
137 + }
138 +
139 + /**
140 + * Returns the gatewayExternalInterfaceMac.
141 + *
142 + * @return gatewayExternalInterfaceMac
143 + */
144 + public MacAddress gatewayExternalInterfaceMac() {
145 + return this.gatewayExternalInterfaceMac;
146 + }
147 +
148 + @Override
149 + public boolean equals(Object obj) {
150 + if (this == obj) {
151 + return true;
152 + }
153 +
154 + if (obj instanceof OpenstackNode) {
155 + OpenstackNode that = (OpenstackNode) obj;
156 +
157 + if (Objects.equals(hostName, that.hostName) &&
158 + Objects.equals(ovsdbIp, that.ovsdbIp) &&
159 + Objects.equals(ovsdbPort, that.ovsdbPort) &&
160 + Objects.equals(bridgeId, that.bridgeId) &&
161 + Objects.equals(openstackNodeType, that.openstackNodeType)) {
162 + return true;
163 + }
164 + }
165 + return false;
166 + }
167 +
168 + @Override
169 + public int hashCode() {
170 + return Objects.hash(hostName, ovsdbIp, ovsdbPort, bridgeId, openstackNodeType);
171 + }
172 +
173 + @Override
174 + public String toString() {
175 + if (openstackNodeType == OpenstackNodeService.OpenstackNodeType.COMPUTENODE) {
176 + return MoreObjects.toStringHelper(getClass())
177 + .add("host", hostName)
178 + .add("ip", ovsdbIp)
179 + .add("port", ovsdbPort)
180 + .add("bridgeId", bridgeId)
181 + .add("openstacknodetype", openstackNodeType)
182 + .toString();
183 + } else {
184 + return MoreObjects.toStringHelper(getClass())
185 + .add("host", hostName)
186 + .add("ip", ovsdbIp)
187 + .add("port", ovsdbPort)
188 + .add("bridgeId", bridgeId)
189 + .add("openstacknodetype", openstackNodeType)
190 + .add("gatewayExternalInterfaceName", gatewayExternalInterfaceName)
191 + .add("gatewayExternalInterfaceMac", gatewayExternalInterfaceMac)
192 + .toString();
193 + }
194 + }
195 +}
196 +
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.openstacknode;
17 +
18 +
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.google.common.collect.Sets;
21 +import org.onlab.packet.Ip4Address;
22 +import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.TpPort;
24 +import org.onosproject.core.ApplicationId;
25 +import org.onosproject.net.DeviceId;
26 +import org.slf4j.Logger;
27 +import java.util.Set;
28 +import org.onosproject.net.config.Config;
29 +import static org.slf4j.LoggerFactory.getLogger;
30 +
31 +/**
32 + * Configuration object for OpensatckNode service.
33 + */
34 +public class OpenstackNodeConfig extends Config<ApplicationId> {
35 +
36 + protected final Logger log = getLogger(getClass());
37 +
38 +
39 + public static final String NODES = "nodes";
40 + public static final String HOST_NAME = "hostname";
41 + public static final String OVSDB_IP = "ovsdbIp";
42 + public static final String OVSDB_PORT = "ovsdbPort";
43 + public static final String BRIDGE_ID = "bridgeId";
44 + public static final String NODE_TYPE = "openstackNodeType";
45 + public static final String GATEWAY_EXTERNAL_INTERFACE_NAME = "gatewayExternalInterfaceName";
46 + public static final String GATEWAY_EXTERNAL_INTERFACE_MAC = "gatewayExternalInterfaceMac";
47 +
48 + /**
49 + * Returns the set of nodes read from network config.
50 + *
51 + * @return set of OpensatckNodeConfig or null
52 + */
53 + public Set<OpenstackNode> openstackNodes() {
54 +
55 + Set<OpenstackNode> nodes = Sets.newHashSet();
56 +
57 + JsonNode jsonNodes = object.get(NODES);
58 + if (jsonNodes == null) {
59 + return null;
60 + }
61 +
62 + jsonNodes.forEach(jsonNode -> {
63 + try {
64 + if (OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()) ==
65 + OpenstackNodeService.OpenstackNodeType.COMPUTENODE) {
66 + nodes.add(new OpenstackNode(
67 + jsonNode.path(HOST_NAME).asText(),
68 + Ip4Address.valueOf(jsonNode.path(OVSDB_IP).asText()),
69 + TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
70 + DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()),
71 + OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()),
72 + null, MacAddress.NONE));
73 + } else {
74 + nodes.add(new OpenstackNode(
75 + jsonNode.path(HOST_NAME).asText(),
76 + Ip4Address.valueOf(jsonNode.path(OVSDB_IP).asText()),
77 + TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
78 + DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()),
79 + OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()),
80 + jsonNode.path(GATEWAY_EXTERNAL_INTERFACE_NAME).asText(),
81 + MacAddress.valueOf(jsonNode.path(GATEWAY_EXTERNAL_INTERFACE_MAC).asText())));
82 + }
83 + } catch (IllegalArgumentException | NullPointerException e) {
84 + log.error("Failed to read {}", e.toString());
85 + }
86 + });
87 + return nodes;
88 + }
89 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.openstacknode;
17 +
18 +import java.util.List;
19 +
20 +/**
21 + * Handles the bootstrap request for compute/gateway node.
22 + */
23 +public interface OpenstackNodeService {
24 +
25 + public enum OpenstackNodeType {
26 + /**
27 + * Compute or Gateway Node.
28 + */
29 + COMPUTENODE,
30 + GATEWAYNODE
31 + }
32 + /**
33 + * Adds a new node to the service.
34 + *
35 + * @param node openstack node
36 + */
37 + void addNode(OpenstackNode node);
38 +
39 + /**
40 + * Deletes a node from the service.
41 + *
42 + * @param node openstack node
43 + */
44 + void deleteNode(OpenstackNode node);
45 +
46 + /**
47 + * Returns nodes known to the service for designated openstacktype.
48 + *
49 + * @param openstackNodeType openstack node type
50 + * @return list of nodes
51 + */
52 + List<OpenstackNode> getNodes(OpenstackNodeType openstackNodeType);
53 +
54 + /**
55 + * Returns the NodeState for a given node.
56 + *
57 + * @param node openstack node
58 + * @return true if the NodeState for a given node is COMPLETE, false otherwise
59 + */
60 + boolean isComplete(OpenstackNode node);
61 +}
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * Application for bootstrapping Compute/Gateway Node in OpenStack.
19 + */
20 +package org.onosproject.openstacknode;
...\ No newline at end of file ...\ No newline at end of file
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
68 <module>openstackrouting</module> 68 <module>openstackrouting</module>
69 <module>cordmcast</module> 69 <module>cordmcast</module>
70 <module>vpls</module> 70 <module>vpls</module>
71 + <module>openstacknode</module>
71 </modules> 72 </modules>
72 73
73 <properties> 74 <properties>
......