Hyunsun Moon
Committed by Jonathan Hart

Support GATEWAY type node bootstrapping

- Create router bridge and pactch port to integration bridge for gateway node
- Refactored to listen map event for node add/update
- Added CLIs

Change-Id: Id653f2a2c01d94036f77e6ce1b1230111f3dbbb1
1 COMPILE_DEPS = [ 1 COMPILE_DEPS = [
2 '//lib:CORE_DEPS', 2 '//lib:CORE_DEPS',
3 + '//lib:org.apache.karaf.shell.console',
4 + '//cli:onos-cli',
3 '//protocols/ovsdb/api:onos-protocols-ovsdb-api', 5 '//protocols/ovsdb/api:onos-protocols-ovsdb-api',
4 '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc', 6 '//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
5 '//core/store/serializers:onos-core-serializers', 7 '//core/store/serializers:onos-core-serializers',
...@@ -14,5 +16,5 @@ onos_app ( ...@@ -14,5 +16,5 @@ onos_app (
14 category = 'Utility', 16 category = 'Utility',
15 url = 'http://onosproject.org', 17 url = 'http://onosproject.org',
16 description = 'SONA Openstack Node Bootstrap Application.', 18 description = 'SONA Openstack Node Bootstrap Application.',
17 - required_app = [ 'org.onosproject.ovsdb' ], 19 + required_app = [ 'org.onosproject.ovsdb-base' ],
18 ) 20 )
......
...@@ -5,26 +5,33 @@ ...@@ -5,26 +5,33 @@
5 "nodes" : [ 5 "nodes" : [
6 { 6 {
7 "hostname" : "compute-01", 7 "hostname" : "compute-01",
8 - "ovsdbIp" : "192.168.56.112", 8 + "type" : "COMPUTE",
9 - "ovsdbPort" : "6640", 9 + "managementIp" : "10.203.25.244",
10 - "bridgeId" : "of:0000000000000001", 10 + "dataIp" : "10.134.34.222",
11 - "openstackNodeType" : "COMPUTENODE" 11 + "integrationBridge" : "of:00000000000000a1"
12 }, 12 },
13 { 13 {
14 "hostname" : "compute-02", 14 "hostname" : "compute-02",
15 - "ovsdbIp" : "192.168.56.106", 15 + "type" : "COMPUTE",
16 - "ovsdbPort" : "6640", 16 + "managementIp" : "10.203.229.42",
17 - "bridgeId" : "of:0000000000000002", 17 + "dataIp" : "10.134.34.223",
18 - "openstackNodeType" : "COMPUTENODE" 18 + "integrationBridge" : "of:00000000000000a2"
19 }, 19 },
20 { 20 {
21 - "hostname" : "network", 21 + "hostname" : "gateway-01",
22 - "ovsdbIp" : "192.168.56.108", 22 + "type" : "GATEWAY",
23 - "ovsdbPort" : "6640", 23 + "managementIp" : "10.203.198.125",
24 - "bridgeId" : "of:0000000000000003", 24 + "dataIp" : "10.134.33.208",
25 - "openstackNodeType" : "GATEWAYNODE", 25 + "integrationBridge" : "of:00000000000000a3",
26 - "gatewayExternalInterfaceName" : "eth1", 26 + "routerBridge" : "of:00000000000000b3"
27 - "gatewayExternalInterfaceMac" : "00:00:00:00:00:10" 27 + },
28 + {
29 + "hostname" : "gateway-02",
30 + "type" : "GATEWAY",
31 + "managementIp" : "10.203.198.131",
32 + "dataIp" : "10.134.33.209",
33 + "integrationBridge" : "of:00000000000000a4",
34 + "routerBridge" : "of:00000000000000b4"
28 } 35 }
29 ] 36 ]
30 } 37 }
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
38 <onos.app.url>http://onosproject.org</onos.app.url> 38 <onos.app.url>http://onosproject.org</onos.app.url>
39 <onos.app.readme>SONA Openstack Node Bootstrap Application</onos.app.readme> 39 <onos.app.readme>SONA Openstack Node Bootstrap Application</onos.app.readme>
40 <onos.app.requires> 40 <onos.app.requires>
41 - org.onosproject.ovsdb 41 + org.onosproject.ovsdb-base
42 </onos.app.requires> 42 </onos.app.requires>
43 </properties> 43 </properties>
44 44
...@@ -58,6 +58,11 @@ ...@@ -58,6 +58,11 @@
58 </dependency> 58 </dependency>
59 <dependency> 59 <dependency>
60 <groupId>org.onosproject</groupId> 60 <groupId>org.onosproject</groupId>
61 + <artifactId>onos-cli</artifactId>
62 + <version>${project.version}</version>
63 + </dependency>
64 + <dependency>
65 + <groupId>org.onosproject</groupId>
61 <artifactId>onos-ovsdb-api</artifactId> 66 <artifactId>onos-ovsdb-api</artifactId>
62 <version>${project.version}</version> 67 <version>${project.version}</version>
63 </dependency> 68 </dependency>
...@@ -69,5 +74,10 @@ ...@@ -69,5 +74,10 @@
69 <groupId>com.fasterxml.jackson.core</groupId> 74 <groupId>com.fasterxml.jackson.core</groupId>
70 <artifactId>jackson-annotations</artifactId> 75 <artifactId>jackson-annotations</artifactId>
71 </dependency> 76 </dependency>
77 + <dependency>
78 + <groupId>org.apache.karaf.shell</groupId>
79 + <artifactId>org.apache.karaf.shell.console</artifactId>
80 + <version>3.0.5</version>
81 + </dependency>
72 </dependencies> 82 </dependencies>
73 </project> 83 </project>
......
1 +/*
2 + * Copyright 2016-present 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 + * Provides constants used in OpenStack node services.
20 + */
21 +public final class Constants {
22 +
23 + private Constants() {
24 + }
25 +
26 + public static final String INTEGRATION_BRIDGE = "br-int";
27 + public static final String ROUTER_BRIDGE = "br-router";
28 + public static final String DEFAULT_TUNNEL = "vxlan";
29 + public static final String PATCH_INTG_BRIDGE = "patch-intg";
30 + public static final String PATCH_ROUT_BRIDGE = "patch-rout";
31 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -17,73 +17,94 @@ package org.onosproject.openstacknode; ...@@ -17,73 +17,94 @@ package org.onosproject.openstacknode;
17 17
18 18
19 import com.fasterxml.jackson.databind.JsonNode; 19 import com.fasterxml.jackson.databind.JsonNode;
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
20 import com.google.common.collect.Sets; 21 import com.google.common.collect.Sets;
21 -import org.onlab.packet.Ip4Address; 22 +import org.onlab.packet.IpAddress;
22 -import org.onlab.packet.MacAddress;
23 -import org.onlab.packet.TpPort;
24 import org.onosproject.core.ApplicationId; 23 import org.onosproject.core.ApplicationId;
25 import org.onosproject.net.DeviceId; 24 import org.onosproject.net.DeviceId;
26 -import org.slf4j.Logger; 25 +import org.onosproject.openstacknode.OpenstackNodeService.NodeType;
27 import java.util.Set; 26 import java.util.Set;
28 import org.onosproject.net.config.Config; 27 import org.onosproject.net.config.Config;
29 -import static org.slf4j.LoggerFactory.getLogger; 28 +
29 +import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
30 +import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
30 31
31 /** 32 /**
32 * Configuration object for OpensatckNode service. 33 * Configuration object for OpensatckNode service.
33 */ 34 */
34 -public class OpenstackNodeConfig extends Config<ApplicationId> { 35 +public final class OpenstackNodeConfig extends Config<ApplicationId> {
36 +
37 + private static final String NODES = "nodes";
38 + private static final String HOST_NAME = "hostname";
39 + private static final String TYPE = "type";
40 + private static final String MANAGEMENT_IP = "managementIp";
41 + private static final String DATA_IP = "dataIp";
42 + private static final String INTEGRATION_BRIDGE = "integrationBridge";
43 + private static final String ROUTER_BRIDGE = "routerBridge";
35 44
36 - protected final Logger log = getLogger(getClass()); 45 + @Override
46 + public boolean isValid() {
47 + boolean result = hasOnlyFields(NODES);
48 +
49 + if (object.get(NODES) == null || object.get(NODES).size() < 1) {
50 + final String msg = "No node is present";
51 + throw new IllegalArgumentException(msg);
52 + }
37 53
54 + for (JsonNode node : object.get(NODES)) {
55 + ObjectNode osNode = (ObjectNode) node;
56 + result &= hasOnlyFields(osNode,
57 + HOST_NAME,
58 + TYPE,
59 + MANAGEMENT_IP,
60 + DATA_IP,
61 + INTEGRATION_BRIDGE,
62 + ROUTER_BRIDGE
63 + );
38 64
39 - public static final String NODES = "nodes"; 65 + result &= isString(osNode, HOST_NAME, MANDATORY);
40 - public static final String HOST_NAME = "hostname"; 66 + result &= isString(osNode, TYPE, MANDATORY);
41 - public static final String OVSDB_IP = "ovsdbIp"; 67 + result &= isIpAddress(osNode, MANAGEMENT_IP, MANDATORY);
42 - public static final String OVSDB_PORT = "ovsdbPort"; 68 + result &= result && isIpAddress(osNode, DATA_IP, MANDATORY);
43 - public static final String BRIDGE_ID = "bridgeId"; 69 + result &= isString(osNode, INTEGRATION_BRIDGE, MANDATORY);
44 - public static final String NODE_TYPE = "openstackNodeType"; 70 +
45 - public static final String GATEWAY_EXTERNAL_INTERFACE_NAME = "gatewayExternalInterfaceName"; 71 + DeviceId.deviceId(osNode.get(INTEGRATION_BRIDGE).asText());
46 - public static final String GATEWAY_EXTERNAL_INTERFACE_MAC = "gatewayExternalInterfaceMac"; 72 + NodeType.valueOf(osNode.get(TYPE).asText());
73 +
74 + if (osNode.get(TYPE).asText().equals(GATEWAY.name())) {
75 + result &= isString(osNode, ROUTER_BRIDGE, MANDATORY);
76 + DeviceId.deviceId(osNode.get(ROUTER_BRIDGE).asText());
77 + }
78 + }
79 + return result;
80 + }
47 81
48 /** 82 /**
49 * Returns the set of nodes read from network config. 83 * Returns the set of nodes read from network config.
50 * 84 *
51 - * @return set of OpensatckNodeConfig or null 85 + * @return set of openstack nodes
52 */ 86 */
53 public Set<OpenstackNode> openstackNodes() { 87 public Set<OpenstackNode> openstackNodes() {
54 -
55 Set<OpenstackNode> nodes = Sets.newHashSet(); 88 Set<OpenstackNode> nodes = Sets.newHashSet();
56 89
57 - JsonNode jsonNodes = object.get(NODES); 90 + for (JsonNode node : object.get(NODES)) {
58 - if (jsonNodes == null) { 91 + NodeType type = NodeType.valueOf(get(node, TYPE));
59 - return null; 92 + OpenstackNode.Builder nodeBuilder = OpenstackNode.builder()
60 - } 93 + .integrationBridge(DeviceId.deviceId(get(node, INTEGRATION_BRIDGE)))
94 + .dataIp(IpAddress.valueOf(get(node, DATA_IP)))
95 + .managementIp(IpAddress.valueOf(get(node, MANAGEMENT_IP)))
96 + .type(type)
97 + .hostname(get(node, HOST_NAME));
61 98
62 - jsonNodes.forEach(jsonNode -> { 99 + if (type.equals(GATEWAY)) {
63 - try { 100 + nodeBuilder.routerBridge(DeviceId.deviceId(get(node, ROUTER_BRIDGE)));
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 } 101 }
83 - } catch (IllegalArgumentException | NullPointerException e) { 102 + nodes.add(nodeBuilder.build());
84 - log.error("Failed to read {}", e.toString());
85 } 103 }
86 - });
87 return nodes; 104 return nodes;
88 } 105 }
106 +
107 + private String get(JsonNode jsonNode, String path) {
108 + return jsonNode.get(path).asText();
109 + }
89 } 110 }
......
...@@ -15,26 +15,33 @@ ...@@ -15,26 +15,33 @@
15 */ 15 */
16 package org.onosproject.openstacknode; 16 package org.onosproject.openstacknode;
17 17
18 +import org.onlab.packet.IpAddress;
19 +import org.onosproject.net.DeviceId;
20 +import org.onosproject.net.PortNumber;
21 +
18 import java.util.List; 22 import java.util.List;
23 +import java.util.Optional;
24 +import java.util.Set;
19 25
20 /** 26 /**
21 * Handles the bootstrap request for compute/gateway node. 27 * Handles the bootstrap request for compute/gateway node.
22 */ 28 */
23 public interface OpenstackNodeService { 29 public interface OpenstackNodeService {
24 30
25 - public enum OpenstackNodeType { 31 + enum NodeType {
26 /** 32 /**
27 * Compute or Gateway Node. 33 * Compute or Gateway Node.
28 */ 34 */
29 - COMPUTENODE, 35 + COMPUTE,
30 - GATEWAYNODE 36 + GATEWAY
31 } 37 }
38 +
32 /** 39 /**
33 - * Adds a new node to the service. 40 + * Adds or updates a new node to the service.
34 * 41 *
35 * @param node openstack node 42 * @param node openstack node
36 */ 43 */
37 - void addNode(OpenstackNode node); 44 + void addOrUpdateNode(OpenstackNode node);
38 45
39 /** 46 /**
40 * Deletes a node from the service. 47 * Deletes a node from the service.
...@@ -44,18 +51,58 @@ public interface OpenstackNodeService { ...@@ -44,18 +51,58 @@ public interface OpenstackNodeService {
44 void deleteNode(OpenstackNode node); 51 void deleteNode(OpenstackNode node);
45 52
46 /** 53 /**
47 - * Returns nodes known to the service for designated openstacktype. 54 + * Returns all nodes known to the service.
48 * 55 *
49 - * @param openstackNodeType openstack node type
50 * @return list of nodes 56 * @return list of nodes
51 */ 57 */
52 - List<OpenstackNode> getNodes(OpenstackNodeType openstackNodeType); 58 + List<OpenstackNode> nodes();
53 59
54 /** 60 /**
55 - * Returns the NodeState for a given node. 61 + * Returns all nodes in complete state.
56 * 62 *
57 - * @param node openstack node 63 + * @return set of nodes
58 - * @return true if the NodeState for a given node is COMPLETE, false otherwise 64 + */
65 + Set<OpenstackNode> completeNodes();
66 +
67 + /**
68 + * Returns node initialization state is complete or not.
69 + *
70 + * @param hostname hostname of the node
71 + * @return true if initial node setup is completed, otherwise false
72 + */
73 + boolean isComplete(String hostname);
74 +
75 + /**
76 + * Returns data network IP address of a given integration bridge device.
77 + *
78 + * @param intBridgeId integration bridge device id
79 + * @return ip address; empty value otherwise
80 + */
81 + Optional<IpAddress> dataIp(DeviceId intBridgeId);
82 +
83 + /**
84 + * Returns tunnel port number of a given integration bridge device.
85 + *
86 + * @param intBridgeId integration bridge device id
87 + * @return port number; or empty value
88 + */
89 + Optional<PortNumber> tunnelPort(DeviceId intBridgeId);
90 +
91 + /**
92 + * Returns router bridge device ID connected to a given integration bridge.
93 + * It returns valid value only if the node type is GATEWAY.
94 + *
95 + * @param intBridgeId device id of the integration bridge
96 + * @return device id of a router bridge; or empty value
97 + */
98 + Optional<DeviceId> routerBridge(DeviceId intBridgeId);
99 +
100 + /**
101 + * Returns port number connected to the router bridge.
102 + * It returns valid value only if the node type is GATEWAY.
103 + *
104 + * @param intBridgeId integration bridge device id
105 + * @return port number; or empty value
59 */ 106 */
60 - boolean isComplete(OpenstackNode node); 107 + Optional<PortNumber> externalPort(DeviceId intBridgeId);
61 } 108 }
......
1 +/*
2 + * Copyright 2016-present 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 that defines possible init state of the OpenStack node.
20 + */
21 +public interface OpenstackNodeState {
22 + /**
23 + * Returns null for no state.
24 + *
25 + * @return null
26 + */
27 + static OpenstackNodeState noState() {
28 + return null;
29 + }
30 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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 +package org.onosproject.openstacknode.cli;
18 +
19 +import org.apache.karaf.shell.commands.Argument;
20 +import org.apache.karaf.shell.commands.Command;
21 +import org.onosproject.cli.AbstractShellCommand;
22 +import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.Port;
24 +import org.onosproject.net.Device;
25 +import org.onosproject.net.device.DeviceService;
26 +import org.onosproject.openstacknode.OpenstackNode;
27 +import org.onosproject.openstacknode.OpenstackNodeService;
28 +
29 +import static org.onosproject.net.AnnotationKeys.PORT_NAME;
30 +import static org.onosproject.openstacknode.Constants.*;
31 +import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
32 +
33 +/**
34 + * Checks detailed node init state.
35 + */
36 +@Command(scope = "onos", name = "openstack-node-check",
37 + description = "Shows detailed node init state")
38 +public class OpenstackNodeCheckCommand extends AbstractShellCommand {
39 +
40 + @Argument(index = 0, name = "hostname", description = "Hostname",
41 + required = true, multiValued = false)
42 + private String hostname = null;
43 +
44 + private static final String MSG_OK = "OK";
45 + private static final String MSG_NO = "NO";
46 +
47 + @Override
48 + protected void execute() {
49 + OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
50 + DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
51 +
52 + OpenstackNode node = nodeService.nodes()
53 + .stream()
54 + .filter(n -> n.hostname().equals(hostname))
55 + .findFirst()
56 + .orElse(null);
57 +
58 + if (node == null) {
59 + print("Cannot find %s from registered nodes", hostname);
60 + return;
61 + }
62 +
63 + print("%n[Integration Bridge Status]");
64 + Device device = deviceService.getDevice(node.intBridge());
65 + if (device != null) {
66 + print("%s %s=%s available=%s %s",
67 + deviceService.isAvailable(device.id()) ? MSG_OK : MSG_NO,
68 + INTEGRATION_BRIDGE,
69 + device.id(),
70 + deviceService.isAvailable(device.id()),
71 + device.annotations());
72 +
73 + print(getPortState(deviceService, node.intBridge(), DEFAULT_TUNNEL));
74 + } else {
75 + print("%s %s=%s is not available",
76 + MSG_NO,
77 + INTEGRATION_BRIDGE,
78 + node.intBridge());
79 + }
80 +
81 + if (node.type().equals(GATEWAY)) {
82 + print("%n[Router Bridge Status]");
83 + device = deviceService.getDevice(node.routerBridge().get());
84 + if (device != null) {
85 + print("%s %s=%s available=%s %s",
86 + deviceService.isAvailable(device.id()) ? MSG_OK : MSG_NO,
87 + ROUTER_BRIDGE,
88 + device.id(),
89 + deviceService.isAvailable(device.id()),
90 + device.annotations());
91 +
92 + print(getPortState(deviceService, node.routerBridge().get(), PATCH_ROUT_BRIDGE));
93 + print(getPortState(deviceService, node.intBridge(), PATCH_INTG_BRIDGE));
94 + } else {
95 + print("%s %s=%s is not available",
96 + MSG_NO,
97 + ROUTER_BRIDGE,
98 + node.intBridge());
99 + }
100 + }
101 + }
102 +
103 + private String getPortState(DeviceService deviceService, DeviceId deviceId, String portName) {
104 + Port port = deviceService.getPorts(deviceId).stream()
105 + .filter(p -> p.annotations().value(PORT_NAME).equals(portName) &&
106 + p.isEnabled())
107 + .findAny().orElse(null);
108 +
109 + if (port != null) {
110 + return String.format("%s %s portNum=%s enabled=%s %s",
111 + port.isEnabled() ? MSG_OK : MSG_NO,
112 + portName,
113 + port.number(),
114 + port.isEnabled() ? Boolean.TRUE : Boolean.FALSE,
115 + port.annotations());
116 + } else {
117 + return String.format("%s %s does not exist", MSG_NO, portName);
118 + }
119 + }
120 +}
1 +/*
2 + * Copyright 2016-present 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 +package org.onosproject.openstacknode.cli;
18 +
19 +import org.apache.karaf.shell.commands.Argument;
20 +import org.apache.karaf.shell.commands.Command;
21 +import org.onosproject.cli.AbstractShellCommand;
22 +import org.onosproject.openstacknode.OpenstackNode;
23 +import org.onosproject.openstacknode.OpenstackNodeService;
24 +
25 +import java.util.NoSuchElementException;
26 +
27 +/**
28 + * Initializes nodes for OpenStack node service.
29 + */
30 +@Command(scope = "onos", name = "openstack-node-init",
31 + description = "Initializes nodes for OpenStack node service")
32 +public class OpenstackNodeInitCommand extends AbstractShellCommand {
33 +
34 + @Argument(index = 0, name = "hostnames", description = "Hostname(s)",
35 + required = true, multiValued = true)
36 + private String[] hostnames = null;
37 +
38 + @Override
39 + protected void execute() {
40 + OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
41 +
42 + for (String hostname : hostnames) {
43 + OpenstackNode node;
44 + try {
45 + node = nodeService.nodes()
46 + .stream()
47 + .filter(n -> n.hostname().equals(hostname))
48 + .findFirst().get();
49 + } catch (NoSuchElementException e) {
50 + print("Unable to find %s", hostname);
51 + continue;
52 + }
53 +
54 + nodeService.addOrUpdateNode(node);
55 + }
56 + }
57 +}
1 +/*
2 + * Copyright 2016-present 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 +package org.onosproject.openstacknode.cli;
18 +
19 +import com.fasterxml.jackson.databind.JsonNode;
20 +import com.fasterxml.jackson.databind.ObjectMapper;
21 +import com.fasterxml.jackson.databind.node.ArrayNode;
22 +import org.apache.karaf.shell.commands.Command;
23 +import org.onosproject.cli.AbstractShellCommand;
24 +import org.onosproject.openstacknode.OpenstackNode;
25 +import org.onosproject.openstacknode.OpenstackNodeService;
26 +
27 +import java.util.Collections;
28 +import java.util.List;
29 +
30 +/**
31 + * Lists all nodes registered to the service.
32 + */
33 +@Command(scope = "onos", name = "openstack-nodes",
34 + description = "Lists all nodes registered in OpenStack node service")
35 +public class OpenstackNodeListCommand extends AbstractShellCommand {
36 +
37 + private static final String COMPLETE = "COMPLETE";
38 + private static final String INCOMPLETE = "INCOMPLETE";
39 +
40 + @Override
41 + protected void execute() {
42 + OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
43 + List<OpenstackNode> nodes = nodeService.nodes();
44 + Collections.sort(nodes, OpenstackNode.OPENSTACK_NODE_COMPARATOR);
45 +
46 + if (outputJson()) {
47 + print("%s", json(nodeService, nodes));
48 + } else {
49 + for (OpenstackNode node : nodes) {
50 + print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, intBridge=%s, routerBridge=%s init=%s",
51 + node.hostname(),
52 + node.type(),
53 + node.managementIp(),
54 + node.dataIp(),
55 + node.intBridge(),
56 + node.routerBridge(),
57 + getState(nodeService, node));
58 + }
59 + print("Total %s nodes", nodeService.nodes().size());
60 + }
61 + }
62 +
63 + private JsonNode json(OpenstackNodeService nodeService, List<OpenstackNode> nodes) {
64 + ObjectMapper mapper = new ObjectMapper();
65 + ArrayNode result = mapper.createArrayNode();
66 + for (OpenstackNode node : nodes) {
67 + result.add(mapper.createObjectNode()
68 + .put("hostname", node.hostname())
69 + .put("type", node.type().name())
70 + .put("managementIp", node.managementIp().toString())
71 + .put("dataIp", node.dataIp().toString())
72 + .put("intBridge", node.intBridge().toString())
73 + .put("routerBridge", node.routerBridge().toString())
74 + .put("state", getState(nodeService, node)));
75 + }
76 + return result;
77 + }
78 +
79 + private String getState(OpenstackNodeService nodeService, OpenstackNode node) {
80 + return nodeService.isComplete(node.hostname()) ? COMPLETE : INCOMPLETE;
81 + }
82 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + * Copyright 2016-present 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 + * Console commands to manage OpenStack nodes.
19 + */
20 +package org.onosproject.openstacknode.cli;
...\ No newline at end of file ...\ No newline at end of file
1 +<!--
2 + ~ Copyright 2016-present 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 +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
17 +
18 + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
19 + <command>
20 + <action class="org.onosproject.openstacknode.cli.OpenstackNodeListCommand"/>
21 + </command>
22 + <command>
23 + <action class="org.onosproject.openstacknode.cli.OpenstackNodeCheckCommand"/>
24 + </command>
25 + <command>
26 + <action class="org.onosproject.openstacknode.cli.OpenstackNodeInitCommand"/>
27 + </command>
28 + </command-bundle>
29 +</blueprint>