Delete Multiple flows in a single click
[controller.git] / opendaylight / web / flows / src / main / java / org / opendaylight / controller / flows / web / Flows.java
index 297c99c0b282e02a726f0d3a532b3e70735f116a..a96d3efcec698d80a243969fd2c1c3df9ee1e2cf 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -9,27 +8,32 @@
 
 package org.opendaylight.controller.flows.web;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import javax.servlet.http.HttpServletRequest;
+
 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.sal.core.Description;
 import org.opendaylight.controller.sal.core.Name;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Switch;
 import org.opendaylight.controller.switchmanager.SwitchConfig;
-import org.opendaylight.controller.usermanager.IUserManager;
-import org.opendaylight.controller.web.IOneWeb;
-import org.springframework.security.core.context.SecurityContextHolder;
+import org.opendaylight.controller.web.DaylightWebUtil;
+import org.opendaylight.controller.web.IDaylightWeb;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -41,14 +45,15 @@ import com.google.gson.Gson;
 
 @Controller
 @RequestMapping("/")
-public class Flows implements IOneWeb {
-       private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
-    private final String WEB_NAME = "Flows";
-    private final String WEB_ID = "flows";
-    private final short WEB_ORDER = 2;
+public class Flows implements IDaylightWeb {
+    private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
+    private static final String WEB_NAME = "Flows";
+
+    private static final String WEB_ID = "flows";
+    private static final short WEB_ORDER = 2;
 
     public Flows() {
-        ServiceHelper.registerGlobalService(IOneWeb.class, this, null);
+        ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
     }
 
     @Override
@@ -66,53 +71,78 @@ public class Flows implements IOneWeb {
         return WEB_ORDER;
     }
 
-       @Override
-       public boolean isAuthorized(UserLevel userLevel) {
-               return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
-       }
-       
+    @Override
+    public boolean isAuthorized(UserLevel userLevel) {
+        return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
+    }
+
     @RequestMapping(value = "/main")
     @ResponseBody
-    public Set<Map<String, Object>> getFlows() {
+    public Map<String, Object> getFlows(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName,
+                containerName, this);
+        if (privilege == Privilege.NONE) {
+            return null;
+        }
+
         // fetch frm
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
-                .getInstance(IForwardingRulesManager.class, "default", this);
-        if (frm == null)
+                .getInstance(IForwardingRulesManager.class, containerName, this);
+        if (frm == null) {
             return null;
+        }
 
         // fetch sm
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null)
+                .getInstance(ISwitchManager.class, containerName, this);
+        if (switchManager == null) {
             return null;
-        
+        }
+
         // get static flow list
         List<FlowConfig> staticFlowList = frm.getStaticFlows();
-        Set<Map<String, Object>> output = new HashSet<Map<String, Object>>();
+        Set<Map<String, Object>> flowSet = new HashSet<Map<String, Object>>();
         for (FlowConfig flowConfig : staticFlowList) {
-               Map<String, Object> entry = new HashMap<String, Object>();
-               entry.put("flow", flowConfig);
-               entry.put("name", flowConfig.getName());
-               
-               Node node = flowConfig.getNode(); 
-               SwitchConfig switchConfig = switchManager.getSwitchConfig(node.getNodeIDString());
-               String nodeName = node.toString();
-               if (switchConfig != null) { nodeName = switchConfig.getNodeName(); }
-               entry.put("node", nodeName);
-               entry.put("nodeId", node.toString());
-               output.add(entry);
-        }
-        
+            Map<String, Object> entry = new HashMap<String, Object>();
+            entry.put("flow", flowConfig);
+            entry.put("name", flowConfig.getName());
+            Node node = flowConfig.getNode();
+            entry.put("node", getNodeDesc(node, switchManager));
+            entry.put("nodeId", node.toString());
+            flowSet.add(entry);
+        }
+
+        Map<String, Object> output = new HashMap<String, Object>(2);
+        output.put("flows", flowSet);
+        output.put("privilege", privilege);
         return output;
     }
 
     @RequestMapping(value = "/node-ports")
     @ResponseBody
-    public Map<String, Object> getNodePorts() {
+    public Map<String, Object> getNodePorts(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
+
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null)
+                .getInstance(ISwitchManager.class, containerName, this);
+        if (switchManager == null) {
             return null;
+        }
 
         Map<String, Object> nodes = new HashMap<String, Object>();
         Map<Short, String> port;
@@ -121,59 +151,73 @@ public class Flows implements IOneWeb {
             port = new HashMap<Short, String>(); // new port
             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
 
-            if (nodeConnectorSet != null)
+            if (nodeConnectorSet != null) {
                 for (NodeConnector nodeConnector : nodeConnectorSet) {
                     String nodeConnectorName = ((Name) switchManager
                             .getNodeConnectorProp(nodeConnector,
                                     Name.NamePropName)).getValue();
-                    port.put((Short) nodeConnector.getID(),
-                             nodeConnectorName + "("
-                             + nodeConnector.getNodeConnectorIDString() + ")");
+                    port.put((Short) nodeConnector.getID(), nodeConnectorName
+                            + "(" + nodeConnector.getNodeConnectorIDString()
+                            + ")");
                 }
-            
+            }
+
             // add ports
             Map<String, Object> entry = new HashMap<String, Object>();
             entry.put("ports", port);
-            
+
             // add name
-            String nodeName = node.getNode().toString();
-            SwitchConfig config = switchManager.getSwitchConfig(node.getNode().getNodeIDString());
-            if (config != null) {
-               nodeName = config.getNodeName();
-            }
-            entry.put("name", nodeName);
-            
+            entry.put("name", getNodeDesc(node.getNode(), switchManager));
+
             // add to the node
             nodes.put(node.getNode().toString(), entry);
         }
 
         return nodes;
     }
-    
+
     @RequestMapping(value = "/node-flows")
     @ResponseBody
-    public Map<String, Object> getNodeFlows() {
+    public Map<String, Object> getNodeFlows(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
+
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null) { return null; }
+                .getInstance(ISwitchManager.class, containerName, this);
+        if (switchManager == null) {
+            return null;
+        }
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
-                .getInstance(IForwardingRulesManager.class, "default", this);
-        if (frm == null) { return null; }
+                .getInstance(IForwardingRulesManager.class, containerName, this);
+        if (frm == null) {
+            return null;
+        }
 
         Map<String, Object> nodes = new HashMap<String, Object>();
 
         for (Switch sw : switchManager.getNetworkDevices()) {
             Node node = sw.getNode();
-            
+
             List<FlowConfig> flows = frm.getStaticFlows(node);
-            
-            String nodeName = node.toString();
-            SwitchConfig config = switchManager.getSwitchConfig(node.getNodeIDString());
-            if (config != null) {
-               nodeName = config.getNodeName();
+
+            String nodeDesc = node.toString();
+            SwitchConfig config = switchManager
+                    .getSwitchConfig(node.toString());
+            if ((config != null)
+                    && (config.getProperty(Description.propertyName) != null)) {
+                nodeDesc = ((Description) config
+                        .getProperty(Description.propertyName)).getValue();
             }
-            
-            nodes.put(nodeName, flows.size());
+
+            nodes.put(nodeDesc, flows.size());
         }
 
         return nodes;
@@ -182,72 +226,141 @@ public class Flows implements IOneWeb {
     @RequestMapping(value = "/flow", method = RequestMethod.POST)
     @ResponseBody
     public String actionFlow(@RequestParam(required = true) String action,
-            @RequestParam(required = false) String body, @RequestParam(required = true) String nodeId) {
-       if (!authorize(UserLevel.NETWORKADMIN)) {
-               return "Operation not authorized";
-       }
-       
+            @RequestParam(required = false) String body,
+            @RequestParam(required = true) String nodeId,
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
+            return "Operation not authorized";
+        }
+
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
-                .getInstance(IForwardingRulesManager.class, "default", this);
-        if (frm == null) { return null; }
+                .getInstance(IForwardingRulesManager.class, containerName, this);
+        if (frm == null) {
+            return null;
+        }
 
         Gson gson = new Gson();
         FlowConfig flow = gson.fromJson(body, FlowConfig.class);
         Node node = Node.fromString(nodeId);
         flow.setNode(node);
-        Status result = null;
+        Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
         if (action.equals("add")) {
-            result = frm.addStaticFlow(flow, false);
+            result = frm.addStaticFlow(flow);
+            DaylightWebUtil.auditlog("Flow", userName, "added", flow.getName(),
+                    containerName);
         }
 
-        return result.getDescription();
+        return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
+                .getDescription();
     }
-    
-    @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
+
+    @RequestMapping(value = "/flow/{nodeId}/{name:.*}", method = RequestMethod.POST)
     @ResponseBody
-    public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
-               @RequestParam(required = true) String action) {
-       if (!authorize(UserLevel.NETWORKADMIN)) { return "Operation not authorized"; }
-       
-       IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
-                .getInstance(IForwardingRulesManager.class, "default", this);
-        if (frm == null) { return null; }
-        
+    public String removeFlow(@PathVariable("nodeId") String nodeId,
+            @PathVariable("name") String name,
+            @RequestParam(required = true) String action,
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
+            return "Operation not authorized";
+        }
+
+        IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
+                .getInstance(IForwardingRulesManager.class, containerName, this);
+        if (frm == null) {
+            return null;
+        }
+
         Status result = null;
         Node node = Node.fromString(nodeId);
         if (node == null) {
             return null;
         }
         if (action.equals("remove")) {
-               result = frm.removeStaticFlow(name, node);
+            result = frm.removeStaticFlow(name, node);
+            if (result.isSuccess()) {
+                DaylightWebUtil.auditlog("Flow", userName, "removed", name,
+                        containerName);
+            }
         } else if (action.equals("toggle")) {
-               FlowConfig config = frm.getStaticFlow(name, node);
-               result = frm.toggleStaticFlowStatus(config);
+            result = frm.toggleStaticFlowStatus(name, node);
+            if (result.isSuccess()) {
+                DaylightWebUtil.auditlog("Flow", userName, "toggled", name,
+                        containerName);
+            }
         } else {
-               result = new Status(StatusCode.BADREQUEST, "Unknown action");
+            result = new Status(StatusCode.BADREQUEST, "Unknown action");
         }
-        
-        return result.getDescription();
+
+        return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
+                .getDescription();
     }
-    
-    /**
-     * Is the operation permitted for the given level
-     * 
-     * @param level
-     */
-    private boolean authorize(UserLevel level) {
-       IUserManager userManager = (IUserManager) ServiceHelper
-                .getGlobalInstance(IUserManager.class, this);
-        if (userManager == null) {
-               return false;
-        }
-        
-        String username = SecurityContextHolder.getContext().getAuthentication().getName();
-        UserLevel userLevel = userManager.getUserLevel(username);
-        if (userLevel.toNumber() <= level.toNumber()) {
-               return true;
-        }
-        return false;
+
+    @SuppressWarnings("unchecked")
+    @RequestMapping(value = "/flow/deleteFlows", method = RequestMethod.POST)
+    @ResponseBody
+    public String removeSelectedFlows(
+            @RequestParam(required = false) String body,
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
+            return "Operation not authorized";
+        }
+
+        IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
+                .getInstance(IForwardingRulesManager.class, containerName, this);
+        if (frm == null) {
+            return "Forwarding Rules Manager is not available";
+        }
+
+        Gson gson = new Gson();
+        List<Map<String, String>> flowList = new ArrayList<Map<String, String>>();
+        flowList = gson.fromJson(body, flowList.getClass());
+        Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
+        String status = "";
+        for (Map<String, String> flowEntry : flowList) {
+            Node node = Node.fromString(flowEntry.get("node"));
+            result = frm.removeStaticFlow(flowEntry.get("name"), node);
+            if (result.isSuccess()) {
+                DaylightWebUtil.auditlog("Flow", userName, "removed",
+                        flowEntry.get("name"), containerName);
+            } else {
+                status = flowEntry.get("name") + ", " + status;
+            }
+        }
+        if (!status.equals("")) {
+            return "Could not remove "
+                    + status.substring(0, status.length() - 2) + " Flow(s)";
+        } else {
+            return "Success";
+        }
+    }
+
+    private String getNodeDesc(Node node, ISwitchManager switchManager) {
+        Description desc = (Description) switchManager.getNodeProp(node,
+                Description.propertyName);
+        String description = (desc == null) ? "" : desc.getValue();
+        return (description.isEmpty() || description.equalsIgnoreCase("none")) ? node
+                .toString() : description;
     }
 
 }