Add REST interface for synchronizing openstack states and rules
Change-Id: I42cd8c73130348b204ea7c98c98d5b16cca6c4e8
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java
index f21b79b..37360b1 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncStateCommand.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.openstacknetworking.cli;
-import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Strings;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
@@ -31,18 +30,15 @@
import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
import org.openstack4j.model.network.Router;
-import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.model.network.Subnet;
-import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
-import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.addRouterIface;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
-import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
/**
* Synchronizes OpenStack network states.
@@ -155,28 +151,6 @@
});
}
- // TODO fix the logic to add router interface to router
- private void addRouterIface(Port osPort, OpenstackRouterAdminService adminService) {
- osPort.getFixedIps().forEach(p -> {
- JsonNode jsonTree = mapper().createObjectNode()
- .put("id", osPort.getDeviceId())
- .put("tenant_id", osPort.getTenantId())
- .put("subnet_id", p.getSubnetId())
- .put("port_id", osPort.getId());
- try {
- RouterInterface rIface = getContext(NeutronRouterInterface.class)
- .readerFor(NeutronRouterInterface.class)
- .readValue(jsonTree);
- if (adminService.routerInterface(rIface.getPortId()) != null) {
- adminService.updateRouterInterface(rIface);
- } else {
- adminService.addRouterInterface(rIface);
- }
- } catch (IOException ignore) {
- }
- });
- }
-
private void printNetwork(Network osNet) {
final String strNet = String.format(NETWORK_FORMAT,
osNet.getId(),
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index 6a42902..2ebf9db 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -20,6 +20,7 @@
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
import org.onosproject.openstacknode.api.OpenstackAuth;
import org.onosproject.openstacknode.api.OpenstackAuth.Perspective;
import org.onosproject.openstacknode.api.OpenstackNode;
@@ -32,7 +33,9 @@
import org.openstack4j.model.ModelEntity;
import org.openstack4j.model.common.Identifier;
import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.RouterInterface;
import org.openstack4j.openstack.OSFactory;
+import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,6 +44,7 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import java.io.IOException;
import java.io.InputStream;
import java.security.cert.X509Certificate;
import java.util.HashMap;
@@ -53,6 +57,7 @@
import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
import static org.onosproject.openstacknetworking.api.Constants.PCI_VENDOR_INFO;
import static org.onosproject.openstacknetworking.api.Constants.portNamePrefixMap;
+import static org.openstack4j.core.transport.ObjectMapperSingleton.getContext;
/**
* An utility that used in openstack networking app.
@@ -259,6 +264,34 @@
}
/**
+ * Adds router interfaces to openstack admin service.
+ * TODO fix the logic to add router interface to router
+ *
+ * @param osPort port
+ * @param adminService openstack admin service
+ */
+ public static void addRouterIface(Port osPort, OpenstackRouterAdminService adminService) {
+ osPort.getFixedIps().forEach(p -> {
+ JsonNode jsonTree = new ObjectMapper().createObjectNode()
+ .put("id", osPort.getDeviceId())
+ .put("tenant_id", osPort.getTenantId())
+ .put("subnet_id", p.getSubnetId())
+ .put("port_id", osPort.getId());
+ try {
+ RouterInterface rIface = getContext(NeutronRouterInterface.class)
+ .readerFor(NeutronRouterInterface.class)
+ .readValue(jsonTree);
+ if (adminService.routerInterface(rIface.getPortId()) != null) {
+ adminService.updateRouterInterface(rIface);
+ } else {
+ adminService.addRouterInterface(rIface);
+ }
+ } catch (IOException ignore) {
+ }
+ });
+ }
+
+ /**
* Builds up and a complete endpoint URL from gateway node.
*
* @param node gateway node
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java
new file mode 100644
index 0000000..e991008
--- /dev/null
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.openstacknetworking.web;
+
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.openstacknetworking.api.Constants;
+import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
+import org.onosproject.openstacknetworking.api.OpenstackSecurityGroupAdminService;
+import org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil;
+import org.onosproject.openstacknode.api.NodeState;
+import org.onosproject.openstacknode.api.OpenstackNode;
+import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
+import org.onosproject.openstacknode.api.OpenstackNodeService;
+import org.onosproject.rest.AbstractWebResource;
+import org.openstack4j.api.OSClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Objects;
+import java.util.Optional;
+
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.addRouterIface;
+import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
+
+/**
+ * REST interface for synchronizing openstack network states and rules.
+ */
+@Path("management")
+public class OpenstackManagementWebResource extends AbstractWebResource {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private static final String DEVICE_OWNER_IFACE = "network:router_interface";
+
+ private final OpenstackSecurityGroupAdminService osSgAdminService =
+ get(OpenstackSecurityGroupAdminService.class);
+ private final OpenstackNetworkAdminService osNetAdminService =
+ get(OpenstackNetworkAdminService.class);
+ private final OpenstackRouterAdminService osRouterAdminService =
+ get(OpenstackRouterAdminService.class);
+ private final OpenstackNodeService osNodeService =
+ get(OpenstackNodeService.class);
+ private final OpenstackNodeAdminService osNodeAdminService =
+ get(OpenstackNodeAdminService.class);
+ private final FlowRuleService flowRuleService = get(FlowRuleService.class);
+ private final CoreService coreService = get(CoreService.class);
+
+ /**
+ * Synchronizes the network states with openstack.
+ *
+ * @return 200 OK with sync result, 404 not found
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("sync/states")
+ public Response syncStates() {
+
+ Optional<OpenstackNode> node = osNodeService.nodes(CONTROLLER).stream().findFirst();
+ if (!node.isPresent()) {
+ throw new ItemNotFoundException("Auth info is not found");
+ }
+
+ OSClient osClient = OpenstackNetworkingUtil.getConnectedClient(node.get());
+
+ if (osClient == null) {
+ throw new ItemNotFoundException("Auth info is not correct");
+ }
+
+ osClient.networking().securitygroup().list().forEach(osSg -> {
+ if (osSgAdminService.securityGroup(osSg.getId()) != null) {
+ osSgAdminService.updateSecurityGroup(osSg);
+ } else {
+ osSgAdminService.createSecurityGroup(osSg);
+ }
+ });
+
+ osClient.networking().network().list().forEach(osNet -> {
+ if (osNetAdminService.network(osNet.getId()) != null) {
+ osNetAdminService.updateNetwork(osNet);
+ } else {
+ osNetAdminService.createNetwork(osNet);
+ }
+ });
+
+ osClient.networking().subnet().list().forEach(osSubnet -> {
+ if (osNetAdminService.subnet(osSubnet.getId()) != null) {
+ osNetAdminService.updateSubnet(osSubnet);
+ } else {
+ osNetAdminService.createSubnet(osSubnet);
+ }
+ });
+
+ osClient.networking().port().list().forEach(osPort -> {
+ if (osNetAdminService.port(osPort.getId()) != null) {
+ osNetAdminService.updatePort(osPort);
+ } else {
+ osNetAdminService.createPort(osPort);
+ }
+ });
+
+ osClient.networking().router().list().forEach(osRouter -> {
+ if (osRouterAdminService.router(osRouter.getId()) != null) {
+ osRouterAdminService.updateRouter(osRouter);
+ } else {
+ osRouterAdminService.createRouter(osRouter);
+ }
+
+ osNetAdminService.ports().stream()
+ .filter(osPort -> Objects.equals(osPort.getDeviceId(), osRouter.getId()) &&
+ Objects.equals(osPort.getDeviceOwner(), DEVICE_OWNER_IFACE))
+ .forEach(osPort -> addRouterIface(osPort, osRouterAdminService));
+ });
+
+ osClient.networking().floatingip().list().forEach(osFloating -> {
+ if (osRouterAdminService.floatingIp(osFloating.getId()) != null) {
+ osRouterAdminService.updateFloatingIp(osFloating);
+ } else {
+ osRouterAdminService.createFloatingIp(osFloating);
+ }
+ });
+
+ return ok(mapper().createObjectNode()).build();
+ }
+
+ /**
+ * Synchronizes the flow rules.
+ *
+ * @return 200 OK with sync result, 404 not found
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("sync/rules")
+ public Response syncRules() {
+
+ osNodeService.completeNodes().forEach(osNode -> {
+ OpenstackNode updated = osNode.updateState(NodeState.INIT);
+ osNodeAdminService.updateNode(updated);
+ });
+
+ return ok(mapper().createObjectNode()).build();
+ }
+
+ /**
+ * Purges the network states.
+ *
+ * @return 200 OK with purge result, 404 not found
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("purge/states")
+ public Response purgeStates() {
+
+ osRouterAdminService.clear();
+ osNetAdminService.clear();
+ osSgAdminService.clear();
+
+ return ok(mapper().createObjectNode()).build();
+ }
+
+ /**
+ * Purges the flow rules installed by openstacknetworking.
+ *
+ * @return 200 OK with purge result, 404 not found
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("purge/rules")
+ public Response purgeRules() {
+
+ ApplicationId appId = coreService.getAppId(Constants.OPENSTACK_NETWORKING_APP_ID);
+ if (appId == null) {
+ throw new ItemNotFoundException("application not found");
+ }
+ flowRuleService.removeFlowRulesById(appId);
+
+ return ok(mapper().createObjectNode()).build();
+ }
+}
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackNetworkingWebApplication.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackNetworkingWebApplication.java
index 8f9e623..f215efe 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackNetworkingWebApplication.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackNetworkingWebApplication.java
@@ -32,7 +32,8 @@
OpenstackRouterWebResource.class,
OpenstackSecurityGroupRuleWebResource.class,
OpenstackSecurityGroupWebResource.class,
- OpenstackSubnetWebResource.class
+ OpenstackSubnetWebResource.class,
+ OpenstackManagementWebResource.class
);
}
}