Skip to content

Commit 71e8ec3

Browse files
committed
Merge branch 'asacamano-master'
2 parents c74aec0 + 397fff5 commit 71e8ec3

File tree

10 files changed

+158
-89
lines changed

10 files changed

+158
-89
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Features
4646
8. Basic Role based authentication.
4747
9. LDAP authentication supported.
4848
10. Root node /zookeeper hidden for safety.
49+
11. ACL supported global level.
4950

5051
Import File Format
5152
====================
@@ -123,7 +124,7 @@ keytool -keystore keystore -alias jetty -genkey -keyalg RSA
123124

124125
Limitations
125126
====================
126-
1. ACLs are not yet fully supported
127+
1. ACLs are fully supported but at a global level.
127128

128129
Screenshots
129130
====================

config.cfg

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ scmRepoPath=//appconfig.txt
99
#if set to true then userSet is used for authentication, else ldap authentication is used.
1010
ldapAuth=false
1111
ldapDomain=mycompany,mydomain
12-
userSet = {"users": [{ "username":"admin" , "password":"manager","role": "ADMIN" },{ "username":"appconfig" , "password":"appconfig","role": "USER" }]}
1312
#ldap authentication url. Ignore if using file based authentication.
1413
ldapUrl=ldap://<ldap_host>:<ldap_port>/dc=mycom,dc=com
1514
#Specific roles for ldap authenticated users. Ignore if using file based authentication.
1615
ldapRoleSet={"users": [{ "username":"domain\\user1" , "role": "ADMIN" }]}
16+
userSet = {"users": [{ "username":"admin" , "password":"manager","role": "ADMIN" },{ "username":"appconfig" , "password":"appconfig","role": "USER" }]}
1717
#Set to prod in production and dev in local. Setting to dev will clear history each time.
1818
env=prod
1919
jdbcClass=org.h2.Driver
@@ -34,4 +34,8 @@ blockPwdOverRest=false
3434
https=false
3535
keystoreFile=/home/user/keystore.jks
3636
keystorePwd=password
37-
keystoreManagerPwd=password
37+
keystoreManagerPwd=password
38+
# The default ACL to use for all creation of nodes. If left blank, then all nodes will be universally accessible
39+
# Permissions are based on single character flags: c (Create), r (read), w (write), d (delete), a (admin), * (all)
40+
# For example defaultAcl={"acls": [{"scheme":"ip", "id":"192.168.1.192", "perms":"*"}, {"scheme":"ip", id":"192.168.1.0/24", "perms":"r"}]
41+
defaultAcl=

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM java:8
22

3-
MAINTAINER Miguel Garcia Puyol <[email protected]
3+
MAINTAINER Miguel Garcia Puyol <[email protected]>
44

55
WORKDIR /var/app
66

src/main/java/com/deem/zkui/controller/Export.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,33 @@
3838
@SuppressWarnings("serial")
3939
@WebServlet(urlPatterns = {"/export"})
4040
public class Export extends HttpServlet {
41-
41+
4242
private final static Logger logger = LoggerFactory.getLogger(Export.class);
43-
43+
4444
@Override
4545
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
4646
logger.debug("Export Get Action!");
4747
try {
4848
Properties globalProps = (Properties) this.getServletContext().getAttribute("globalProps");
4949
String zkServer = globalProps.getProperty("zkServer");
5050
String[] zkServerLst = zkServer.split(",");
51-
51+
5252
String authRole = (String) request.getSession().getAttribute("authRole");
5353
if (authRole == null) {
5454
authRole = ZooKeeperUtil.ROLE_USER;
5555
}
5656
String zkPath = request.getParameter("zkPath");
5757
StringBuilder output = new StringBuilder();
5858
output.append("#App Config Dashboard (ACD) dump created on :").append(new Date()).append("\n");
59-
Set<LeafBean> leaves = ZooKeeperUtil.INSTANCE.exportTree(zkPath, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]), authRole);
59+
Set<LeafBean> leaves = ZooKeeperUtil.INSTANCE.exportTree(zkPath, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")), authRole);
6060
for (LeafBean leaf : leaves) {
6161
output.append(leaf.getPath()).append('=').append(leaf.getName()).append('=').append(ServletUtil.INSTANCE.externalizeNodeValue(leaf.getValue())).append('\n');
6262
}// for all leaves
6363
response.setContentType("text/plain");
6464
try (PrintWriter out = response.getWriter()) {
6565
out.write(output.toString());
6666
}
67-
67+
6868
} catch (InterruptedException | KeeperException ex) {
6969
logger.error(Arrays.toString(ex.getStackTrace()));
7070
ServletUtil.INSTANCE.renderError(request, response, ex.getMessage());

src/main/java/com/deem/zkui/controller/Home.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
5656
Map<String, Object> templateParam = new HashMap<>();
5757
String zkPath = request.getParameter("zkPath");
5858
String navigate = request.getParameter("navigate");
59-
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
59+
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl"));
6060
List<String> nodeLst;
6161
List<LeafBean> leafLst;
6262
String currentPath, parentPath, displayPath;
@@ -130,7 +130,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
130130
case "Save Node":
131131
if (!newNode.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
132132
//Save the new node.
133-
ZooKeeperUtil.INSTANCE.createFolder(currentPath + newNode, "foo", "bar", ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
133+
ZooKeeperUtil.INSTANCE.createFolder(currentPath + newNode, "foo", "bar", ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
134134
request.getSession().setAttribute("flashMsg", "Node created!");
135135
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Creating node: " + currentPath + newNode);
136136
}
@@ -139,7 +139,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
139139
case "Save Property":
140140
if (!newProperty.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
141141
//Save the new node.
142-
ZooKeeperUtil.INSTANCE.createNode(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
142+
ZooKeeperUtil.INSTANCE.createNode(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
143143
request.getSession().setAttribute("flashMsg", "Property Saved!");
144144
if (ZooKeeperUtil.INSTANCE.checkIfPwdField(newProperty)) {
145145
newValue = ZooKeeperUtil.INSTANCE.SOPA_PIPA;
@@ -151,7 +151,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
151151
case "Update Property":
152152
if (!newProperty.equals("") && !currentPath.equals("") && authRole.equals(ZooKeeperUtil.ROLE_ADMIN)) {
153153
//Save the new node.
154-
ZooKeeperUtil.INSTANCE.setPropertyValue(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
154+
ZooKeeperUtil.INSTANCE.setPropertyValue(currentPath, newProperty, newValue, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
155155
request.getSession().setAttribute("flashMsg", "Property Updated!");
156156
if (ZooKeeperUtil.INSTANCE.checkIfPwdField(newProperty)) {
157157
newValue = ZooKeeperUtil.INSTANCE.SOPA_PIPA;
@@ -161,7 +161,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
161161
response.sendRedirect("/home?zkPath=" + displayPath);
162162
break;
163163
case "Search":
164-
Set<LeafBean> searchResult = ZooKeeperUtil.INSTANCE.searchTree(searchStr, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]), authRole);
164+
Set<LeafBean> searchResult = ZooKeeperUtil.INSTANCE.searchTree(searchStr, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")), authRole);
165165
templateParam.put("searchResult", searchResult);
166166
ServletUtil.INSTANCE.renderHtml(request, response, templateParam, "search.ftl.html");
167167
break;
@@ -171,15 +171,15 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
171171
if (propChkGroup != null) {
172172
for (String prop : propChkGroup) {
173173
List delPropLst = Arrays.asList(prop);
174-
ZooKeeperUtil.INSTANCE.deleteLeaves(delPropLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
174+
ZooKeeperUtil.INSTANCE.deleteLeaves(delPropLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
175175
request.getSession().setAttribute("flashMsg", "Delete Completed!");
176176
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Deleting Property: " + delPropLst.toString());
177177
}
178178
}
179179
if (nodeChkGroup != null) {
180180
for (String node : nodeChkGroup) {
181181
List delNodeLst = Arrays.asList(node);
182-
ZooKeeperUtil.INSTANCE.deleteFolders(delNodeLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
182+
ZooKeeperUtil.INSTANCE.deleteFolders(delNodeLst, ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
183183
request.getSession().setAttribute("flashMsg", "Delete Completed!");
184184
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "Deleting Nodes: " + delNodeLst.toString());
185185
}

src/main/java/com/deem/zkui/controller/Import.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
136136
}
137137
br.close();
138138

139-
ZooKeeperUtil.INSTANCE.importData(importFile, Boolean.valueOf(scmOverwrite), ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]));
139+
ZooKeeperUtil.INSTANCE.importData(importFile, Boolean.valueOf(scmOverwrite), ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl")));
140140
for (String line : importFile) {
141141
if (line.startsWith("-")) {
142142
dao.insertHistory((String) request.getSession().getAttribute("authName"), request.getRemoteAddr(), "File: " + uploadFileName + ", Deleting Entry: " + line);

src/main/java/com/deem/zkui/controller/Logout.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
4343
Properties globalProps = (Properties) getServletContext().getAttribute("globalProps");
4444
String zkServer = globalProps.getProperty("zkServer");
4545
String[] zkServerLst = zkServer.split(",");
46-
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
46+
ZooKeeper zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0],globalProps.getProperty("defaultAcl"));
4747
request.getSession().invalidate();
4848
zk.close();
4949
response.sendRedirect("/login");

src/main/java/com/deem/zkui/controller/RestAccess.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
@SuppressWarnings("serial")
4040
@WebServlet(urlPatterns = {"/acd/appconfig"})
4141
public class RestAccess extends HttpServlet {
42-
42+
4343
private final static Logger logger = LoggerFactory.getLogger(RestAccess.class);
44-
44+
4545
@Override
4646
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
4747
logger.debug("Rest Action!");
@@ -61,11 +61,11 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
6161
String[] propNames = request.getParameterValues("propNames");
6262
String propValue = "";
6363
LeafBean propertyNode;
64-
64+
6565
if (hostName == null) {
6666
hostName = ServletUtil.INSTANCE.getRemoteAddr(request);
6767
}
68-
zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0]);
68+
zk = ServletUtil.INSTANCE.getZookeeper(request, response, zkServerLst[0], globalProps.getProperty("defaultAcl"));
6969
//get the path of the hosts entry.
7070
LeafBean hostsNode = null;
7171
//If app name is mentioned then lookup path is appended with it.
@@ -74,14 +74,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
7474
} else {
7575
hostsNode = ZooKeeperUtil.INSTANCE.getNodeValue(zk, ZooKeeperUtil.ZK_HOSTS, ZooKeeperUtil.ZK_HOSTS + "/" + hostName, hostName, accessRole);
7676
}
77-
77+
7878
String lookupPath = hostsNode.getStrValue();
7979
logger.trace("Root Path:" + lookupPath);
8080
String[] pathElements = lookupPath.split("/");
8181

8282
//Form all combinations of search path you want to look up the property in.
8383
List<String> searchPath = new ArrayList<>();
84-
84+
8585
StringBuilder pathSubSet = new StringBuilder();
8686
for (String pathElement : pathElements) {
8787
pathSubSet.append(pathElement);
@@ -100,9 +100,9 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
100100
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + clusterName + "/" + hostName, zk)) {
101101
searchPath.add(lookupPath + "/" + clusterName + "/" + hostName);
102102
}
103-
103+
104104
} else if (appName != null && clusterName == null) {
105-
105+
106106
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + hostName, zk)) {
107107
searchPath.add(lookupPath + "/" + hostName);
108108
}
@@ -112,7 +112,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
112112
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + appName + "/" + hostName, zk)) {
113113
searchPath.add(lookupPath + "/" + appName + "/" + hostName);
114114
}
115-
115+
116116
} else if (appName != null && clusterName != null) {
117117
//Order in which these paths are listed is important as the lookup happens in that order.
118118
//Precedence is give to cluster over app.
@@ -137,7 +137,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
137137
if (ZooKeeperUtil.INSTANCE.nodeExists(lookupPath + "/" + clusterName + "/" + appName + "/" + hostName, zk)) {
138138
searchPath.add(lookupPath + "/" + clusterName + "/" + appName + "/" + hostName);
139139
}
140-
140+
141141
}
142142

143143
//Search the property in all lookup paths.
@@ -153,14 +153,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
153153
if (propValue != null) {
154154
resultOut.append(propName).append("=").append(propValue).append("\n");
155155
}
156-
156+
157157
}
158-
158+
159159
response.setContentType("text/plain");
160160
try (PrintWriter out = response.getWriter()) {
161161
out.write(resultOut.toString());
162162
}
163-
163+
164164
} catch (KeeperException | InterruptedException ex) {
165165
logger.error(Arrays.toString(ex.getStackTrace()));
166166
ServletUtil.INSTANCE.renderError(request, response, ex.getMessage());
@@ -169,6 +169,6 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
169169
ServletUtil.INSTANCE.closeZookeeper(zk);
170170
}
171171
}
172-
172+
173173
}
174174
}

src/main/java/com/deem/zkui/utils/ServletUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ public void renderError(HttpServletRequest request, HttpServletResponse response
9191

9292
}
9393

94-
public ZooKeeper getZookeeper(HttpServletRequest request, HttpServletResponse response, String zkServer) {
94+
public ZooKeeper getZookeeper(HttpServletRequest request, HttpServletResponse response, String zkServer,String acl) {
9595
try {
9696

9797
HttpSession session = request.getSession();
9898
ZooKeeper zk = (ZooKeeper) session.getAttribute("zk");
9999
if (zk == null || zk.getState() != ZooKeeper.States.CONNECTED) {
100100
zk = ZooKeeperUtil.INSTANCE.createZKConnection(zkServer);
101+
ZooKeeperUtil.INSTANCE.setDefaultAcl(acl);
101102
if (zk.getState() != ZooKeeper.States.CONNECTED) {
102103
session.setAttribute("zk", null);
103104
} else {

0 commit comments

Comments
 (0)