Repository: ambari Updated Branches: refs/heads/trunk a94ebcfb6 -> 89870f28a
AMBARI-17129. Set necessary HBase configuration to enable SPNEGO authentication if desired (Josh Elser via rlevas) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/89870f28 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/89870f28 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/89870f28 Branch: refs/heads/trunk Commit: 89870f28a204b782f5d25eb09e6e3c5bfa496acc Parents: a94ebcf Author: Josh Elser <[email protected]> Authored: Thu Jun 16 17:36:32 2016 -0400 Committer: Robert Levas <[email protected]> Committed: Thu Jun 16 17:36:48 2016 -0400 ---------------------------------------------------------------------- .../server/upgrade/UpgradeCatalog240.java | 68 ++++++++++++++++++++ .../HBASE/0.96.0.2.0/alerts.json | 4 +- .../stacks/HDP/2.5/services/HBASE/kerberos.json | 18 ++++++ .../server/upgrade/UpgradeCatalog240Test.java | 67 +++++++++++++++++++ 4 files changed, 156 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/89870f28/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java index 30b77f8..81b5653 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog240.java @@ -172,6 +172,8 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { private static final String PRINCIPAL_TYPE_TABLE = "adminprincipaltype"; private static final String PRINCIPAL_TABLE = "adminprincipal"; protected static final String HBASE_SITE_CONFIG = "hbase-site"; + protected static final String HBASE_SPNEGO_PRINCIPAL_KEY = "hbase.security.authentication.spnego.kerberos.principal"; + protected static final String HBASE_SPNEGO_KEYTAB_KEY = "hbase.security.authentication.spnego.kerberos.keytab"; private static final Map<String, Integer> ROLE_ORDER; @@ -363,6 +365,7 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { updateYarnEnv(); updatePhoenixConfigs(); updateSparkConfigs(); + updateHBaseConfigs(); updateFalconConfigs(); updateKerberosDescriptorArtifacts(); removeHiveOozieDBConnectionConfigs(); @@ -2493,4 +2496,69 @@ public class UpgradeCatalog240 extends AbstractUpgradeCatalog { roleAuthorizationDAO.merge(roleAuthorization); } } + + /** + * Update HBase Kerberos configurations. Ambari 2.4 will alter the HBase web UIs to + * support SPNEGO authentication. HBase needs to have new keytab and principal properties + * to enable SPNEGO authentication (if the user so chooses to enable it). + */ + protected void updateHBaseConfigs() throws AmbariException { + final AmbariManagementController controller = injector.getInstance(AmbariManagementController.class); + final Clusters clusters = controller.getClusters(); + + if (null != clusters) { + Map<String, Cluster> clusterMap = clusters.getClusters(); + + if (null != clusterMap && !clusterMap.isEmpty()) { + for (final Cluster cluster : clusterMap.values()) { + Set<String> installedServices = cluster.getServices().keySet(); + StackId stackId = cluster.getCurrentStackVersion(); + + // HBase is installed and Kerberos is enabled + if (installedServices.contains("HBASE") && SecurityType.KERBEROS == cluster.getSecurityType() && isAtLeastHdp25(stackId)) { + Config hbaseSite = cluster.getDesiredConfigByType(HBASE_SITE_CONFIG); + if (null != hbaseSite) { + Map<String, String> hbaseSiteProperties = hbaseSite.getProperties(); + // Get any existing config properties (they probably don't exist) + String principal = hbaseSiteProperties.get(HBASE_SPNEGO_PRINCIPAL_KEY); + String keytab = hbaseSiteProperties.get(HBASE_SPNEGO_KEYTAB_KEY); + + final Map<String, String> updatedKerberosProperties = new HashMap<>(); + + // Set the principal for SPNEGO if it's not already set + if (null == principal) { + final KerberosDescriptor defaultDescriptor = getKerberosDescriptor(cluster); + final KerberosIdentityDescriptor spnegoDescriptor = defaultDescriptor.getIdentity("spnego"); + if (null != spnegoDescriptor) { + // Add the SPNEGO config for the principal + KerberosPrincipalDescriptor principalDescriptor = spnegoDescriptor.getPrincipalDescriptor(); + if (null != principalDescriptor) { + updatedKerberosProperties.put(HBASE_SPNEGO_PRINCIPAL_KEY, principalDescriptor.getValue()); + } + } + } + + // Set the keytab for SPNEGO if it's not already set + if (null == keytab) { + final KerberosDescriptor defaultDescriptor = getKerberosDescriptor(cluster); + final KerberosIdentityDescriptor spnegoDescriptor = defaultDescriptor.getIdentity("spnego"); + if (null != spnegoDescriptor) { + // Add the SPNEGO config for the keytab + KerberosKeytabDescriptor keytabDescriptor = spnegoDescriptor.getKeytabDescriptor(); + if (null != keytabDescriptor) { + updatedKerberosProperties.put(HBASE_SPNEGO_KEYTAB_KEY, keytabDescriptor.getFile()); + } + } + } + + // Update the configuration if we changed anything + if (!updatedKerberosProperties.isEmpty()) { + updateConfigurationProperties(HBASE_SITE_CONFIG, updatedKerberosProperties, true, false); + } + } + } + } + } + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/89870f28/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/alerts.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/alerts.json b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/alerts.json index 50a7ceb..1b3ae25 100644 --- a/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/alerts.json +++ b/ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/alerts.json @@ -67,7 +67,9 @@ "uri": { "http": "{{hbase-site/hbase.master.info.port}}", "default_port": 60010, - "connection_timeout": 5.0 + "connection_timeout": 5.0, + "kerberos_keytab": "{{hbase-site/hbase.security.authentication.spnego.kerberos.principal}}", + "kerberos_principal": "{{hbase-site/hbase.security.authentication.spnego.kerberos.keytab}}" }, "reporting": { "ok": { http://git-wip-us.apache.org/repos/asf/ambari/blob/89870f28/ambari-server/src/main/resources/stacks/HDP/2.5/services/HBASE/kerberos.json ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HBASE/kerberos.json b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HBASE/kerberos.json index 8be8bda..ada02ad 100644 --- a/ambari-server/src/main/resources/stacks/HDP/2.5/services/HBASE/kerberos.json +++ b/ambari-server/src/main/resources/stacks/HDP/2.5/services/HBASE/kerberos.json @@ -72,6 +72,15 @@ }, "configuration": "hbase-site/hbase.master.keytab.file" } + }, + { + "name": "/spnego", + "principal": { + "configuration": "hbase-site/hbase.security.authentication.spnego.kerberos.principal" + }, + "keytab": { + "configuration": "hbase-site/hbase.security.authentication.spnego.kerberos.keytab" + } } ] }, @@ -98,6 +107,15 @@ }, "configuration": "hbase-site/hbase.regionserver.keytab.file" } + }, + { + "name": "/spnego", + "principal": { + "configuration": "hbase-site/hbase.security.authentication.spnego.kerberos.principal" + }, + "keytab": { + "configuration": "hbase-site/hbase.security.authentication.spnego.kerberos.keytab" + } } ] }, http://git-wip-us.apache.org/repos/asf/ambari/blob/89870f28/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java index 244df76..1288053 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog240Test.java @@ -510,6 +510,7 @@ public class UpgradeCatalog240Test { Method upgradeCapSchedulerView = UpgradeCatalog240.class.getDeclaredMethod("upgradeCapSchedulerView"); Method updatePhoenixConfigs = UpgradeCatalog240.class.getDeclaredMethod("updatePhoenixConfigs"); Method updateSparkConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateSparkConfigs"); + Method updateHBaseConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateHBaseConfigs"); Method updateKerberosDescriptorArtifacts = AbstractUpgradeCatalog.class.getDeclaredMethod("updateKerberosDescriptorArtifacts"); Method updateFalconConfigs = UpgradeCatalog240.class.getDeclaredMethod("updateFalconConfigs"); Method fixAuthorizationDescriptions = UpgradeCatalog240.class.getDeclaredMethod("fixAuthorizationDescriptions"); @@ -554,6 +555,7 @@ public class UpgradeCatalog240Test { .addMockedMethod(fixAuthorizationDescriptions) .addMockedMethod(removeAuthorizations) .addMockedMethod(addConnectionTimeoutParamForWebAndMetricAlerts) + .addMockedMethod(updateHBaseConfigs) .createMock(); Field field = AbstractUpgradeCatalog.class.getDeclaredField("dbAccessor"); @@ -588,6 +590,7 @@ public class UpgradeCatalog240Test { upgradeCatalog240.fixAuthorizationDescriptions(); upgradeCatalog240.removeAuthorizations(); upgradeCatalog240.addConnectionTimeoutParamForWebAndMetricAlerts(); + upgradeCatalog240.updateHBaseConfigs(); replay(upgradeCatalog240, dbAccessor); @@ -1948,5 +1951,69 @@ public class UpgradeCatalog240Test { easyMockSupport.verifyAll(); } + @Test + public void testHBaseSpnegoPropertiesAreAdded() throws Exception{ + // Tests that we switch from the HBase service principal and keytab to the SPNEGO service principal and keytab. + final String spnegoPrincipal = "HTTP/[email protected]"; + final String spnegoKeytab = "/etc/security/keytabs/spnego.service.keytab"; + final Map<String, String> oldProperties = new HashMap<>(); + final Map<String, String> newProperties = new HashMap<String, String>(); + newProperties.put(UpgradeCatalog240.HBASE_SPNEGO_PRINCIPAL_KEY, spnegoPrincipal); + newProperties.put(UpgradeCatalog240.HBASE_SPNEGO_KEYTAB_KEY, spnegoKeytab); + + final EasyMockSupport easyMockSupport = new EasyMockSupport(); + + // Set up all of the injected mocks to trigger the upgrade scenario + AmbariManagementController controller = easyMockSupport.createNiceMock(AmbariManagementController.class); + KerberosDescriptor kerberosDescriptor = easyMockSupport.createNiceMock(KerberosDescriptor.class); + KerberosIdentityDescriptor kerberosIdentityDescriptor = easyMockSupport.createNiceMock(KerberosIdentityDescriptor.class); + KerberosPrincipalDescriptor principalDescriptor = easyMockSupport.createNiceMock(KerberosPrincipalDescriptor.class); + KerberosKeytabDescriptor keytabDescriptor = easyMockSupport.createNiceMock(KerberosKeytabDescriptor.class); + Clusters clusters = easyMockSupport.createNiceMock(Clusters.class); + final Cluster cluster = easyMockSupport.createNiceMock(Cluster.class); + Config mockHbaseSite = easyMockSupport.createNiceMock(Config.class); + // HBase and Kerberos are both "installed" + final Map<String, Service> mockServices = new HashMap<>(); + mockServices.put("HBASE", null); + final StackId stackId = new StackId("HDP-2.5"); + + expect(controller.getClusters()).andReturn(clusters).once(); + expect(clusters.getClusters()).andReturn(Collections.singletonMap("normal", cluster)).once(); + expect(cluster.getCurrentStackVersion()).andReturn(stackId); + expect(cluster.getServices()).andReturn(mockServices).once(); + expect(cluster.getSecurityType()).andReturn(SecurityType.KERBEROS).anyTimes(); + expect(cluster.getDesiredConfigByType(UpgradeCatalog240.HBASE_SITE_CONFIG)).andReturn(mockHbaseSite).atLeastOnce(); + expect(mockHbaseSite.getProperties()).andReturn(oldProperties).anyTimes(); + + // Stub out the KerberosDescriptor down to the Principal and Keytab Descriptors + expect(kerberosDescriptor.getIdentity("spnego")).andReturn(kerberosIdentityDescriptor).anyTimes(); + expect(kerberosIdentityDescriptor.getPrincipalDescriptor()).andReturn(principalDescriptor).anyTimes(); + expect(kerberosIdentityDescriptor.getKeytabDescriptor()).andReturn(keytabDescriptor).anyTimes(); + expect(principalDescriptor.getValue()).andReturn(spnegoPrincipal).anyTimes(); + expect(keytabDescriptor.getFile()).andReturn(spnegoKeytab).anyTimes(); + + Injector injector = easyMockSupport.createNiceMock(Injector.class); + expect(injector.getInstance(AmbariManagementController.class)).andReturn(controller).anyTimes(); + + easyMockSupport.replayAll(); + + UpgradeCatalog240 upgradeCatalog240 = createMockBuilder(UpgradeCatalog240.class) + .withConstructor(Injector.class) + .withArgs(injector) + .addMockedMethod("updateConfigurationProperties", String.class, Map.class, boolean.class, boolean.class) + .addMockedMethod("getKerberosDescriptor", Cluster.class) + .createMock(); + + expect(upgradeCatalog240.getKerberosDescriptor(cluster)).andReturn(kerberosDescriptor).once(); + + upgradeCatalog240.updateConfigurationProperties(UpgradeCatalog240.HBASE_SITE_CONFIG, newProperties, true, false); + expectLastCall().once(); + + replay(upgradeCatalog240); + + // Expected that we see the configuration updates fire + upgradeCatalog240.updatePhoenixConfigs(); + easyMockSupport.verifyAll(); + } }
