AMBARI-6950. Jobs View: set up default access to Jobs view for operators and users on initial install and also upgrade.
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f6d7e8b3 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f6d7e8b3 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f6d7e8b3 Branch: refs/heads/branch-alerts-dev Commit: f6d7e8b3a930d1bed8843a4b439d9a6a912dd16f Parents: 6fddbb7 Author: Siddharth Wagle <[email protected]> Authored: Wed Aug 20 14:16:55 2014 -0700 Committer: Siddharth Wagle <[email protected]> Committed: Wed Aug 20 14:18:26 2014 -0700 ---------------------------------------------------------------------- .../apache/ambari/server/orm/dao/ViewDAO.java | 18 +++++ .../server/orm/entities/ViewInstanceEntity.java | 13 +++- .../server/upgrade/UpgradeCatalog170.java | 71 ++++++++++++++++++++ .../server/upgrade/UpgradeCatalog170Test.java | 53 +++++++++++---- .../controllers/main/admin/access_controller.js | 66 ------------------ ambari-web/app/routes/main.js | 20 +++--- contrib/views/jobs/src/main/resources/view.xml | 3 - 7 files changed, 150 insertions(+), 94 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ViewDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ViewDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ViewDAO.java index 13f7b04..bbbab63 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ViewDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ViewDAO.java @@ -51,6 +51,24 @@ public class ViewDAO { } /** + * Find a view with a given common name. + * + * @param viewCommonName common name of view to find + * + * @return a matching view or null + */ + public ViewEntity findByCommonName(String viewCommonName) { + if (viewCommonName != null) { + for (ViewEntity viewEntity : findAll()) { + if (viewCommonName.equals(viewEntity.getCommonName())) { + return viewEntity; + } + } + } + return null; + } + + /** * Find all views. * * @return all views or an empty List http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java index 66917e7..643bac2 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ViewInstanceEntity.java @@ -226,13 +226,24 @@ public class ViewInstanceEntity implements ViewInstanceDefinition { * @param name the instance name */ public ViewInstanceEntity(ViewEntity view, String name) { + this(view, name, view.getLabel()); + } + + /** + * Construct a view instance definition. + * + * @param view the parent view definition + * @param name the instance name + * @param label the instance label + */ + public ViewInstanceEntity(ViewEntity view, String name, String label) { this.name = name; this.instanceConfig = null; this.view = view; this.viewName = view.getName(); this.description = null; this.visible = 'Y'; - this.label = view.getLabel(); + this.label = label; } http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java index 144900e..eb3a578 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java @@ -46,6 +46,7 @@ import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo; import org.apache.ambari.server.orm.dao.ClusterDAO; import org.apache.ambari.server.orm.dao.DaoUtils; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; +import org.apache.ambari.server.orm.dao.KeyValueDAO; import org.apache.ambari.server.orm.dao.PermissionDAO; import org.apache.ambari.server.orm.dao.PrincipalDAO; import org.apache.ambari.server.orm.dao.PrincipalTypeDAO; @@ -58,6 +59,7 @@ import org.apache.ambari.server.orm.dao.ViewInstanceDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.HostRoleCommandEntity; import org.apache.ambari.server.orm.entities.HostRoleCommandEntity_; +import org.apache.ambari.server.orm.entities.KeyValueEntity; import org.apache.ambari.server.orm.entities.PermissionEntity; import org.apache.ambari.server.orm.entities.PrincipalEntity; import org.apache.ambari.server.orm.entities.PrincipalTypeEntity; @@ -72,6 +74,7 @@ import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigHelper; +import org.apache.ambari.server.view.configuration.InstanceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -96,6 +99,10 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog { private static final String ALERT_TABLE_GROUP_TARGET = "alert_group_target"; private static final String ALERT_TABLE_GROUPING = "alert_grouping"; private static final String ALERT_TABLE_NOTICE = "alert_notice"; + public static final String JOBS_VIEW_NAME = "JOBS"; + public static final String JOBS_VIEW_INSTANCE_NAME = "JOBS_1"; + public static final String SHOW_JOBS_FOR_NON_ADMIN_KEY = "showJobsForNonAdmin"; + public static final String JOBS_VIEW_INSTANCE_LABEL = "Jobs"; //SourceVersion is only for book-keeping purpos @Override @@ -560,6 +567,7 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog { addMissingConfigs(); renamePigProperties(); upgradePermissionModel(); + addJobsViewPermissions(); } /** @@ -981,4 +989,67 @@ public class UpgradeCatalog170 extends AbstractUpgradeCatalog { } } } + + protected void addJobsViewPermissions() { + + final UserDAO userDAO = injector.getInstance(UserDAO.class); + final ResourceTypeDAO resourceTypeDAO = injector.getInstance(ResourceTypeDAO.class); + final ResourceDAO resourceDAO = injector.getInstance(ResourceDAO.class); + final ViewDAO viewDAO = injector.getInstance(ViewDAO.class); + final ViewInstanceDAO viewInstanceDAO = injector.getInstance(ViewInstanceDAO.class); + final KeyValueDAO keyValueDAO = injector.getInstance(KeyValueDAO.class); + final PermissionDAO permissionDAO = injector.getInstance(PermissionDAO.class); + final PrivilegeDAO privilegeDAO = injector.getInstance(PrivilegeDAO.class); + + ViewEntity jobsView = viewDAO.findByCommonName(JOBS_VIEW_NAME); + if (jobsView != null) { + ViewInstanceEntity jobsInstance = jobsView.getInstanceDefinition(JOBS_VIEW_INSTANCE_NAME); + if (jobsInstance == null) { + jobsInstance = new ViewInstanceEntity(jobsView, JOBS_VIEW_INSTANCE_NAME, JOBS_VIEW_INSTANCE_LABEL); + ResourceEntity resourceEntity = new ResourceEntity(); + resourceEntity.setResourceType(resourceTypeDAO.findByName( + ViewEntity.getViewName( + jobsView.getCommonName(), + jobsView.getVersion()))); + jobsInstance.setResource(resourceEntity); + jobsView.addInstanceDefinition(jobsInstance); + resourceDAO.create(resourceEntity); + viewInstanceDAO.create(jobsInstance); + viewDAO.merge(jobsView); + } + // get showJobsForNonAdmin value and remove it + boolean showJobsForNonAdmin = false; + KeyValueEntity showJobsKeyValueEntity = keyValueDAO.findByKey(SHOW_JOBS_FOR_NON_ADMIN_KEY); + if (showJobsKeyValueEntity != null) { + String value = showJobsKeyValueEntity.getValue(); + showJobsForNonAdmin = Boolean.parseBoolean(value); + keyValueDAO.remove(showJobsKeyValueEntity); + } + if (showJobsForNonAdmin) { + ResourceEntity jobsResource = jobsInstance.getResource(); + PermissionEntity viewUsePermission = permissionDAO.findViewUsePermission(); + for (UserEntity userEntity : userDAO.findAll()) { + // check if user has VIEW.USE privilege for JOBS view + List<PrivilegeEntity> privilegeEntities = privilegeDAO.findAllByPrincipal( + Collections.singletonList(userEntity.getPrincipal())); + boolean hasJobsUsePrivilege = false; + for (PrivilegeEntity privilegeEntity : privilegeEntities) { + if (privilegeEntity.getResource().getId() == jobsInstance.getResource().getId() && + privilegeEntity.getPermission().getId() == viewUsePermission.getId()) { + hasJobsUsePrivilege = true; + break; + } + } + // if not - add VIEW.use privilege + if (!hasJobsUsePrivilege) { + PrivilegeEntity privilegeEntity = new PrivilegeEntity(); + privilegeEntity.setResource(jobsResource); + privilegeEntity.setPermission(viewUsePermission); + privilegeEntity.setPrincipal(userEntity.getPrincipal()); + privilegeDAO.create(privilegeEntity); + } + } + } + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java index 6262a2b..fbee5e2 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog170Test.java @@ -63,6 +63,7 @@ import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.dao.ClusterDAO; +import org.apache.ambari.server.orm.dao.KeyValueDAO; import org.apache.ambari.server.orm.dao.PermissionDAO; import org.apache.ambari.server.orm.dao.PrincipalDAO; import org.apache.ambari.server.orm.dao.PrincipalTypeDAO; @@ -74,6 +75,9 @@ import org.apache.ambari.server.orm.dao.ViewDAO; import org.apache.ambari.server.orm.dao.ViewInstanceDAO; import org.apache.ambari.server.orm.entities.ClusterEntity; import org.apache.ambari.server.orm.entities.HostRoleCommandEntity; +import org.apache.ambari.server.orm.entities.KeyValueEntity; +import org.apache.ambari.server.orm.entities.PrivilegeEntity; +import org.apache.ambari.server.orm.entities.ResourceEntity; import org.apache.ambari.server.orm.entities.UserEntity; import org.apache.ambari.server.orm.entities.ViewEntity; import org.apache.ambari.server.orm.entities.ViewInstanceEntity; @@ -231,6 +235,7 @@ public class UpgradeCatalog170Test { ViewInstanceDAO viewInstanceDAO = createNiceMock(ViewInstanceDAO.class); PermissionDAO permissionDAO = createNiceMock(PermissionDAO.class); PrivilegeDAO privilegeDAO = createNiceMock(PrivilegeDAO.class); + KeyValueDAO keyValueDAO = createNiceMock(KeyValueDAO.class); EntityTransaction trans = createNiceMock(EntityTransaction.class); CriteriaBuilder cb = createNiceMock(CriteriaBuilder.class); @@ -316,18 +321,19 @@ public class UpgradeCatalog170Test { expect(configHelper.findConfigTypesByPropertyName(new StackId("HDP", "2.1"), "content")).andReturn(envDicts).once(); expect(configHelper.getPropertyValueFromStackDefenitions(cluster, "hadoop-env", "content")).andReturn("env file contents").once(); - expect(injector.getInstance(UserDAO.class)).andReturn(userDAO).once(); - expect(injector.getInstance(PrincipalDAO.class)).andReturn(principalDAO).once(); - expect(injector.getInstance(PrincipalTypeDAO.class)).andReturn(principalTypeDAO).once(); - expect(injector.getInstance(ClusterDAO.class)).andReturn(clusterDAO).once(); - expect(injector.getInstance(ResourceTypeDAO.class)).andReturn(resourceTypeDAO).once(); - expect(injector.getInstance(ResourceDAO.class)).andReturn(resourceDAO).once(); - expect(injector.getInstance(ViewDAO.class)).andReturn(viewDAO).once(); - expect(injector.getInstance(ViewInstanceDAO.class)).andReturn(viewInstanceDAO).once(); - expect(injector.getInstance(PermissionDAO.class)).andReturn(permissionDAO).once(); - expect(injector.getInstance(PrivilegeDAO.class)).andReturn(privilegeDAO).once(); - - expect(userDAO.findAll()).andReturn(Collections.<UserEntity> emptyList()).anyTimes(); + expect(injector.getInstance(UserDAO.class)).andReturn(userDAO).anyTimes(); + expect(injector.getInstance(PrincipalDAO.class)).andReturn(principalDAO).anyTimes(); + expect(injector.getInstance(PrincipalTypeDAO.class)).andReturn(principalTypeDAO).anyTimes(); + expect(injector.getInstance(ClusterDAO.class)).andReturn(clusterDAO).anyTimes(); + expect(injector.getInstance(ResourceTypeDAO.class)).andReturn(resourceTypeDAO).anyTimes(); + expect(injector.getInstance(ResourceDAO.class)).andReturn(resourceDAO).anyTimes(); + expect(injector.getInstance(ViewDAO.class)).andReturn(viewDAO).anyTimes(); + expect(injector.getInstance(ViewInstanceDAO.class)).andReturn(viewInstanceDAO).anyTimes(); + expect(injector.getInstance(PermissionDAO.class)).andReturn(permissionDAO).anyTimes(); + expect(injector.getInstance(PrivilegeDAO.class)).andReturn(privilegeDAO).anyTimes(); + expect(injector.getInstance(KeyValueDAO.class)).andReturn(keyValueDAO).anyTimes(); + + expect(userDAO.findAll()).andReturn(Collections.<UserEntity> emptyList()).times(2); expect(clusterDAO.findAll()).andReturn(Collections.<ClusterEntity> emptyList()).anyTimes(); expect(viewDAO.findAll()).andReturn(Collections.<ViewEntity> emptyList()).anyTimes(); expect(viewInstanceDAO.findAll()).andReturn(Collections.<ViewInstanceEntity> emptyList()).anyTimes(); @@ -338,9 +344,29 @@ public class UpgradeCatalog170Test { expect(cluster.getDesiredConfigByType("pig-properties")).andReturn(pigConfig).anyTimes(); expect(pigConfig.getProperties()).andReturn(pigSettings).anyTimes(); + ViewEntity jobsView = createNiceMock(ViewEntity.class); + KeyValueEntity showJobsKeyValue = createNiceMock(KeyValueEntity.class); + UserEntity user = createNiceMock(UserEntity.class); + + expect(userDAO.findAll()).andReturn(Collections.singletonList(user)); + expect(jobsView.getCommonName()).andReturn(UpgradeCatalog170.JOBS_VIEW_NAME); + expect(jobsView.getVersion()).andReturn("1.0.0"); + expect(viewDAO.findByCommonName(UpgradeCatalog170.JOBS_VIEW_NAME)).andReturn(jobsView).once(); + expect(showJobsKeyValue.getValue()).andReturn("true"); + expect(keyValueDAO.findByKey(UpgradeCatalog170.SHOW_JOBS_FOR_NON_ADMIN_KEY)).andReturn(showJobsKeyValue); + expect(privilegeDAO.findAllByPrincipal(anyObject(List.class))).andReturn(Collections.<PrivilegeEntity>emptyList()); + expect(viewDAO.merge(jobsView)).andReturn(jobsView); + + resourceDAO.create(anyObject(ResourceEntity.class)); + viewInstanceDAO.create(anyObject(ViewInstanceEntity.class)); + keyValueDAO.remove(showJobsKeyValue); + privilegeDAO.create(anyObject(PrivilegeEntity.class)); + replay(entityManager, trans, upgradeCatalog, cb, cq, hrc, q); replay(dbAccessor, configuration, injector, cluster, clusters, amc, config, configHelper, pigConfig); replay(userDAO, clusterDAO, viewDAO, viewInstanceDAO, permissionDAO); + replay(resourceTypeDAO, resourceDAO, keyValueDAO, privilegeDAO); + replay(jobsView, showJobsKeyValue, user); Class<?> c = AbstractUpgradeCatalog.class; Field f = c.getDeclaredField("configuration"); @@ -355,7 +381,8 @@ public class UpgradeCatalog170Test { upgradeCatalog.executeDMLUpdates(); - verify(upgradeCatalog, dbAccessor, configuration, injector, cluster, clusters, amc, config, configHelper); + verify(upgradeCatalog, dbAccessor, configuration, injector, cluster, clusters, amc, config, configHelper, + jobsView, showJobsKeyValue, privilegeDAO, viewDAO, viewInstanceDAO, resourceDAO, keyValueDAO); } http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-web/app/controllers/main/admin/access_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/access_controller.js b/ambari-web/app/controllers/main/admin/access_controller.js deleted file mode 100644 index 82bc9f3..0000000 --- a/ambari-web/app/controllers/main/admin/access_controller.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 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. - */ - -var App = require('app'); - -App.MainAdminAccessController = Em.Controller.extend(App.UserPref, { - name:'mainAdminAccessController', - - /** - * Show jobs by default - * @type {bool} - */ - showJobs: false, - - /** - * User pref key - * @type {string} - */ - persistKey: 'showJobsForNonAdmin', - - /** - * Handle Save button click event - */ - save: function() { - this.postUserPref(this.get('persistKey'), this.get('showJobs')); - }, - - loadShowJobsForUsers: function () { - var dfd = $.Deferred(); - this.getUserPref(this.get('persistKey')).done(function (value) { - dfd.resolve(value); - }).fail(function(value) { - dfd.resolve(value); - }); - return dfd.promise(); - }, - - getUserPrefSuccessCallback: function (data) { - this.set('showJobs', data); - return data; - }, - - getUserPrefErrorCallback: function () { - if (App.get('isAdmin')) { - this.postUserPref(this.get('persistKey'), false); - } - this.set('showJobs', false); - return true; - } - -}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/ambari-web/app/routes/main.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/routes/main.js b/ambari-web/app/routes/main.js index 7598695..b73627a 100644 --- a/ambari-web/app/routes/main.js +++ b/ambari-web/app/routes/main.js @@ -26,18 +26,16 @@ module.exports = Em.Route.extend({ console.log('in /main:enter'); router.getAuthenticated().done(function (loggedIn) { if (loggedIn) { - App.router.get('mainAdminAccessController').loadShowJobsForUsers().done(function () { - App.router.get('clusterController').loadClusterName(false).done(function () { - if (App.get('testMode')) { - router.get('mainController').initialize(); - } else { - App.router.get('mainController').checkServerClientVersion().done(function () { - App.router.get('clusterController').loadClientServerClockDistance().done(function () { - router.get('mainController').initialize(); - }); + App.router.get('clusterController').loadClusterName(false).done(function () { + if (App.get('testMode')) { + router.get('mainController').initialize(); + } else { + App.router.get('mainController').checkServerClientVersion().done(function () { + App.router.get('clusterController').loadClientServerClockDistance().done(function () { + router.get('mainController').initialize(); }); - } - }); + }); + } }); // TODO: redirect to last known state } else { http://git-wip-us.apache.org/repos/asf/ambari/blob/f6d7e8b3/contrib/views/jobs/src/main/resources/view.xml ---------------------------------------------------------------------- diff --git a/contrib/views/jobs/src/main/resources/view.xml b/contrib/views/jobs/src/main/resources/view.xml index 0c47bda..c48f6b5 100644 --- a/contrib/views/jobs/src/main/resources/view.xml +++ b/contrib/views/jobs/src/main/resources/view.xml @@ -18,7 +18,4 @@ limitations under the License. Kerberos, LDAP, Custom. Binary/Htt <name>JOBS</name> <label>Jobs View</label> <version>1.0.0</version> - <instance> - <name>JOBS_1</name> - </instance> </view>
