AMBARI-16274. Views: Simplify View Configuration for Remote Ambari Managed Cluster. (Gaurav Nagar via dipayanb)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c150f0de Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c150f0de Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c150f0de Branch: refs/heads/trunk Commit: c150f0ded83c0a2f4eac1d5bf12a0fbb643c9610 Parents: bc82a6e Author: Dipayan Bhowmick <[email protected]> Authored: Wed May 11 14:22:34 2016 +0530 Committer: Dipayan Bhowmick <[email protected]> Committed: Wed May 11 14:22:34 2016 +0530 ---------------------------------------------------------------------- .../main/resources/ui/admin-web/app/index.html | 280 ++++++++-------- .../ambariViews/CreateViewInstanceCtrl.js | 70 +++- .../controllers/ambariViews/ViewsEditCtrl.js | 86 +++-- .../remoteClusters/RemoteClustersCreateCtrl.js | 63 ++++ .../remoteClusters/RemoteClustersEditCtrl.js | 159 +++++++++ .../remoteClusters/RemoteClustersListCtrl.js | 106 ++++++ .../ui/admin-web/app/scripts/i18n.config.js | 20 +- .../ui/admin-web/app/scripts/routes.js | 17 + .../app/scripts/services/RemoteCluster.js | 118 +++++++ .../ui/admin-web/app/scripts/services/View.js | 3 +- .../resources/ui/admin-web/app/styles/main.css | 25 ++ .../admin-web/app/views/ambariViews/create.html | 38 ++- .../admin-web/app/views/ambariViews/edit.html | 50 ++- .../ui/admin-web/app/views/leftNavbar.html | 13 +- .../remoteClusters/editRemoteClusterPage.html | 77 +++++ .../app/views/remoteClusters/list.html | 80 +++++ .../remoteClusters/modals/changePassword.html | 46 +++ .../views/remoteClusters/remoteClusterPage.html | 66 ++++ .../RemoteClusterResourceDefinition.java | 51 +++ .../resources/ResourceInstanceFactoryImpl.java | 4 + .../api/services/RemoteClustersService.java | 139 ++++++++ .../internal/DefaultProviderModule.java | 2 + .../internal/RemoteClusterResourceProvider.java | 327 +++++++++++++++++++ .../internal/ViewInstanceResourceProvider.java | 9 + .../ambari/server/controller/spi/Resource.java | 4 +- .../server/orm/dao/RemoteAmbariClusterDAO.java | 101 ++++++ .../orm/entities/RemoteAmbariClusterEntity.java | 201 ++++++++++++ .../RemoteAmbariClusterServiceEntity.java | 108 ++++++ .../ambari/server/orm/entities/ViewEntity.java | 9 + .../server/orm/entities/ViewInstanceEntity.java | 29 ++ .../server/upgrade/UpgradeCatalog240.java | 37 +++ .../ambari/server/view/RemoteAmbariCluster.java | 190 +++++++++++ .../view/RemoteAmbariClusterRegistry.java | 116 +++++++ .../RemoteAmbariConfigurationReadException.java | 29 ++ .../server/view/RemoteAmbariStreamProvider.java | 118 +++++++ .../server/view/ViewAmbariStreamProvider.java | 51 +-- .../ambari/server/view/ViewContextImpl.java | 23 +- .../apache/ambari/server/view/ViewRegistry.java | 50 ++- .../server/view/configuration/ViewConfig.java | 15 + .../main/resources/Ambari-DDL-Derby-CREATE.sql | 29 +- .../main/resources/Ambari-DDL-MySQL-CREATE.sql | 25 +- .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 23 ++ .../resources/Ambari-DDL-Postgres-CREATE.sql | 25 +- .../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 29 +- .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 23 ++ .../resources/Ambari-DDL-SQLServer-CREATE.sql | 25 +- .../src/main/resources/META-INF/persistence.xml | 2 + .../RemoteClusterResourceProviderTest.java | 193 +++++++++++ .../server/upgrade/UpgradeCatalog240Test.java | 30 ++ .../server/view/RemoteAmbariClusterTest.java | 90 +++++ .../view/ViewAmbariStreamProviderTest.java | 8 +- .../view/configuration/ViewConfigTest.java | 7 + .../view/AmbariClusterStreamProvider.java | 90 +++++ .../apache/ambari/view/AmbariHttpException.java | 41 +++ .../ambari/view/AmbariStreamProvider.java | 6 +- .../org/apache/ambari/view/ClusterType.java | 40 +++ .../org/apache/ambari/view/ViewContext.java | 8 + .../ambari/view/ViewInstanceDefinition.java | 8 + ambari-views/src/main/resources/view.xsd | 5 + .../capacityscheduler/ConfigurationService.java | 43 +-- .../src/main/resources/view.xml | 25 +- .../ConfigurationServiceTest.java | 5 - .../hive/resources/uploads/UploadService.java | 2 +- .../view/slider/rest/client/BaseHttpClient.java | 28 +- .../ambari/view/utils/ambari/AmbariApi.java | 177 ++-------- .../ambari/view/utils/ambari/RemoteCluster.java | 104 ------ .../ambari/view/utils/ambari/Services.java | 8 +- .../ambari/URLStreamProviderBasicAuth.java | 122 ------- .../utils/hdfs/AuthConfigurationBuilder.java | 14 +- .../view/utils/hdfs/ConfigurationBuilder.java | 14 +- .../view/utils/ambari/RemoteClusterTest.java | 137 -------- .../ambari/view/utils/ambari/ServicesTest.java | 14 +- .../ambari/URLStreamProviderBasicAuthTest.java | 159 --------- 73 files changed, 3458 insertions(+), 1031 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/index.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/index.html b/ambari-admin/src/main/resources/ui/admin-web/app/index.html index 8d7e8e7..a4a5b28 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/index.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/index.html @@ -17,156 +17,160 @@ --> <!doctype html> <html class="no-js"> - <head> - <meta charset="utf-8"> - <title>Ambari</title> - <meta name="description" content=""> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <link rel="shortcut icon" href="/img/logo.png" type="image/x-icon"> - <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> +<head> + <meta charset="utf-8"> + <title>Ambari</title> + <meta name="description" content=""> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <link rel="shortcut icon" href="/img/logo.png" type="image/x-icon"> + <!-- Place favicon.ico and apple-touch-icon.png in the root directory --> - <!-- build:css styles/vendor.css --> - <!-- bower:css --> - <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" /> - <link rel="stylesheet" href="bower_components/angular-bootstrap-toggle-switch/style/bootstrap3/angular-toggle-switch-bootstrap-3.css" /> - <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css"/> - <!-- endbower --> - <!-- endbuild --> + <!-- build:css styles/vendor.css --> + <!-- bower:css --> + <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" /> + <link rel="stylesheet" href="bower_components/angular-bootstrap-toggle-switch/style/bootstrap3/angular-toggle-switch-bootstrap-3.css" /> + <link rel="stylesheet" href="bower_components/font-awesome/css/font-awesome.min.css"/> + <!-- endbower --> + <!-- endbuild --> - <!-- build:css styles/main.css --> - <link rel="stylesheet" href="styles/main.css"> - <!-- endbuild --> + <!-- build:css styles/main.css --> + <link rel="stylesheet" href="styles/main.css"> + <!-- endbuild --> - </head> - <body ng-app="ambariAdminConsole"> - <!--[if lt IE 9]> - <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> - <![endif]--> +</head> +<body ng-app="ambariAdminConsole"> +<!--[if lt IE 9]> +<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> +<![endif]--> - <div id="top-nav" ng-controller="MainCtrl"> - <header class="navbar navbar-static-top navbar-inverse"> - <div class="navbar-inner"> - <div class="container"> - <a href="/#/main/dashboard" class="logo"><img src="/img/logo-white.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}"></a> - <a href="/#/main/dashboard" class="brand" title="{{'common.apacheAmbari' | translate}}">{{'common.ambari' | translate}}</a> - <ul class="nav navbar-nav navbar-right"> - <li> - <div class="btn-group navbar-views-dropdown" dropdown is-open="viewsdropdown.isopen" ng-mouseover="viewsdropdown.isopen=true" ng-mouseout="viewsdropdown.isopen=false"> - <a href="/#/main/views" ng-click="gotoViewsDashboard()" class="dropdown-toggle"><i class="fa fa-th"></i></a> - <ul class="dropdown-menu" role="menu"> - <li ng-repeat="instance in viewInstances"><a href="/#/main{{instance.context_path}}" ng-click="about()">{{instance.label}}</a></li> - <li ng-show="!viewInstances.length" class="disabled"><a>{{'common.noViews' | translate}}</a></li> - </ul> - </div> - </li> - <li> - <div class="btn-group" dropdown is-open="status.isopen"> - <button type="button" class="btn btn-default dropdown-toggle navbar-btn" ng-disabled="disabled"> - <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span> - </button> - <ul class="dropdown-menu" role="menu"> - <li><a href ng-click="about()">{{'common.about' | translate}}</a></li> - <li class="divider"></li> - <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li> - </ul> - </div> - </li> - </ul> - </div> - </div> - </header> +<div id="top-nav" ng-controller="MainCtrl"> + <header class="navbar navbar-static-top navbar-inverse"> + <div class="navbar-inner"> + <div class="container"> + <a href="/#/main/dashboard" class="logo"><img src="/img/logo-white.png" alt="{{'common.apacheAmbari' | translate}}" title="{{'common.apacheAmbari' | translate}}"></a> + <a href="/#/main/dashboard" class="brand" title="{{'common.apacheAmbari' | translate}}">{{'common.ambari' | translate}}</a> + <ul class="nav navbar-nav navbar-right"> + <li> + <div class="btn-group navbar-views-dropdown" dropdown is-open="viewsdropdown.isopen" ng-mouseover="viewsdropdown.isopen=true" ng-mouseout="viewsdropdown.isopen=false"> + <a href="/#/main/views" ng-click="gotoViewsDashboard()" class="dropdown-toggle"><i class="fa fa-th"></i></a> + <ul class="dropdown-menu" role="menu"> + <li ng-repeat="instance in viewInstances"><a href="/#/main{{instance.context_path}}" ng-click="about()">{{instance.label}}</a></li> + <li ng-show="!viewInstances.length" class="disabled"><a>{{'common.noViews' | translate}}</a></li> + </ul> + </div> + </li> + <li> + <div class="btn-group" dropdown is-open="status.isopen"> + <button type="button" class="btn btn-default dropdown-toggle navbar-btn" ng-disabled="disabled"> + <i class="fa fa-user"></i> {{currentUser}} <span class="caret"></span> + </button> + <ul class="dropdown-menu" role="menu"> + <li><a href ng-click="about()">{{'common.about' | translate}}</a></li> + <li class="divider"></li> + <li><a href ng-click="signOut()">{{'common.signOut' | translate}}</a></li> + </ul> + </div> + </li> + </ul> + </div> </div> + </header> +</div> - <div class="container"> - <div class="row"> - <div class="col-sm-3"> - <div ng-include="'views/leftNavbar.html'" ng-controller="NavbarCtrl"></div> - </div> - <div class="col-sm-9"> - <ng-view></ng-view> - </div> - </div> +<div class="container"> + <div class="row"> + <div class="col-sm-3"> + <div ng-include="'views/leftNavbar.html'" ng-controller="NavbarCtrl"></div> + </div> + <div class="col-sm-9"> + <ng-view></ng-view> </div> + </div> +</div> - <!-- build:js scripts/vendor.js --> - <!-- bower:js --> - <script src="bower_components/jquery/dist/jquery.js"></script> - <script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> - <script src="bower_components/angular/angular.js"></script> - <script src="bower_components/angular-animate/angular-animate.js"></script> - <script src="bower_components/angular-route/angular-route.js"></script> - <script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script> - <script src="bower_components/lodash/dist/lodash.compat.js"></script> - <script src="bower_components/restangular/dist/restangular.js"></script> - <script src="bower_components/angular-bootstrap-toggle-switch/angular-toggle-switch.min.js"></script> - <script src="bower_components/angular-translate/angular-translate.min.js"></script> - <!-- endbower --> - <!-- endbuild --> +<!-- build:js scripts/vendor.js --> +<!-- bower:js --> +<script src="bower_components/jquery/dist/jquery.js"></script> +<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script> +<script src="bower_components/angular/angular.js"></script> +<script src="bower_components/angular-animate/angular-animate.js"></script> +<script src="bower_components/angular-route/angular-route.js"></script> +<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script> +<script src="bower_components/lodash/dist/lodash.compat.js"></script> +<script src="bower_components/restangular/dist/restangular.js"></script> +<script src="bower_components/angular-bootstrap-toggle-switch/angular-toggle-switch.min.js"></script> +<script src="bower_components/angular-translate/angular-translate.min.js"></script> +<!-- endbower --> +<!-- endbuild --> - <!-- build:js scripts/plugins.js --> - <script src="bower_components/bootstrap/js/affix.js"></script> - <script src="bower_components/bootstrap/js/alert.js"></script> - <script src="bower_components/bootstrap/js/dropdown.js"></script> - <script src="bower_components/bootstrap/js/tooltip.js"></script> - <script src="bower_components/bootstrap/js/modal.js"></script> - <script src="bower_components/bootstrap/js/transition.js"></script> - <script src="bower_components/bootstrap/js/button.js"></script> - <script src="bower_components/bootstrap/js/popover.js"></script> - <script src="bower_components/bootstrap/js/carousel.js"></script> - <script src="bower_components/bootstrap/js/scrollspy.js"></script> - <script src="bower_components/bootstrap/js/collapse.js"></script> - <script src="bower_components/bootstrap/js/tab.js"></script> +<!-- build:js scripts/plugins.js --> +<script src="bower_components/bootstrap/js/affix.js"></script> +<script src="bower_components/bootstrap/js/alert.js"></script> +<script src="bower_components/bootstrap/js/dropdown.js"></script> +<script src="bower_components/bootstrap/js/tooltip.js"></script> +<script src="bower_components/bootstrap/js/modal.js"></script> +<script src="bower_components/bootstrap/js/transition.js"></script> +<script src="bower_components/bootstrap/js/button.js"></script> +<script src="bower_components/bootstrap/js/popover.js"></script> +<script src="bower_components/bootstrap/js/carousel.js"></script> +<script src="bower_components/bootstrap/js/scrollspy.js"></script> +<script src="bower_components/bootstrap/js/collapse.js"></script> +<script src="bower_components/bootstrap/js/tab.js"></script> - <!-- endbuild --> +<!-- endbuild --> - <!-- build:js scripts/main.js --> - <script src="scripts/app.js"></script> - <script src="scripts/routes.js"></script> - <script src="scripts/i18n.config.js"></script> - <script src="scripts/controllers/mainCtrl.js"></script> - <script src="scripts/controllers/NavbarCtrl.js"></script> - <script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script> - <script src="scripts/controllers/loginActivities/LoginActivitiesMainCtrl.js"></script> - <script src="scripts/controllers/loginActivities/LoginMessageMainCtrl.js"></script> - <script src="scripts/controllers/loginActivities/HomeDirectoryCtrl.js"></script> - <script src="scripts/controllers/users/UsersCreateCtrl.js"></script> - <script src="scripts/controllers/users/UsersListCtrl.js"></script> - <script src="scripts/controllers/users/UsersShowCtrl.js"></script> - <script src="scripts/controllers/groups/GroupsListCtrl.js"></script> - <script src="scripts/controllers/groups/GroupsCreateCtrl.js"></script> - <script src="scripts/controllers/groups/GroupsEditCtrl.js"></script> - <script src="scripts/controllers/ambariViews/ViewsListCtrl.js"></script> - <script src="scripts/controllers/ambariViews/ViewsEditCtrl.js"></script> - <script src="scripts/controllers/ambariViews/ViewUrlCtrl.js"></script> - <script src="scripts/controllers/ambariViews/ViewUrlEditCtrl.js"></script> - <script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script> - <script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script> - <script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script> - <script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script> - <script src="scripts/controllers/stackVersions/StackVersionsListCtrl.js"></script> - <script src="scripts/controllers/stackVersions/StackVersionsEditCtrl.js"></script> - <script src="scripts/directives/linkToDir.js"></script> - <script src="scripts/directives/PasswordVerify.js"></script> - <script src="scripts/directives/disabledTooltip.js"></script> - <script src="scripts/directives/editableList.js"></script> - <script src="scripts/services/UserConstants.js"></script> - <script src="scripts/services/User.js"></script> - <script src="scripts/services/Group.js"></script> - <script src="scripts/services/View.js"></script> - <script src="scripts/services/Cluster.js"></script> - <script src="scripts/services/Alert.js"></script> - <script src="scripts/services/PermissionLoader.js"></script> - <script src="scripts/services/PermissionsSaver.js"></script> - <script src="scripts/services/ConfirmationModal.js"></script> - <script src="scripts/services/Auth.js"></script> - <script src="scripts/services/GetDifference.js"></script> - <script src="scripts/services/UnsavedDialog.js"></script> - <script src="scripts/services/Stack.js"></script> - <script src="scripts/services/AddRepositoryModal.js"></script> - <script src="scripts/services/RoleDetailsModal.js"></script> - <!-- endbuild --> +<!-- build:js scripts/main.js --> +<script src="scripts/app.js"></script> +<script src="scripts/routes.js"></script> +<script src="scripts/i18n.config.js"></script> +<script src="scripts/controllers/mainCtrl.js"></script> +<script src="scripts/controllers/NavbarCtrl.js"></script> +<script src="scripts/controllers/authentication/AuthenticationMainCtrl.js"></script> +<script src="scripts/controllers/loginActivities/LoginActivitiesMainCtrl.js"></script> +<script src="scripts/controllers/loginActivities/LoginMessageMainCtrl.js"></script> +<script src="scripts/controllers/loginActivities/HomeDirectoryCtrl.js"></script> +<script src="scripts/controllers/users/UsersCreateCtrl.js"></script> +<script src="scripts/controllers/users/UsersListCtrl.js"></script> +<script src="scripts/controllers/users/UsersShowCtrl.js"></script> +<script src="scripts/controllers/groups/GroupsListCtrl.js"></script> +<script src="scripts/controllers/groups/GroupsCreateCtrl.js"></script> +<script src="scripts/controllers/groups/GroupsEditCtrl.js"></script> +<script src="scripts/controllers/ambariViews/ViewsListCtrl.js"></script> +<script src="scripts/controllers/ambariViews/ViewsEditCtrl.js"></script> +<script src="scripts/controllers/ambariViews/ViewUrlCtrl.js"></script> +<script src="scripts/controllers/ambariViews/ViewUrlEditCtrl.js"></script> +<script src="scripts/controllers/ambariViews/CreateViewInstanceCtrl.js"></script> +<script src="scripts/controllers/clusters/ClustersManageAccessCtrl.js"></script> +<script src="scripts/controllers/clusters/UserAccessListCtrl.js"></script> +<script src="scripts/controllers/stackVersions/StackVersionsCreateCtrl.js"></script> +<script src="scripts/controllers/stackVersions/StackVersionsListCtrl.js"></script> +<script src="scripts/controllers/stackVersions/StackVersionsEditCtrl.js"></script> +<script src="scripts/controllers/remoteClusters/RemoteClustersCreateCtrl.js"></script> +<script src="scripts/controllers/remoteClusters/RemoteClustersListCtrl.js"></script> +<script src="scripts/controllers/remoteClusters/RemoteClustersEditCtrl.js"></script> +<script src="scripts/directives/linkToDir.js"></script> +<script src="scripts/directives/PasswordVerify.js"></script> +<script src="scripts/directives/disabledTooltip.js"></script> +<script src="scripts/directives/editableList.js"></script> +<script src="scripts/services/UserConstants.js"></script> +<script src="scripts/services/User.js"></script> +<script src="scripts/services/Group.js"></script> +<script src="scripts/services/RemoteCluster.js"></script> +<script src="scripts/services/View.js"></script> +<script src="scripts/services/Cluster.js"></script> +<script src="scripts/services/Alert.js"></script> +<script src="scripts/services/PermissionLoader.js"></script> +<script src="scripts/services/PermissionsSaver.js"></script> +<script src="scripts/services/ConfirmationModal.js"></script> +<script src="scripts/services/Auth.js"></script> +<script src="scripts/services/GetDifference.js"></script> +<script src="scripts/services/UnsavedDialog.js"></script> +<script src="scripts/services/Stack.js"></script> +<script src="scripts/services/AddRepositoryModal.js"></script> +<script src="scripts/services/RoleDetailsModal.js"></script> +<!-- endbuild --> </body> </html> http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js index 127bc74..034b113 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/CreateViewInstanceCtrl.js @@ -18,7 +18,7 @@ 'use strict'; angular.module('ambariAdminConsole') -.controller('CreateViewInstanceCtrl',['$scope', 'View', 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) { +.controller('CreateViewInstanceCtrl',['$scope', 'View','RemoteCluster' , 'Alert', 'Cluster', '$routeParams', '$location', 'UnsavedDialog', '$translate', function($scope, View, RemoteCluster, Alert, Cluster, $routeParams, $location, UnsavedDialog, $translate) { var $t = $translate.instant; $scope.form = {}; $scope.constants = { @@ -54,9 +54,10 @@ angular.module('ambariAdminConsole') icon64_path: '', properties: parameters, description: '', - isLocalCluster: false + clusterType: 'NONE' }; loadClusters(); + loadRemoteClusters(); }); } @@ -91,26 +92,46 @@ angular.module('ambariAdminConsole') $scope.clusterConfigurable = false; $scope.clusterConfigurableErrorMsg = ""; $scope.clusters = []; - $scope.noClusterAvailible = true; + $scope.remoteClusters = []; + $scope.noLocalClusterAvailible = true; + $scope.noRemoteClusterAvailible = true; $scope.cluster = null; + $scope.data = {}; + $scope.data.remoteCluster = null; $scope.numberOfClusterConfigs = 0; $scope.numberOfSettingConfigs = 0; - function loadClusters () { - Cluster.getAllClusters().then(function (clusters) { - if(clusters.length >0){ - clusters.forEach(function(cluster) { - $scope.clusters.push(cluster.Clusters.cluster_name) - }); - $scope.noClusterAvailible = false; - $scope.instance.isLocalCluster = $scope.clusterConfigurable; - }else{ - $scope.clusters.push($t('common.noClusters')); - } - $scope.cluster = $scope.clusters[0]; - }); + function loadClusters() { + Cluster.getAllClusters().then(function (clusters) { + if(clusters.length >0){ + clusters.forEach(function(cluster) { + $scope.clusters.push(cluster.Clusters.cluster_name) + }); + $scope.noLocalClusterAvailible = false; + if($scope.clusterConfigurable){ + $scope.instance.clusterType = "LOCAL_AMBARI"; + } + }else{ + $scope.clusters.push($t('common.noClusters')); + } + $scope.cluster = $scope.clusters[0]; + }); } + function loadRemoteClusters() { + RemoteCluster.listAll().then(function (clusters) { + if(clusters.length >0){ + clusters.forEach(function(cluster) { + $scope.remoteClusters.push(cluster.ClusterInfo.name) + }); + $scope.noRemoteClusterAvailible = false; + }else{ + $scope.remoteClusters.push($t('common.noClusters')); + } + $scope.data.remoteCluster = $scope.remoteClusters[0]; + }); + } + $scope.versions = []; $scope.version = null; @@ -128,7 +149,20 @@ angular.module('ambariAdminConsole') $scope.form.instanceCreateForm.submitted = true; if($scope.form.instanceCreateForm.$valid){ $scope.form.instanceCreateForm.isSaving = true; - $scope.instance.clusterName = $scope.cluster; + + switch($scope.instance.clusterType) { + case 'LOCAL_AMBARI': + console.log($scope.cluster); + $scope.instance.clusterName = $scope.cluster; + break; + case 'REMOTE_AMBARI': + console.log($scope.data.remoteCluster); + $scope.instance.clusterName = $scope.data.remoteCluster; + break; + default: + $scope.instance.clusterName = null; + } + console.log($scope.instance.clusterName); View.createInstance($scope.instance) .then(function(data) { Alert.success($t('views.alerts.instanceCreated', {instanceName: $scope.instance.instance_name})); @@ -145,7 +179,7 @@ angular.module('ambariAdminConsole') var errorMessage = data.message; var showGeneralError = true; - if (data.status >= 400 && !$scope.instance.isLocalCluster) { + if (data.status >= 400 && $scope.instance.clusterType == 'NONE') { try { var errorObject = JSON.parse(errorMessage); errorMessage = errorObject.detail; http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js index 480f85d..b4a9656 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/ambariViews/ViewsEditCtrl.js @@ -18,7 +18,7 @@ 'use strict'; angular.module('ambariAdminConsole') - .controller('ViewsEditCtrl', ['$scope', '$routeParams' , 'Cluster', 'View', 'Alert', 'PermissionLoader', 'PermissionSaver', 'ConfirmationModal', '$location', 'UnsavedDialog', '$translate', function($scope, $routeParams, Cluster, View, Alert, PermissionLoader, PermissionSaver, ConfirmationModal, $location, UnsavedDialog, $translate) { + .controller('ViewsEditCtrl', ['$scope', '$routeParams', 'RemoteCluster', 'Cluster', 'View', 'Alert', 'PermissionLoader', 'PermissionSaver', 'ConfirmationModal', '$location', 'UnsavedDialog', '$translate', function($scope, $routeParams, RemoteCluster, Cluster, View, Alert, PermissionLoader, PermissionSaver, ConfirmationModal, $location, UnsavedDialog, $translate) { var $t = $translate.instant; $scope.identity = angular.identity; $scope.isConfigurationEmpty = true; @@ -62,14 +62,16 @@ angular.module('ambariAdminConsole') } function initCtrlVariables(instance) { - if(instance.ViewInstanceInfo.cluster_handle) { - $scope.isLocalCluster = true; - $scope.cluster = instance.ViewInstanceInfo.cluster_handle; - }else{ - $scope.isLocalCluster = false; - $scope.cluster = $scope.clusters.length > 0 ? $scope.clusters[0] : $t('common.noClusters'); - } - $scope.originalLocalCluster = $scope.isLocalCluster; + $scope.data.clusterType = instance.ViewInstanceInfo.cluster_type; + switch($scope.data.clusterType) { + case 'LOCAL_AMBARI': + $scope.cluster = instance.ViewInstanceInfo.cluster_handle; + break; + case 'REMOTE_AMBARI': + $scope.data.remoteCluster = instance.ViewInstanceInfo.cluster_handle; + break; + } + $scope.originalClusterType = $scope.data.clusterType; $scope.isConfigurationEmpty = !$scope.numberOfClusterConfigs; $scope.isSettingsEmpty = !$scope.numberOfSettingsConfigs; } @@ -101,7 +103,7 @@ angular.module('ambariAdminConsole') function filterClusterConfigs() { $scope.configurationMeta.forEach(function (element) { - if (element.masked && !$scope.editConfigurationDisabled && element.clusterConfig && !$scope.isLocalCluster) { + if (element.masked && !$scope.editConfigurationDisabled && element.clusterConfig && $scope.data.clusterType == 'NONE') { $scope.configuration[element.name] = ''; } if(!element.clusterConfig) { @@ -150,9 +152,13 @@ angular.module('ambariAdminConsole') $scope.clusterConfigurable = false; $scope.clusterConfigurableErrorMsg = ""; $scope.clusters = []; + $scope.remoteClusters = []; $scope.cluster = null; - $scope.noClusterAvailible = true; - + $scope.noLocalClusterAvailible = true; + $scope.noRemoteClusterAvailible = true; + $scope.data = {}; + $scope.data.remoteCluster = null; + $scope.data.clusterType = 'NONE'; $scope.editSettingsDisabled = true; $scope.editDetailsSettingsDisabled = true; @@ -199,13 +205,29 @@ angular.module('ambariAdminConsole') clusters.forEach(function(cluster) { $scope.clusters.push(cluster.Clusters.cluster_name) }); - $scope.noClusterAvailible = false; + $scope.noLocalClusterAvailible = false; }else{ $scope.clusters.push($t('common.noClusters')); } $scope.cluster = $scope.clusters[0]; }); + loadRemoteClusters(); + + function loadRemoteClusters() { + RemoteCluster.listAll().then(function (clusters) { + if(clusters.length >0){ + clusters.forEach(function(cluster) { + $scope.remoteClusters.push(cluster.ClusterInfo.name) + }); + $scope.noRemoteClusterAvailible = false; + }else{ + $scope.remoteClusters.push($t('common.noClusters')); + } + $scope.data.remoteCluster = $scope.remoteClusters[0]; + }); + } + $scope.saveSettings = function(callback) { if( $scope.settingsForm.$valid ){ @@ -292,18 +314,28 @@ angular.module('ambariAdminConsole') 'properties':{} } }; - if($scope.isLocalCluster) { - data.ViewInstanceInfo.cluster_handle = $scope.cluster; - } else { - data.ViewInstanceInfo.cluster_handle = null; - $scope.configurationMeta.forEach(function (element) { - if(element.clusterConfig) { - data.ViewInstanceInfo.properties[element.name] = $scope.configuration[element.name]; - } - }); - $scope.clearClusterInheritedPermissions(); - } - $scope.originalLocalCluster = $scope.isLocalCluster; + + data.ViewInstanceInfo.cluster_type = $scope.data.clusterType; + + switch($scope.data.clusterType) { + case 'LOCAL_AMBARI': + data.ViewInstanceInfo.cluster_handle = $scope.cluster; + break; + case 'REMOTE_AMBARI': + data.ViewInstanceInfo.cluster_handle = $scope.data.remoteCluster; + break; + default : + data.ViewInstanceInfo.cluster_handle = null; + $scope.configurationMeta.forEach(function (element) { + if(element.clusterConfig) { + data.ViewInstanceInfo.properties[element.name] = $scope.configuration[element.name]; + } + }); + $scope.clearClusterInheritedPermissions(); + + } + + $scope.originalClusterType = $scope.data.clusterType; return View.updateInstance($routeParams.viewId, $routeParams.version, $routeParams.instanceId, data) .success(function() { $scope.editConfigurationDisabled = true; @@ -315,7 +347,7 @@ angular.module('ambariAdminConsole') //TODO: maybe the BackEnd should sanitize the string beforehand? errorMessage = errorMessage.substr(errorMessage.indexOf("\{")); - if (data.status >= 400 && !$scope.isLocalCluster) { + if (data.status >= 400 && $scope.data.clusterType == 'NONE') { try { var errorObject = JSON.parse(errorMessage); errorMessage = errorObject.detail; @@ -335,7 +367,7 @@ angular.module('ambariAdminConsole') }; $scope.cancelConfiguration = function() { angular.extend($scope.configuration, $scope.configurationBeforeEdit); - $scope.isLocalCluster = $scope.originalLocalCluster; + $scope.data.clusterType = $scope.originalClusterType; $scope.editConfigurationDisabled = true; $scope.propertiesForm.$setPristine(); }; http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersCreateCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersCreateCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersCreateCtrl.js new file mode 100644 index 0000000..e669c82 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersCreateCtrl.js @@ -0,0 +1,63 @@ +/** + * 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. + */ +'use strict'; + +angular.module('ambariAdminConsole') +.controller('RemoteClustersCreateCtrl', ['$scope', '$routeParams', '$location', 'Alert', '$translate', 'Cluster', 'AddRepositoryModal' , 'Settings', 'RemoteCluster', function($scope, $routeParams, $location, Alert, $translate, Cluster, AddRepositoryModal, Settings, RemoteCluster) { + var $t = $translate.instant; + + $scope.cluster = {}; + + $scope.registerRemoteCluster = function () { + $scope.form.submitted = true; + if ($scope.form.$valid){ + var payload = { + "ClusterInfo" :{ + "name" : $scope.cluster.cluster_name, + "url" : $scope.cluster.cluster_url, + "username" : $scope.cluster.cluster_user, + "password" : $scope.cluster.cluster_password + } + }; + + var config = { + headers : { + 'X-Requested-By': 'Ambari;' + } + } + + RemoteCluster.register(payload, config).then(function(data) { + Alert.success($t('common.alerts.remoteClusterRegistered', {clusterName: payload.ClusterInfo.name})); + $scope.form.$setPristine(); + $location.path('/remoteClusters/'+ $scope.cluster.cluster_name +'/edit') + }) + .catch(function(data) { + console.log(data); + Alert.error(data.message); + }); + + } + }; + + $scope.cancel = function () { + $scope.editVersionDisabled = true; + $location.path('/remoteClusters'); + }; + + +}]); http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersEditCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersEditCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersEditCtrl.js new file mode 100644 index 0000000..20eb552 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersEditCtrl.js @@ -0,0 +1,159 @@ +/** + * 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. + */ +'use strict'; + +angular.module('ambariAdminConsole') +.controller('RemoteClustersEditCtrl', ['$scope', '$modal', '$routeParams', '$location', 'Alert', '$translate', 'Cluster', 'Settings','RemoteCluster', 'ConfirmationModal', function($scope, $modal, $routeParams, $location, Alert, $translate, Cluster, Settings, RemoteCluster, ConfirmationModal) { + var $t = $translate.instant; + + $scope.cluster = {}; + + $scope.openChangePwdDialog = function() { + var modalInstance = $modal.open({ + templateUrl: 'views/remoteClusters/modals/changePassword.html', + resolve: { + clusterName: function() { + return $scope.cluster.cluster_name; + }, + clusterUrl: function() { + return $scope.cluster.cluster_url; + }, + clusterUser: function() { + return $scope.cluster.cluster_user; + } + }, + controller: ['$scope', 'clusterName', 'clusterUrl', 'clusterUser', 'Settings','Alert', function($scope, clusterName, clusterUrl , clusterUser , Settings, Alert) { + $scope.passwordData = { + password: '', + currentUserName: clusterUser || '' + }; + + $scope.form = {}; + + $scope.currentUser = clusterUser; + $scope.clusterName = clusterName; + $scope.clusterUrl = clusterUrl; + + $scope.ok = function() { + $scope.form.passwordChangeForm.submitted = true; + + + if ($scope.form.passwordChangeForm.$valid){ + + var payload = { + "ClusterInfo" :{ + "name" : $scope.clusterName, + "url" : $scope.clusterUrl, + "username" : $scope.passwordData.currentUserName, + "password" : $scope.passwordData.password //This field will go once backend API changes are done. + } + }; + + var config = { + headers : { + 'X-Requested-By': 'Ambari;' + } + } + + RemoteCluster.edit(payload, config).then(function(data) { + Alert.success($t('views.alerts.credentialsUpdated')); + $scope.form.passwordChangeForm.$setPristine(); + }) + .catch(function(data) { + console.log(data); + Alert.error(data.message); + }); + + modalInstance.dismiss('cancel'); + } + + }; + $scope.cancel = function() { + modalInstance.dismiss('cancel'); + }; + }] + }); + }; + + $scope.deleteCluster = function() { + ConfirmationModal.show( + $t('common.deregisterCluster', { + term: $t('common.cluster') + }), + $t('common.deleteConfirmation', { + instanceType: $t('common.cluster').toLowerCase(), + instanceName: '"' + $scope.cluster.cluster_name + '"' + }) + ).then(function() { + RemoteCluster.deregister($scope.cluster.cluster_name).then(function() { + $location.path('/remoteClusters'); + }); + }); + }; + + $scope.editRemoteCluster = function () { + $scope.form.submitted = true; + if ($scope.form.$valid){ + var payload = { + "ClusterInfo" :{ + "name" : $scope.cluster.cluster_name, + "url" : $scope.cluster.cluster_url, + "username" : $scope.cluster.cluster_user + } + }; + + var config = { + headers : { + 'X-Requested-By': 'Ambari;' + } + } + + RemoteCluster.edit(payload, config).then(function(data) { + Alert.success($t('views.alerts.savedRemoteClusterInformation')); + $scope.form.$setPristine(); + }) + .catch(function(data) { + console.log(data); + Alert.error(data.message); + }); + } + }; + + $scope.cancel = function () { + $scope.editVersionDisabled = true; + $location.path('/remoteClusters'); + }; + + // Fetch remote cluster details + $scope.fetchRemoteClusterDetails = function (clusterName) { + + RemoteCluster.getDetails(clusterName).then(function(response) { + $scope.cluster.cluster_name = response.ClusterInfo.name + $scope.cluster.cluster_url = response.ClusterInfo.url; + $scope.cluster.cluster_user = response.ClusterInfo.username; + }) + .catch(function(data) { + console.log(data); + }); + + }; + + $scope.fetchRemoteClusterDetails($routeParams.clusterName); + + +}]); http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js new file mode 100644 index 0000000..4eb3633 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/controllers/remoteClusters/RemoteClustersListCtrl.js @@ -0,0 +1,106 @@ +/** + * 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. + */ +'use strict'; + +angular.module('ambariAdminConsole') +.controller('RemoteClustersListCtrl', ['$scope', '$routeParams', '$translate', 'RemoteCluster' ,'UserConstants', function ($scope, $routeParams, $translate, RemoteCluster, UserConstants) { + var $t = $translate.instant; + + $scope.clusterName = $routeParams.clusterName; + + $scope.constants = { + groups: $t('common.clusters').toLowerCase() + }; + + $scope.groupsPerPage = 10; + $scope.currentPage = 1; + $scope.totalGroups = 1; + $scope.currentNameFilter = ''; + $scope.maxVisiblePages=20; + $scope.tableInfo = { + total: 0, + showed: 0 + }; + + $scope.isNotEmptyFilter = true; + + $scope.pageChanged = function() { + loadRemoteClusters(); + }; + $scope.groupsPerPageChanges = function() { + loadRemoteClusters(); + }; + + $scope.resetPagination = function() { + $scope.currentPage = 1; + loadRemoteClusters(); + }; + + $scope.typeFilterOptions = [ + $t('common.any') + ]; + + $scope.currentTypeFilter = $scope.typeFilterOptions[0]; + + $scope.clearFilters = function () { + $scope.currentNameFilter = ''; + $scope.currentTypeFilter = $scope.typeFilterOptions[0]; + $scope.resetPagination(); + }; + + function loadRemoteClusters(){ + RemoteCluster.all({ + currentPage: $scope.currentPage, + groupsPerPage: $scope.groupsPerPage, + searchString: $scope.currentNameFilter, + service: $scope.currentTypeFilter + }).then(function(remoteclusters) { + + $scope.totalGroups = remoteclusters.itemTotal; + $scope.tableInfo.total = remoteclusters.itemTotal; + $scope.tableInfo.showed = remoteclusters.items.length; + + $scope.remoteClusters = remoteclusters.items; + + remoteclusters.items.map(function(clusteritem){ + clusteritem.ClusterInfo.services.map(function(service){ + var serviceIndex = $scope.typeFilterOptions.indexOf(service); + if(serviceIndex == -1){ + $scope.typeFilterOptions.push(service); + } + }) + }) + + }) + .catch(function(data) { + console.error('Error in fetching remote clusters.', data); + }); + }; + + loadRemoteClusters(); + + $scope.$watch( + function (scope) { + return Boolean(scope.currentNameFilter || (scope.currentTypeFilter)); + }, + function (newValue, oldValue, scope) { + scope.isNotEmptyFilter = newValue; + } + ); + +}]); http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js index 80a5352..c74ed77 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/i18n.config.js @@ -30,6 +30,7 @@ angular.module('ambariAdminConsole') 'about': 'About', 'version': 'Version', 'signOut': 'Sign out', + 'register':'Register', 'clusters': 'Clusters', 'views': 'Views', 'viewUrls': 'View URLs', @@ -50,9 +51,12 @@ angular.module('ambariAdminConsole') 'type': 'Type', 'add': 'Add {{term}}', 'delete': 'Delete {{term}}', + 'deregisterCluster': 'Deregister Cluster', 'cannotDelete': 'Cannot Delete {{term}}', 'privileges': 'Privileges', 'cluster': 'Cluster', + 'remoteClusters': 'Remote Clusters', + 'services':'Services', 'clusterRole': 'Cluster Role', 'viewPermissions': 'View Permissions', 'getInvolved': 'Get involved!', @@ -126,6 +130,7 @@ angular.module('ambariAdminConsole') 'fieldIsRequired': 'This field is required.', 'noSpecialChars': 'Must not contain special characters!', 'nothingToDisplay': 'No {{term}} to display.', + 'noRemoteClusterDisplay':'No Remote Clusters to display.', 'noPrivileges': 'No {{term}} privileges', 'noPrivilegesDescription': 'This {{term}} does not have any privileges.', 'timeOut': 'You will be automatically logged out in <b>{{time}}</b> seconds due to inactivity.', @@ -134,11 +139,13 @@ angular.module('ambariAdminConsole') 'cannotLoadPrivileges': 'Cannot load privileges', 'cannotLoadClusterStatus': 'Cannot load cluster status', 'clusterRenamed': 'The cluster has been renamed to {{clusterName}}.', + 'remoteClusterRegistered': 'The cluster has been registered as {{clusterName}}.', 'cannotRenameCluster': 'Cannot rename cluster to {{clusterName}}', 'tooShort': 'Too short', 'tooLong': 'Too long', 'onlyText': 'Only lowercase alphanumeric characters are allowed.', - 'onlyAnScore': 'Invalid input, only alphanumerics allowed eg: My_default_view' + 'onlyAnScore': 'Invalid input, only alphanumerics allowed eg: My_default_view', + 'passwordRequired':'Password Required' } }, @@ -195,6 +202,8 @@ angular.module('ambariAdminConsole') 'instanceDescription': 'Instance Description', 'clusterConfiguration': 'Cluster Configuration', 'localCluster': 'Local Ambari Managed Cluster', + 'remoteCluster': 'Remote Cluster', + 'registerRemoteCluster' : 'Register Remote Cluster', 'clusterName': 'Cluster Name', 'custom': 'Custom', 'icon': 'Icon', @@ -241,7 +250,9 @@ angular.module('ambariAdminConsole') 'cannotDeleteInstance': 'Cannot delete instance', 'cannotLoadViews': 'Cannot load views', 'cannotLoadViewUrls': 'Cannot load view URLs', - 'cannotLoadViewUrl': 'Cannot load view URL' + 'cannotLoadViewUrl': 'Cannot load view URL', + 'savedRemoteClusterInformation':'Remote cluster information is saved.', + 'credentialsUpdated':'Credentials Updated.' } }, @@ -296,7 +307,9 @@ angular.module('ambariAdminConsole') 'userName': 'User name', 'admin': 'Admin', 'ambariAdmin': 'Ambari Admin', + 'ambariClusterURL':'Ambari Cluster URL', 'changePassword': 'Change Password', + 'updateCredentials':'Update Credentials', 'changePasswordFor': 'Change Password for {{userName}}', 'yourPassword': 'Your Password', 'newPassword': 'New User Password', @@ -335,8 +348,9 @@ angular.module('ambariAdminConsole') }, 'alerts': { - 'passwordRequired': 'Password required!', + 'passwordRequired': 'Password required', 'wrongPassword': 'Password must match!', + 'usernameRequired':'Username Required', 'cannotChange': 'Cannot Change {{term}}', 'userCreated': 'Created user <a href="#/users/{{encUserName}}">{{userName}}</a>', 'userCreationError': 'User creation error', http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js index 0566969..81b4d28 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/routes.js @@ -136,6 +136,23 @@ angular.module('ambariAdminConsole') controller: 'StackVersionsEditCtrl' } }, + remoteClusters: { + list: { + url: '/remoteClusters', + templateUrl: 'views/remoteClusters/list.html', + controller: 'RemoteClustersListCtrl' + }, + create: { + url: '/remoteClusters/create', + templateUrl: 'views/remoteClusters/remoteClusterPage.html', + controller: 'RemoteClustersCreateCtrl' + }, + edit: { + url: '/remoteClusters/:clusterName/edit', + templateUrl: 'views/remoteClusters/editRemoteClusterPage.html', + controller: 'RemoteClustersEditCtrl' + } + }, clusters: { manageAccess: { url: '/clusters/:id/manageAccess', http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js new file mode 100644 index 0000000..e4826e6 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/RemoteCluster.js @@ -0,0 +1,118 @@ +/** + * 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. + */ +'use strict'; + +angular.module('ambariAdminConsole') + .factory('RemoteCluster', ['$http', '$q', 'Settings', function($http, $q, Settings) { + + function RemoteCluster(){ + } + + RemoteCluster.edit = function(payload, config){ + var deferred = $q.defer(); + + $http.put(Settings.baseUrl + '/remoteclusters/' + payload.ClusterInfo.name , payload, config) + .success(function (data) { + deferred.resolve(data) + }) + .error(function (data) { + deferred.reject(data); + }); + return deferred.promise; + } + + + RemoteCluster.getDetails = function(clusterName) { + var deferred = $q.defer(); + + $http.get( Settings.baseUrl + '/remoteclusters/' + clusterName) + .success(function(response) { + deferred.resolve(response); + }) + .error(function(data) { + deferred.reject(data); + }); + + return deferred.promise; + + }; + + RemoteCluster.deregister = function(clusterName){ + var deferred = $q.defer(); + + $http.delete( Settings.baseUrl + '/remoteclusters/' + clusterName) + .success(function(response) { + deferred.resolve(response); + }) + .error(function(data) { + deferred.reject(data); + }); + + return deferred.promise; + + }; + + RemoteCluster.register = function(payload, config){ + var deferred = $q.defer(); + + $http.post(Settings.baseUrl + '/remoteclusters/' + payload.ClusterInfo.name , payload, config) + .success(function (data) { + deferred.resolve(data) + }) + .error(function (data) { + deferred.reject(data); + }); + return deferred.promise; + } + + RemoteCluster.all = function(params) { + var deferred = $q.defer(); + + $http.get(Settings.baseUrl + "/remoteclusters?" + + 'ClusterInfo/name.matches(.*'+params.searchString+'.*)' + + '&fields=*' + + '&from='+ (params.currentPage-1)*params.groupsPerPage + + '&page_size=' + params.groupsPerPage + + (params.service === 'Any' ? '' : '&ClusterInfo/services.matches(.*'+params.service+'.*)') + ) + .success(function(response) { + deferred.resolve(response); + }) + .error(function(data) { + deferred.reject(data); + }); + return deferred.promise; + }; + + RemoteCluster.listAll = function() { + var deferred = $q.defer(); + + /* TODO :: Add params like RemoteCluster.matches and &from , &page_size */ + $http.get(Settings.baseUrl + "/remoteclusters?fields=ClusterInfo/services") + .success(function(response) { + deferred.resolve(response.items); + }) + .error(function(data) { + deferred.reject(data); + }); + return deferred.promise; + }; + + return RemoteCluster; + + }]); http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js index 780352d..dfe7ba8 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js +++ b/ambari-admin/src/main/resources/ui/admin-web/app/scripts/services/View.js @@ -325,8 +325,9 @@ angular.module('ambariAdminConsole') }); data.properties = settings; + data.cluster_type = instanceInfo.clusterType; - if(instanceInfo.isLocalCluster) { + if(instanceInfo.clusterName != null) { data.cluster_handle = instanceInfo.clusterName; } else { angular.extend(data.properties, properties); http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css index c573b72..fbad224 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css +++ b/ambari-admin/src/main/resources/ui/admin-web/app/styles/main.css @@ -1626,6 +1626,31 @@ thead.view-permission-header > tr > th { margin:0px; } +.proxied-field-wrap { + display:block; + position:absolute; + height:0; + width:0; + overflow:hidden; +} + +legend.legendStyle { + padding-left: 5px; + padding-right: 5px; + font-size: 16px; +} + +fieldset.fsStyle { + border: 1px solid #DDD; + padding: 4px; + margin: 15px 0; +} + +legend { + width: auto; + border-bottom: 0; +} + .cluster-inherited-permission { border-bottom: 2px solid #ddd; padding-bottom: 10px; http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html index eaff70b..051d720 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/create.html @@ -115,7 +115,7 @@ </div> </div> - <div class="panel panel-default" ng-hide="!numberOfClusterConfigs"> + <div class="panel panel-default" ng-hide="!numberOfClusterConfigs && !clusterConfigurable"> <div class="panel-heading"> <h3 class="panel-title">{{'views.clusterConfiguration' | translate}}</h3> </div> @@ -123,7 +123,7 @@ <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter"> <div class="checkbox create-checkbox-cluster"> <label> - <input type="radio" ng-disabled="!clusterConfigurable || noClusterAvailible" ng-model="instance.isLocalCluster" ng-change="enableLocalCluster()" ng-value="true" class="visibilityCheckbox"> {{'views.localCluster' | translate}} + <input type="radio" ng-disabled="!clusterConfigurable || noLocalClusterAvailible" ng-model="instance.clusterType" ng-change="enableLocalCluster()" value="LOCAL_AMBARI" class="visibilityCheckbox"> {{'views.localCluster' | translate}} </label> </div> @@ -133,17 +133,39 @@ <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label> <div> <div class="col-sm-9"> - <select ng-model="cluster" ng-disabled="!instance.isLocalCluster" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in clusters"></select> + <select ng-model="cluster" ng-disabled="instance.clusterType != 'LOCAL_AMBARI' || noLocalClusterAvailible" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in clusters"></select> </div> </div> </div> </div> </div> - <div class="panel-body property-form"> + + <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter"> + <div class="checkbox create-checkbox-cluster"> + <label> + <input type="radio" ng-disabled="!clusterConfigurable || noRemoteClusterAvailible" ng-model="instance.clusterType" ng-change="enableLocalCluster()" value="REMOTE_AMBARI" class="visibilityCheckbox"> {{'views.remoteCluster' | translate}} + </label> + </div> + + <div class="form-horizontal property-form"> + <div class="form-group"> + + <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label> + <div> + <div class="col-sm-9"> + <select ng-model="data.remoteCluster" ng-disabled="instance.clusterType != 'REMOTE_AMBARI' || noRemoteClusterAvailable" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in remoteClusters"></select> + </div> + </div> + </div> + </div> + + </div> + + <div class="panel-body property-form" ng-hide="!numberOfClusterConfigs"> <div class="checkbox"> <label> - <input type="radio" ng-model="instance.isLocalCluster" ng-value="false" class="visibilityCheckbox"> {{'views.custom' | translate}} + <input type="radio" ng-model="instance.clusterType" value="NONE" class="visibilityCheckbox"> {{'views.custom' | translate}} </label> </div> <div class="alert alert-danger bottom-margin top-margin" ng-show='form.instanceCreateForm.generalValidationError'> @@ -154,11 +176,11 @@ <label for="" class="col-sm-3 control-label" ng-class="{'not-required': !parameter.required}">{{parameter.label || parameter.displayName}}{{parameter.required ? '*' : ''}}</label> <div ng-switch="parameter.type"> <div class="col-sm-9 checkbox" ng-switch-when="boolean"> - <input type="checkbox" class="viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.isLocalCluster" ng-required="parameter.required && instance.isLocalCluster" ng-model="parameter.value" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter"> + <input type="checkbox" class="viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.clusterType == 'NONE'" ng-required="parameter.required && (instance.clusterType == 'NONE')" ng-model="parameter.value" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter"> </div> <div class="col-sm-9" ng-switch-default> - <input type="{{parameter.masked ? 'password' : 'text'}}" class="form-control viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.isLocalCluster" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required && !instance.isLocalCluster" ng-model="parameter.value" autocomplete="off" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter" placeholder="{{parameter.placeholder}}"> - <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted && !instance.isLocalCluster'> + <input type="{{parameter.masked ? 'password' : 'text'}}" class="form-control viewproperty-input" name="{{parameter.name}}" ng-disabled="instance.clusterType != 'NONE'" ng-change="form.instanceCreateForm[parameter.name].validationError=''" ng-required="parameter.required && (instance.clusterType == 'NONE')" ng-model="parameter.value" autocomplete="off" popover="{{parameter.description}}" popover-title="{{parameter.name}}" popover-trigger="mouseenter" placeholder="{{parameter.placeholder}}"> + <div class="alert alert-danger no-margin-bottom top-margin" ng-show="form.instanceCreateForm[parameter.name].$error.required && form.instanceCreateForm.submitted && (instance.clusterType == 'NONE')"> {{'common.alerts.fieldIsRequired' | translate}} </div> <div class="alert alert-danger no-margin-bottom top-margin" ng-show='form.instanceCreateForm[parameter.name].validationError'> http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html index 4003137..92cde74 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/ambariViews/edit.html @@ -158,18 +158,18 @@ </div> </div> -<div class="panel panel-default" ng-hide="isConfigurationEmpty"> +<div class="panel panel-default" ng-hide="isConfigurationEmpty && !clusterConfigurable"> <div class="panel-heading clearfix"> <h3 class="panel-title pull-left">{{'views.clusterConfiguration' | translate}}</h3> <div class="pull-right" ng-switch="instance.ViewInstanceInfo.static"> - <a href ng-switch-when="false" ng-hide="isConfigurationEmpty" ng-click="togglePropertiesEditing()" ng-show="editConfigurationDisabled" class="properties-toggle"> <span class="glyphicon glyphicon-pencil"></span> {{'views.edit' | translate}}</a> - <a href ng-switch-when="true" ng-hide="isConfigurationEmpty" class="properties-toggle disabled"> <span class="glyphicon glyphicon-pencil"></span> {{'views.edit' | translate}}</a> + <a href ng-switch-when="false" ng-hide="isConfigurationEmpty && !clusterConfigurable" ng-click="togglePropertiesEditing()" ng-show="editConfigurationDisabled" class="properties-toggle"> <span class="glyphicon glyphicon-pencil"></span> {{'views.edit' | translate}}</a> + <a href ng-switch-when="true" ng-hide="isConfigurationEmpty && !clusterConfigurable" class="properties-toggle disabled"> <span class="glyphicon glyphicon-pencil"></span> {{'views.edit' | translate}}</a> </div> </div> <div class="panel-body property-form" popover="{{clusterConfigurableErrorMsg}}" popover-trigger="mouseenter"> <div class="checkbox"> <label> - <input type="radio" ng-model="$parent.isLocalCluster" ng-change="enableLocalCluster()" ng-disabled="!clusterConfigurable || editConfigurationDisabled || noClusterAvailible" ng-value="true" class="visibilityCheckbox"> {{'views.localCluster' | translate}} + <input type="radio" ng-model="data.clusterType" ng-change="enableLocalCluster()" ng-disabled="!clusterConfigurable || editConfigurationDisabled || noLocalClusterAvailible" value="LOCAL_AMBARI" class="visibilityCheckbox"> {{'views.localCluster' | translate}} </label> </div> <div class="form-horizontal property-form"> @@ -177,18 +177,34 @@ <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label> <div> <div class="col-sm-9"> - <select ng-model="cluster" ng-disabled="!$parent.isLocalCluster || editConfigurationDisabled" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in clusters"></select> + <select ng-model="cluster" ng-disabled="(data.clusterType != 'LOCAL_AMBARI') || editConfigurationDisabled" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in clusters"></select> </div> </div> </div> </div> <p> </p> - <div class="checkbox"> + <div class="checkbox"> + <label> + <input type="radio" ng-model="data.clusterType" ng-change="enableLocalCluster()" ng-disabled="!clusterConfigurable || editConfigurationDisabled || noRemoteClusterAvailible" value="REMOTE_AMBARI" class="visibilityCheckbox"> {{'views.remoteCluster' | translate}} + </label> + </div> + <div class="form-horizontal property-form"> + <div class="form-group"> + <label for="" class="control-label col-sm-3 ng-binding not-required" >{{'views.clusterName' | translate}}</label> + <div> + <div class="col-sm-9"> + <select ng-model="data.remoteCluster" ng-disabled="(data.clusterType != 'REMOTE_AMBARI') || editConfigurationDisabled" ng-change="onClusterChange()" class="clusters-name-dropdown form-control" ng-options="o as o for o in remoteClusters"></select> + </div> + </div> + </div> + </div> + <p> </p> + <div class="checkbox" ng-hide="isConfigurationEmpty"> <label> <input type="radio" - ng-model="$parent.isLocalCluster" + ng-model="data.clusterType" ng-disabled="editConfigurationDisabled" - ng-value="false" + value="NONE" ng-change="disableLocalCluster()" class="visibilityCheckbox"> {{'views.custom' | translate}} @@ -196,20 +212,20 @@ </div> </div> <div class="panel-body edit-view-custom-wrap"> - <form name="propertiesForm" class="form-horizontal property-form" ng-hide="isConfigurationEmpty" novalidate> + <form name="propertiesForm" class="form-horizontal property-form" novalidate> <fieldset> - <div class="form-group" ng-repeat="property in configurationMeta | filter:{clusterConfig:true}" ng-class="{'has-error' : (!editConfigurationDisabled && !isLocalCluster && ((property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled) || propertiesForm[property.name].validationError))}"> + <div class="form-group" ng-hide="isConfigurationEmpty" ng-repeat="property in configurationMeta | filter:{clusterConfig:true}" ng-class="{'has-error' : (!editConfigurationDisabled && (data.clusterType == 'NONE') && ((property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled) || propertiesForm[property.name].validationError))}"> <label for="" class="control-label col-sm-3" ng-class="{'not-required': !property.required}">{{property.label || property.displayName}}{{property.required ? '*' : ''}}</label> <div ng-switch="property.type"> <div class="col-sm-9 checkbox" ng-switch-when="boolean"> - <input type="checkbox" class="propertie-input" ng-disabled="isLocalCluster || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter"> + <input type="checkbox" class="propertie-input" ng-disabled="(data.clusterType != 'NONE') || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" ng-true-value="true" ng-false-value="false" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter"> </div> <div class="col-sm-9" ng-switch-default> - <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required && !isLocalCluster" ng-change="propertiesForm[property.name].validationError=''" ng-disabled="isLocalCluster || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}"> - <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled && !isLocalCluster'> + <input type="{{property.masked ? 'password' : 'text'}}" class="form-control propertie-input" ng-required="property.required && (data.clusterType == 'NONE')" ng-change="propertiesForm[property.name].validationError=''" ng-disabled="(data.clusterType != 'NONE') || editConfigurationDisabled" name="{{property.name}}" ng-model="configuration[property.name]" popover="{{property.description}}" popover-title="{{property.name}}" popover-trigger="mouseenter" placeholder="{{property.placeholder}}"> + <div class="alert alert-danger no-margin-bottom top-margin" ng-show="property.required && propertiesForm[property.name].$error.required && !editConfigurationDisabled && (data.clusterType == 'NONE')"> {{'common.alerts.fieldIsRequired' | translate}} </div> - <div class="alert alert-danger no-margin-bottom top-margin" ng-show='property.required && propertiesForm[property.name].validationError && !editConfigurationDisabled && !isLocalCluster'> + <div class="alert alert-danger no-margin-bottom top-margin" ng-show="property.required && propertiesForm[property.name].validationError && !editConfigurationDisabled && (data.clusterType == 'NONE')"> {{propertiesForm[property.name].validationMessage}} </div> </div> @@ -223,7 +239,7 @@ </div> </fieldset> </form> - <div ng-show="isConfigurationEmpty"> + <div ng-show="isConfigurationEmpty && !clusterConfigurable"> <div class="alert alert-info">{{'views.alerts.notDefined' | translate: '{term: constants.props}'}}</div> </div> </div> @@ -258,7 +274,7 @@ </tr> </tbody> </table> - <div ng-show="!isPermissionsEmpty && isLocalCluster && editConfigurationDisabled"> + <div ng-show="!isPermissionsEmpty && (data.clusterType == 'LOCAL_AMBARI') && editConfigurationDisabled"> <div class="col-sm-12 cluster-inherited-permission"> <strong>{{'views.clusterPermissions.label' | translate}}</strong> </div> @@ -277,4 +293,4 @@ <div class="alert alert-info">{{'views.alerts.notDefined' | translate: '{term: constants.perms}'}}</div> </div> </div> -</div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html index f93867c..f99e0cc 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/leftNavbar.html @@ -53,9 +53,9 @@ <i class="glyphicon glyphicon-remove"></i> </button> <button - type="submit" - class="btn btn-primary btn-xs" - ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}"> + type="submit" + class="btn btn-primary btn-xs" + ng-class="{'disabled': editClusterNameForm.newClusterName.$invalid || editCluster.name == cluster.Clusters.cluster_name}"> <i class="glyphicon glyphicon-ok"></i> </button> </div> @@ -78,10 +78,13 @@ <li><p class="noclusters">{{'common.noClusters' | translate}}</p></li> </ul> </div> - <ul class="nav nav-pills nav-stacked" ng-show="cluster && totalRepos > 0"> - <li ng-class="{active: isActive('stackVersions.list')}"> + <ul class="nav nav-pills nav-stacked" > + <li ng-class="{active: isActive('stackVersions.list')}" ng-show="cluster && totalRepos > 0"> <a href="#/stackVersions">{{'common.versions' | translate}}</a> </li> + <li ng-class="{active: isActive('remoteClusters.list')}"> + <a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a> + </li> </ul> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/editRemoteClusterPage.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/editRemoteClusterPage.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/editRemoteClusterPage.html new file mode 100644 index 0000000..b5890bf --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/editRemoteClusterPage.html @@ -0,0 +1,77 @@ +<!-- +* 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. +--> +<div class="clearfix"> + <ol class="breadcrumb pull-left"> + <li><a href="#/remoteClusters">{{'common.remoteClusters' | translate}}</a></li> + <li class="active">{{cluster.cluster_name}}</li> + </ol> + <div class="pull-right top-margin-4"> + <div> + <button class="btn deleteuser-btn btn-danger" ng-click="deleteCluster()">{{'common.deregisterCluster' | translate}}</button> + </div> + </div> +</div> +<hr> + + + + +<form class="form-horizontal create-user-form" role="form" novalidate name="form" autocomplete="off"> + + <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}"> + <label for="clustername" class="col-sm-2 control-label">{{'views.clusterName' | translate}}</label> + <div class="col-sm-10"> + <input type="text" id="clustername" disabled class="form-control" name="cluster_name" ng-pattern="/[a-zA-Z0-9\-]*/" placeholder="Cluster Name" ng-model="cluster.cluster_name" required autocomplete="off"> + <div class="alert alert-danger top-margin" ng-show="form.cluster_name.$error.required && form.submitted"> {{'common.alerts.fieldIsRequired' | translate}}</div> + </div> + </div> + + <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}"> + <label for="clusterurl" class="col-sm-2 control-label">{{'users.ambariClusterURL' | translate}}</label> + <div class="col-sm-10"> + <input type="text" id="clusterurl" class="form-control" name="cluster_url" placeholder="Ambari Cluster URL" ng-model="cluster.cluster_url" required autocomplete="off"> + <div class="alert alert-danger top-margin" ng-show="form.cluster_url.$error.required && form.submitted"> {{'common.alerts.fieldIsRequired' | translate}}</div> + </div> + </div> + + <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}" style="display: none" > + <label for="clusteruser" class="col-sm-2 control-label"> {{'users.roles.clusterUser' | translate}}</label> + <div class="col-sm-10"> + <input type="text" id="clusteruser" class="form-control" name="cluster_user" placeholder="Cluster User" ng-model="cluster.cluster_user" required autocomplete="off"> + <div class="alert alert-danger top-margin" ng-show="form.cluster_user.$error.required && form.submitted"> {{'common.alerts.fieldIsRequired' | translate}}</div> + </div> + </div> + + <div class="form-group"> + <label for="" class="col-sm-2 control-label"></label> + <div class="col-sm-10"> + <div> + <a href ng-click="openChangePwdDialog()" class="btn btn-default changepassword">{{'users.updateCredentials' | translate}}</a> + </div> + </div> + </div> + + + <div class="form-group"> + <div class="col-sm-offset-2 col-sm-10"> + <button class="btn btn-primary pull-right left-margin saveremotecluster" ng-click="editRemoteCluster()">{{'common.controls.save' | translate}}</button> + <a class="btn btn-default pull-right cancel" href ng-click="cancel()">{{'common.controls.cancel' | translate}}</a> + </div> + </div> + +</form> http://git-wip-us.apache.org/repos/asf/ambari/blob/c150f0de/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html new file mode 100644 index 0000000..e386ffd --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/remoteClusters/list.html @@ -0,0 +1,80 @@ +<!-- +* 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. +--> + +<div class="users-pane"> + <div class="clearfix"> + <ol class="breadcrumb pull-left"> + <li class="active">Remote Clusters</li> + </ol> + <div class="pull-right top-margin-4"> + <a href="#/remoteClusters/create" class="btn btn-primary"> + <span class="glyphicon glyphicon-plus"></span> + {{'views.registerRemoteCluster' | translate}} + </a> + </div> + </div> + <hr> + <table class="table table-striped table-hover"> + <thead> + <tr> + <th class="col-sm-3"> + <div class="search-container"> + <label for="">{{'views.clusterName' | translate}}</label> + <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="currentNameFilter" ng-change="resetPagination()"> + <button type="button" class="close" ng-show="currentNameFilter" ng-click="currentNameFilter=''; resetPagination()"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button> + </div> + </th> + <th class="col-sm-9"> + <label for="">{{'common.services' | translate}}</label> + <select class="form-control typefilter" + ng-model="currentTypeFilter" + ng-options="item for item in typeFilterOptions" + ng-change="resetPagination();"> + </select> + </th> + </tr> + </thead> + <tbody> + <tr ng-repeat="remoteCluster in remoteClusters" > + <td class="col-sm-3"><a href="#/remoteClusters/{{remoteCluster.ClusterInfo.name}}/edit">{{ remoteCluster.ClusterInfo.name }}</a></td> + <td class="col-sm-9"> + <span ng-repeat="service in remoteCluster.ClusterInfo.services" ng-if="remoteCluster.ClusterInfo.services.length > 0">{{ service }} {{$last ? '' : ','}} </span> + <span ng-if="remoteCluster.ClusterInfo.services.length == 0">--</span> + </td> + </tr> + </tbody> + + </table> + <div class="alert alert-info col-sm-12" ng-show="!remoteClusters.length"> + {{'common.alerts.noRemoteClusterDisplay' | translate}} + </div> + <div class="col-sm-12 table-bar"> + <div class="pull-left filtered-info"> + <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.groups}'}}</span> + <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span> + </div> + <div class="pull-right left-margin"> + <pagination class="paginator" total-items="totalGroups" max-size="maxVisiblePages" items-per-page="groupsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> + </div> + <div class="pull-right"> + <select class="form-control" ng-model="groupsPerPage" ng-change="groupsPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select> + </div> + </div> + +</div> +
