azkaban-memoizeit
Changes
build.xml 10(+8 -2)
src/java/azkaban/execapp/FlowRunner.java 68(+55 -13)
src/java/azkaban/execapp/JobRunner.java 12(+12 -0)
src/java/azkaban/project/Project.java 56(+23 -33)
src/java/azkaban/project/ProjectManager.java 18(+17 -1)
src/java/azkaban/user/XmlUserManager.java 21(+10 -11)
src/sql/update_2.0_to_2.1.sql 10(+9 -1)
src/web/css/azkaban.css 33(+24 -9)
src/web/js/azkaban.permission.view.js 171(+126 -45)
Details
build.xml 10(+8 -2)
diff --git a/build.xml b/build.xml
index e48342a..244b7e4 100644
--- a/build.xml
+++ b/build.xml
@@ -71,12 +71,18 @@
<delete dir="${dist.sql.package.dir}" />
<mkdir dir="${dist.sql.package.dir}" />
+ <concat destfile="${dist.sql.package.dir}/create-all-sql-${version}.sql" fixlastline="yes">
+ <fileset dir="${sql.src.dir}" >
+ <exclude name="update*.sql"/>
+ </fileset>
+ </concat>
+
<copy todir="${dist.sql.package.dir}" >
<fileset dir="${sql.src.dir}" />
</copy>
- <tar destfile="${dist.sql.package.dir}/${name}-sql-script-${version}.tar.gz" compression="gzip" longfile="gnu">
- <tarfileset dir="${dist.sql.package.dir}" prefix="azkaban-${version}" filemode="755" />
+ <tar destfile="${dist.sql.package.dir}/${name}-sql-script-${version}.tar.gz" compression="gzip" longfile="gnu">
+ <tarfileset dir="${dist.sql.package.dir}" prefix="azkaban-${version}" filemode="755" />
</tar>
</target>
diff --git a/src/java/azkaban/execapp/event/FlowWatcher.java b/src/java/azkaban/execapp/event/FlowWatcher.java
index 2e4f576..4a13a4b 100644
--- a/src/java/azkaban/execapp/event/FlowWatcher.java
+++ b/src/java/azkaban/execapp/event/FlowWatcher.java
@@ -10,7 +10,7 @@ import azkaban.executor.ExecutableNode;
import azkaban.executor.Status;
public abstract class FlowWatcher {
- private static final Logger logger = Logger.getLogger(FlowWatcher.class);
+ private Logger logger;
private int execId;
private ExecutableFlow flow;
@@ -25,15 +25,19 @@ public abstract class FlowWatcher {
this.flow = flow;
}
+ public void setLogger(Logger logger) {
+ this.logger = logger;
+ }
+
+ protected Logger getLogger() {
+ return this.logger;
+ }
+
/**
* Called to fire events to the JobRunner listeners
* @param jobId
*/
protected synchronized void handleJobFinished(String jobId, Status status) {
- if (cancelWatch) {
- return;
- }
-
BlockingStatus block = map.get(jobId);
if (block != null) {
block.changeStatus(status);
diff --git a/src/java/azkaban/execapp/event/LocalFlowWatcher.java b/src/java/azkaban/execapp/event/LocalFlowWatcher.java
index ea78174..afe9248 100644
--- a/src/java/azkaban/execapp/event/LocalFlowWatcher.java
+++ b/src/java/azkaban/execapp/event/LocalFlowWatcher.java
@@ -3,6 +3,7 @@ package azkaban.execapp.event;
import azkaban.execapp.FlowRunner;
import azkaban.execapp.JobRunner;
+import azkaban.execapp.event.Event.Type;
import azkaban.executor.ExecutableNode;
public class LocalFlowWatcher extends FlowWatcher {
@@ -30,17 +31,30 @@ public class LocalFlowWatcher extends FlowWatcher {
runner.removeListener(watcherListener);
runner = null;
+ getLogger().info("Stopping watcher, and unblocking pipeline");
super.failAllWatches();
}
public class LocalFlowWatcherListener implements EventListener {
@Override
public void handleEvent(Event event) {
- if (event.getRunner() instanceof JobRunner) {
- JobRunner runner = (JobRunner)event.getRunner();
- ExecutableNode node = runner.getNode();
-
- handleJobFinished(node.getJobId(), node.getStatus());
+ if (event.getType() == Type.JOB_FINISHED) {
+ if (event.getRunner() instanceof FlowRunner) {
+ Object data = event.getData();
+ if (data instanceof ExecutableNode) {
+ ExecutableNode node = (ExecutableNode)data;
+ handleJobFinished(node.getJobId(), node.getStatus());
+ }
+ }
+ else if (event.getRunner() instanceof JobRunner) {
+ JobRunner runner = (JobRunner)event.getRunner();
+ ExecutableNode node = runner.getNode();
+
+ handleJobFinished(node.getJobId(), node.getStatus());
+ }
+ }
+ else if (event.getType() == Type.FLOW_FINISHED) {
+ stopWatcher();
}
}
}
src/java/azkaban/execapp/FlowRunner.java 68(+55 -13)
diff --git a/src/java/azkaban/execapp/FlowRunner.java b/src/java/azkaban/execapp/FlowRunner.java
index f6f9612..005e720 100644
--- a/src/java/azkaban/execapp/FlowRunner.java
+++ b/src/java/azkaban/execapp/FlowRunner.java
@@ -4,9 +4,9 @@ import java.io.File;
import java.io.IOException;
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 java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -40,7 +40,7 @@ import azkaban.utils.PropsUtils;
public class FlowRunner extends EventHandler implements Runnable {
private static final Layout DEFAULT_LAYOUT = new PatternLayout("%d{dd-MM-yyyy HH:mm:ss z} %c{1} %p - %m\n");
// We check update every 5 minutes, just in case things get stuck. But for the most part, we'll be idling.
- private static final long CHECK_WAIT_MS = 5*60*60*1000;
+ private static final long CHECK_WAIT_MS = 5*60*1000;
private Logger logger;
private Layout loggerLayout = DEFAULT_LAYOUT;
@@ -65,6 +65,7 @@ public class FlowRunner extends EventHandler implements Runnable {
private Map<String, Props> jobOutputProps = new HashMap<String, Props>();
private Props globalProps;
+ private Props commonProps;
private final JobTypeManager jobtypeManager;
private JobRunnerEventListener listener = new JobRunnerEventListener();
@@ -78,7 +79,7 @@ public class FlowRunner extends EventHandler implements Runnable {
// Watches external flows for execution.
private FlowWatcher watcher = null;
- private HashSet<String> proxyUsers = null;
+ private Set<String> proxyUsers = null;
private boolean validateUserProxy;
private String jobLogFileSize = "5MB";
@@ -94,7 +95,6 @@ public class FlowRunner extends EventHandler implements Runnable {
this.flow = flow;
this.executorLoader = executorLoader;
this.projectLoader = projectLoader;
- this.executorService = Executors.newFixedThreadPool(numJobThreads);
this.execDir = new File(flow.getExecutionPath());
this.jobtypeManager = jobtypeManager;
@@ -115,6 +115,11 @@ public class FlowRunner extends EventHandler implements Runnable {
return this;
}
+ public FlowRunner setNumJobThreads(int jobs) {
+ numJobThreads = jobs;
+ return this;
+ }
+
public FlowRunner setJobLogSettings(String jobLogFileSize, int jobLogNumFiles) {
this.jobLogFileSize = jobLogFileSize;
this.jobLogNumFiles = jobLogNumFiles;
@@ -133,6 +138,9 @@ public class FlowRunner extends EventHandler implements Runnable {
public void run() {
try {
+ if (this.executorService == null) {
+ this.executorService = Executors.newFixedThreadPool(numJobThreads);
+ }
setupFlowExecution();
flow.setStartTime(System.currentTimeMillis());
@@ -153,7 +161,9 @@ public class FlowRunner extends EventHandler implements Runnable {
}
finally {
if (watcher != null) {
+ logger.info("Watcher is attached. Stopping watcher.");
watcher.stopWatcher();
+ logger.info("Watcher cancelled status is " + watcher.isWatchCancelled());
}
flow.setEndTime(System.currentTimeMillis());
@@ -171,10 +181,15 @@ public class FlowRunner extends EventHandler implements Runnable {
String flowId = flow.getFlowId();
// Add a bunch of common azkaban properties
- PropsUtils.addCommonFlowProperties(flow);
+ commonProps = PropsUtils.addCommonFlowProperties(flow);
// Create execution dir
createLogger(flowId);
+
+ if (this.watcher != null) {
+ this.watcher.setLogger(logger);
+ }
+
logger.info("Running execid:" + execId + " flow:" + flowId + " project:" + projectId + " version:" + version);
if (pipelineExecId != null) {
logger.info("Running simulateously with " + pipelineExecId + ". Pipelining level " + pipelineLevel);
@@ -289,7 +304,7 @@ public class FlowRunner extends EventHandler implements Runnable {
else {
List<ExecutableNode> jobsReadyToRun = findReadyJobsToRun();
- if (!jobsReadyToRun.isEmpty()) {
+ if (!jobsReadyToRun.isEmpty() && !flowCancelled) {
for (ExecutableNode node : jobsReadyToRun) {
long currentTime = System.currentTimeMillis();
@@ -313,19 +328,21 @@ public class FlowRunner extends EventHandler implements Runnable {
logger.info("Killing " + node.getJobId() + " due to prior errors.");
node.setStartTime(currentTime);
node.setEndTime(currentTime);
+ fireEventListeners(Event.create(this, Type.JOB_FINISHED, node));
} // If disabled, then we auto skip
else if (node.getStatus() == Status.DISABLED) {
logger.info("Skipping disabled job " + node.getJobId() + ".");
node.setStartTime(currentTime);
node.setEndTime(currentTime);
node.setStatus(Status.SKIPPED);
+ fireEventListeners(Event.create(this, Type.JOB_FINISHED, node));
}
}
updateFlow();
}
else {
- if (isFlowFinished()) {
+ if (isFlowFinished() || flowCancelled ) {
flowFinished = true;
break;
}
@@ -339,6 +356,32 @@ public class FlowRunner extends EventHandler implements Runnable {
}
}
+ if (flowCancelled) {
+ try {
+ logger.info("Flow was force cancelled cleaning up.");
+ for(JobRunner activeRunner : activeJobRunners.values()) {
+ activeRunner.cancel();
+ }
+
+ for (ExecutableNode node: flow.getExecutableNodes()) {
+ if (Status.isStatusFinished(node.getStatus())) {
+ continue;
+ }
+ else if (node.getStatus() == Status.DISABLED) {
+ node.setStatus(Status.SKIPPED);
+ }
+ else {
+ node.setStatus(Status.KILLED);
+ }
+ fireEventListeners(Event.create(this, Type.JOB_FINISHED, node));
+ }
+ } catch (Exception e) {
+ logger.error(e);
+ }
+
+ updateFlow();
+ }
+
logger.info("Finishing up flow. Awaiting Termination");
executorService.shutdown();
@@ -419,12 +462,10 @@ public class FlowRunner extends EventHandler implements Runnable {
ExecutionOptions options = flow.getExecutionOptions();
@SuppressWarnings("unchecked")
Props flowProps = new Props(null, options.getFlowParameters());
-
- if (flowProps.size() > 0) {
- flowProps.setParent(parentProps);
- parentProps = flowProps;
- }
-
+ flowProps.putAll(commonProps);
+ flowProps.setParent(parentProps);
+ parentProps = flowProps;
+
// We add the previous job output and put into this props.
if (previousOutput != null) {
Props earliestParent = previousOutput.getEarliestAncestor();
@@ -531,6 +572,7 @@ public class FlowRunner extends EventHandler implements Runnable {
if (watcher != null) {
logger.info("Watcher is attached. Stopping watcher.");
watcher.stopWatcher();
+ logger.info("Watcher cancelled status is " + watcher.isWatchCancelled());
}
logger.info("Cancelling " + activeJobRunners.size() + " jobs.");
diff --git a/src/java/azkaban/execapp/FlowRunnerManager.java b/src/java/azkaban/execapp/FlowRunnerManager.java
index a293ac7..d707c1f 100644
--- a/src/java/azkaban/execapp/FlowRunnerManager.java
+++ b/src/java/azkaban/execapp/FlowRunnerManager.java
@@ -75,6 +75,7 @@ public class FlowRunnerManager implements EventListener {
private ExecutorService executorService;
private SubmitterThread submitterThread;
private CleanerThread cleanerThread;
+ private int numJobThreadPerFlow = 10;
private ExecutorLoader executorLoader;
private ProjectLoader projectLoader;
@@ -119,6 +120,7 @@ public class FlowRunnerManager implements EventListener {
//azkaban.temp.dir
numThreads = props.getInt("executor.flow.threads", DEFAULT_NUM_EXECUTING_FLOWS);
+ numJobThreadPerFlow = props.getInt("flow.num.job.threads", numJobThreadPerFlow);
executorService = Executors.newFixedThreadPool(numThreads);
this.executorLoader = executorLoader;
@@ -388,11 +390,12 @@ public class FlowRunnerManager implements EventListener {
}
FlowRunner runner = new FlowRunner(flow, executorLoader, projectLoader, jobtypeManager);
- runner.setFlowWatcher(watcher);
- runner.setJobLogSettings(jobLogChunkSize, jobLogNumFiles);
- runner.setValidateProxyUser(validateProxyUser);
- runner.setGlobalProps(globalProps);
- runner.addListener(this);
+ runner.setFlowWatcher(watcher)
+ .setJobLogSettings(jobLogChunkSize, jobLogNumFiles)
+ .setValidateProxyUser(validateProxyUser)
+ .setGlobalProps(globalProps)
+ .setNumJobThreads(numJobThreadPerFlow)
+ .addListener(this);
// Check again.
if (runningFlows.containsKey(execId)) {
src/java/azkaban/execapp/JobRunner.java 12(+12 -0)
diff --git a/src/java/azkaban/execapp/JobRunner.java b/src/java/azkaban/execapp/JobRunner.java
index 40bc1ec..5f8cade 100644
--- a/src/java/azkaban/execapp/JobRunner.java
+++ b/src/java/azkaban/execapp/JobRunner.java
@@ -85,6 +85,7 @@ public class JobRunner extends EventHandler implements Runnable {
private long delayStartMs = 0;
private boolean cancelled = false;
+ private BlockingStatus currentBlockStatus = null;
public JobRunner(ExecutableNode node, Props props, File workingDir, ExecutorLoader loader, JobTypeManager jobtypeManager) {
this.props = props;
@@ -223,19 +224,25 @@ public class JobRunner extends EventHandler implements Runnable {
for(BlockingStatus bStatus: blockingStatus) {
logger.info("Waiting on pipelined job " + bStatus.getJobId());
+ currentBlockStatus = bStatus;
bStatus.blockOnFinishedStatus();
logger.info("Pipelined job " + bStatus.getJobId() + " finished.");
+ if (watcher.isWatchCancelled()) {
+ break;
+ }
}
}
if (watcher.isWatchCancelled()) {
logger.info("Job was cancelled while waiting on pipeline. Quiting.");
node.setStartTime(System.currentTimeMillis());
node.setEndTime(System.currentTimeMillis());
+ node.setStatus(Status.FAILED);
fireEvent(Event.create(this, Type.JOB_FINISHED));
return;
}
}
+ currentBlockStatus = null;
long currentTime = System.currentTimeMillis();
if (delayStartMs > 0) {
logger.info("Delaying start of execution for " + delayStartMs + " milliseconds.");
@@ -390,6 +397,11 @@ public class JobRunner extends EventHandler implements Runnable {
logError("Cancel has been called.");
this.cancelled = true;
+ BlockingStatus status = currentBlockStatus;
+ if (status != null) {
+ status.unblock();
+ }
+
// Cancel code here
if (job == null) {
logError("Job hasn't started yet.");
diff --git a/src/java/azkaban/executor/ExecutableFlow.java b/src/java/azkaban/executor/ExecutableFlow.java
index 408ed6d..883a19f 100644
--- a/src/java/azkaban/executor/ExecutableFlow.java
+++ b/src/java/azkaban/executor/ExecutableFlow.java
@@ -94,12 +94,12 @@ public class ExecutableFlow {
return flowProps.values();
}
- public void setProxyUsers(HashSet<String> proxyUsers) {
- this.proxyUsers = proxyUsers;
+ public void addAllProxyUsers(Collection<String> proxyUsers) {
+ this.proxyUsers.addAll(proxyUsers);
}
- public HashSet<String> getProxyUsers() {
- return this.proxyUsers;
+ public Set<String> getProxyUsers() {
+ return new HashSet<String>(this.proxyUsers);
}
public void setExecutionOptions(ExecutionOptions options) {
@@ -286,7 +286,6 @@ public class ExecutableFlow {
flowObj.put("nodes", nodes);
ArrayList<String> proxyUserList = new ArrayList<String>(proxyUsers);
-
flowObj.put("proxyUsers", proxyUserList);
return flowObj;
@@ -357,7 +356,6 @@ public class ExecutableFlow {
this.flowStatus = Status.fromInteger((Integer)updateData.get("status"));
- System.out.println("Updating status to " + flowStatus);
this.startTime = JSONUtils.getLongFromObject(updateData.get("startTime"));
this.endTime = JSONUtils.getLongFromObject(updateData.get("endTime"));
this.updateTime = JSONUtils.getLongFromObject(updateData.get("updateTime"));
@@ -406,7 +404,7 @@ public class ExecutableFlow {
if(flowObj.containsKey("proxyUsers")) {
ArrayList<String> proxyUserList = (ArrayList<String>) flowObj.get("proxyUsers");
- exFlow.setProxyUsers(new HashSet<String>(proxyUserList));
+ exFlow.addAllProxyUsers(proxyUserList);
}
return exFlow;
diff --git a/src/java/azkaban/executor/ExecutorManager.java b/src/java/azkaban/executor/ExecutorManager.java
index 3f482bc..07b81a8 100644
--- a/src/java/azkaban/executor/ExecutorManager.java
+++ b/src/java/azkaban/executor/ExecutorManager.java
@@ -79,7 +79,7 @@ public class ExecutorManager {
executingManager = new ExecutingManagerUpdaterThread();
executingManager.start();
- long executionLogsRetentionMs = props.getLong("azkaban.execution.logs.retention.ms", DEFAULT_EXECUTION_LOGS_RETENTION_MS);
+ long executionLogsRetentionMs = props.getLong("execution.logs.retention.ms", DEFAULT_EXECUTION_LOGS_RETENTION_MS);
cleanerThread = new CleanerThread(executionLogsRetentionMs);
cleanerThread.start();
}
diff --git a/src/java/azkaban/jobtype/JobTypeManager.java b/src/java/azkaban/jobtype/JobTypeManager.java
index dc24db7..3bfc51d 100644
--- a/src/java/azkaban/jobtype/JobTypeManager.java
+++ b/src/java/azkaban/jobtype/JobTypeManager.java
@@ -81,7 +81,7 @@ public class JobTypeManager
private void loadDefaultTypes() throws JobTypeManagerException{
jobToClass.put("command", ProcessJob.class);
jobToClass.put("javaprocess", JavaProcessJob.class);
- jobToClass.put("propertyPusher", NoopJob.class);
+ jobToClass.put("noop", NoopJob.class);
jobToClass.put("python", PythonJob.class);
jobToClass.put("ruby", RubyJob.class);
jobToClass.put("script", ScriptJob.class);
src/java/azkaban/project/Project.java 56(+23 -33)
diff --git a/src/java/azkaban/project/Project.java b/src/java/azkaban/project/Project.java
index 7344820..d2e1f52 100644
--- a/src/java/azkaban/project/Project.java
+++ b/src/java/azkaban/project/Project.java
@@ -17,11 +17,13 @@
package azkaban.project;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import azkaban.flow.Flow;
import azkaban.user.Permission;
@@ -44,14 +46,6 @@ public class Project {
private Map<String, Flow> flows = null;
private HashSet<String> proxyUsers = new HashSet<String>();
- public HashSet<String> getProxyUsers() {
- return proxyUsers;
- }
-
- public void setProxyUsers(HashSet<String> proxyUsers) {
- this.proxyUsers = proxyUsers;
- }
-
public Project(int id, String name) {
this.id = id;
this.name = name;
@@ -101,6 +95,26 @@ public class Project {
return permissions;
}
+ public Set<String> getProxyUsers() {
+ return new HashSet<String>(proxyUsers);
+ }
+
+ public void addAllProxyUsers(Collection<String> proxyUsers) {
+ this.proxyUsers.addAll(proxyUsers);
+ }
+
+ public boolean hasProxyUser(String proxy) {
+ return this.proxyUsers.contains(proxy);
+ }
+
+ public void addProxyUser(String user) {
+ this.proxyUsers.add(user);
+ }
+
+ public void removeProxyUser(String user) {
+ this.proxyUsers.remove(user);
+ }
+
public boolean hasPermission(User user, Type type) {
Permission perm = userPermissionMap.get(user.getUserId());
if (perm != null && (perm.isPermissionSet(Type.ADMIN) || perm.isPermissionSet(type))) {
@@ -294,8 +308,7 @@ public class Project {
}
List<String> proxyUserList = (List<String>) projectObject.get("proxyUsers");
- HashSet<String> proxyUsers = new HashSet<String>(proxyUserList);
- project.setProxyUsers(proxyUsers);
+ project.addAllProxyUsers(proxyUserList);
return project;
}
@@ -409,27 +422,4 @@ public class Project {
public void setVersion(int version) {
this.version = version;
}
-
- public List<String> getProxyUserList() {
- return new ArrayList<String>(proxyUsers);
- }
-
-// public Object getSettingsObject() {
-// HashMap<String, Object> projectObject = new HashMap<String, Object>();
-// ArrayList<String> proxyUserList = new ArrayList<String>(proxyUsers);
-// projectObject.put("proxyUsers", proxyUserList);
-//
-// return projectObject;
-// }
-//
-// @SuppressWarnings("unchecked")
-// public static HashSet<String> proxyUserFromSettingsObj(Object object) {
-// Map<String, Object> settingsObj = (Map<String, Object>) object;
-//
-// List<String> proxyUserList = (List<String>) settingsObj.get("proxyUsers");
-// HashSet<String> proxyUsers = new HashSet<String>(proxyUserList);
-//
-// return proxyUsers;
-// }
-
}
diff --git a/src/java/azkaban/project/ProjectLogEvent.java b/src/java/azkaban/project/ProjectLogEvent.java
index c6e8577..af38a65 100644
--- a/src/java/azkaban/project/ProjectLogEvent.java
+++ b/src/java/azkaban/project/ProjectLogEvent.java
@@ -7,7 +7,16 @@ public class ProjectLogEvent {
* Only represent from 0 to 255 different codes.
*/
public static enum EventType {
- ERROR(128), CREATED(1), DELETED(2), USER_PERMISSION(3), GROUP_PERMISSION(4), DESCRIPTION(5), UPLOADED(6), SCHEDULE(7), SLA(8);
+ ERROR(128),
+ CREATED(1),
+ DELETED(2),
+ USER_PERMISSION(3),
+ GROUP_PERMISSION(4),
+ DESCRIPTION(5),
+ UPLOADED(6),
+ SCHEDULE(7),
+ SLA(8),
+ PROXY_USER(9);
private int numVal;
@@ -37,6 +46,8 @@ public class ProjectLogEvent {
return SCHEDULE;
case 8:
return SLA;
+ case 9:
+ return PROXY_USER;
case 128:
return ERROR;
default:
src/java/azkaban/project/ProjectManager.java 18(+17 -1)
diff --git a/src/java/azkaban/project/ProjectManager.java b/src/java/azkaban/project/ProjectManager.java
index a5be28b..f610e40 100644
--- a/src/java/azkaban/project/ProjectManager.java
+++ b/src/java/azkaban/project/ProjectManager.java
@@ -41,7 +41,7 @@ public class ProjectManager {
this.projectVersionRetention = (props.getInt("project.version.retention", 3));
logger.info("Project version retention is set to " + projectVersionRetention);
- this.creatorDefaultPermissions = props.getBoolean("azkaban.creator.default.permissions", true);
+ this.creatorDefaultPermissions = props.getBoolean("creator.default.proxy", true);
if (!tempDir.exists()) {
tempDir.mkdirs();
@@ -235,6 +235,22 @@ public class ProjectManager {
projectLoader.updateProjectSettings(project);
}
+ public void addProjectProxyUser(Project project, String proxyName, User modifier) throws ProjectManagerException {
+ logger.info("User " + modifier.getUserId() + " adding proxy user " + proxyName + " to project " + project.getName());
+ project.addProxyUser(proxyName);
+
+ projectLoader.postEvent(project, EventType.PROXY_USER, modifier.getUserId(), "Proxy user " + proxyName + " is added to project.");
+ updateProjectSetting(project);
+ }
+
+ public void removeProjectProxyUser(Project project, String proxyName, User modifier) throws ProjectManagerException {
+ logger.info("User " + modifier.getUserId() + " removing proxy user " + proxyName + " from project " + project.getName());
+ project.removeProxyUser(proxyName);
+
+ projectLoader.postEvent(project, EventType.PROXY_USER, modifier.getUserId(), "Proxy user " + proxyName + " has been removed form the project.");
+ updateProjectSetting(project);
+ }
+
public void updateProjectPermission(Project project, String name, Permission perm, boolean group, User modifier) throws ProjectManagerException {
logger.info("User " + modifier.getUserId() + " updating permissions for project " + project.getName() + " for " + name + " " + perm.toString());
projectLoader.updatePermission(project, name, perm, group);
diff --git a/src/java/azkaban/scheduler/ScheduleManager.java b/src/java/azkaban/scheduler/ScheduleManager.java
index fab237a..5688f66 100644
--- a/src/java/azkaban/scheduler/ScheduleManager.java
+++ b/src/java/azkaban/scheduler/ScheduleManager.java
@@ -371,7 +371,7 @@ public class ScheduleManager {
// Create ExecutableFlow
ExecutableFlow exflow = new ExecutableFlow(flow);
exflow.setSubmitUser(runningSched.getSubmitUser());
- exflow.setProxyUsers(project.getProxyUsers());
+ exflow.addAllProxyUsers(project.getProxyUsers());
ExecutionOptions flowOptions = runningSched.getExecutionOptions();
if(flowOptions == null) {
src/java/azkaban/user/XmlUserManager.java 21(+10 -11)
diff --git a/src/java/azkaban/user/XmlUserManager.java b/src/java/azkaban/user/XmlUserManager.java
index 042a081..55ee224 100644
--- a/src/java/azkaban/user/XmlUserManager.java
+++ b/src/java/azkaban/user/XmlUserManager.java
@@ -66,7 +66,7 @@ public class XmlUserManager implements UserManager {
private HashMap<String, String> userPassword;
private HashMap<String, Role> roles;
private HashMap<String, Set<String>> groupRoles;
- private HashMap<String, HashSet<String>> proxyUserMap;
+ private HashMap<String, Set<String>> proxyUserMap;
/**
* The constructor.
@@ -89,7 +89,7 @@ public class XmlUserManager implements UserManager {
HashMap<String, String> userPassword = new HashMap<String, String>();
HashMap<String, Role> roles = new HashMap<String, Role>();
HashMap<String, Set<String>> groupRoles = new HashMap<String, Set<String>>();
- HashMap<String, HashSet<String>> proxyUserMap = new HashMap<String, HashSet<String>>();
+ HashMap<String, Set<String>> proxyUserMap = new HashMap<String, Set<String>>();
// Creating the document builder to parse xml.
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
@@ -143,7 +143,7 @@ public class XmlUserManager implements UserManager {
}
}
- private void parseUserTag(Node node, HashMap<String, User> users, HashMap<String, String> userPassword, HashMap<String, HashSet<String>> proxyUserMap) {
+ private void parseUserTag(Node node, HashMap<String, User> users, HashMap<String, String> userPassword, HashMap<String, Set<String>> proxyUserMap) {
NamedNodeMap userAttrMap = node.getAttributes();
Node userNameAttr = userAttrMap.getNamedItem(USERNAME_ATTR);
if (userNameAttr == null) {
@@ -175,16 +175,15 @@ public class XmlUserManager implements UserManager {
Node proxy = userAttrMap.getNamedItem(PROXY_ATTR);
if (proxy != null) {
String value = proxy.getNodeValue();
- String[] groupSplit = value.split("\\s*,\\s*");
- for (String group : groupSplit) {
- if(proxyUserMap.containsKey(username)) {
- proxyUserMap.get(username).add(group);
- }
- else {
- HashSet<String> proxySet = new HashSet<String>();
- proxySet.add(group);
+ String[] proxySplit = value.split("\\s*,\\s*");
+ for (String proxyUser : proxySplit) {
+ Set<String> proxySet = proxyUserMap.get(username);
+ if (proxySet == null) {
+ proxySet = new HashSet<String>();
proxyUserMap.put(username, proxySet);
}
+
+ proxySet.add(proxyUser);
}
}
diff --git a/src/java/azkaban/webapp/AzkabanWebServer.java b/src/java/azkaban/webapp/AzkabanWebServer.java
index 5ce6985..e3fe50f 100644
--- a/src/java/azkaban/webapp/AzkabanWebServer.java
+++ b/src/java/azkaban/webapp/AzkabanWebServer.java
@@ -448,7 +448,6 @@ public class AzkabanWebServer implements AzkabanServer {
//root.addServlet(new ServletHolder(new HdfsBrowserServlet()), "/hdfs/*");
root.setAttribute(AzkabanServletContextListener.AZKABAN_SERVLET_CONTEXT_KEY, app);
-
try {
server.start();
}
diff --git a/src/java/azkaban/webapp/servlet/ExecutorServlet.java b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
index a9d5d17..ea19307 100644
--- a/src/java/azkaban/webapp/servlet/ExecutorServlet.java
+++ b/src/java/azkaban/webapp/servlet/ExecutorServlet.java
@@ -763,7 +763,7 @@ public class ExecutorServlet extends LoginAbstractAzkabanServlet {
ExecutableFlow exflow = new ExecutableFlow(flow);
exflow.setSubmitUser(user.getUserId());
- exflow.setProxyUsers(project.getProxyUsers());
+ exflow.addAllProxyUsers(project.getProxyUsers());
ExecutionOptions options = HttpRequestUtils.parseFlowOptions(req);
exflow.setExecutionOptions(options);
diff --git a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
index 455e441..0b2d413 100644
--- a/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
+++ b/src/java/azkaban/webapp/servlet/ProjectManagerServlet.java
@@ -28,7 +28,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -235,6 +234,11 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
ajaxAddProxyUser(project, ret, req, user);
}
}
+ else if (ajaxName.equals("removeProxyUser")) {
+ if (handleAjaxPermission(project, user, Type.ADMIN, ret)) {
+ ajaxRemoveProxyUser(project, ret, req, user);
+ }
+ }
else if (ajaxName.equals("fetchFlowExecutions")) {
if (handleAjaxPermission(project, user, Type.READ, ret)) {
ajaxFetchFlowExecutions(project, ret, req);
@@ -569,53 +573,34 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
ret.put("nodes", nodeList);
}
+
private void ajaxAddProxyUser(Project project, HashMap<String, Object> ret, HttpServletRequest req, User user) throws ServletException {
String name = getParam(req, "name");
logger.info("Adding proxy user " + name + " by " + user.getUserId());
-
-
-
- boolean doProxy = Boolean.parseBoolean(getParam(req, "doProxy"));
-
-
- HashSet<String> proxyUsers = project.getProxyUsers();
- //add
- if(doProxy) {
- if(proxyUsers.contains(name)) {
- return;
- }
- else {
- if(userManager.validateProxyUser(name, user)) {
- proxyUsers.add(name);
- }
- else {
- ret.put("error", "User " + user.getUserId() + " has no permission to add " + name + " as proxy user for project " + project.getName());
- return;
- }
+ if(userManager.validateProxyUser(name, user)) {
+ try {
+ projectManager.addProjectProxyUser(project, name, user);
+ } catch (ProjectManagerException e) {
+ ret.put("error", e.getMessage());
}
}
else {
- if(!proxyUsers.contains(name)) {
- return;
- }
- else {
- if(userManager.validateProxyUser(name, user)) {
- proxyUsers.remove(name);
- }
- else {
- ret.put("error", "User " + user.getUserId() + " has no permission to remove " + name + " as proxy user for project " + project.getName());
- return;
- }
- }
+ ret.put("error", "User " + user.getUserId() + " has no permission to add " + name + " as proxy user.");
+ return;
}
+ }
+
+ private void ajaxRemoveProxyUser(Project project, HashMap<String, Object> ret, HttpServletRequest req, User user) throws ServletException {
+ String name = getParam(req, "name");
+
+ logger.info("Removing proxy user " + name + " by " + user.getUserId());
+
try {
- projectManager.updateProjectSetting(project);
+ projectManager.removeProjectProxyUser(project, name, user);
} catch (ProjectManagerException e) {
- // TODO Auto-generated catch block
ret.put("error", e.getMessage());
}
-
}
private void ajaxAddPermission(Project project, HashMap<String, Object> ret, HttpServletRequest req, User user) throws ServletException {
@@ -862,9 +847,20 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
page.add("admin", true);
}
- page.add("permissions", project.getUserPermissions());
- page.add("groupPermissions", project.getGroupPermissions());
- page.add("proxyUsers", project.getProxyUserList());
+ List<Pair<String, Permission>> userPermission = project.getUserPermissions();
+ if (userPermission != null && !userPermission.isEmpty()) {
+ page.add("permissions", userPermission);
+ }
+
+ List<Pair<String, Permission>> groupPermission = project.getGroupPermissions();
+ if (groupPermission != null && !groupPermission.isEmpty()) {
+ page.add("groupPermissions", groupPermission);
+ }
+
+ Set<String> proxyUsers = project.getProxyUsers();
+ if (proxyUsers != null && !proxyUsers.isEmpty()) {
+ page.add("proxyUsers", proxyUsers);
+ }
if(hasPermission(project, user, Type.ADMIN)) {
page.add("isAdmin", true);
@@ -1174,6 +1170,9 @@ public class ProjectManagerServlet extends LoginAbstractAzkabanServlet {
if (perm.isPermissionSet(Type.EXECUTE) || adminPerm) {
page.add("exec", true);
}
+ else {
+ page.add("exec", false);
+ }
List<Flow> flows = project.getFlows();
if (!flows.isEmpty()) {
diff --git a/src/java/azkaban/webapp/servlet/velocity/permissionspage.vm b/src/java/azkaban/webapp/servlet/velocity/permissionspage.vm
index 046d1c0..3d73924 100644
--- a/src/java/azkaban/webapp/servlet/velocity/permissionspage.vm
+++ b/src/java/azkaban/webapp/servlet/velocity/permissionspage.vm
@@ -103,8 +103,8 @@
<tbody>
#if($permissions)
#foreach($perm in $permissions)
- <tr id="${perm.first}-row" >
- <td class="tb-name">#if($perm.first == $username) ${perm.first} <span class="sublabel">(you)</span> #else $perm.first #end</td>
+ <tr>
+ <td class="tb-username">#if($perm.first == $username) ${perm.first} <span class="sublabel">(you)</span> #else $perm.first #end</td>
#if ($perm.second.isPermissionNameSet("ADMIN"))
<td><input id="${perm.first}-admin-checkbox" type="checkbox" name="admin" disabled="disabled" checked="true"></input></td>
<td><input id="${perm.first}-read-checkbox" type="checkbox" name="read" disabled="disabled" checked="true"></input></td>
@@ -147,8 +147,8 @@
<tbody>
#if($groupPermissions)
#foreach($perm in $groupPermissions)
- <tr id="${perm.first}-row" >
- <td class="tb-name">#if($perm.first == $username) ${perm.first} <span class="sublabel">(you)</span> #else $perm.first #end</td>
+ <tr>
+ <td class="tb-username">#if($perm.first == $username) ${perm.first} <span class="sublabel">(you)</span> #else $perm.first #end</td>
#if ($perm.second.isPermissionNameSet("ADMIN"))
<td><input id="group-${perm.first}-admin-checkbox" type="checkbox" name="admin" disabled="disabled" checked="true"></input></td>
<td><input id="group-${perm.first}-read-checkbox" type="checkbox" name="read" disabled="disabled" checked="true"></input></td>
@@ -174,17 +174,11 @@
</tbody>
</table>
- <br></br>
+ <br/>
<table id="proxy-user-table" class="all-jobs permission-table">
<thead>
<tr>
<th class="tb-username">Proxy User</th>
- <th class="tb-perm">Admin</th>
- <th class="tb-read">Read</th>
- <th class="tb-write">Write</th>
- <th class="tb-execute">Execute</th>
- <th class="tb-schedule">Schedule</th>
- <th class="tb-proxy">Proxy</th>
#if($isAdmin)
<th class="tb-action"></th>
#end
@@ -193,17 +187,10 @@
<tbody>
#if($proxyUsers)
#foreach($proxyUser in $proxyUsers)
- <tr id="${proxyUser}-row" >
- <td class="tb-name">#if($proxyUser == $username) ${proxyUser} <span class="sublabel">(you)</span> #else $proxyUser #end</td>
- <td><input id="proxy-${proxyUser}-admin-checkbox" type="checkbox" name="admin" disabled="disabled" ></input></td>
- <td><input id="proxy-${proxyUser}-read-checkbox" type="checkbox" name="read" disabled="disabled" ></input></td>
- <td><input id="proxy-${proxyUser}-write-checkbox" type="checkbox" name="write" disabled="disabled" ></input></td>
- <td><input id="proxy-${proxyUser}-execute-checkbox" type="checkbox" name="execute" disabled="disabled" ></input></td>
- <td><input id="proxy-${proxyUser}-schedule-checkbox" type="checkbox" name="schedule" disabled="disabled" ></input></td>
- <td><input id="proxy-${proxyUser}-proxy-checkbox" type="checkbox" name="proxy" disabled="disabled" checked="true"></input></td>
-
+ <tr>
+ <td class="tb-username">#if($proxyUser == $username) ${proxyUser} <span class="sublabel">(you)</span> #else $proxyUser #end</td>
#if($isAdmin)
- <td><button id="proxy-${proxyUser}" class="change-btn btn2">Change</button></td>
+ <td><button id="proxy-${proxyUser}" name="${proxyUser}" class="remove-btn btn2">Remove</button></td>
#end
</tr>
#end
@@ -216,6 +203,29 @@
</div>
+ <div id="remove-proxy" class="modal">
+ <h3>Remove Proxy User</h3>
+ <div id="removeProxyErrorMsg" class="box-error-message"></div>
+ <p id="proxyRemoveMsg">Removing Proxy User </p>
+ <div class="actions">
+ <a class="yes btn2" id="remove-proxy-btn" href="#">Remove Proxy User</a>
+ <a class="no simplemodal-close btn3" href="#">Cancel</a>
+ </div>
+ </div>
+
+ <div id="add-proxy" class="modal">
+ <h3 id="proxy-title">Add Proxy User</h3>
+ <div id="proxyErrorMsg" class="box-error-message"></div>
+ <dl>
+ <dt>Proxy</dt>
+ <dd><input id="proxy-user-box" name="proxyid" type="text" /></dd>
+ </dl>
+ <div class="actions">
+ <a class="yes btn2" id="add-proxy-btn" href="#">Add Proxy User</a>
+ <a class="no simplemodal-close btn3" href="#">Cancel</a>
+ </div>
+ </div>
+
<div id="change-permission" class="modal">
<h3 id="change-title">Change Permissions</h3>
<div id="errorMsg" class="box-error-message"></div>
@@ -236,10 +246,6 @@
<dt>Schedule</dt>
<dd><input id="schedule-change" name="schedule" type="checkbox" /></dd>
</div>
- <div id="proxyCheckBox" hidden=true>
- <dt>Proxy</dt>
- <dd><input id="proxy-change" name="proxy" type="checkbox" /></dd>
- </div>
</dl>
</fieldset>
</div>
@@ -247,12 +253,12 @@
<a class="yes btn2" id="change-btn" href="#">Commit</a>
<a class="no simplemodal-close btn3" href="#">Cancel</a>
</div>
- <div id="invalid-session" class="modal">
- <h3>Invalid Session</h3>
- <p>Session has expired. Please re-login.</p>
- <div class="actions">
- <a class="yes btn2" id="login-btn" href="#">Re-login</a>
- </div>
+ </div>
+ <div id="invalid-session" class="modal">
+ <h3>Invalid Session</h3>
+ <p>Session has expired. Please re-login.</p>
+ <div class="actions">
+ <a class="yes btn2" id="login-btn" href="#">Re-login</a>
</div>
</div>
</body>
src/web/css/azkaban.css 33(+24 -9)
diff --git a/src/web/css/azkaban.css b/src/web/css/azkaban.css
index b187638..aadf527 100644
--- a/src/web/css/azkaban.css
+++ b/src/web/css/azkaban.css
@@ -735,10 +735,22 @@ tr:hover td {
#user-box {
background-color: #FFF;
- border-width: 1px;
- border-color: #CCC;
+ margin-left: 10px;
width: 300px;
+ border-style: solid;
+ border-color: #CCC;
+ height: 20px;
+ font-size: 11pt;
+}
+
+#proxy-user-box {
+ background-color: #FFF;
margin-left: 10px;
+ width: 300px;
+ border-style: solid;
+ border-color: #CCC;
+ height: 20px;
+ font-size: 11pt;
}
#create-project #overwrite {
@@ -2065,31 +2077,32 @@ table.parameters tr td {
}
.permission-table .tb-username {
- margin: 0px;
+ text-align:left;
+ padding-left: 10px;
}
.permission-table .tb-perm {
- width: 60px;
+ width: 41px;
margin: 0px;
}
.permission-table .tb-admin {
- width: 60px;
+ width: 41px;
margin: 0px;
}
.permission-table .tb-read {
- width: 60px;
+ width: 33px;
margin: 0px;
}
.permission-table .tb-write {
- width: 60px;
+ width: 34px;
margin: 0px;
}
.permission-table .tb-execute {
- width: 60px;
+ width: 51px;
margin: 0px;
}
@@ -2100,7 +2113,9 @@ table.parameters tr td {
.permission-table .tb-action {
margin: 0px;
- width: 100px;
+ width: 70px;
+ min-width: 70px;
+ max-width: 70px;
}
.permission-table thead tr th.tb-username {
src/web/js/azkaban.permission.view.js 171(+126 -45)
diff --git a/src/web/js/azkaban.permission.view.js b/src/web/js/azkaban.permission.view.js
index 869d1f3..67c826b 100644
--- a/src/web/js/azkaban.permission.view.js
+++ b/src/web/js/azkaban.permission.view.js
@@ -2,7 +2,7 @@ $.namespace('azkaban');
var permissionTableView;
var groupPermissionTableView;
-var proxyTableView;
+
azkaban.PermissionTableView= Backbone.View.extend({
events : {
"click button": "handleChangePermission"
@@ -19,6 +19,113 @@ azkaban.PermissionTableView= Backbone.View.extend({
}
});
+var proxyTableView;
+azkaban.ProxyTableView= Backbone.View.extend({
+ events : {
+ "click button": "handleRemoveProxy"
+ },
+ initialize : function(settings) {
+ },
+ render: function() {
+ },
+ handleRemoveProxy: function(evt) {
+ removeProxyView.display($(evt.currentTarget).attr("name"));
+ }
+});
+
+var removeProxyView;
+azkaban.RemoveProxyView = Backbone.View.extend({
+ events: {
+ "click #remove-proxy-btn": "handleRemoveProxy"
+ },
+ initialize : function(settings) {
+ $('#removeProxyErrorMsg').hide();
+ },
+ display: function(proxyName) {
+ this.el.proxyName = proxyName;
+ $("#proxyRemoveMsg").text("Removing proxy user '" + proxyName + "'");
+ $(this.el).modal({
+ closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+ position: ["20%",],
+ containerId: 'confirm-container',
+ containerCss: {
+ 'height': '220px',
+ 'width': '565px'
+ },
+ onShow: function (dialog) {
+ var modal = this;
+ $("#removeProxyErrorMsg").hide();
+ }
+ });
+ },
+ handleRemoveProxy: function() {
+ var requestURL = contextURL + "/manager";
+ var proxyName = this.el.proxyName;
+
+ $.get(
+ requestURL,
+ {"project": projectName, "name": proxyName, "ajax":"removeProxyUser"},
+ function(data) {
+ console.log("Output");
+ if (data.error) {
+ $("#removeProxyErrorMsg").text(data.error);
+ $("#removeProxyErrorMsg").show();
+ return;
+ }
+
+ var replaceURL = requestURL + "?project=" + projectName +"&permissions";
+ window.location.replace(replaceURL);
+ },
+ "json"
+ );
+ }
+});
+
+var addProxyView;
+azkaban.AddProxyView = Backbone.View.extend({
+ events: {
+ "click #add-proxy-btn": "handleAddProxy"
+ },
+ initialize : function(settings) {
+ $('#proxyErrorMsg').hide();
+ },
+ display: function() {
+ $(this.el).modal({
+ closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
+ position: ["20%",],
+ containerId: 'confirm-container',
+ containerCss: {
+ 'height': '220px',
+ 'width': '565px'
+ },
+ onShow: function (dialog) {
+ var modal = this;
+ $("#errorMsg").hide();
+ }
+ });
+ },
+ handleAddProxy: function() {
+ var requestURL = contextURL + "/manager";
+ var name = $('#proxy-user-box').val();
+
+ $.get(
+ requestURL,
+ {"project": projectName, "name": name, "ajax":"addProxyUser"},
+ function(data) {
+ console.log("Output");
+ if (data.error) {
+ $("#proxyErrorMsg").text(data.error);
+ $("#proxyErrorMsg").show();
+ return;
+ }
+
+ var replaceURL = requestURL + "?project=" + projectName +"&permissions";
+ window.location.replace(replaceURL);
+ },
+ "json"
+ );
+ }
+});
var changePermissionView;
azkaban.ChangePermissionView= Backbone.View.extend({
@@ -44,7 +151,6 @@ azkaban.ChangePermissionView= Backbone.View.extend({
$('#user-box').val(this.userid);
this.newPerm = newPerm;
this.group = group;
- this.proxy = proxy;
var prefix = userid;
var adminInput = $("#" + prefix + "-admin-checkbox");
@@ -52,7 +158,6 @@ azkaban.ChangePermissionView= Backbone.View.extend({
var writeInput = $("#" + prefix + "-write-checkbox");
var executeInput = $("#" + prefix + "-execute-checkbox");
var scheduleInput = $("#" + prefix + "-schedule-checkbox");
- var proxyInput = $("#" + prefix + "-proxy-checkbox");
if (newPerm) {
if (group) {
@@ -72,39 +177,22 @@ azkaban.ChangePermissionView= Backbone.View.extend({
this.permission.write = false;
this.permission.execute = false;
this.permission.schedule = false;
- this.doProxy = false;
-
}
else {
if (group) {
$('#change-title').text("Change Group Permissions");
}
- else if(proxy){
- $('#change-title').text("Change Proxy User Permissions");
- this.doProxy = $(proxyInput).attr("checked");
- }
else {
$('#change-title').text("Change User Permissions");
}
$('#user-box').attr("disabled", "disabled");
-
-
- this.permission.admin = $(adminInput).attr("checked");
- this.permission.read = $(readInput).attr("checked");
- this.permission.write = $(writeInput).attr("checked");
- this.permission.execute = $(executeInput).attr("checked");
- this.permission.schedule = $(scheduleInput).attr("checked");
- this.doProxy = $(proxyInput).attr("checked");
- }
-
- if(proxy) {
- document.getElementById("otherCheckBoxes").hidden=true;
- document.getElementById("proxyCheckBox").hidden=false;
- } else {
- document.getElementById("otherCheckBoxes").hidden=false;
- document.getElementById("proxyCheckBox").hidden=true;
+ this.permission.admin = $(adminInput).is(":checked");
+ this.permission.read = $(readInput).is(":checked");
+ this.permission.write = $(writeInput).is(":checked");
+ this.permission.execute = $(executeInput).is(":checked");
+ this.permission.schedule = $(scheduleInput).is(":checked");
}
this.changeCheckbox();
@@ -123,9 +211,6 @@ azkaban.ChangePermissionView= Backbone.View.extend({
$("#errorMsg").hide();
}
});
-
-
-
},
render: function() {
},
@@ -142,8 +227,6 @@ azkaban.ChangePermissionView= Backbone.View.extend({
},
changeCheckbox : function(evt) {
var perm = this.permission;
- var proxy = this.proxy;
- var doProxy = this.doProxy;
if (perm.admin) {
$("#admin-change").attr("checked", true);
@@ -158,9 +241,6 @@ azkaban.ChangePermissionView= Backbone.View.extend({
$("#schedule-change").attr("checked", true);
$("#schedule-change").attr("disabled", "disabled");
-
- $("#proxy-change").attr("checked", false);
- $("#proxy-change").attr("disabled", "disabled");
}
else {
$("#admin-change").attr("checked", false);
@@ -176,16 +256,12 @@ azkaban.ChangePermissionView= Backbone.View.extend({
$("#schedule-change").attr("checked", perm.schedule);
$("#schedule-change").attr("disabled", null);
-
- $("#proxy-change").attr("checked", doProxy);
- $("#proxy-change").attr("disabled", null);
-
}
$("#change-btn").removeClass("btn-disabled");
$("#change-btn").attr("disabled", null);
- if (perm.admin || perm.read || perm.write || perm.execute || perm.schedule || doProxy) {
+ if (perm.admin || perm.read || perm.write || perm.execute || perm.schedule) {
$("#change-btn").text("Commit");
}
else {
@@ -202,14 +278,18 @@ azkaban.ChangePermissionView= Backbone.View.extend({
var requestURL = contextURL + "/manager";
var name = $('#user-box').val();
var command = this.newPerm ? "addPermission" : "changePermission";
- if(this.proxy) {
- command = "addProxyUser";
- }
var group = this.group;
+ var permission = {};
+ permission.admin = $("#admin-change").is(":checked");
+ permission.read = $("#read-change").is(":checked");
+ permission.write = $("#write-change").is(":checked");
+ permission.execute = $("#execute-change").is(":checked");
+ permission.schedule = $("#schedule-change").is(":checked");
+
$.get(
requestURL,
- {"project": projectName, "name": name, "ajax":command, "permissions": this.permission, "doProxy": this.doProxy, "group": group},
+ {"project": projectName, "name": name, "ajax":command, "permissions": this.permission, "group": group},
function(data) {
console.log("Output");
if (data.error) {
@@ -229,9 +309,10 @@ azkaban.ChangePermissionView= Backbone.View.extend({
$(function() {
permissionTableView = new azkaban.PermissionTableView({el:$('#permissions-table'), group: false, proxy: false});
groupPermissionTableView = new azkaban.PermissionTableView({el:$('#group-permissions-table'), group: true, proxy: false});
- proxyTableView = new azkaban.PermissionTableView({el:$('#proxy-user-table'), group: false, proxy: true});
+ proxyTableView = new azkaban.ProxyTableView({el:$('#proxy-user-table'), group: false, proxy: true});
changePermissionView = new azkaban.ChangePermissionView({el:$('#change-permission')});
-
+ addProxyView = new azkaban.AddProxyView({el:$('#add-proxy')});
+ removeProxyView = new azkaban.RemoveProxyView({el:$('#remove-proxy')});
$('#addUser').bind('click', function() {
changePermissionView.display("", true, false, false);
});
@@ -241,7 +322,7 @@ $(function() {
});
$('#addProxyUser').bind('click', function() {
- changePermissionView.display("", true, false, true);
+ addProxyView.display();
});
});