mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-05 04:06:49 +02:00
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
This commit is contained in:
parent
89478668d2
commit
34bbe17ef0
@ -1,5 +1,7 @@
|
||||
COMPILE_DEPS = [
|
||||
'//lib:CORE_DEPS',
|
||||
'//lib:org.apache.karaf.shell.console',
|
||||
'//cli:onos-cli',
|
||||
'//protocols/ovsdb/api:onos-protocols-ovsdb-api',
|
||||
'//protocols/ovsdb/rfc:onos-protocols-ovsdb-rfc',
|
||||
'//core/store/serializers:onos-core-serializers',
|
||||
@ -14,5 +16,5 @@ onos_app (
|
||||
category = 'Utility',
|
||||
url = 'http://onosproject.org',
|
||||
description = 'SONA Openstack Node Bootstrap Application.',
|
||||
required_app = [ 'org.onosproject.ovsdb' ],
|
||||
required_app = [ 'org.onosproject.ovsdb-base' ],
|
||||
)
|
||||
|
||||
@ -3,29 +3,36 @@
|
||||
"org.onosproject.openstacknode" : {
|
||||
"openstacknode" : {
|
||||
"nodes" : [
|
||||
{
|
||||
"hostname" : "compute-01",
|
||||
"ovsdbIp" : "192.168.56.112",
|
||||
"ovsdbPort" : "6640",
|
||||
"bridgeId" : "of:0000000000000001",
|
||||
"openstackNodeType" : "COMPUTENODE"
|
||||
},
|
||||
{
|
||||
"hostname" : "compute-02",
|
||||
"ovsdbIp" : "192.168.56.106",
|
||||
"ovsdbPort" : "6640",
|
||||
"bridgeId" : "of:0000000000000002",
|
||||
"openstackNodeType" : "COMPUTENODE"
|
||||
},
|
||||
{
|
||||
"hostname" : "network",
|
||||
"ovsdbIp" : "192.168.56.108",
|
||||
"ovsdbPort" : "6640",
|
||||
"bridgeId" : "of:0000000000000003",
|
||||
"openstackNodeType" : "GATEWAYNODE",
|
||||
"gatewayExternalInterfaceName" : "eth1",
|
||||
"gatewayExternalInterfaceMac" : "00:00:00:00:00:10"
|
||||
}
|
||||
{
|
||||
"hostname" : "compute-01",
|
||||
"type" : "COMPUTE",
|
||||
"managementIp" : "10.203.25.244",
|
||||
"dataIp" : "10.134.34.222",
|
||||
"integrationBridge" : "of:00000000000000a1"
|
||||
},
|
||||
{
|
||||
"hostname" : "compute-02",
|
||||
"type" : "COMPUTE",
|
||||
"managementIp" : "10.203.229.42",
|
||||
"dataIp" : "10.134.34.223",
|
||||
"integrationBridge" : "of:00000000000000a2"
|
||||
},
|
||||
{
|
||||
"hostname" : "gateway-01",
|
||||
"type" : "GATEWAY",
|
||||
"managementIp" : "10.203.198.125",
|
||||
"dataIp" : "10.134.33.208",
|
||||
"integrationBridge" : "of:00000000000000a3",
|
||||
"routerBridge" : "of:00000000000000b3"
|
||||
},
|
||||
{
|
||||
"hostname" : "gateway-02",
|
||||
"type" : "GATEWAY",
|
||||
"managementIp" : "10.203.198.131",
|
||||
"dataIp" : "10.134.33.209",
|
||||
"integrationBridge" : "of:00000000000000a4",
|
||||
"routerBridge" : "of:00000000000000b4"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<onos.app.url>http://onosproject.org</onos.app.url>
|
||||
<onos.app.readme>SONA Openstack Node Bootstrap Application</onos.app.readme>
|
||||
<onos.app.requires>
|
||||
org.onosproject.ovsdb
|
||||
org.onosproject.ovsdb-base
|
||||
</onos.app.requires>
|
||||
</properties>
|
||||
|
||||
@ -56,6 +56,11 @@
|
||||
<artifactId>onos-core-serializers</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.onosproject</groupId>
|
||||
<artifactId>onos-cli</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.onosproject</groupId>
|
||||
<artifactId>onos-ovsdb-api</artifactId>
|
||||
@ -69,5 +74,10 @@
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.karaf.shell</groupId>
|
||||
<artifactId>org.apache.karaf.shell.console</artifactId>
|
||||
<version>3.0.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.onosproject.openstacknode;
|
||||
|
||||
/**
|
||||
* Provides constants used in OpenStack node services.
|
||||
*/
|
||||
public final class Constants {
|
||||
|
||||
private Constants() {
|
||||
}
|
||||
|
||||
public static final String INTEGRATION_BRIDGE = "br-int";
|
||||
public static final String ROUTER_BRIDGE = "br-router";
|
||||
public static final String DEFAULT_TUNNEL = "vxlan";
|
||||
public static final String PATCH_INTG_BRIDGE = "patch-intg";
|
||||
public static final String PATCH_ROUT_BRIDGE = "patch-rout";
|
||||
}
|
||||
@ -16,14 +16,16 @@
|
||||
package org.onosproject.openstacknode;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Strings;
|
||||
import org.onlab.packet.IpAddress;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onlab.packet.TpPort;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.openstacknode.OpenstackNodeService.NodeType;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
@ -31,118 +33,121 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
*/
|
||||
public final class OpenstackNode {
|
||||
|
||||
private final String hostName;
|
||||
private final IpAddress ovsdbIp;
|
||||
private final TpPort ovsdbPort;
|
||||
private final DeviceId bridgeId;
|
||||
private final OpenstackNodeService.OpenstackNodeType openstackNodeType;
|
||||
private final String gatewayExternalInterfaceName;
|
||||
private final MacAddress gatewayExternalInterfaceMac;
|
||||
private static final String OVSDB = "ovsdb:";
|
||||
|
||||
private final String hostname;
|
||||
private final NodeType type;
|
||||
private final IpAddress managementIp;
|
||||
private final IpAddress dataIp;
|
||||
private final DeviceId integrationBridge;
|
||||
private final Optional<DeviceId> routerBridge;
|
||||
private final OpenstackNodeState state;
|
||||
|
||||
public static final Comparator<OpenstackNode> OPENSTACK_NODE_COMPARATOR =
|
||||
(node1, node2) -> node1.hostName().compareTo(node2.hostName());
|
||||
(node1, node2) -> node1.hostname().compareTo(node2.hostname());
|
||||
|
||||
/**
|
||||
* Creates a new node.
|
||||
*
|
||||
* @param hostName hostName
|
||||
* @param ovsdbIp OVSDB server IP address
|
||||
* @param ovsdbPort OVSDB server port number
|
||||
* @param bridgeId integration bridge identifier
|
||||
* @param openstackNodeType openstack node type
|
||||
* @param gatewayExternalInterfaceName gatewayExternalInterfaceName
|
||||
* @param gatewayExternalInterfaceMac gatewayExternalInterfaceMac
|
||||
*/
|
||||
public OpenstackNode(String hostName, IpAddress ovsdbIp, TpPort ovsdbPort, DeviceId bridgeId,
|
||||
OpenstackNodeService.OpenstackNodeType openstackNodeType,
|
||||
String gatewayExternalInterfaceName,
|
||||
MacAddress gatewayExternalInterfaceMac) {
|
||||
this.hostName = checkNotNull(hostName, "hostName cannot be null");
|
||||
this.ovsdbIp = checkNotNull(ovsdbIp, "ovsdbIp cannot be null");
|
||||
this.ovsdbPort = checkNotNull(ovsdbPort, "ovsdbPort cannot be null");
|
||||
this.bridgeId = checkNotNull(bridgeId, "bridgeId cannot be null");
|
||||
this.openstackNodeType = checkNotNull(openstackNodeType, "openstackNodeType cannot be null");
|
||||
this.gatewayExternalInterfaceName = gatewayExternalInterfaceName;
|
||||
this.gatewayExternalInterfaceMac = gatewayExternalInterfaceMac;
|
||||
|
||||
if (openstackNodeType == OpenstackNodeService.OpenstackNodeType.GATEWAYNODE) {
|
||||
checkNotNull(gatewayExternalInterfaceName, "gatewayExternalInterfaceName cannot be null");
|
||||
checkNotNull(gatewayExternalInterfaceMac, "gatewayExternalInterfaceMac cannot be null");
|
||||
}
|
||||
private OpenstackNode(String hostname,
|
||||
NodeType type,
|
||||
IpAddress managementIp,
|
||||
IpAddress dataIp,
|
||||
DeviceId integrationBridge,
|
||||
Optional<DeviceId> routerBridge,
|
||||
OpenstackNodeState state) {
|
||||
this.hostname = hostname;
|
||||
this.type = type;
|
||||
this.managementIp = managementIp;
|
||||
this.dataIp = dataIp;
|
||||
this.integrationBridge = integrationBridge;
|
||||
this.routerBridge = routerBridge;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OVSDB server IP address.
|
||||
* Returns OpenStack node with new state.
|
||||
*
|
||||
* @return ip address
|
||||
* @param node openstack node
|
||||
* @param state openstack node init state
|
||||
* @return openstack node
|
||||
*/
|
||||
public IpAddress ovsdbIp() {
|
||||
return this.ovsdbIp;
|
||||
public static OpenstackNode getUpdatedNode(OpenstackNode node, OpenstackNodeState state) {
|
||||
return new OpenstackNode(node.hostname,
|
||||
node.type,
|
||||
node.managementIp,
|
||||
node.dataIp,
|
||||
node.integrationBridge,
|
||||
node.routerBridge,
|
||||
state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OVSDB server port number.
|
||||
* Returns hostname of the node.
|
||||
*
|
||||
* @return port number
|
||||
* @return hostname
|
||||
*/
|
||||
public TpPort ovsdbPort() {
|
||||
return this.ovsdbPort;
|
||||
public String hostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hostName.
|
||||
* Returns the type of the node.
|
||||
*
|
||||
* @return hostName
|
||||
* @return node type
|
||||
*/
|
||||
public String hostName() {
|
||||
return this.hostName;
|
||||
public NodeType type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the integration bridge.
|
||||
* Returns the management network IP address of the node.
|
||||
*
|
||||
* @return management network ip address
|
||||
*/
|
||||
public IpAddress managementIp() {
|
||||
return managementIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data network IP address of the node.
|
||||
*
|
||||
* @return data network ip address
|
||||
*/
|
||||
public IpAddress dataIp() {
|
||||
return dataIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integration bridge device ID.
|
||||
*
|
||||
* @return device id
|
||||
*/
|
||||
public DeviceId intBrId() {
|
||||
return this.bridgeId;
|
||||
public DeviceId intBridge() {
|
||||
return integrationBridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier of the OVSDB device.
|
||||
* Returns the router bridge device ID.
|
||||
* It returns valid value only if the node type is GATEWAY.
|
||||
*
|
||||
* @return device id; or empty device id
|
||||
*/
|
||||
public Optional<DeviceId> routerBridge() {
|
||||
return routerBridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the init state of the node.
|
||||
*
|
||||
* @return init state
|
||||
*/
|
||||
public OpenstackNodeState state() {
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the device ID of the OVSDB session of the node.
|
||||
*
|
||||
* @return device id
|
||||
*/
|
||||
public DeviceId ovsdbId() {
|
||||
return DeviceId.deviceId(OVSDB.concat(this.ovsdbIp.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the openstack node type.
|
||||
*
|
||||
* @return openstack node type
|
||||
*/
|
||||
public OpenstackNodeService.OpenstackNodeType openstackNodeType() {
|
||||
return this.openstackNodeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gatewayExternalInterfaceName.
|
||||
*
|
||||
* @return gatewayExternalInterfaceName
|
||||
*/
|
||||
public String gatewayExternalInterfaceName() {
|
||||
return this.gatewayExternalInterfaceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the gatewayExternalInterfaceMac.
|
||||
*
|
||||
* @return gatewayExternalInterfaceMac
|
||||
*/
|
||||
public MacAddress gatewayExternalInterfaceMac() {
|
||||
return this.gatewayExternalInterfaceMac;
|
||||
return DeviceId.deviceId("ovsdb:" + managementIp.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -153,12 +158,12 @@ public final class OpenstackNode {
|
||||
|
||||
if (obj instanceof OpenstackNode) {
|
||||
OpenstackNode that = (OpenstackNode) obj;
|
||||
|
||||
if (Objects.equals(hostName, that.hostName) &&
|
||||
Objects.equals(ovsdbIp, that.ovsdbIp) &&
|
||||
Objects.equals(ovsdbPort, that.ovsdbPort) &&
|
||||
Objects.equals(bridgeId, that.bridgeId) &&
|
||||
Objects.equals(openstackNodeType, that.openstackNodeType)) {
|
||||
if (Objects.equals(hostname, that.hostname) &&
|
||||
Objects.equals(type, that.type) &&
|
||||
Objects.equals(managementIp, that.managementIp) &&
|
||||
Objects.equals(dataIp, that.dataIp) &&
|
||||
Objects.equals(integrationBridge, that.integrationBridge) &&
|
||||
Objects.equals(routerBridge, that.routerBridge)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -167,29 +172,142 @@ public final class OpenstackNode {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(hostName, ovsdbIp, ovsdbPort, bridgeId, openstackNodeType);
|
||||
return Objects.hash(hostname,
|
||||
type,
|
||||
managementIp,
|
||||
dataIp,
|
||||
integrationBridge,
|
||||
routerBridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (openstackNodeType == OpenstackNodeService.OpenstackNodeType.COMPUTENODE) {
|
||||
return MoreObjects.toStringHelper(getClass())
|
||||
.add("host", hostName)
|
||||
.add("ip", ovsdbIp)
|
||||
.add("port", ovsdbPort)
|
||||
.add("bridgeId", bridgeId)
|
||||
.add("openstacknodetype", openstackNodeType)
|
||||
.toString();
|
||||
} else {
|
||||
return MoreObjects.toStringHelper(getClass())
|
||||
.add("host", hostName)
|
||||
.add("ip", ovsdbIp)
|
||||
.add("port", ovsdbPort)
|
||||
.add("bridgeId", bridgeId)
|
||||
.add("openstacknodetype", openstackNodeType)
|
||||
.add("gatewayExternalInterfaceName", gatewayExternalInterfaceName)
|
||||
.add("gatewayExternalInterfaceMac", gatewayExternalInterfaceMac)
|
||||
.toString();
|
||||
return MoreObjects.toStringHelper(getClass())
|
||||
.add("hostname", hostname)
|
||||
.add("type", type)
|
||||
.add("managementIp", managementIp)
|
||||
.add("dataIp", dataIp)
|
||||
.add("integrationBridge", integrationBridge)
|
||||
.add("routerBridge", routerBridge)
|
||||
.add("state", state)
|
||||
.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new builder instance.
|
||||
*
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder of OpenStack node entities.
|
||||
*/
|
||||
public static final class Builder {
|
||||
private String hostname;
|
||||
private NodeType type;
|
||||
private IpAddress managementIp;
|
||||
private IpAddress dataIp;
|
||||
private DeviceId integrationBridge;
|
||||
private Optional<DeviceId> routerBridge = Optional.empty();
|
||||
private OpenstackNodeState state = OpenstackNodeState.noState();
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
public OpenstackNode build() {
|
||||
checkArgument(!Strings.isNullOrEmpty(hostname));
|
||||
checkNotNull(type);
|
||||
checkNotNull(managementIp);
|
||||
checkNotNull(dataIp);
|
||||
checkNotNull(integrationBridge);
|
||||
checkNotNull(routerBridge);
|
||||
return new OpenstackNode(hostname,
|
||||
type,
|
||||
managementIp,
|
||||
dataIp,
|
||||
integrationBridge,
|
||||
routerBridge,
|
||||
state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the hostname.
|
||||
*
|
||||
* @param hostname hostname
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder hostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the node type.
|
||||
*
|
||||
* @param type openstack node type
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder type(NodeType type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the management network IP address.
|
||||
*
|
||||
* @param managementIp management ip address
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder managementIp(IpAddress managementIp) {
|
||||
this.managementIp = managementIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the data network IP address.
|
||||
*
|
||||
* @param dataIp data network ip address
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder dataIp(IpAddress dataIp) {
|
||||
this.dataIp = dataIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the integration bridge ID.
|
||||
*
|
||||
* @param integrationBridge integration bridge device id
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder integrationBridge(DeviceId integrationBridge) {
|
||||
this.integrationBridge = integrationBridge;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the router bridge ID.
|
||||
*
|
||||
* @param routerBridge router bridge device ID
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder routerBridge(DeviceId routerBridge) {
|
||||
this.routerBridge = Optional.ofNullable(routerBridge);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the init state.
|
||||
*
|
||||
* @param state node init state
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder state(OpenstackNodeState state) {
|
||||
this.state = state;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,73 +17,94 @@ package org.onosproject.openstacknode;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.onlab.packet.Ip4Address;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onlab.packet.TpPort;
|
||||
import org.onlab.packet.IpAddress;
|
||||
import org.onosproject.core.ApplicationId;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.slf4j.Logger;
|
||||
import org.onosproject.openstacknode.OpenstackNodeService.NodeType;
|
||||
import java.util.Set;
|
||||
import org.onosproject.net.config.Config;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
|
||||
import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
|
||||
|
||||
/**
|
||||
* Configuration object for OpensatckNode service.
|
||||
*/
|
||||
public class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
|
||||
protected final Logger log = getLogger(getClass());
|
||||
private static final String NODES = "nodes";
|
||||
private static final String HOST_NAME = "hostname";
|
||||
private static final String TYPE = "type";
|
||||
private static final String MANAGEMENT_IP = "managementIp";
|
||||
private static final String DATA_IP = "dataIp";
|
||||
private static final String INTEGRATION_BRIDGE = "integrationBridge";
|
||||
private static final String ROUTER_BRIDGE = "routerBridge";
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
boolean result = hasOnlyFields(NODES);
|
||||
|
||||
public static final String NODES = "nodes";
|
||||
public static final String HOST_NAME = "hostname";
|
||||
public static final String OVSDB_IP = "ovsdbIp";
|
||||
public static final String OVSDB_PORT = "ovsdbPort";
|
||||
public static final String BRIDGE_ID = "bridgeId";
|
||||
public static final String NODE_TYPE = "openstackNodeType";
|
||||
public static final String GATEWAY_EXTERNAL_INTERFACE_NAME = "gatewayExternalInterfaceName";
|
||||
public static final String GATEWAY_EXTERNAL_INTERFACE_MAC = "gatewayExternalInterfaceMac";
|
||||
if (object.get(NODES) == null || object.get(NODES).size() < 1) {
|
||||
final String msg = "No node is present";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
for (JsonNode node : object.get(NODES)) {
|
||||
ObjectNode osNode = (ObjectNode) node;
|
||||
result &= hasOnlyFields(osNode,
|
||||
HOST_NAME,
|
||||
TYPE,
|
||||
MANAGEMENT_IP,
|
||||
DATA_IP,
|
||||
INTEGRATION_BRIDGE,
|
||||
ROUTER_BRIDGE
|
||||
);
|
||||
|
||||
result &= isString(osNode, HOST_NAME, MANDATORY);
|
||||
result &= isString(osNode, TYPE, MANDATORY);
|
||||
result &= isIpAddress(osNode, MANAGEMENT_IP, MANDATORY);
|
||||
result &= result && isIpAddress(osNode, DATA_IP, MANDATORY);
|
||||
result &= isString(osNode, INTEGRATION_BRIDGE, MANDATORY);
|
||||
|
||||
DeviceId.deviceId(osNode.get(INTEGRATION_BRIDGE).asText());
|
||||
NodeType.valueOf(osNode.get(TYPE).asText());
|
||||
|
||||
if (osNode.get(TYPE).asText().equals(GATEWAY.name())) {
|
||||
result &= isString(osNode, ROUTER_BRIDGE, MANDATORY);
|
||||
DeviceId.deviceId(osNode.get(ROUTER_BRIDGE).asText());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of nodes read from network config.
|
||||
*
|
||||
* @return set of OpensatckNodeConfig or null
|
||||
* @return set of openstack nodes
|
||||
*/
|
||||
public Set<OpenstackNode> openstackNodes() {
|
||||
|
||||
Set<OpenstackNode> nodes = Sets.newHashSet();
|
||||
|
||||
JsonNode jsonNodes = object.get(NODES);
|
||||
if (jsonNodes == null) {
|
||||
return null;
|
||||
}
|
||||
for (JsonNode node : object.get(NODES)) {
|
||||
NodeType type = NodeType.valueOf(get(node, TYPE));
|
||||
OpenstackNode.Builder nodeBuilder = OpenstackNode.builder()
|
||||
.integrationBridge(DeviceId.deviceId(get(node, INTEGRATION_BRIDGE)))
|
||||
.dataIp(IpAddress.valueOf(get(node, DATA_IP)))
|
||||
.managementIp(IpAddress.valueOf(get(node, MANAGEMENT_IP)))
|
||||
.type(type)
|
||||
.hostname(get(node, HOST_NAME));
|
||||
|
||||
jsonNodes.forEach(jsonNode -> {
|
||||
try {
|
||||
if (OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()) ==
|
||||
OpenstackNodeService.OpenstackNodeType.COMPUTENODE) {
|
||||
nodes.add(new OpenstackNode(
|
||||
jsonNode.path(HOST_NAME).asText(),
|
||||
Ip4Address.valueOf(jsonNode.path(OVSDB_IP).asText()),
|
||||
TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
|
||||
DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()),
|
||||
OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()),
|
||||
null, MacAddress.NONE));
|
||||
} else {
|
||||
nodes.add(new OpenstackNode(
|
||||
jsonNode.path(HOST_NAME).asText(),
|
||||
Ip4Address.valueOf(jsonNode.path(OVSDB_IP).asText()),
|
||||
TpPort.tpPort(jsonNode.path(OVSDB_PORT).asInt()),
|
||||
DeviceId.deviceId(jsonNode.path(BRIDGE_ID).asText()),
|
||||
OpenstackNodeService.OpenstackNodeType.valueOf(jsonNode.path(NODE_TYPE).asText()),
|
||||
jsonNode.path(GATEWAY_EXTERNAL_INTERFACE_NAME).asText(),
|
||||
MacAddress.valueOf(jsonNode.path(GATEWAY_EXTERNAL_INTERFACE_MAC).asText())));
|
||||
}
|
||||
} catch (IllegalArgumentException | NullPointerException e) {
|
||||
log.error("Failed to read {}", e.toString());
|
||||
if (type.equals(GATEWAY)) {
|
||||
nodeBuilder.routerBridge(DeviceId.deviceId(get(node, ROUTER_BRIDGE)));
|
||||
}
|
||||
});
|
||||
nodes.add(nodeBuilder.build());
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private String get(JsonNode jsonNode, String path) {
|
||||
return jsonNode.get(path).asText();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -15,26 +15,33 @@
|
||||
*/
|
||||
package org.onosproject.openstacknode;
|
||||
|
||||
import org.onlab.packet.IpAddress;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.PortNumber;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Handles the bootstrap request for compute/gateway node.
|
||||
*/
|
||||
public interface OpenstackNodeService {
|
||||
|
||||
public enum OpenstackNodeType {
|
||||
enum NodeType {
|
||||
/**
|
||||
* Compute or Gateway Node.
|
||||
*/
|
||||
COMPUTENODE,
|
||||
GATEWAYNODE
|
||||
COMPUTE,
|
||||
GATEWAY
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new node to the service.
|
||||
* Adds or updates a new node to the service.
|
||||
*
|
||||
* @param node openstack node
|
||||
*/
|
||||
void addNode(OpenstackNode node);
|
||||
void addOrUpdateNode(OpenstackNode node);
|
||||
|
||||
/**
|
||||
* Deletes a node from the service.
|
||||
@ -44,18 +51,58 @@ public interface OpenstackNodeService {
|
||||
void deleteNode(OpenstackNode node);
|
||||
|
||||
/**
|
||||
* Returns nodes known to the service for designated openstacktype.
|
||||
* Returns all nodes known to the service.
|
||||
*
|
||||
* @param openstackNodeType openstack node type
|
||||
* @return list of nodes
|
||||
*/
|
||||
List<OpenstackNode> getNodes(OpenstackNodeType openstackNodeType);
|
||||
List<OpenstackNode> nodes();
|
||||
|
||||
/**
|
||||
* Returns the NodeState for a given node.
|
||||
* Returns all nodes in complete state.
|
||||
*
|
||||
* @param node openstack node
|
||||
* @return true if the NodeState for a given node is COMPLETE, false otherwise
|
||||
* @return set of nodes
|
||||
*/
|
||||
boolean isComplete(OpenstackNode node);
|
||||
Set<OpenstackNode> completeNodes();
|
||||
|
||||
/**
|
||||
* Returns node initialization state is complete or not.
|
||||
*
|
||||
* @param hostname hostname of the node
|
||||
* @return true if initial node setup is completed, otherwise false
|
||||
*/
|
||||
boolean isComplete(String hostname);
|
||||
|
||||
/**
|
||||
* Returns data network IP address of a given integration bridge device.
|
||||
*
|
||||
* @param intBridgeId integration bridge device id
|
||||
* @return ip address; empty value otherwise
|
||||
*/
|
||||
Optional<IpAddress> dataIp(DeviceId intBridgeId);
|
||||
|
||||
/**
|
||||
* Returns tunnel port number of a given integration bridge device.
|
||||
*
|
||||
* @param intBridgeId integration bridge device id
|
||||
* @return port number; or empty value
|
||||
*/
|
||||
Optional<PortNumber> tunnelPort(DeviceId intBridgeId);
|
||||
|
||||
/**
|
||||
* Returns router bridge device ID connected to a given integration bridge.
|
||||
* It returns valid value only if the node type is GATEWAY.
|
||||
*
|
||||
* @param intBridgeId device id of the integration bridge
|
||||
* @return device id of a router bridge; or empty value
|
||||
*/
|
||||
Optional<DeviceId> routerBridge(DeviceId intBridgeId);
|
||||
|
||||
/**
|
||||
* Returns port number connected to the router bridge.
|
||||
* It returns valid value only if the node type is GATEWAY.
|
||||
*
|
||||
* @param intBridgeId integration bridge device id
|
||||
* @return port number; or empty value
|
||||
*/
|
||||
Optional<PortNumber> externalPort(DeviceId intBridgeId);
|
||||
}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.onosproject.openstacknode;
|
||||
|
||||
/**
|
||||
* Entity that defines possible init state of the OpenStack node.
|
||||
*/
|
||||
public interface OpenstackNodeState {
|
||||
/**
|
||||
* Returns null for no state.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
static OpenstackNodeState noState() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.onosproject.openstacknode.cli;
|
||||
|
||||
import org.apache.karaf.shell.commands.Argument;
|
||||
import org.apache.karaf.shell.commands.Command;
|
||||
import org.onosproject.cli.AbstractShellCommand;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.Port;
|
||||
import org.onosproject.net.Device;
|
||||
import org.onosproject.net.device.DeviceService;
|
||||
import org.onosproject.openstacknode.OpenstackNode;
|
||||
import org.onosproject.openstacknode.OpenstackNodeService;
|
||||
|
||||
import static org.onosproject.net.AnnotationKeys.PORT_NAME;
|
||||
import static org.onosproject.openstacknode.Constants.*;
|
||||
import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
|
||||
|
||||
/**
|
||||
* Checks detailed node init state.
|
||||
*/
|
||||
@Command(scope = "onos", name = "openstack-node-check",
|
||||
description = "Shows detailed node init state")
|
||||
public class OpenstackNodeCheckCommand extends AbstractShellCommand {
|
||||
|
||||
@Argument(index = 0, name = "hostname", description = "Hostname",
|
||||
required = true, multiValued = false)
|
||||
private String hostname = null;
|
||||
|
||||
private static final String MSG_OK = "OK";
|
||||
private static final String MSG_NO = "NO";
|
||||
|
||||
@Override
|
||||
protected void execute() {
|
||||
OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
|
||||
DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
|
||||
|
||||
OpenstackNode node = nodeService.nodes()
|
||||
.stream()
|
||||
.filter(n -> n.hostname().equals(hostname))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (node == null) {
|
||||
print("Cannot find %s from registered nodes", hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
print("%n[Integration Bridge Status]");
|
||||
Device device = deviceService.getDevice(node.intBridge());
|
||||
if (device != null) {
|
||||
print("%s %s=%s available=%s %s",
|
||||
deviceService.isAvailable(device.id()) ? MSG_OK : MSG_NO,
|
||||
INTEGRATION_BRIDGE,
|
||||
device.id(),
|
||||
deviceService.isAvailable(device.id()),
|
||||
device.annotations());
|
||||
|
||||
print(getPortState(deviceService, node.intBridge(), DEFAULT_TUNNEL));
|
||||
} else {
|
||||
print("%s %s=%s is not available",
|
||||
MSG_NO,
|
||||
INTEGRATION_BRIDGE,
|
||||
node.intBridge());
|
||||
}
|
||||
|
||||
if (node.type().equals(GATEWAY)) {
|
||||
print("%n[Router Bridge Status]");
|
||||
device = deviceService.getDevice(node.routerBridge().get());
|
||||
if (device != null) {
|
||||
print("%s %s=%s available=%s %s",
|
||||
deviceService.isAvailable(device.id()) ? MSG_OK : MSG_NO,
|
||||
ROUTER_BRIDGE,
|
||||
device.id(),
|
||||
deviceService.isAvailable(device.id()),
|
||||
device.annotations());
|
||||
|
||||
print(getPortState(deviceService, node.routerBridge().get(), PATCH_ROUT_BRIDGE));
|
||||
print(getPortState(deviceService, node.intBridge(), PATCH_INTG_BRIDGE));
|
||||
} else {
|
||||
print("%s %s=%s is not available",
|
||||
MSG_NO,
|
||||
ROUTER_BRIDGE,
|
||||
node.intBridge());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getPortState(DeviceService deviceService, DeviceId deviceId, String portName) {
|
||||
Port port = deviceService.getPorts(deviceId).stream()
|
||||
.filter(p -> p.annotations().value(PORT_NAME).equals(portName) &&
|
||||
p.isEnabled())
|
||||
.findAny().orElse(null);
|
||||
|
||||
if (port != null) {
|
||||
return String.format("%s %s portNum=%s enabled=%s %s",
|
||||
port.isEnabled() ? MSG_OK : MSG_NO,
|
||||
portName,
|
||||
port.number(),
|
||||
port.isEnabled() ? Boolean.TRUE : Boolean.FALSE,
|
||||
port.annotations());
|
||||
} else {
|
||||
return String.format("%s %s does not exist", MSG_NO, portName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.onosproject.openstacknode.cli;
|
||||
|
||||
import org.apache.karaf.shell.commands.Argument;
|
||||
import org.apache.karaf.shell.commands.Command;
|
||||
import org.onosproject.cli.AbstractShellCommand;
|
||||
import org.onosproject.openstacknode.OpenstackNode;
|
||||
import org.onosproject.openstacknode.OpenstackNodeService;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* Initializes nodes for OpenStack node service.
|
||||
*/
|
||||
@Command(scope = "onos", name = "openstack-node-init",
|
||||
description = "Initializes nodes for OpenStack node service")
|
||||
public class OpenstackNodeInitCommand extends AbstractShellCommand {
|
||||
|
||||
@Argument(index = 0, name = "hostnames", description = "Hostname(s)",
|
||||
required = true, multiValued = true)
|
||||
private String[] hostnames = null;
|
||||
|
||||
@Override
|
||||
protected void execute() {
|
||||
OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
|
||||
|
||||
for (String hostname : hostnames) {
|
||||
OpenstackNode node;
|
||||
try {
|
||||
node = nodeService.nodes()
|
||||
.stream()
|
||||
.filter(n -> n.hostname().equals(hostname))
|
||||
.findFirst().get();
|
||||
} catch (NoSuchElementException e) {
|
||||
print("Unable to find %s", hostname);
|
||||
continue;
|
||||
}
|
||||
|
||||
nodeService.addOrUpdateNode(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.onosproject.openstacknode.cli;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import org.apache.karaf.shell.commands.Command;
|
||||
import org.onosproject.cli.AbstractShellCommand;
|
||||
import org.onosproject.openstacknode.OpenstackNode;
|
||||
import org.onosproject.openstacknode.OpenstackNodeService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Lists all nodes registered to the service.
|
||||
*/
|
||||
@Command(scope = "onos", name = "openstack-nodes",
|
||||
description = "Lists all nodes registered in OpenStack node service")
|
||||
public class OpenstackNodeListCommand extends AbstractShellCommand {
|
||||
|
||||
private static final String COMPLETE = "COMPLETE";
|
||||
private static final String INCOMPLETE = "INCOMPLETE";
|
||||
|
||||
@Override
|
||||
protected void execute() {
|
||||
OpenstackNodeService nodeService = AbstractShellCommand.get(OpenstackNodeService.class);
|
||||
List<OpenstackNode> nodes = nodeService.nodes();
|
||||
Collections.sort(nodes, OpenstackNode.OPENSTACK_NODE_COMPARATOR);
|
||||
|
||||
if (outputJson()) {
|
||||
print("%s", json(nodeService, nodes));
|
||||
} else {
|
||||
for (OpenstackNode node : nodes) {
|
||||
print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, intBridge=%s, routerBridge=%s init=%s",
|
||||
node.hostname(),
|
||||
node.type(),
|
||||
node.managementIp(),
|
||||
node.dataIp(),
|
||||
node.intBridge(),
|
||||
node.routerBridge(),
|
||||
getState(nodeService, node));
|
||||
}
|
||||
print("Total %s nodes", nodeService.nodes().size());
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode json(OpenstackNodeService nodeService, List<OpenstackNode> nodes) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
ArrayNode result = mapper.createArrayNode();
|
||||
for (OpenstackNode node : nodes) {
|
||||
result.add(mapper.createObjectNode()
|
||||
.put("hostname", node.hostname())
|
||||
.put("type", node.type().name())
|
||||
.put("managementIp", node.managementIp().toString())
|
||||
.put("dataIp", node.dataIp().toString())
|
||||
.put("intBridge", node.intBridge().toString())
|
||||
.put("routerBridge", node.routerBridge().toString())
|
||||
.put("state", getState(nodeService, node)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getState(OpenstackNodeService nodeService, OpenstackNode node) {
|
||||
return nodeService.isComplete(node.hostname()) ? COMPLETE : INCOMPLETE;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Console commands to manage OpenStack nodes.
|
||||
*/
|
||||
package org.onosproject.openstacknode.cli;
|
||||
@ -0,0 +1,29 @@
|
||||
<!--
|
||||
~ Copyright 2016-present Open Networking Laboratory
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
|
||||
|
||||
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
|
||||
<command>
|
||||
<action class="org.onosproject.openstacknode.cli.OpenstackNodeListCommand"/>
|
||||
</command>
|
||||
<command>
|
||||
<action class="org.onosproject.openstacknode.cli.OpenstackNodeCheckCommand"/>
|
||||
</command>
|
||||
<command>
|
||||
<action class="org.onosproject.openstacknode.cli.OpenstackNodeInitCommand"/>
|
||||
</command>
|
||||
</command-bundle>
|
||||
</blueprint>
|
||||
Loading…
x
Reference in New Issue
Block a user