Explorar o código

AMBARI-1059. Refactor cluster management. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418929 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako %!s(int64=12) %!d(string=hai) anos
pai
achega
2e87803c3d

+ 25 - 0
ambari-web/app/assets/data/users/users.json

@@ -0,0 +1,25 @@
+{
+  "href": "http://ambari:8080/api/clusters/mycluster/users",
+  "items": [
+    {
+      "href" : "http://ambari:8080/api/users/admin",
+      "Users" :
+      { "user_name" : "admin", "roles" : "admin,user" }
+    },
+    {
+      "href" : "http://ambari:8080/api/users/user",
+      "Users" :
+      { "user_name" : "user", "roles" : "user" }
+    },
+    {
+      "href" : "http://ambari:8080/api/users/john",
+      "Users" :
+      { "user_name" : "john", "roles" : "admin,user" }
+    },
+    {
+      "href" : "http://ambari:8080/api/users/mike",
+      "Users" :
+      { "user_name" : "mike", "roles" : "user" }
+    }
+  ]
+}

+ 12 - 0
ambari-web/app/assets/data/wizard/stack/hdp/version01/MAPREDUCE.json

@@ -681,6 +681,18 @@
       "value": "128",
       "description": "Limit on the length of counter group names in jobs. Names\n  exceeding this limit will be truncated.\n  ",
       "filename": "mapred-site.xml"
+    },
+    {
+      "name": "mapreduce.history.server.embedded",
+      "value": "false",
+      "description": "",
+      "filename": "mapred-site.xml"
+    },
+    {
+      "name": "mapreduce.history.server.http.address",
+      "value": "localhost:51111",
+      "description": "",
+      "filename": "mapred-site.xml"
     }
   ],
   "components": [

+ 19 - 12
ambari-web/app/controllers/global/cluster_controller.js

@@ -39,7 +39,8 @@ App.ClusterController = Em.Controller.extend({
     'services': false,
     'cluster' : false,
     'racks' : false,
-    'alerts' : false
+    'alerts' : false,
+    'users' : false
   }),
   /**
    * load cluster name
@@ -72,8 +73,8 @@ App.ClusterController = Em.Controller.extend({
   /**
    * Provides the URL to use for NAGIOS server. This URL
    * is helpful in getting alerts data from server and also
-   * in populating links in UI. 
-   * 
+   * in populating links in UI.
+   *
    * If null is returned, it means NAGIOS service is not installed.
    */
   nagiosUrl: function () {
@@ -98,7 +99,7 @@ App.ClusterController = Em.Controller.extend({
       return null;
     }
   }.property('dataLoadList.services'),
-  
+
   isNagiosInstalled: function(){
     if(App.testMode){
       return true;
@@ -108,7 +109,7 @@ App.ClusterController = Em.Controller.extend({
       return nagiosSvc!=null;
     }
   }.property('dataLoadList.services'),
-  
+
   /**
    * Sorted list of alerts.
    * Changes whenever alerts are loaded.
@@ -129,9 +130,9 @@ App.ClusterController = Em.Controller.extend({
     });
     return sortedArray;
   }.property('dataLoadList.alerts'),
-  
+
   /**
-   * This method automatically loads alerts when Nagios URL 
+   * This method automatically loads alerts when Nagios URL
    * changes. Once done it will trigger dataLoadList.alerts
    * property, which will trigger the alerts property.
    */
@@ -163,7 +164,7 @@ App.ClusterController = Em.Controller.extend({
       console.log("No Nagios URL provided.")
     }
   }.observes('nagiosUrl'),
-  
+
   /**
    *
    *  load all data and update load status
@@ -178,7 +179,7 @@ App.ClusterController = Em.Controller.extend({
      var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=*');
      var servicesUrl1 = this.getUrl('/data/dashboard/services.json', '/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/host_components/*');
      var servicesUrl2 = this.getUrl('/data/dashboard/services.json', '/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/ServiceComponentInfo');
-
+     var usersUrl = this.getUrl('/data/users/users.json', '/users/?fields=*');
      var runsUrl = App.testMode ? "/data/apps/runs.json" : "/api/jobhistory/workflow";
 
      var racksUrl = "/data/racks/racks.json";
@@ -205,7 +206,13 @@ App.ClusterController = Em.Controller.extend({
         self.updateLoadStatus('hosts');
       }
     });
-    
+
+    App.HttpClient.get(usersUrl, App.usersMapper,{
+      complete:function(jqXHR, textStatus){
+        self.updateLoadStatus('users');
+      }
+    });
+
     //////////////////////////////
     // Hack for services START  //
     //////////////////////////////
@@ -245,7 +252,7 @@ App.ClusterController = Em.Controller.extend({
               }
             });
             nameNode1.ServiceComponentInfo = nameNode2.ServiceComponentInfo;
-            
+
             App.servicesMapper.map(metricsJson);
             self.updateLoadStatus('services');
           }
@@ -262,7 +269,7 @@ App.ClusterController = Em.Controller.extend({
     /////////////////////////////
     // Hack for services END   //
     /////////////////////////////
-    
+
   }.observes('clusterName'),
   clusterName: function(){
     return (this.get('cluster')) ? this.get('cluster').Clusters.cluster_name : 'mycluster';

+ 31 - 0
ambari-web/app/controllers/main/admin/user/edit.js

@@ -20,5 +20,36 @@ var App = require('app');
 
 App.MainAdminUserEditController = Em.Controller.extend({
   name:'mainAdminUserEditController',
+  sendCommandToServer : function(url, postData, callback){
+    var url =  (App.testMode) ?
+        '/data/wizard/deploy/poll_1.json' : //content is the same as ours
+        '/api/clusters/' + App.router.getClusterName() + url;
+
+    var method = App.testMode ? 'GET' : 'PUT';
+
+    $.ajax({
+      type: method,
+      url: url,
+      data: JSON.stringify(postData),
+      dataType: 'json',
+      timeout: 5000,
+      success: function(data){
+        if(data && data.Requests){
+          callback(data.Requests.id);
+        } else{
+          callback(null);
+          console.log('cannot get request id from ', data);
+        }
+      },
+
+      error: function (request, ajaxOptions, error) {
+        //do something
+        callback(null);
+        console.log('error on change component host status')
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
   content:false
 })

+ 1 - 1
ambari-web/app/controllers/wizard/step2_controller.js

@@ -138,7 +138,7 @@ App.WizardStep2Controller = Em.Controller.extend({
       return false;
     }
 
-    var bootStrapData = JSON.stringify({'sshKey': this.get('sshKey'), hosts: this.get('hostNameArr')});
+    var bootStrapData = JSON.stringify({'verbose': true, 'sshKey': this.get('sshKey'), hosts: this.get('hostNameArr')});
 
     // TODO: skipping bootstrap for now
     if (true) {

+ 6 - 0
ambari-web/app/controllers/wizard/step8_controller.js

@@ -104,6 +104,9 @@ App.WizardStep8Controller = Em.Controller.extend({
   getGlobConfigValue: function (templateName, expression) {
     var express = expression.match(/<(.*?)>/g);
     var value = expression;
+    if (express == null) {
+      return expression;
+    }
     express.forEach(function (_express) {
       //console.log("The value of template is: " + _express);
       var index = parseInt(_express.match(/\[([\d]*)(?=\])/)[1]);
@@ -907,7 +910,10 @@ App.WizardStep8Controller = Em.Controller.extend({
     var mrProperties = {};
     configs.forEach(function (_configProperty) {
       mrProperties[_configProperty.name] = _configProperty.value;
+      console.log("STEP*: name of the property is: " + _configProperty.name);
+      console.log("STEP8: value of the property is: " + _configProperty.value);
     }, this);
+
     return {type: 'mapred-site', tag: 'version1', properties: mrProperties};
   },
 

+ 9 - 2
ambari-web/app/data/config_mapping.js

@@ -444,10 +444,10 @@ module.exports = [
     "filename": "mapred-site.xml"
   },
   {
-    "name": "mapred.job.tracker.http.addres",
+    "name": "mapred.job.tracker.http.address",
     "templateName": ["jobtracker_host"],
     "foreignKey": null,
-    "value": "<templateName[0]>:50300",
+    "value": "<templateName[0]>:50030",
     "filename": "mapred-site.xml"
   },
   {
@@ -499,6 +499,13 @@ module.exports = [
     "value": "<templateName[0]>\/tt.service.keytab",
     "filename": "mapred-site.xml"
   },
+  {
+    "name": "mapreduce.history.server.embedded",
+    "templateName": [],
+    "foreignKey": null,
+    "value": "false",
+    "filename": "mapred-site.xml"
+  },
   {
     "name": "mapreduce.history.server.http.address",
     "templateName": ["jobtracker_host"],

+ 13 - 0
ambari-web/app/data/config_properties.js

@@ -1389,6 +1389,19 @@ module.exports =
       "isVisible": true,
       "serviceName": "MAPREDUCE"
     },
+    /* TODO: Uncomment when RCA integration is ready
+    {
+      "id": "puppet var",
+      "name": "enable_rca",
+      "displayName": "Enable RCA",
+      "description": "Enable RCA",
+      "defaultValue": true,
+      "isReconfigurable": true,
+      "displayType": "checkbox",
+      "isVisible": true,
+      "serviceName": "MAPREDUCE"
+    },
+    */
     /*{
       "id": "puppet var",
       "name": "mapred-site.xml",

+ 1 - 0
ambari-web/app/initialize.js

@@ -38,6 +38,7 @@ require('mappers/jobs_mapper');
 require('mappers/runs_mapper');
 require('mappers/racks_mapper');
 require('mappers/alerts_mapper');
+require('mappers/users_mapper');
 
 require('utils/http_client');
 

+ 27 - 0
ambari-web/app/mappers/users_mapper.js

@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+App.usersMapper = App.QuickDataMapper.create({
+  model : App.User,
+  config : {
+    user_name : 'Users.user_name',
+    roles : 'Users.roles'
+  }
+
+});

+ 8 - 4
ambari-web/app/models/user.js

@@ -26,9 +26,12 @@ App.UserModel = Em.Object.extend({
 
 App.User = DS.Model.extend({
   userName:DS.attr('string'),
-  admin:DS.attr('boolean'),
   password:DS.attr('string'),
-  auditItems:DS.hasMany('App.ServiceAudit')
+  roles:DS.attr('string'),
+  auditItems:DS.hasMany('App.ServiceAudit'),
+  admin: function () {
+    return !!(/^admin/.test(this.get('roles')))
+  }.property('userName')
 });
 
 App.UserForm = App.Form.extend({
@@ -88,7 +91,8 @@ App.UserForm = App.Form.extend({
     return isValid;
   }
 });
-
+App.User.FIXTURES = [];
+/*
 App.User.FIXTURES = [
   {
     id:1,
@@ -117,4 +121,4 @@ App.User.FIXTURES = [
     password:'test',
     admin:0
   }
-];
+];*/

+ 2 - 3
ambari-web/app/templates/main/admin/user.hbs

@@ -22,10 +22,9 @@
 <table class="table table-bordered table-striped span6">
   <thead>
   <tr>
-    <th style="width:10%">ID&nbsp;(test)</th>
     <th style="width:50%">{{t admin.users.username}}</th>
-    <th style="width:20%">{{t admin.users.privileges}}<i class="icon-question-sign"></i></th>
-    <th style="width:20%">Action</th>
+    <th style="width:15%">{{t admin.users.privileges}}<i class="icon-question-sign"></i></th>
+    <th style="width:15%">Action</th>
   </tr>
   </thead>
   <tbody>

+ 0 - 1
ambari-web/app/templates/main/admin/user/row.hbs

@@ -17,7 +17,6 @@
 }}
 
 <tr>
-  <td>{{user.id}}</td>
   <td>{{user.userName}}</td>
   <td>{{view Ember.Checkbox disabledBinding="view.disableCheckBoxes" checkedBinding="user.admin"}}</td>
   <td>

+ 1 - 1
ambari-web/app/views/main/admin.js

@@ -19,5 +19,5 @@
 var App = require('app');
 
 App.MainAdminView = Em.View.extend({
-    templateName: require('templates/main/admin'),
+    templateName: require('templates/main/admin')
 });

+ 0 - 3
ambari-web/app/views/main/admin/user.js

@@ -21,9 +21,6 @@ var App = require('app');
 App.MainAdminUserView = Em.View.extend({
   templateName: require('templates/main/admin/user'),
   users: App.User.find(),
-//  users: function(){
-//    return App.router.get('mainAdminUserController.content');
-//  }.property('mainAdminUserController.content'),
   delete: function(event, context){
     console.log("EVENT:");
     console.log(event);

+ 21 - 2
ambari-web/app/views/main/admin/user/edit.js

@@ -23,8 +23,27 @@ App.MainAdminUserEditView = Em.View.extend({
   userId: false,
   create: function(event){
     var form = this.get("userForm");
-    if(form.isValid() && form.save()) {
-      App.router.transitionTo("allUsers");
+    if(form.isValid()) {
+      var controller = this.get('controller');
+      var roles="user";
+      if(form.getValues().admin=="") roles="admin";
+      controller.sendCommandToServer('/users/' + form.getValues().userName, {
+        Users: {
+          password: form.getValues().password,
+          roles: roles
+        }
+      }, function (requestId) {
+
+        if (!requestId) {
+          return;
+        }
+
+        if(App.testMode)  form.save();
+
+        App.router.transitionTo("allUsers");
+      })
+
+
     }
   },