Skip to content

Commit

Permalink
Merge branch 'asacamano-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gitorko committed Jul 3, 2015
2 parents c74aec0 + 397fff5 commit 71e8ec3
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 89 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Features
8. Basic Role based authentication.
9. LDAP authentication supported.
10. Root node /zookeeper hidden for safety.
11. ACL supported global level.

Import File Format
====================
Expand Down Expand Up @@ -123,7 +124,7 @@ keytool -keystore keystore -alias jetty -genkey -keyalg RSA

Limitations
====================
1. ACLs are not yet fully supported
1. ACLs are fully supported but at a global level.

Screenshots
====================
Expand Down
8 changes: 6 additions & 2 deletions config.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ scmRepoPath=//appconfig.txt
#if set to true then userSet is used for authentication, else ldap authentication is used.
ldapAuth=false
ldapDomain=mycompany,mydomain
userSet = {"users": [{ "username":"admin" , "password":"manager","role": "ADMIN" },{ "username":"appconfig" , "password":"appconfig","role": "USER" }]}
#ldap authentication url. Ignore if using file based authentication.
ldapUrl=ldap://<ldap_host>:<ldap_port>/dc=mycom,dc=com
#Specific roles for ldap authenticated users. Ignore if using file based authentication.
ldapRoleSet={"users": [{ "username":"domain\\user1" , "role": "ADMIN" }]}
userSet = {"users": [{ "username":"admin" , "password":"manager","role": "ADMIN" },{ "username":"appconfig" , "password":"appconfig","role": "USER" }]}
#Set to prod in production and dev in local. Setting to dev will clear history each time.
env=prod
jdbcClass=org.h2.Driver
Expand All @@ -34,4 +34,8 @@ blockPwdOverRest=false
https=false
keystoreFile=/home/user/keystore.jks
keystorePwd=password
keystoreManagerPwd=password
keystoreManagerPwd=password
# The default ACL to use for all creation of nodes. If left blank, then all nodes will be universally accessible
# Permissions are based on single character flags: c (Create), r (read), w (write), d (delete), a (admin), * (all)
# For example defaultAcl={"acls": [{"scheme":"ip", "id":"192.168.1.192", "perms":"*"}, {"scheme":"ip", id":"192.168.1.0/24", "perms":"r"}]
defaultAcl=
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM java:8

MAINTAINER Miguel Garcia Puyol <miguelpuyol@gmail.com
MAINTAINER Miguel Garcia Puyol <miguelpuyol@gmail.com>

WORKDIR /var/app

Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/deem/zkui/controller/Export.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,33 @@
@SuppressWarnings("serial")
@WebServlet(urlPatterns = {"/export"})
public class Export extends HttpServlet {

private final static Logger logger = LoggerFactory.getLogger(Export.class);

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.debug("Export Get Action!");
try {
Properties globalProps = (Properties) this.getServletContext().getAttribute("globalProps");
String zkServer = globalProps.getProperty("zkServer");
String[] zkServerLst = zkServer.split(",");

String authRole = (String) request.getSession().getAttribute("authRole");
if (authRole == null) {
authRole = ZooKeeperUtil.ROLE_USER;
}
String zkPath = request.getParameter("zkPath");
StringBuilder output = new StringBuilder();
output.append("#App Config Dashboard (ACD) dump created on :").append(new Date()).append("\n");
Set<LeafBean> leaves = ZooKeeperUtil.INSTANCE.exportTree(zkPath, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]), authRole);
Set<LeafBean> leaves = ZooKeeperUtil.INSTANCE.exportTree(zkPath, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")), authRole);
for (LeafBean leaf : leaves) {
output.append(leaf.getPath()).append('=').append(leaf.getName()).append('=').append(ServletUtil.INSTANCE.externalizeNodeValue(leaf.getValue())).append('\n');
}// for all leaves
response.setContentType("text/plain");
try (PrintWriter out = response.getWriter()) {
out.write(output.toString());
}

} catch (InterruptedException | KeeperException ex) {
logger.error(Arrays.toString(ex.getStackTrace()));
ServletUtil.INSTANCE.renderError(request, response, ex.getMessage());
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/deem/zkui/controller/Home.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
Map<String, Object> templateParam = new HashMap<>();
String zkPath = request.getParameter("zkPath");
String navigate = request.getParameter("navigate");
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl"));
List<String> nodeLst;
List<LeafBean> leafLst;
String currentPath, parentPath, displayPath;
Expand Down Expand Up @@ -130,7 +130,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
case "Save Node":
if (!newNode.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
//Save the new node.
ZooKeeperUtil.INSTANCE.createFolder(currentPath + newNode, "foo", "bar", ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.createFolder(currentPath + newNode, "foo", "bar", ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
request.getSession().setAttribute("flashMsg", "Node created!");
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Creating node: " + currentPath + newNode);
}
Expand All @@ -139,7 +139,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
case "Save Property":
if (!newProperty.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
//Save the new node.
ZooKeeperUtil.INSTANCE.createNode(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.createNode(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
request.getSession().setAttribute("flashMsg", "Property Saved!");
if (ZooKeeperUtil.INSTANCE.checkIfPwdField(newProperty)) {
newValue = ZooKeeperUtil.INSTANCE.SOPA_PIPA;
Expand All @@ -151,7 +151,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
case "Update Property":
if (!newProperty.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
//Save the new node.
ZooKeeperUtil.INSTANCE.setPropertyValue(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.setPropertyValue(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
request.getSession().setAttribute("flashMsg", "Property Updated!");
if (ZooKeeperUtil.INSTANCE.checkIfPwdField(newProperty)) {
newValue = ZooKeeperUtil.INSTANCE.SOPA_PIPA;
Expand All @@ -161,7 +161,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
response.sendRedirect("/home?zkPath=" + displayPath);
break;
case "Search":
Set<LeafBean> searchResult = ZooKeeperUtil.INSTANCE.searchTree(searchStr, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]), authRole);
Set<LeafBean> searchResult = ZooKeeperUtil.INSTANCE.searchTree(searchStr, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")), authRole);
templateParam.put("searchResult", searchResult);
ServletUtil.INSTANCE.renderHtml(request, response, templateParam, "search.ftl.html");
break;
Expand All @@ -171,15 +171,15 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
if (propChkGroup != null) {
for (String prop : propChkGroup) {
List delPropLst = Arrays.asList(prop);
ZooKeeperUtil.INSTANCE.deleteLeaves(delPropLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.deleteLeaves(delPropLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
request.getSession().setAttribute("flashMsg", "Delete Completed!");
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Deleting Property: " + delPropLst.toString());
}
}
if (nodeChkGroup != null) {
for (String node : nodeChkGroup) {
List delNodeLst = Arrays.asList(node);
ZooKeeperUtil.INSTANCE.deleteFolders(delNodeLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.deleteFolders(delNodeLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
request.getSession().setAttribute("flashMsg", "Delete Completed!");
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Deleting Nodes: " + delNodeLst.toString());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/deem/zkui/controller/Import.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
}
br.close();

ZooKeeperUtil.INSTANCE.importData(importFile, Boolean.valueOf(scmOverwrite), ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
ZooKeeperUtil.INSTANCE.importData(importFile, Boolean.valueOf(scmOverwrite), ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
for (String line : importFile) {
if (line.startsWith("-")) {
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "File: " + uploadFileName + ", Deleting Entry: " + line);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/deem/zkui/controller/Logout.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
Properties globalProps = (Properties) getServletContext().getAttribute("globalProps");
String zkServer = globalProps.getProperty("zkServer");
String[] zkServerLst = zkServer.split(",");
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0],globalProps.getProperty("defaultAcl"));
request.getSession().invalidate();
zk.close();
response.sendRedirect("/login");
Expand Down
28 changes: 14 additions & 14 deletions src/main/java/com/deem/zkui/controller/RestAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
@SuppressWarnings("serial")
@WebServlet(urlPatterns = {"/acd/appconfig"})
public class RestAccess extends HttpServlet {

private final static Logger logger = LoggerFactory.getLogger(RestAccess.class);

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.debug("Rest Action!");
Expand All @@ -61,11 +61,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
String[] propNames = request.getParameterValues("propNames");
String propValue = "";
LeafBean propertyNode;

if (hostName == null) {
hostName = ServletUtil.INSTANCE.getRemoteAddr(request);
}
zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl"));
//get the path of the hosts entry.
LeafBean hostsNode = null;
//If app name is mentioned then lookup path is appended with it.
Expand All @@ -74,14 +74,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
} else {
hostsNode = ZooKeeperUtil.INSTANCE.getNodeValue(zk, ZooKeeperUtil.ZK_HOSTS, ZooKeeperUtil.ZK_HOSTS + "/" + hostName, hostName, accessRole);
}

String lookupPath = hostsNode.getStrValue();
logger.trace("Root Path:" + lookupPath);
String[] pathElements = lookupPath.split("/");

//Form all combinations of search path you want to look up the property in.
List<String> searchPath = new ArrayList<>();

StringBuilder pathSubSet = new StringBuilder();
for (String pathElement : pathElements) {
pathSubSet.append(pathElement);
Expand All @@ -100,9 +100,9 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + clusterName + "/" + hostName, zk)) {
searchPath.add(lookupPath + "/" + clusterName + "/" + hostName);
}

} else if (appName != null && clusterName == null) {

if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + hostName, zk)) {
searchPath.add(lookupPath + "/" + hostName);
}
Expand All @@ -112,7 +112,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + appName + "/" + hostName, zk)) {
searchPath.add(lookupPath + "/" + appName + "/" + hostName);
}

} else if (appName != null && clusterName != null) {
//Order in which these paths are listed is important as the lookup happens in that order.
//Precedence is give to cluster over app.
Expand All @@ -137,7 +137,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + clusterName + "/" + appName + "/" + hostName, zk)) {
searchPath.add(lookupPath + "/" + clusterName + "/" + appName + "/" + hostName);
}

}

//Search the property in all lookup paths.
Expand All @@ -153,14 +153,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
if (propValue != null) {
resultOut.append(propName).append("=").append(propValue).append("\n");
}

}

response.setContentType("text/plain");
try (PrintWriter out = response.getWriter()) {
out.write(resultOut.toString());
}

} catch (KeeperException | InterruptedException ex) {
logger.error(Arrays.toString(ex.getStackTrace()));
ServletUtil.INSTANCE.renderError(request, response, ex.getMessage());
Expand All @@ -169,6 +169,6 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
ServletUtil.INSTANCE.closeZookeeper(zk);
}
}

}
}
3 changes: 2 additions & 1 deletion src/main/java/com/deem/zkui/utils/ServletUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,14 @@ public void renderError(HttpServletRequest request, HttpServletResponse response

}

public ZooKeeper getZookeeper(HttpServletRequest request, HttpServletResponse response, String zkServer) {
public ZooKeeper getZookeeper(HttpServletRequest request, HttpServletResponse response, String zkServer,String acl) {
try {

HttpSession session = request.getSession();
ZooKeeper zk = (ZooKeeper) session.getAttribute("zk");
if (zk == null || zk.getState() != ZooKeeper.States.CONNECTED) {
zk = ZooKeeperUtil.INSTANCE.createZKConnection(zkServer);
ZooKeeperUtil.INSTANCE.setDefaultAcl(acl);
if (zk.getState() != ZooKeeper.States.CONNECTED) {
session.setAttribute("zk", null);
} else {
Expand Down
Loading

0 comments on commit 71e8ec3

Please sign in to comment.