You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ey...@apache.org on 2011/09/30 03:10:44 UTC

svn commit: r1177472 - in /incubator/ambari/trunk: agent/src/main/python/ambari_agent/ client/src/main/java/org/apache/ambari/common/rest/entities/agent/ controller/conf/ controller/src/main/java/org/apache/ambari/controller/ controller/src/main/java/o...

Author: eyang
Date: Fri Sep 30 01:10:43 2011
New Revision: 1177472

URL: http://svn.apache.org/viewvc?rev=1177472&view=rev
Log:
AMBARI-15. Implemented controller side of authentication. (Eric Yang)
AMBARI-11. Renamed serverName to role, and send heartbeat more eagerly if there is pending results. (Eric Yang)

Added:
    incubator/ambari/trunk/controller/conf/auth.conf
Modified:
    incubator/ambari/trunk/agent/src/main/python/ambari_agent/ActionQueue.py
    incubator/ambari/trunk/agent/src/main/python/ambari_agent/Controller.py
    incubator/ambari/trunk/agent/src/main/python/ambari_agent/ServerStatus.py
    incubator/ambari/trunk/agent/src/main/python/ambari_agent/shell.py
    incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/Action.java
    incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ActionResult.java
    incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ServerStatus.java
    incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java
    incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java
    incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ControllerResource.java
    incubator/ambari/trunk/controller/src/main/resources/WEB-INF/jetty.xml
    incubator/ambari/trunk/controller/src/main/resources/WEB-INF/web.xml

Modified: incubator/ambari/trunk/agent/src/main/python/ambari_agent/ActionQueue.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/agent/src/main/python/ambari_agent/ActionQueue.py?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/agent/src/main/python/ambari_agent/ActionQueue.py (original)
+++ incubator/ambari/trunk/agent/src/main/python/ambari_agent/ActionQueue.py Fri Sep 30 01:10:43 2011
@@ -67,20 +67,22 @@ class ActionQueue(threading.Thread):
                'id'         : action['id'], 
                'clusterId'  : action['clusterId'],
                'kind'       : action['kind'], 
-               'serverName' : action['serverName'] 
+               'component'  : action['component'], 
+               'role'       : action['role'] 
              }
-    self.sh.startProcess(action['serverName'], action['commands'][0]['cmd'], action['user'])
+    self.sh.startProcess(action['component'], action['role'], action['commands'][0]['cmd'], action['user'])
     return result
 
   # Run stop action, stop a server process.
   def stopAction(self, action):
     result = { 
-               'id': action['id'], 
-               'kind': action['kind'], 
-               'clusterId': action['clusterId'], 
-               'serverName': action['serverName']
+               'id'        : action['id'], 
+               'kind'      : action['kind'], 
+               'clusterId' : action['clusterId'], 
+               'component' : action['component'],
+               'role'      : action['role']
              }
-    self.sh.stopProcess(action['serverName'], action['signal'])
+    self.sh.stopProcess(action['component'], action['role'], action['signal'])
     return result
 
   # Run commands action
@@ -100,7 +102,7 @@ class ActionQueue(threading.Thread):
       script = cmd['cmd']
       if script[0]=="ambari-write-file":
         response = writeFile(script)
-      else
+      else:
         response = self.sh.run(script, cmd['user'])
       exitCode = response['exit_code']
       if exitCode==0:

Modified: incubator/ambari/trunk/agent/src/main/python/ambari_agent/Controller.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/agent/src/main/python/ambari_agent/Controller.py?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/agent/src/main/python/ambari_agent/Controller.py (original)
+++ incubator/ambari/trunk/agent/src/main/python/ambari_agent/Controller.py Fri Sep 30 01:10:43 2011
@@ -58,11 +58,12 @@ class Controller(threading.Thread):
     id='unknown'
     if self.credential!=None:
       auth_handler = urllib2.HTTPBasicAuthHandler()
-      auth_handler.add_password(uri=self.url,
+      auth_handler.add_password(realm="Controller",
+                                uri=self.url,
                                 user=self.credential['user'],
                                 passwd=self.credential['password'])
       opener = urllib2.build_opener(auth_handler)
-      urllib2.install_openner(opener)
+      urllib2.install_opener(opener)
     while True:
       try:
         data = json.dumps(self.heartbeat.build(id))
@@ -76,7 +77,10 @@ class Controller(threading.Thread):
         self.actionQueue.put(data)
       except URLError, err:
         logger.error(err.code)
-      time.sleep(5)
+      if self.actionQueue.isIdle():
+        time.sleep(30)
+      else:
+        time.sleep(1)
 
 def main(argv=None):
   # Allow Ctrl-C
@@ -107,7 +111,8 @@ def main(argv=None):
 
   logger.info('Starting Controller RPC Thread: %s' % ' '.join(sys.argv))
 
-  controller = Controller(options.url, None)
+  credential = { 'user' : 'controller', 'password' : 'controller' }
+  controller = Controller(options.url, credential)
   controller.start()
   controller.run()
 

Modified: incubator/ambari/trunk/agent/src/main/python/ambari_agent/ServerStatus.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/agent/src/main/python/ambari_agent/ServerStatus.py?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/agent/src/main/python/ambari_agent/ServerStatus.py (original)
+++ incubator/ambari/trunk/agent/src/main/python/ambari_agent/ServerStatus.py Fri Sep 30 01:10:43 2011
@@ -31,7 +31,13 @@ class ServerStatus:
     list = []
     servers = sh.getServerTracker()
     for server in servers:
-      list.append({ server : 'STARTED' })
+      (component, role) = server.split(".")
+      result = {
+                 'component' : component,
+                 'role' : role,
+                 'state' : 'STARTED'
+               }
+      list.append(result)
     return list
 
 def main(argv=None):

Modified: incubator/ambari/trunk/agent/src/main/python/ambari_agent/shell.py
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/agent/src/main/python/ambari_agent/shell.py?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/agent/src/main/python/ambari_agent/shell.py (original)
+++ incubator/ambari/trunk/agent/src/main/python/ambari_agent/shell.py Fri Sep 30 01:10:43 2011
@@ -41,31 +41,33 @@ class shellRunner:
     return {'exit_code': code, 'output': out, 'error': err}
 
   # Start a process and presist its state
-  def startProcess(self, serverName, script, user):
+  def startProcess(self, component, role, script, user):
     global serverTracker
-    if not serverName in serverTracker:
+    process = component+"."+role
+    if not process in serverTracker:
       cmd = " "
       cmd = cmd.join(script)
       child_pid = os.fork()
       if child_pid == 0:
         p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, close_fds=True)
         p.wait()
-        serverTracker[serverName] = None
+        serverTracker[process] = None
       else:
-        serverTracker[serverName] = child_pid
+        serverTracker[process] = child_pid
 
   # Stop a process and remove presisted state
-  def stopProcess(self, serverName, sig):
+  def stopProcess(self, component, role, sig):
     global serverTracker
-    if serverName in serverTracker:
+    process = component+"."+role
+    if process in serverTracker:
       if sig=='TERM':
-        os.kill(serverTracker[serverName], signal.SIGTERM)
+        os.kill(serverTracker[process], signal.SIGTERM)
         # TODO: gracefully check if process is still alive
         # before remove from serverTracker
-        del serverTracker[serverName]
+        del serverTracker[process]
       else:
-        os.kill(serverTracker[serverName], signal.SIGKILL)
-        del serverTracker[serverName]
+        os.kill(serverTracker[process], signal.SIGKILL)
+        del serverTracker[process]
 
   def getServerTracker(self):
     return serverTracker

Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/Action.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/Action.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/Action.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/Action.java Fri Sep 30 01:10:43 2011
@@ -42,7 +42,7 @@ public class Action {
   @XmlElement
   public String component;
   @XmlElement
-  public String serverName;
+  public String role;
   @XmlElement
   public Signal signal;
   @XmlElement
@@ -86,16 +86,16 @@ public class Action {
     return component;
   }
   
-  public String getServerName() {
-    return serverName;
+  public String getRole() {
+    return role;
   }
   
   public void setComponent(String component) {
     this.component = component;
   }
   
-  public void setServerName(String serverName) {
-    this.serverName = serverName;
+  public void setRole(String role) {
+    this.role = role;
   }
   
   public Signal getSignal() {

Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ActionResult.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ActionResult.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ActionResult.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ActionResult.java Fri Sep 30 01:10:43 2011
@@ -50,7 +50,7 @@ public class ActionResult {
   @XmlElement
   private String component;
   @XmlElement
-  private String serverName;
+  private String role;
 
   public String getClusterId() {
     return clusterId;
@@ -97,15 +97,15 @@ public class ActionResult {
     return this.component;
   }
   
-  public String getServerName() {
-    return serverName;
-  }
-  
   public void setComponent(String component) {
     this.component = component;
   }
+
+  public String getRole() {
+    return role;
+  }  
   
-  public void setServerName(String serverName) {
-    this.serverName = serverName;
+  public void setRole(String role) {
+    this.role = role;
   }
 }

Modified: incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ServerStatus.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ServerStatus.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ServerStatus.java (original)
+++ incubator/ambari/trunk/client/src/main/java/org/apache/ambari/common/rest/entities/agent/ServerStatus.java Fri Sep 30 01:10:43 2011
@@ -29,15 +29,15 @@ import javax.xml.bind.annotation.adapter
 @XmlType(name = "", propOrder = {})
 public class ServerStatus {
   public String component;
-  public String serverName;
+  public String role;
   public State state;
   
   public ServerStatus() {  
   }
   
-  public ServerStatus(String component, String serverName, State state) {
+  public ServerStatus(String component, String role, State state) {
     this.component = component;
-    this.serverName = serverName;
+    this.role = role;
     this.state = state;
   }
 
@@ -49,12 +49,12 @@ public class ServerStatus {
     this.component = component;  
   }
   
-  public String getServerName() {
-    return serverName;
+  public String getRole() {
+    return role;
   }
   
-  public void setServerName(String serverName) {
-    this.serverName = serverName;
+  public void setServerName(String role) {
+    this.role = role;
   }
   
   public State getState() {

Added: incubator/ambari/trunk/controller/conf/auth.conf
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/conf/auth.conf?rev=1177472&view=auto
==============================================================================
--- incubator/ambari/trunk/controller/conf/auth.conf (added)
+++ incubator/ambari/trunk/controller/conf/auth.conf Fri Sep 30 01:10:43 2011
@@ -0,0 +1 @@
+controller: controller, user

Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/Controller.java Fri Sep 30 01:10:43 2011
@@ -24,7 +24,15 @@ import org.apache.commons.logging.LogFac
 import org.apache.ambari.common.util.DaemonWatcher;
 import org.apache.ambari.common.util.ExceptionUtil;
 
+import org.mortbay.jetty.Handler;
 import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.DefaultHandler;
+import org.mortbay.jetty.handler.HandlerCollection;
+import org.mortbay.jetty.security.Constraint;
+import org.mortbay.jetty.security.ConstraintMapping;
+import org.mortbay.jetty.security.HashUserRealm;
+import org.mortbay.jetty.security.SecurityHandler;
+import org.mortbay.jetty.security.UserRealm;
 import org.mortbay.jetty.servlet.Context;
 import org.mortbay.jetty.servlet.DefaultServlet;
 import org.mortbay.jetty.servlet.ServletHolder;
@@ -67,6 +75,22 @@ public class Controller {
         "org.apache.ambari.controller.rest.config.ExtendedWadlGeneratorConfig");
       root.addServlet(sh, "/v1/*");
       sh.setInitOrder(2);
+      
+      Constraint constraint = new Constraint();
+      constraint.setName(Constraint.__BASIC_AUTH);;
+      constraint.setRoles(new String[]{"user","admin","moderator"});
+      constraint.setAuthenticate(true);
+       
+      ConstraintMapping cm = new ConstraintMapping();
+      cm.setConstraint(constraint);
+      cm.setPathSpec("/v1/controller/*");
+      
+      SecurityHandler security = new SecurityHandler();
+      security.setUserRealm(new HashUserRealm("Controller",
+          System.getenv("AMBARI_CONF_DIR")+"/auth.conf"));
+      security.setConstraintMappings(new ConstraintMapping[]{cm});
+
+      root.addHandler(security);
       server.setStopAtShutdown(true);
       server.start();
     } catch (Exception e) {

Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/HeartbeatHandler.java Fri Sep 30 01:10:43 2011
@@ -108,7 +108,7 @@ public class HeartbeatHandler {
       for (ServerStatus status : serverStatuses) {
         if (status.getState() == State.STARTED) {
           componentServers.serverStarted(status.getComponent(), 
-              status.getServerName());
+              status.getRole());
         }
       }
 

Modified: incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ControllerResource.java
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ControllerResource.java?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ControllerResource.java (original)
+++ incubator/ambari/trunk/controller/src/main/java/org/apache/ambari/controller/rest/resources/ControllerResource.java Fri Sep 30 01:10:43 2011
@@ -83,7 +83,7 @@ public class ControllerResource {
     Action action = new Action();
     action.setUser("hdfs");
     action.setComponent("hdfs");
-    action.setServerName("datanode");
+    action.setRole("datanode");
     action.setKind(Kind.STOP_ACTION);
     action.setSignal(Signal.KILL);
     action.setClusterId("cluster-001");
@@ -97,7 +97,7 @@ public class ControllerResource {
     action2.setCommands(commands);
     action2.setCleanUpCommands(cleanUps);
     action2.setComponent("hdfs");
-    action2.setServerName("datanode");
+    action2.setRole("datanode");
 
     Action action3 = new Action();
     action3.setUser("hdfs");
@@ -147,7 +147,7 @@ public class ControllerResource {
       actionResult2.setCleanUpResults(cleanUpResults);
       actionResult2.setKind(Kind.START_ACTION);
       actionResult2.setComponent("hadoop");
-      actionResult2.setServerName("datanode");
+      actionResult2.setRole("datanode");
 
       actionResults.add(actionResult);
       actionResults.add(actionResult2);
@@ -206,7 +206,7 @@ public class ControllerResource {
     Action action = new Action();
     action.setUser("hdfs");
     action.setComponent("hdfs");
-    action.setServerName("datanode");
+    action.setRole("datanode");
     action.setKind(Kind.STOP_ACTION);
     action.setSignal(Signal.KILL);
     action.setClusterId("cluster-001");
@@ -220,11 +220,28 @@ public class ControllerResource {
     action2.setCommands(commands);
     action2.setCleanUpCommands(cleanUps);
     action2.setComponent("hdfs");
-    action2.setServerName("datanode");
+    action2.setRole("datanode");
     
+    Action action3 = new Action();
+    action3.setUser("hdfs");
+    action3.setKind(Kind.RUN_ACTION);
+    action3.setId("action-003");
+    action3.setClusterId("cluster-002");
+    List<Command> configFiles = new ArrayList<Command>();
+    String[] writeFile = { 
+        "ambari-write-file",
+        "hdfs",
+        "hadoop",
+        "0700",
+        "/tmp/test",
+        "content of file"
+        };
+    configFiles.add(new Command("hdfs", writeFile));
+    action3.setCommands(configFiles);
     List<Action> actions = new ArrayList<Action>();
     actions.add(action);
     actions.add(action2);
+    actions.add(action3);
     controllerResponse.setActions(actions);
     return controllerResponse;
   }

Modified: incubator/ambari/trunk/controller/src/main/resources/WEB-INF/jetty.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/resources/WEB-INF/jetty.xml?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/resources/WEB-INF/jetty.xml (original)
+++ incubator/ambari/trunk/controller/src/main/resources/WEB-INF/jetty.xml Fri Sep 30 01:10:43 2011
@@ -206,4 +206,19 @@
     <Set name="sendDateHeader">true</Set>
     <Set name="gracefulShutdown">1000</Set>
 
+    <!-- =========================================================== -->
+    <!-- shared key authentication                                   -->
+    <!-- =========================================================== -->
+    <Set name="UserRealms">
+      <Array type="org.mortbay.jetty.security.UserRealm">
+        <Item>
+          <New class="org.mortbay.jetty.security.HashUserRealm">
+           <Set name="name">Auth</Set>
+           <Set name="config"><SystemProperty name="AMBARI_CONF_DIR" default="."/>/auth.conf</Set>
+           <Set name="refreshInterval">0</Set>
+          </New>
+        </Item>
+      </Array>
+    </Set>
+
 </Configure>

Modified: incubator/ambari/trunk/controller/src/main/resources/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/controller/src/main/resources/WEB-INF/web.xml?rev=1177472&r1=1177471&r2=1177472&view=diff
==============================================================================
--- incubator/ambari/trunk/controller/src/main/resources/WEB-INF/web.xml (original)
+++ incubator/ambari/trunk/controller/src/main/resources/WEB-INF/web.xml Fri Sep 30 01:10:43 2011
@@ -23,9 +23,9 @@
    version="2.5"> 
 
     <description>
-      HMS Controller
+      Ambari Controller
     </description>
-    <display-name>HMS Controller</display-name>
+    <display-name>Ambari Controller</display-name>
 
     <servlet>
       <servlet-name>REST_API</servlet-name>
@@ -42,4 +42,22 @@
       <url-pattern>/v1/*</url-pattern>
     </servlet-mapping>    
 
+    <security-role>
+    <role-name>user</role-name>
+    </security-role>
+
+    <login-config>
+    <realm-name>Controller</realm-name>
+    </login-config>
+
+    <security-constraint>
+    <web-resource-collection>
+    <web-resource-name>Controller Resource</web-resource-name>
+    <url-pattern>/v1/controller/*</url-pattern>
+    </web-resource-collection>
+
+    <auth-constraint>
+    <role-name>user</role-name>
+    </auth-constraint>
+    </security-constraint>
 </web-app>