From 917beb4b9d80434ce34bcdf879ec8552448efd37 Mon Sep 17 00:00:00 2001 From: daniel park Date: Thu, 16 Mar 2017 18:07:15 +0900 Subject: [PATCH] [ONOS-6150] OpenstackNode application support creation of vlan interface on open vswitch Change-Id: I4342a8bd5f8a0a802e05f6b89a7962e5d3c9c9af --- .../impl/OpenstackRoutingIcmpHandler.java | 2 +- apps/openstacknode/network-cfg.json | 74 ++++++++----------- .../openstacknode/OpenstackNode.java | 46 ++++++++++-- .../openstacknode/OpenstackNodeConfig.java | 28 +++++-- .../openstacknode/OpenstackNodeManager.java | 38 +++++++++- .../cli/OpenstackNodeCheckCommand.java | 3 +- .../cli/OpenstackNodeListCommand.java | 5 +- 7 files changed, 131 insertions(+), 65 deletions(-) diff --git a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java index 2cafcd686a..3f5adee9a8 100644 --- a/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java +++ b/apps/openstacknetworking/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackRoutingIcmpHandler.java @@ -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); diff --git a/apps/openstacknode/network-cfg.json b/apps/openstacknode/network-cfg.json index daecd85767..6cca7ed7eb 100644 --- a/apps/openstacknode/network-cfg.json +++ b/apps/openstacknode/network-cfg.json @@ -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" - } } } } diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNode.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNode.java index 2d73a85f71..0ff91a9925 100644 --- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNode.java +++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNode.java @@ -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 dataIp; private final DeviceId integrationBridge; private final Optional routerBridge; private final Optional uplink; // TODO remove this when we use single ONOS cluster for both openstackNode and vRouter private final Optional routerController; + private final Optional vlanPort; private final NodeState state; public static final Comparator OPENSTACK_NODE_COMPARATOR = @@ -53,11 +54,12 @@ public final class OpenstackNode { private OpenstackNode(String hostname, NodeType type, IpAddress managementIp, - IpAddress dataIp, + Optional dataIp, DeviceId integrationBridge, Optional routerBridge, Optional uplink, Optional routerController, + Optional 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 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 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 dataIp = Optional.empty(); private DeviceId integrationBridge; private Optional routerBridge = Optional.empty(); private Optional uplink = Optional.empty(); + private Optional vlanPort = Optional.empty(); // TODO remove this when we use single ONOS cluster for both openstackNode and vRouter private Optional 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. * diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeConfig.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeConfig.java index c20e678a32..0f264e95a4 100644 --- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeConfig.java +++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeConfig.java @@ -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 { 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 { } 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 { 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 { */ public Set openstackNodes() { Set 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 { } 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(); } } diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java index 09b4f5252f..5276c586f6 100644 --- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java +++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/OpenstackNodeManager.java @@ -253,9 +253,17 @@ public final class OpenstackNodeManager extends ListenerRegistry systemIfaces(OpenstackNode node) { - Set ifaces = Sets.newHashSet(DEFAULT_TUNNEL); + Set 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); diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java index 84803c14af..4d54abd8d8 100644 --- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java +++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeCheckCommand.java @@ -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, diff --git a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeListCommand.java b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeListCommand.java index 2649b05e44..a20d27837c 100644 --- a/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeListCommand.java +++ b/apps/openstacknode/src/main/java/org/onosproject/openstacknode/cli/OpenstackNodeListCommand.java @@ -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()));