From 65c9b2ea72201b67ece5d6e5e210857d69df743c Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 13 Aug 2013 12:55:20 -0700 Subject: [PATCH] Log all configuration(add/modify/delete) changes to a new log file audit.log Change-Id: Icf16c88dbbd703dafe634f145f9e52f1e425f843 Signed-off-by: Sapan Shah --- .../main/resources/configuration/logback.xml | 22 +++++++++++++++---- .../commons/utils/NorthboundUtils.java | 22 +++++++++++++++++++ .../northbound/FlowProgrammerNorthbound.java | 4 ++++ .../northbound/HostTrackerNorthbound.java | 2 ++ .../northbound/StaticRoutingNorthbound.java | 5 +++-- .../northbound/SubnetsNorthboundJAXRS.java | 11 ++++++++++ .../northbound/SwitchNorthbound.java | 4 ++++ .../northbound/TopologyNorthboundJAXRS.java | 2 ++ .../controller/devices/web/Devices.java | 9 ++++++++ .../controller/flows/web/Flows.java | 8 +++++++ .../controller/web/DaylightWebAdmin.java | 20 ++++++++++++++--- .../controller/web/DaylightWebUtil.java | 22 +++++++++++++++++++ 12 files changed, 122 insertions(+), 9 deletions(-) diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml index 08dabdeedb..de0a3bcd19 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml @@ -1,4 +1,4 @@ - + @@ -13,18 +13,28 @@ 1 + + 10MB + + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n - + + logs/audit.log + true + + %date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n + + - + @@ -55,4 +65,8 @@ - + + + + + \ No newline at end of file diff --git a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/utils/NorthboundUtils.java b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/utils/NorthboundUtils.java index f98189319b..9f47e0c971 100644 --- a/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/utils/NorthboundUtils.java +++ b/opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/utils/NorthboundUtils.java @@ -13,6 +13,8 @@ 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.usermanager.IUserManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NorthboundUtils { @@ -37,6 +39,10 @@ public class NorthboundUtils { } }; + private static final String AUDIT = "audit"; + + private static final Logger logger = LoggerFactory.getLogger(AUDIT); + // Suppress default constructor for noninstantiability private NorthboundUtils() { } @@ -114,4 +120,20 @@ public class NorthboundUtils { return true; } + public static void auditlog(String moduleName, String user, String action, String resource, + String containerName) { + String auditMsg = ""; + String mode = "REST"; + if (containerName != null) { + auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource + " in container " + + containerName; + } else { + auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource; + } + logger.info(auditMsg); + } + + public static void auditlog(String moduleName, String user, String action, String resource) { + auditlog(moduleName, user, action, resource, null); + } } diff --git a/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java b/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java index d3cbc4acee..6bccc2d2e9 100644 --- a/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java +++ b/opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java @@ -322,7 +322,9 @@ public class FlowProgrammerNorthbound { } Status status = frm.addStaticFlow(flowConfig.getValue()); + if (status.isSuccess()) { + NorthboundUtils.auditlog("Flow", username, "added", name, containerName); return Response.status(Response.Status.CREATED).build(); } throw new InternalServerErrorException(status.getDescription()); @@ -385,6 +387,7 @@ public class FlowProgrammerNorthbound { Status status = frm.removeStaticFlow(name, node); if (status.isSuccess()) { + NorthboundUtils.auditlog("Flow", username, "removed", name, containerName); return Response.ok().build(); } throw new InternalServerErrorException(status.getDescription()); @@ -446,6 +449,7 @@ public class FlowProgrammerNorthbound { Status status = frm.toggleStaticFlowStatus(staticFlow); if (status.isSuccess()) { + NorthboundUtils.auditlog("Flow", username, "toggled", name, containerName); return Response.ok().build(); } throw new InternalServerErrorException(status.getDescription()); diff --git a/opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java b/opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java index 642c5ccbaa..285967522c 100644 --- a/opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java +++ b/opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java @@ -310,6 +310,7 @@ public class HostTrackerNorthbound { Status status = hostTracker.addStaticHost(networkAddress, dataLayerAddress, nc, vlan); if (status.isSuccess()) { + NorthboundUtils.auditlog("Static Host", username, "added", networkAddress, containerName); return Response.status(Response.Status.CREATED).build(); } else if (status.getCode().equals(StatusCode.BADREQUEST)) { throw new UnsupportedMediaTypeException(status.getDescription()); @@ -364,6 +365,7 @@ public class HostTrackerNorthbound { Status status = hostTracker.removeStaticHost(networkAddress); if (status.isSuccess()) { + NorthboundUtils.auditlog("Static Host", username, "removed", networkAddress, containerName); return Response.ok().build(); } throw new InternalServerErrorException(status.getDescription()); diff --git a/opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java b/opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java index b85f5641c7..3deb8dfa7b 100644 --- a/opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java +++ b/opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java @@ -58,8 +58,7 @@ import org.opendaylight.controller.sal.utils.Status; @Path("/") public class StaticRoutingNorthbound { - - private String username; + private String username; @Context public void setSecurityContext(SecurityContext context) { @@ -197,6 +196,7 @@ public class StaticRoutingNorthbound { sRoute.getPrefix(), sRoute.getNextHop()); Status response = staticRouting.addStaticRoute(cfgObject); if (response.isSuccess()) { + NorthboundUtils.auditlog("Static Route", username, "added", name, containerName); return Response.status(Response.Status.CREATED).build(); } throw new ResourceConflictException(response.getDescription()); @@ -241,6 +241,7 @@ public class StaticRoutingNorthbound { Status status = staticRouting.removeStaticRoute(name); if (status.isSuccess()) { + NorthboundUtils.auditlog("Static Route", username, "removed", name, containerName); return Response.ok().build(); } throw new ResourceNotFoundException(status.getDescription()); diff --git a/opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java b/opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java index 17780fc70d..8c555f2673 100644 --- a/opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java +++ b/opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java @@ -160,6 +160,7 @@ public class SubnetsNorthboundJAXRS { SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet, new HashSet(0)); Status status = switchManager.addSubnet(cfgObject); if (status.isSuccess()) { + NorthboundUtils.auditlog("Subnet Gateway", username, "added", subnetName, containerName); return Response.status(Response.Status.CREATED).build(); } throw new InternalServerErrorException(status.getDescription()); @@ -198,6 +199,7 @@ public class SubnetsNorthboundJAXRS { } Status status = switchManager.removeSubnet(subnetName); if (status.isSuccess()) { + NorthboundUtils.auditlog("Subnet Gateway", username, "removed", subnetName, containerName); return Response.status(Response.Status.OK).build(); } throw new InternalServerErrorException(status.getDescription()); @@ -274,6 +276,9 @@ public class SubnetsNorthboundJAXRS { for (String s : newPorts) { Status st = switchManager.addPortsToSubnet(name, s); successful = successful && st.isSuccess(); + if(successful){ + NorthboundUtils.auditlog("Subnet Gateway", username, "added", s +" to "+name, containerName); + } } } @@ -393,6 +398,9 @@ public class SubnetsNorthboundJAXRS { for (String port : ports) { st = switchManager.addPortsToSubnet(name, port); successful = successful && st.isSuccess(); + if(successful){ + NorthboundUtils.auditlog("Subnet Gateway", username, "added", st +" to "+name, containerName); + } } } else if (action.equals("delete")) { // delete existing ports @@ -400,6 +408,9 @@ public class SubnetsNorthboundJAXRS { for (String port : ports) { st = switchManager.removePortsFromSubnet(name, port); successful = successful && st.isSuccess(); + if(successful){ + NorthboundUtils.auditlog("Subnet Gateway", username, "removed", st +" from "+name, containerName); + } } } else { return Response.status(Response.Status.BAD_REQUEST).build(); diff --git a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java index d6d9be9e9f..e67d1b7568 100644 --- a/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java +++ b/opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java @@ -303,6 +303,9 @@ public class SwitchNorthbound { nodeProperties.remove(propertyName.toLowerCase()); SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties); status = switchManager.updateNodeConfig(newSwitchConfig); + if(status.isSuccess()){ + NorthboundUtils.auditlog("Static Route", username, "updated", nodeId, containerName); + } } } return NorthboundUtils.getResponse(status); @@ -519,6 +522,7 @@ public class SwitchNorthbound { .fromStringNoNode(nodeConnectorType, nodeConnectorId, node); Status ret = switchManager.removeNodeConnectorProp(nc, propertyName); if (ret.isSuccess()) { + NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName); return Response.ok().build(); } throw new ResourceNotFoundException(ret.getDescription()); diff --git a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java index 323e2d2211..fb4e8229ff 100644 --- a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java +++ b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java @@ -195,6 +195,7 @@ public class TopologyNorthboundJAXRS { Status status = topologyManager.addUserLink(userLinkConfig.getValue()); if (status.isSuccess()) { + NorthboundUtils.auditlog("User Link", username, "added", userLinkConfig.getValue().getName(), containerName); return Response.status(Response.Status.CREATED).build(); } throw new InternalServerErrorException(status.getDescription()); @@ -236,6 +237,7 @@ public class TopologyNorthboundJAXRS { Status ret = topologyManager.deleteUserLink(name); if (ret.isSuccess()) { + NorthboundUtils.auditlog("User Link", username, "removed", name, containerName); return Response.ok().build(); } throw new ResourceNotFoundException(ret.getDescription()); diff --git a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java index f92e92ec17..15ad9e9887 100644 --- a/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java +++ b/opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java @@ -256,6 +256,7 @@ public class Devices implements IDaylightWeb { } else { resultBean.setStatus(true); resultBean.setMessage("Updated node information successfully"); + DaylightWebUtil.auditlog("Node", userName, "updated", nodeId + " to "+ nodeName, containerName); } } catch (Exception e) { resultBean.setStatus(false); @@ -338,6 +339,7 @@ public class Devices implements IDaylightWeb { if (addStaticRouteResult.isSuccess()) { result.setStatus(true); result.setMessage("Static Route saved successfully"); + DaylightWebUtil.auditlog("Static Route", userName, "added", routeName, containerName); } else { result.setStatus(false); result.setMessage(addStaticRouteResult.getDescription()); @@ -381,6 +383,7 @@ public class Devices implements IDaylightWeb { resultBean.setMessage(result.getDescription()); break; } + DaylightWebUtil.auditlog("Static Route", userName, "removed", route, containerName); } } catch (Exception e) { resultBean.setStatus(false); @@ -451,6 +454,7 @@ public class Devices implements IDaylightWeb { if (result.isSuccess()) { resultBean.setStatus(true); resultBean.setMessage("Added gateway address successfully"); + DaylightWebUtil.auditlog("Subnet Gateway", userName, "added", gatewayName, containerName); } else { resultBean.setStatus(false); resultBean.setMessage(result.getDescription()); @@ -491,6 +495,7 @@ public class Devices implements IDaylightWeb { resultBean.setMessage(result.getDescription()); break; } + DaylightWebUtil.auditlog("Subnet Gateway", userName, "removed", subnet, containerName); } } catch (Exception e) { resultBean.setStatus(false); @@ -526,6 +531,7 @@ public class Devices implements IDaylightWeb { resultBean.setStatus(true); resultBean .setMessage("Added ports to subnet gateway address successfully"); + DaylightWebUtil.auditlog("Ports to Subnet Gateway", userName, "added",nodeId+"/"+ ports, containerName); } else { resultBean.setStatus(false); resultBean.setMessage(result.getDescription()); @@ -564,6 +570,7 @@ public class Devices implements IDaylightWeb { resultBean.setStatus(true); resultBean .setMessage("Deleted port from subnet gateway address successfully"); + DaylightWebUtil.auditlog("Ports from Subnet Gateway", userName, "removed", nodePort, containerName); } else { resultBean.setStatus(false); resultBean.setMessage(result.getDescription()); @@ -695,6 +702,7 @@ public class Devices implements IDaylightWeb { if (result.isSuccess()) { resultBean.setStatus(true); resultBean.setMessage("SPAN Port added successfully"); + DaylightWebUtil.auditlog("SPAN Port", userName, "added", cfgObject.getNodeId(), containerName); } else { resultBean.setStatus(false); resultBean.setMessage(result.getDescription()); @@ -740,6 +748,7 @@ public class Devices implements IDaylightWeb { resultBean.setMessage(result.getDescription()); break; } + DaylightWebUtil.auditlog("SPAN Port", userName, "removed", cfgObject.getNodeId(), containerName); } } } catch (Exception e) { diff --git a/opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java b/opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java index 4396c957bf..9444360eec 100644 --- a/opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java +++ b/opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java @@ -47,6 +47,7 @@ import com.google.gson.Gson; 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; @@ -237,6 +238,7 @@ public class Flows implements IDaylightWeb { Status result = new Status(StatusCode.BADREQUEST, "Invalid request"); if (action.equals("add")) { result = frm.addStaticFlow(flow); + DaylightWebUtil.auditlog("Flow", userName, "added", flow.getName(), containerName); } return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result @@ -270,8 +272,14 @@ public class Flows implements IDaylightWeb { } if (action.equals("remove")) { result = frm.removeStaticFlow(name, node); + if(result.isSuccess()) { + DaylightWebUtil.auditlog("Flow", userName, "removed", name, containerName); + } } else if (action.equals("toggle")) { result = frm.toggleStaticFlowStatus(name, node); + if(result.isSuccess()) { + DaylightWebUtil.auditlog("Flow", userName, "toggled", name, containerName); + } } else { result = new Status(StatusCode.BADREQUEST, "Unknown action"); } diff --git a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java index ba2075ddb6..524cb62b3a 100644 --- a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java +++ b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java @@ -30,6 +30,9 @@ import com.google.gson.Gson; @Controller @RequestMapping("/admin") public class DaylightWebAdmin { + + + @RequestMapping("/users") @ResponseBody public List getUsers() { @@ -69,7 +72,11 @@ public class DaylightWebAdmin { Status result = (action.equals("add")) ? userManager .addLocalUser(config) : userManager.removeLocalUser(config); - + if(result.getCode().equals(StatusCode.SUCCESS)) { + String userAction=(action.equals("add")) ? "added":"removed"; + DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), userAction, config.getUser()); + return "Success"; + } return result.getDescription(); } @@ -93,7 +100,12 @@ public class DaylightWebAdmin { return "Operation not permitted"; } - return userManager.removeLocalUser(userName).getDescription(); + Status result = userManager.removeLocalUser(userName); + if(result.getCode().equals(StatusCode.SUCCESS)) { + DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "removed", userName); + return "Success"; + } + return result.getDescription(); } @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST) @@ -115,7 +127,9 @@ public class DaylightWebAdmin { } Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword); - + if(status.isSuccess()){ + DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username); + } return status; } diff --git a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java index ab2abe9c9e..3add0e6a40 100644 --- a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java +++ b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java @@ -5,9 +5,14 @@ import org.opendaylight.controller.sal.authorization.Privilege; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.usermanager.IUserManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DaylightWebUtil { + private static final String AUDIT = "audit"; + private static final Logger logger = LoggerFactory.getLogger(AUDIT); + /** * Returns the access privilege the user has on the specified container * @@ -52,4 +57,21 @@ public class DaylightWebUtil { return Privilege.NONE; } + + public static void auditlog(String moduleName, String user, String action, String resource, + String containerName) { + String auditMsg = ""; + String mode = "WEB"; + if (containerName != null) { + auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource + " in container " + + containerName; + } else { + auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource; + } + logger.info(auditMsg); + } + + public static void auditlog(String moduleName, String user, String action, String resource) { + auditlog(moduleName, user, action, resource, null); + } } \ No newline at end of file -- 2.36.6