mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-04 19:56:49 +02:00
[ONOS-6150] OpenstackNode application support creation of vlan interface on open vswitch
Change-Id: I4342a8bd5f8a0a802e05f6b89a7962e5d3c9c9af
This commit is contained in:
parent
93722efa8f
commit
917beb4b9d
@ -427,7 +427,7 @@ public class OpenstackRoutingIcmpHandler {
|
||||
// don't need to add gateway here and there
|
||||
GatewayNode gnode = GatewayNode.builder()
|
||||
.gatewayDeviceId(osNode.intBridge())
|
||||
.dataIpAddress(osNode.dataIp().getIp4Address())
|
||||
.dataIpAddress(osNode.dataIp().get().getIp4Address())
|
||||
.uplinkIntf(osNode.externalPortName().get())
|
||||
.build();
|
||||
gatewayService.addGatewayNode(gnode);
|
||||
|
||||
@ -2,41 +2,35 @@
|
||||
"apps" : {
|
||||
"org.onosproject.openstacknode" : {
|
||||
"openstacknode" : {
|
||||
"nodes" : [
|
||||
{
|
||||
"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",
|
||||
"uplinkPort" : "veth1",
|
||||
"routerController" : "172.17.0.2"
|
||||
},
|
||||
{
|
||||
"hostname" : "gateway-02",
|
||||
"type" : "GATEWAY",
|
||||
"managementIp" : "10.203.198.131",
|
||||
"dataIp" : "10.134.33.209",
|
||||
"integrationBridge" : "of:00000000000000a4",
|
||||
"routerBridge" : "of:00000000000000b4",
|
||||
"uplinkPort" : "veth1",
|
||||
"routerController" : "172.17.0.2"
|
||||
}
|
||||
"nodes" : [
|
||||
{
|
||||
"hostname" : "compute-01",
|
||||
"type" : "COMPUTE",
|
||||
"managementIp" : "172.16.130.4",
|
||||
"dataIp" : "172.16.130.4",
|
||||
"vlanPort" : "eth2",
|
||||
"integrationBridge" : "of:00000000000000a1"
|
||||
},
|
||||
{
|
||||
"hostname" : "compute-02",
|
||||
"type" : "COMPUTE",
|
||||
"managementIp" : "172.16.130.6",
|
||||
"dataIp" : "172.16.130.6",
|
||||
"vlanPort" : "eth2",
|
||||
"integrationBridge" : "of:00000000000000a2"
|
||||
},
|
||||
{
|
||||
"hostname" : "gateway-01",
|
||||
"type" : "GATEWAY",
|
||||
"managementIp" : "172.16.130.8",
|
||||
"dataIp" : "172.16.130.7",
|
||||
"vlanPort" : "eth2",
|
||||
"integrationBridge" : "of:00000000000000a3",
|
||||
"routerBridge" : "of:00000000000000b1",
|
||||
"uplinkPort" : "quagga-router",
|
||||
"routerController" : "172.17.0.2"
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -51,16 +45,6 @@
|
||||
"basic" : {
|
||||
"driver" : "sona"
|
||||
}
|
||||
},
|
||||
"of:00000000000000b1" : {
|
||||
"basic" : {
|
||||
"driver" : "softrouter"
|
||||
}
|
||||
},
|
||||
"of:00000000000000b2" : {
|
||||
"basic" : {
|
||||
"driver" : "softrouter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +39,13 @@ public final class OpenstackNode {
|
||||
private final String hostname;
|
||||
private final NodeType type;
|
||||
private final IpAddress managementIp;
|
||||
private final IpAddress dataIp;
|
||||
private final Optional<IpAddress> dataIp;
|
||||
private final DeviceId integrationBridge;
|
||||
private final Optional<DeviceId> routerBridge;
|
||||
private final Optional<String> uplink;
|
||||
// TODO remove this when we use single ONOS cluster for both openstackNode and vRouter
|
||||
private final Optional<IpAddress> routerController;
|
||||
private final Optional<String> vlanPort;
|
||||
private final NodeState state;
|
||||
|
||||
public static final Comparator<OpenstackNode> OPENSTACK_NODE_COMPARATOR =
|
||||
@ -53,11 +54,12 @@ public final class OpenstackNode {
|
||||
private OpenstackNode(String hostname,
|
||||
NodeType type,
|
||||
IpAddress managementIp,
|
||||
IpAddress dataIp,
|
||||
Optional<IpAddress> dataIp,
|
||||
DeviceId integrationBridge,
|
||||
Optional<DeviceId> routerBridge,
|
||||
Optional<String> uplink,
|
||||
Optional<IpAddress> routerController,
|
||||
Optional<String> vlanPort,
|
||||
NodeState state) {
|
||||
this.hostname = hostname;
|
||||
this.type = type;
|
||||
@ -67,6 +69,7 @@ public final class OpenstackNode {
|
||||
this.routerBridge = routerBridge;
|
||||
this.uplink = uplink;
|
||||
this.routerController = routerController;
|
||||
this.vlanPort = vlanPort;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@ -86,6 +89,7 @@ public final class OpenstackNode {
|
||||
node.routerBridge,
|
||||
node.uplink,
|
||||
node.routerController,
|
||||
node.vlanPort,
|
||||
state);
|
||||
}
|
||||
|
||||
@ -119,9 +123,9 @@ public final class OpenstackNode {
|
||||
/**
|
||||
* Returns the data network IP address of the node.
|
||||
*
|
||||
* @return data network ip address
|
||||
* @return data network ip address; or empty value
|
||||
*/
|
||||
public IpAddress dataIp() {
|
||||
public Optional<IpAddress> dataIp() {
|
||||
return dataIp;
|
||||
}
|
||||
|
||||
@ -165,6 +169,15 @@ public final class OpenstackNode {
|
||||
return uplink;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vlan interface name.
|
||||
*
|
||||
* @return vlan interface name; or empty value
|
||||
*/
|
||||
public Optional<String> vlanPort() {
|
||||
return vlanPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the init state of the node.
|
||||
*
|
||||
@ -212,7 +225,8 @@ public final class OpenstackNode {
|
||||
Objects.equals(integrationBridge, that.integrationBridge) &&
|
||||
Objects.equals(routerBridge, that.routerBridge) &&
|
||||
Objects.equals(uplink, that.uplink) &&
|
||||
Objects.equals(routerController, that.routerController)) {
|
||||
Objects.equals(routerController, that.routerController) &&
|
||||
Objects.equals(vlanPort, that.vlanPort)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -228,7 +242,8 @@ public final class OpenstackNode {
|
||||
integrationBridge,
|
||||
routerBridge,
|
||||
uplink,
|
||||
routerController);
|
||||
routerController,
|
||||
vlanPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -242,6 +257,7 @@ public final class OpenstackNode {
|
||||
.add("routerBridge", routerBridge)
|
||||
.add("uplink", uplink)
|
||||
.add("routerController", routerController)
|
||||
.add("vlanport", vlanPort)
|
||||
.add("state", state)
|
||||
.toString();
|
||||
}
|
||||
@ -262,10 +278,11 @@ public final class OpenstackNode {
|
||||
private String hostname;
|
||||
private NodeType type;
|
||||
private IpAddress managementIp;
|
||||
private IpAddress dataIp;
|
||||
private Optional<IpAddress> dataIp = Optional.empty();
|
||||
private DeviceId integrationBridge;
|
||||
private Optional<DeviceId> routerBridge = Optional.empty();
|
||||
private Optional<String> uplink = Optional.empty();
|
||||
private Optional<String> vlanPort = Optional.empty();
|
||||
// TODO remove this when we use single ONOS cluster for both openstackNode and vRouter
|
||||
private Optional<IpAddress> routerController = Optional.empty();
|
||||
private NodeState state = INIT;
|
||||
@ -282,6 +299,7 @@ public final class OpenstackNode {
|
||||
checkNotNull(routerBridge);
|
||||
checkNotNull(uplink);
|
||||
checkNotNull(routerController);
|
||||
checkNotNull(vlanPort);
|
||||
|
||||
if (type == NodeType.GATEWAY) {
|
||||
checkArgument(routerBridge.isPresent());
|
||||
@ -297,6 +315,7 @@ public final class OpenstackNode {
|
||||
routerBridge,
|
||||
uplink,
|
||||
routerController,
|
||||
vlanPort,
|
||||
state);
|
||||
}
|
||||
|
||||
@ -340,7 +359,7 @@ public final class OpenstackNode {
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder dataIp(IpAddress dataIp) {
|
||||
this.dataIp = dataIp;
|
||||
this.dataIp = Optional.ofNullable(dataIp);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -389,6 +408,17 @@ public final class OpenstackNode {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the vlan interface name.
|
||||
*
|
||||
* @param vlanPort vlan interface name
|
||||
* @return openstack node builder
|
||||
*/
|
||||
public Builder vlanPort(String vlanPort) {
|
||||
this.vlanPort = Optional.ofNullable(vlanPort);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns node builder with the init state.
|
||||
*
|
||||
|
||||
@ -27,6 +27,7 @@ import java.util.Set;
|
||||
import org.onosproject.net.config.Config;
|
||||
|
||||
import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
|
||||
import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
|
||||
import static org.onosproject.openstacknode.OpenstackNodeService.NodeType.GATEWAY;
|
||||
|
||||
/**
|
||||
@ -46,6 +47,7 @@ public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
private static final String UPLINK_PORT_NAME = "uplinkPort";
|
||||
// TODO remove this when vRouter supports multiple switches
|
||||
private static final String ROUTER_CONTROLLER = "routerController";
|
||||
private static final String VLAN_PORT_NAME = "vlanPort";
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
@ -57,6 +59,10 @@ public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
}
|
||||
|
||||
for (JsonNode node : object.get(NODES)) {
|
||||
if (get(node, DATA_IP) == null && get(node, VLAN_PORT_NAME) == null) {
|
||||
final String msg = "There is neither tunnel interface nor vlan port";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
ObjectNode osNode = (ObjectNode) node;
|
||||
result &= hasOnlyFields(osNode,
|
||||
HOST_NAME,
|
||||
@ -66,14 +72,16 @@ public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
INTEGRATION_BRIDGE,
|
||||
ROUTER_BRIDGE,
|
||||
UPLINK_PORT_NAME,
|
||||
ROUTER_CONTROLLER
|
||||
ROUTER_CONTROLLER,
|
||||
VLAN_PORT_NAME
|
||||
);
|
||||
|
||||
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);
|
||||
result &= isString(osNode, VLAN_PORT_NAME, OPTIONAL);
|
||||
result &= isIpAddress(osNode, DATA_IP, OPTIONAL);
|
||||
|
||||
DeviceId.deviceId(osNode.get(INTEGRATION_BRIDGE).asText());
|
||||
NodeType.valueOf(osNode.get(TYPE).asText());
|
||||
@ -95,16 +103,22 @@ public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
*/
|
||||
public Set<OpenstackNode> openstackNodes() {
|
||||
Set<OpenstackNode> nodes = Sets.newHashSet();
|
||||
|
||||
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));
|
||||
|
||||
if (get(node, DATA_IP) != null) {
|
||||
nodeBuilder.dataIp(IpAddress.valueOf(get(node, DATA_IP)));
|
||||
}
|
||||
|
||||
if (get(node, VLAN_PORT_NAME) != null) {
|
||||
nodeBuilder.vlanPort(get(node, VLAN_PORT_NAME));
|
||||
}
|
||||
|
||||
if (type.equals(GATEWAY)) {
|
||||
nodeBuilder.routerBridge(DeviceId.deviceId(get(node, ROUTER_BRIDGE)))
|
||||
.uplink(get(node, UPLINK_PORT_NAME))
|
||||
@ -116,6 +130,10 @@ public final class OpenstackNodeConfig extends Config<ApplicationId> {
|
||||
}
|
||||
|
||||
private String get(JsonNode jsonNode, String path) {
|
||||
return jsonNode.get(path).asText();
|
||||
JsonNode jNode = jsonNode.get(path);
|
||||
if (jNode == null || jNode.isMissingNode()) {
|
||||
return null;
|
||||
}
|
||||
return jNode.asText();
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,9 +253,17 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
|
||||
connectOvsdb(node);
|
||||
return;
|
||||
}
|
||||
|
||||
process(new OpenstackNodeEvent(DEVICE_CREATED, node));
|
||||
|
||||
createTunnelInterface(node);
|
||||
if (node.dataIp().isPresent()) {
|
||||
createTunnelInterface(node);
|
||||
}
|
||||
|
||||
if (node.vlanPort().isPresent()) {
|
||||
addVlanPort(node);
|
||||
}
|
||||
|
||||
if (node.type().equals(NodeType.GATEWAY)) {
|
||||
createPatchInterface(node);
|
||||
addUplink(node);
|
||||
@ -294,7 +302,7 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
|
||||
log.warn("Failed to get node for {}", deviceId);
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(node.dataIp());
|
||||
return node.dataIp();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -348,7 +356,11 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
|
||||
return INIT;
|
||||
}
|
||||
|
||||
if (!isIfaceCreated(node.ovsdbId(), DEFAULT_TUNNEL)) {
|
||||
if (node.dataIp().isPresent() && !isIfaceCreated(node.ovsdbId(), DEFAULT_TUNNEL)) {
|
||||
return DEVICE_CREATED;
|
||||
}
|
||||
|
||||
if (node.vlanPort().isPresent() && !isIfaceCreated(node.ovsdbId(), node.vlanPort().get())) {
|
||||
return DEVICE_CREATED;
|
||||
}
|
||||
|
||||
@ -491,6 +503,22 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
|
||||
node.uplink().get());
|
||||
}
|
||||
|
||||
private void addVlanPort(OpenstackNode node) {
|
||||
if (isIfaceCreated(node.ovsdbId(), node.vlanPort().get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Device device = deviceService.getDevice(node.ovsdbId());
|
||||
if (device == null || !device.is(BridgeConfig.class)) {
|
||||
log.error("Failed to add port {} on {}", node.vlanPort().get(), node.ovsdbId());
|
||||
return;
|
||||
}
|
||||
|
||||
BridgeConfig bridgeConfig = device.as(BridgeConfig.class);
|
||||
bridgeConfig.addPort(BridgeName.bridgeName(INTEGRATION_BRIDGE),
|
||||
node.vlanPort().get());
|
||||
}
|
||||
|
||||
private boolean isOvsdbConnected(OpenstackNode node) {
|
||||
OvsdbNodeId ovsdb = new OvsdbNodeId(node.managementIp(), ovsdbPort);
|
||||
OvsdbClientService client = ovsdbController.getOvsdbClient(ovsdb);
|
||||
@ -504,7 +532,9 @@ public final class OpenstackNodeManager extends ListenerRegistry<OpenstackNodeEv
|
||||
}
|
||||
|
||||
private Set<String> systemIfaces(OpenstackNode node) {
|
||||
Set<String> ifaces = Sets.newHashSet(DEFAULT_TUNNEL);
|
||||
Set<String> ifaces = Sets.newHashSet();
|
||||
node.dataIp().ifPresent(ip -> ifaces.add(DEFAULT_TUNNEL));
|
||||
node.vlanPort().ifPresent(p -> ifaces.add(p));
|
||||
if (node.type().equals(NodeType.GATEWAY)) {
|
||||
ifaces.add(PATCH_INTG_BRIDGE);
|
||||
ifaces.add(PATCH_ROUT_BRIDGE);
|
||||
|
||||
@ -74,7 +74,8 @@ public class OpenstackNodeCheckCommand extends AbstractShellCommand {
|
||||
deviceService.isAvailable(device.id()),
|
||||
device.annotations());
|
||||
|
||||
print(getPortState(deviceService, node.intBridge(), DEFAULT_TUNNEL));
|
||||
node.dataIp().ifPresent(ip -> print(getPortState(deviceService, node.intBridge(), DEFAULT_TUNNEL)));
|
||||
node.vlanPort().ifPresent(p -> print(getPortState(deviceService, node.intBridge(), p)));
|
||||
} else {
|
||||
print("%s %s=%s is not available",
|
||||
MSG_NO,
|
||||
|
||||
@ -44,11 +44,13 @@ public class OpenstackNodeListCommand extends AbstractShellCommand {
|
||||
print("%s", json(nodes));
|
||||
} else {
|
||||
for (OpenstackNode node : nodes) {
|
||||
print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, intBridge=%s, routerBridge=%s init=%s",
|
||||
print("hostname=%s, type=%s, managementIp=%s, dataIp=%s, vlanPort=%s," +
|
||||
"intBridge=%s, routerBridge=%s init=%s",
|
||||
node.hostname(),
|
||||
node.type(),
|
||||
node.managementIp(),
|
||||
node.dataIp(),
|
||||
node.vlanPort(),
|
||||
node.intBridge(),
|
||||
node.routerBridge(),
|
||||
node.state());
|
||||
@ -66,6 +68,7 @@ public class OpenstackNodeListCommand extends AbstractShellCommand {
|
||||
.put("type", node.type().name())
|
||||
.put("managementIp", node.managementIp().toString())
|
||||
.put("dataIp", node.dataIp().toString())
|
||||
.put("vlanPort", node.vlanPort().toString())
|
||||
.put("intBridge", node.intBridge().toString())
|
||||
.put("routerBridge", node.routerBridge().toString())
|
||||
.put("state", node.state().name()));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user