/* * 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. */ package org.apache.ambari.server.controller; import static org.easymock.EasyMock.anyLong; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.anyString; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.getCurrentArguments; import static org.easymock.EasyMock.isNull; import static org.easymock.EasyMock.newCapture; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.lang.reflect.Method; import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.persistence.EntityManager; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.Role; import org.apache.ambari.server.actionmanager.ActionManager; import org.apache.ambari.server.actionmanager.HostRoleCommand; import org.apache.ambari.server.actionmanager.HostRoleCommandFactory; import org.apache.ambari.server.actionmanager.HostRoleCommandFactoryImpl; import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.actionmanager.StageFactory; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorHelper; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; import org.apache.ambari.server.audit.AuditLogger; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.internal.RequestStageContainer; import org.apache.ambari.server.controller.spi.ClusterController; import org.apache.ambari.server.controller.utilities.KerberosChecker; import org.apache.ambari.server.metadata.CachedRoleCommandOrderProvider; import org.apache.ambari.server.metadata.RoleCommandOrder; import org.apache.ambari.server.metadata.RoleCommandOrderProvider; import org.apache.ambari.server.orm.DBAccessor; import org.apache.ambari.server.orm.dao.ArtifactDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO; import org.apache.ambari.server.security.SecurityHelper; import org.apache.ambari.server.security.credential.PrincipalKeyCredential; import org.apache.ambari.server.security.encryption.CredentialStoreService; import org.apache.ambari.server.security.encryption.CredentialStoreServiceImpl; import org.apache.ambari.server.security.encryption.CredentialStoreType; import org.apache.ambari.server.serveraction.ActionLog; import org.apache.ambari.server.serveraction.kerberos.ConfigureAmbariIdentitiesServerAction; import org.apache.ambari.server.serveraction.kerberos.CreateKeytabFilesServerAction; import org.apache.ambari.server.serveraction.kerberos.CreatePrincipalsServerAction; import org.apache.ambari.server.serveraction.kerberos.KDCType; import org.apache.ambari.server.serveraction.kerberos.KerberosConfigDataFileWriterFactory; import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException; import org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCredentialsException; import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException; import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandler; import org.apache.ambari.server.serveraction.kerberos.KerberosOperationHandlerFactory; import org.apache.ambari.server.stack.StackManagerFactory; import org.apache.ambari.server.stageplanner.RoleGraphFactory; 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.state.Host; import org.apache.ambari.server.state.HostState; import org.apache.ambari.server.state.SecurityState; import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentHost; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.State; import org.apache.ambari.server.state.UpgradeContextFactory; import org.apache.ambari.server.state.cluster.ClusterFactory; import org.apache.ambari.server.state.host.HostFactory; import org.apache.ambari.server.state.kerberos.KerberosComponentDescriptor; import org.apache.ambari.server.state.kerberos.KerberosConfigurationDescriptor; import org.apache.ambari.server.state.kerberos.KerberosDescriptor; import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory; import org.apache.ambari.server.state.kerberos.KerberosIdentityDescriptor; import org.apache.ambari.server.state.kerberos.KerberosKeytabDescriptor; import org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor; import org.apache.ambari.server.state.kerberos.KerberosPrincipalType; import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor; import org.apache.ambari.server.state.stack.OsFamily; import org.apache.ambari.server.topology.TopologyManager; import org.apache.ambari.server.utils.StageUtils; import org.apache.directory.server.kerberos.shared.keytab.Keytab; import org.easymock.Capture; import org.easymock.CaptureType; import org.easymock.EasyMock; import org.easymock.EasyMockSupport; import org.easymock.IAnswer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.assistedinject.FactoryModuleBuilder; @SuppressWarnings("unchecked") public class KerberosHelperTest extends EasyMockSupport { private static Injector injector; private final ClusterController clusterController = createStrictMock(ClusterController.class); private final KerberosDescriptorFactory kerberosDescriptorFactory = createStrictMock(KerberosDescriptorFactory.class); private final KerberosConfigDataFileWriterFactory kerberosConfigDataFileWriterFactory = createStrictMock(KerberosConfigDataFileWriterFactory.class); private final AmbariMetaInfo metaInfo = createMock(AmbariMetaInfo.class); private final TopologyManager topologyManager = createMock(TopologyManager.class); private final Configuration configuration = createMock(Configuration.class); @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { reset(clusterController); reset(metaInfo); final KerberosOperationHandlerFactory kerberosOperationHandlerFactory = createMock(KerberosOperationHandlerFactory.class); expect(kerberosOperationHandlerFactory.getKerberosOperationHandler(KDCType.NONE)) .andReturn(null) .anyTimes(); expect(kerberosOperationHandlerFactory.getKerberosOperationHandler(KDCType.MIT_KDC)) .andReturn(new KerberosOperationHandler() { @Override public void open(PrincipalKeyCredential administratorCredentials, String defaultRealm, Map<String, String> kerberosConfiguration) throws KerberosOperationException { setAdministratorCredential(administratorCredentials); setDefaultRealm(defaultRealm); setOpen(true); } @Override public void close() throws KerberosOperationException { } @Override public boolean principalExists(String principal) throws KerberosOperationException { return "principal".equals(principal); } @Override public Integer createPrincipal(String principal, String password, boolean service) throws KerberosOperationException { return null; } @Override public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException { return null; } @Override public boolean removePrincipal(String principal) throws KerberosOperationException { return false; } @Override public boolean createKeytabFile(Keytab keytab, File destinationKeytabFile) throws KerberosOperationException { return true; } }) .anyTimes(); Method methodGetConfiguredTemporaryDirectory = KerberosHelperImpl.class.getDeclaredMethod("getConfiguredTemporaryDirectory"); final KerberosHelperImpl kerberosHelper = createMockBuilder(KerberosHelperImpl.class) .addMockedMethod(methodGetConfiguredTemporaryDirectory) .createMock(); expect(kerberosHelper.getConfiguredTemporaryDirectory()).andReturn(temporaryFolder.getRoot()).anyTimes(); injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { install(new FactoryModuleBuilder().build(UpgradeContextFactory.class)); install(new FactoryModuleBuilder().build(RoleGraphFactory.class)); bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class)); bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class)); bind(ClusterFactory.class).toInstance(createNiceMock(ClusterFactory.class)); bind(HostFactory.class).toInstance(createNiceMock(HostFactory.class)); bind(SecurityHelper.class).toInstance(createNiceMock(SecurityHelper.class)); bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); bind(AmbariCustomCommandExecutionHelper.class).toInstance(createNiceMock(AmbariCustomCommandExecutionHelper.class)); bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class)); bind(AmbariMetaInfo.class).toInstance(metaInfo); bind(ActionManager.class).toInstance(createNiceMock(ActionManager.class)); bind(RequestFactory.class).toInstance(createNiceMock(RequestFactory.class)); bind(StageFactory.class).toInstance(createNiceMock(StageFactory.class)); bind(Clusters.class).toInstance(createNiceMock(Clusters.class)); bind(ConfigHelper.class).toInstance(createNiceMock(ConfigHelper.class)); bind(KerberosOperationHandlerFactory.class).toInstance(kerberosOperationHandlerFactory); bind(ClusterController.class).toInstance(clusterController); bind(KerberosDescriptorFactory.class).toInstance(kerberosDescriptorFactory); bind(KerberosConfigDataFileWriterFactory.class).toInstance(kerberosConfigDataFileWriterFactory); bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class)); bind(KerberosHelper.class).toInstance(kerberosHelper); bind(CredentialStoreService.class).to(CredentialStoreServiceImpl.class); bind(CreatePrincipalsServerAction.class).toInstance(createMock(CreatePrincipalsServerAction.class)); bind(CreateKeytabFilesServerAction.class).toInstance(createMock(CreateKeytabFilesServerAction.class)); bind(ConfigureAmbariIdentitiesServerAction.class).toInstance(createMock(ConfigureAmbariIdentitiesServerAction.class)); bind(StackAdvisorHelper.class).toInstance(createMock(StackAdvisorHelper.class)); bind(HostRoleCommandDAO.class).toInstance(createNiceMock(HostRoleCommandDAO.class)); bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class)); bind(ArtifactDAO.class).toInstance(createNiceMock(ArtifactDAO.class)); bind(KerberosPrincipalDAO.class).toInstance(createNiceMock(KerberosPrincipalDAO.class)); bind(RoleCommandOrderProvider.class).to(CachedRoleCommandOrderProvider.class); bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class); requestStaticInjection(KerberosChecker.class); } }); //todo: StageUtils shouldn't be called for this test StageUtils.setTopologyManager(topologyManager); expect(topologyManager.getPendingHostComponents()).andReturn( Collections.<String, Collection<String>>emptyMap()).anyTimes(); StageUtils.setConfiguration(configuration); expect(configuration.getApiSSLAuthentication()).andReturn(false).anyTimes(); expect(configuration.getClientApiPort()).andReturn(8080).anyTimes(); expect(configuration.getServerTempDir()).andReturn(temporaryFolder.getRoot().getAbsolutePath()).anyTimes(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); if (!credentialStoreService.isInitialized(CredentialStoreType.TEMPORARY)) { ((CredentialStoreServiceImpl) credentialStoreService).initializeTemporaryCredentialStore(10, TimeUnit.MINUTES, false); } } @After public void tearDown() throws Exception { } @Test(expected = AmbariException.class) public void testMissingClusterEnv() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); Cluster cluster = createNiceMock(Cluster.class); RequestStageContainer requestStageContainer = createNiceMock(RequestStageContainer.class); replayAll(); kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, requestStageContainer, true); verifyAll(); } @Test(expected = AmbariException.class) public void testMissingKrb5Conf() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("ldap_url")).andReturn("").once(); expect(kerberosEnvProperties.get("container_dn")).andReturn("").once(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).once(); final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(kerberosEnvConfig).once(); replayAll(); kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, null, true); verifyAll(); } @Test(expected = AmbariException.class) public void testMissingKerberosEnvConf() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("realm")).andReturn("EXAMPLE.COM").once(); expect(kerberosEnvProperties.get("kdc_hosts")).andReturn("10.0.100.1").once(); final Map<String, String> krb5ConfProperties = createMock(Map.class); expect(krb5ConfProperties.get("kadmin_host")).andReturn("10.0.100.1").once(); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).once(); final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).once(); replayAll(); kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, null, true); verifyAll(); } @Test public void testEnableKerberos() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), "mit-kdc", "true"); } @Test public void testEnableKerberos_UpgradeFromAmbari170KerberizedCluster() throws Exception { testEnableKerberos_UpgradeFromAmbari170KerberizedCluster(new PrincipalKeyCredential("principal", "password"), "mit-kdc", "true"); } @Test public void testEnableKerberos_ManageIdentitiesFalseKdcNone() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), "none", "false"); } @Test(expected = AmbariException.class) public void testEnableKerberos_ManageIdentitiesTrueKdcNone() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), "none", "true"); } @Test(expected = KerberosInvalidConfigurationException.class) public void testEnableKerberos_ManageIdentitiesTrueKdcNull() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), null, "true"); } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testEnableKerberosMissingCredentials() throws Exception { try { testEnableKerberos(null, "mit-kdc", "true"); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Missing KDC administrator credentials")); throw e; } } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testEnableKerberosInvalidCredentials() throws Exception { try { testEnableKerberos(new PrincipalKeyCredential("invalid_principal", "password"), "mit-kdc", "true"); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Invalid KDC administrator credentials")); throw e; } } @Test public void testEnableKerberos_GetKerberosDescriptorFromCluster() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), "mit-kdc", "true"); } @Test public void testEnableKerberos_GetKerberosDescriptorFromStack() throws Exception { testEnableKerberos(new PrincipalKeyCredential("principal", "password"), "mit-kdc", "true"); } @Test public void testEnsureIdentities() throws Exception { testEnsureIdentities(new PrincipalKeyCredential("principal", "password"), null); } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testEnsureIdentitiesMissingCredentials() throws Exception { try { testEnsureIdentities(null, null); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Missing KDC administrator credentials")); throw e; } } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testEnsureIdentitiesInvalidCredentials() throws Exception { try { testEnsureIdentities(new PrincipalKeyCredential("invalid_principal", "password"), null); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Invalid KDC administrator credentials")); throw e; } } @Test public void testEnsureIdentities_FilteredHosts() throws Exception { testEnsureIdentities(new PrincipalKeyCredential("principal", "password"), Collections.singleton("hostA")); } @Test public void testDeleteIdentities() throws Exception { testDeleteIdentities(new PrincipalKeyCredential("principal", "password")); } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testDeleteIdentitiesMissingCredentials() throws Exception { try { testDeleteIdentities(null); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Missing KDC administrator credentials")); throw e; } } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testDeleteIdentitiesInvalidCredentials() throws Exception { try { testDeleteIdentities(new PrincipalKeyCredential("invalid_principal", "password")); } catch (IllegalArgumentException e) { Assert.assertTrue(e.getMessage().startsWith("Invalid KDC administrator credentials")); throw e; } } @Test public void testExecuteCustomOperationsInvalidOperation() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final Cluster cluster = createNiceMock(Cluster.class); try { kerberosHelper.executeCustomOperations(cluster, Collections.singletonMap("invalid_operation", "false"), null, true); } catch (Throwable t) { Assert.fail("Exception should not have been thrown"); } } @Test(expected = AmbariException.class) public void testRegenerateKeytabsInvalidValue() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final Cluster cluster = createNiceMock(Cluster.class); kerberosHelper.executeCustomOperations(cluster, Collections.singletonMap(KerberosHelper.DIRECTIVE_REGENERATE_KEYTABS, "false"), null, true); Assert.fail("AmbariException should have failed"); } @Test public void testRegenerateKeytabsValidateRequestStageContainer() throws Exception { testRegenerateKeytabs(new PrincipalKeyCredential("principal", "password"), true, false); } @Test public void testRegenerateKeytabsValidateSkipInvalidHost() throws Exception { testRegenerateKeytabs(new PrincipalKeyCredential("principal", "password"), true, true); } @Test public void testRegenerateKeytabs() throws Exception { testRegenerateKeytabs(new PrincipalKeyCredential("principal", "password"), false, false); } @Test public void testDisableKerberos() throws Exception { testDisableKerberos(new PrincipalKeyCredential("principal", "password")); } @Test public void testCreateTestIdentity_ManageIdentitiesDefault() throws Exception { testCreateTestIdentity(new PrincipalKeyCredential("principal", "password"), null); } @Test public void testCreateTestIdentity_ManageIdentitiesTrue() throws Exception { testCreateTestIdentity(new PrincipalKeyCredential("principal", "password"), Boolean.TRUE); } @Test public void testCreateTestIdentity_ManageIdentitiesFalse() throws Exception { testCreateTestIdentity(new PrincipalKeyCredential("principal", "password"), Boolean.FALSE); } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testCreateTestIdentityNoCredentials_ManageIdentitiesDefault() throws Exception { testCreateTestIdentity(null, null); } @Test(expected = KerberosMissingAdminCredentialsException.class) public void testCreateTestIdentityNoCredentials_ManageIdentitiesTrue() throws Exception { testCreateTestIdentity(null, Boolean.TRUE); } @Test public void testCreateTestIdentityNoCredentials_ManageIdentitiesFalse() throws Exception { testCreateTestIdentity(null, Boolean.FALSE); } @Test public void testDeleteTestIdentity() throws Exception { testDeleteTestIdentity(new PrincipalKeyCredential("principal", "password")); } @Test(expected = IllegalArgumentException.class) public void testGetActiveIdentities_MissingCluster() throws Exception { testGetActiveIdentities(null, null, null, null, true, SecurityType.KERBEROS); } @Test public void testGetActiveIdentities_SecurityTypeKerberos_All() throws Exception { testGetActiveIdentities_All(SecurityType.KERBEROS); } @Test public void testGetActiveIdentities_SecurityTypeNone_All() throws Exception { testGetActiveIdentities_All(SecurityType.NONE); } @Test public void testGetActiveIdentities_SingleHost() throws Exception { Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", "host1", null, null, true, SecurityType.KERBEROS); Assert.assertNotNull(identities); Assert.assertEquals(1, identities.size()); Collection<KerberosIdentityDescriptor> hostIdentities; hostIdentities = identities.get("host1"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(3, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity2", new HashMap<String, Object>() { { put("principal_name", "component2/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service2-site/component2.kerberos.principal"); put("principal_local_username", "service2"); put("keytab_file", "${keytab_dir}/service2.keytab"); put("keytab_owner_name", "service2"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service2-site/component2.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); } @Test public void addAmbariServerIdentity_CreateAmbariPrincipal() throws Exception { addAmbariServerIdentity(Collections.singletonMap("create_ambari_principal", "true")); } @Test public void addAmbariServerIdentity_DoNotCreateAmbariPrincipal() throws Exception { addAmbariServerIdentity(Collections.singletonMap("create_ambari_principal", "false")); } @Test public void addAmbariServerIdentity_MissingProperty() throws Exception { addAmbariServerIdentity(Collections.singletonMap("not_create_ambari_principal", "value")); } @Test public void addAmbariServerIdentity_MissingKerberosEnv() throws Exception { addAmbariServerIdentity(null); } @Test public void testGetActiveIdentities_SingleService() throws Exception { Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, "SERVICE1", null, true, SecurityType.KERBEROS); Assert.assertNotNull(identities); Assert.assertEquals(3, identities.size()); Collection<KerberosIdentityDescriptor> hostIdentities; hostIdentities = identities.get("host1"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(2, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); hostIdentities = identities.get("host2"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(2, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); } @Test public void testGetActiveIdentities_SingleServiceSingleHost() throws Exception { Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", "host2", "SERVICE1", null, true, SecurityType.KERBEROS); Assert.assertNotNull(identities); Assert.assertEquals(1, identities.size()); Collection<KerberosIdentityDescriptor> hostIdentities; hostIdentities = identities.get("host2"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(2, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); } @Test public void testGetActiveIdentities_SingleComponent() throws Exception { Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, null, "COMPONENT2", true, SecurityType.KERBEROS); Assert.assertNotNull(identities); Assert.assertEquals(3, identities.size()); Collection<KerberosIdentityDescriptor> hostIdentities; hostIdentities = identities.get("host1"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(1, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity2", new HashMap<String, Object>() { { put("principal_name", "component2/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service2-site/component2.kerberos.principal"); put("principal_local_username", "service2"); put("keytab_file", "${keytab_dir}/service2.keytab"); put("keytab_owner_name", "service2"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service2-site/component2.keytab.file"); put("keytab_cachable", false); } }); }}); hostIdentities = identities.get("host2"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(1, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity2", new HashMap<String, Object>() { { put("principal_name", "component2/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service2-site/component2.kerberos.principal"); put("principal_local_username", "service2"); put("keytab_file", "${keytab_dir}/service2.keytab"); put("keytab_owner_name", "service2"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service2-site/component2.keytab.file"); put("keytab_cachable", false); } }); }}); } private void testGetActiveIdentities_All(SecurityType clusterSecurityType) throws Exception { Map<String, Collection<KerberosIdentityDescriptor>> identities = testGetActiveIdentities("c1", null, null, null, true, clusterSecurityType); Assert.assertNotNull(identities); Assert.assertEquals(3, identities.size()); Collection<KerberosIdentityDescriptor> hostIdentities; hostIdentities = identities.get("host1"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(3, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity2", new HashMap<String, Object>() { { put("principal_name", "component2/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service2-site/component2.kerberos.principal"); put("principal_local_username", "service2"); put("keytab_file", "${keytab_dir}/service2.keytab"); put("keytab_owner_name", "service2"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service2-site/component2.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host1@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); hostIdentities = identities.get("host2"); Assert.assertNotNull(hostIdentities); Assert.assertEquals(3, hostIdentities.size()); validateIdentities(hostIdentities, new HashMap<String, Map<String, Object>>() {{ put("identity1", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/component1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/component1.keytab.file"); put("keytab_cachable", false); } }); put("identity2", new HashMap<String, Object>() { { put("principal_name", "component2/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service2-site/component2.kerberos.principal"); put("principal_local_username", "service2"); put("keytab_file", "${keytab_dir}/service2.keytab"); put("keytab_owner_name", "service2"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service2-site/component2.keytab.file"); put("keytab_cachable", false); } }); put("identity3", new HashMap<String, Object>() { { put("principal_name", "service1/host2@EXAMPLE.COM"); put("principal_type", KerberosPrincipalType.SERVICE); put("principal_configuration", "service1-site/service1.kerberos.principal"); put("principal_local_username", "service1"); put("keytab_file", "${keytab_dir}/service1.service.keytab"); put("keytab_owner_name", "service1"); put("keytab_owner_access", "rw"); put("keytab_group_name", "hadoop"); put("keytab_group_access", ""); put("keytab_configuration", "service1-site/service1.keytab.file"); put("keytab_cachable", false); } }); }}); } private void validateIdentities(Collection<KerberosIdentityDescriptor> identities, HashMap<String, Map<String, Object>> expectedDataMap) { Assert.assertEquals(expectedDataMap.size(), identities.size()); for (KerberosIdentityDescriptor identity : identities) { Map<String, Object> expectedData = expectedDataMap.get(identity.getName()); Assert.assertNotNull(expectedData); KerberosPrincipalDescriptor principal = identity.getPrincipalDescriptor(); Assert.assertNotNull(principal); Assert.assertEquals(expectedData.get("principal_name"), principal.getName()); Assert.assertEquals(expectedData.get("principal_type"), principal.getType()); Assert.assertEquals(expectedData.get("principal_configuration"), principal.getConfiguration()); Assert.assertEquals(expectedData.get("principal_local_username"), principal.getLocalUsername()); KerberosKeytabDescriptor keytab = identity.getKeytabDescriptor(); Assert.assertNotNull(keytab); Assert.assertEquals(expectedData.get("keytab_file"), keytab.getFile()); Assert.assertEquals(expectedData.get("keytab_owner_name"), keytab.getOwnerName()); Assert.assertEquals(expectedData.get("keytab_owner_access"), keytab.getOwnerAccess()); Assert.assertEquals(expectedData.get("keytab_group_name"), keytab.getGroupName()); Assert.assertEquals(expectedData.get("keytab_group_access"), keytab.getGroupAccess()); Assert.assertEquals(expectedData.get("keytab_configuration"), keytab.getConfiguration()); Assert.assertEquals(Boolean.TRUE.equals(expectedData.get("keytab_cachable")), keytab.isCachable()); } } private void testEnableKerberos_UpgradeFromAmbari170KerberizedCluster(final PrincipalKeyCredential PrincipalKeyCredential, String kdcType, String manageIdentities) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); boolean identitiesManaged = (manageIdentities == null) || !"false".equalsIgnoreCase(manageIdentities); final StackId stackVersion = createMock(StackId.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1.getSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch1.getDesiredSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch1.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); expect(sch1.getState()).andReturn(State.INSTALLED).anyTimes(); sch1.setDesiredSecurityState(SecurityState.SECURED_KERBEROS); expect(expectLastCall()).once(); sch1.setSecurityState(SecurityState.SECURING); expect(expectLastCall()).once(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); expect(sch2.getSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch2.getDesiredSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch2.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch2.getHostName()).andReturn("host1").anyTimes(); expect(sch2.getState()).andReturn(State.INSTALLED).anyTimes(); sch2.setDesiredSecurityState(SecurityState.SECURED_KERBEROS); expect(expectLastCall()).once(); sch2.setSecurityState(SecurityState.SECURING); expect(expectLastCall()).once(); final Host host = createMockHost("host1"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(1); serviceKerberos.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); service1.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); service2.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn(kdcType).anyTimes(); expect(kerberosEnvProperties.get("manage_identities")).andReturn(manageIdentities).anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); expect(kerberosEnvProperties.get("create_ambari_principal")).andReturn("false").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Collections.singleton(host), SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); add(sch1); add(sch2); } }) .once(); if (identitiesManaged) { final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); } expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(Collections.singletonList(schKerberosClient)) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor2 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getService("KERBEROS")).andReturn(null).once(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).once(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).once(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); // Create Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); if (identitiesManaged) { // Create Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(0L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Distribute Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); } // Update Configs Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // TODO: Add more of these when more stages are added. // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); replayAll(); // Needed by infrastructure metaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, requestStageContainer, null); verifyAll(); } private void testEnableKerberos(final PrincipalKeyCredential PrincipalKeyCredential, String kdcType, String manageIdentities) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); boolean identitiesManaged = (manageIdentities == null) || !"false".equalsIgnoreCase(manageIdentities); final StackId stackVersion = createMock(StackId.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); expect(sch1.getState()).andReturn(State.INSTALLED).anyTimes(); sch1.setDesiredSecurityState(SecurityState.SECURED_KERBEROS); expect(expectLastCall()).once(); sch1.setSecurityState(SecurityState.SECURING); expect(expectLastCall()).once(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); expect(sch2.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch2.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch2.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch2.getHostName()).andReturn("host1").anyTimes(); expect(sch2.getState()).andReturn(State.INSTALLED).anyTimes(); sch2.setDesiredSecurityState(SecurityState.SECURED_KERBEROS); expect(expectLastCall()).once(); sch2.setSecurityState(SecurityState.SECURING); expect(expectLastCall()).once(); final Host host = createMockHost("host1"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(1); serviceKerberos.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); service1.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); service2.setSecurityState(SecurityState.SECURED_KERBEROS); expectLastCall().once(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn(kdcType).anyTimes(); expect(kerberosEnvProperties.get("manage_identities")).andReturn(manageIdentities).anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); expect(kerberosEnvProperties.get("create_ambari_principal")).andReturn("false").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Collections.singleton(host), SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); add(sch1); add(sch2); } }) .once(); expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(Collections.singletonList(schKerberosClient)) .once(); if (identitiesManaged) { final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); } final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor2 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getService("KERBEROS")).andReturn(null).once(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).once(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).once(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); // Create Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); if (identitiesManaged) { // Create Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); // Create Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(0L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); // Distribute Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); } // Update Configs Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); // TODO: Add more of these when more stages are added. // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); replayAll(); // Needed by infrastructure metaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.toggleKerberos(cluster, SecurityType.KERBEROS, requestStageContainer, null); verifyAll(); } private void testDisableKerberos(final PrincipalKeyCredential PrincipalKeyCredential) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final StackId stackVersion = createMock(StackId.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(schKerberosClient.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").times(1); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").once(); expect(sch1.getSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch1.getDesiredSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch1.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); expect(sch1.getState()).andReturn(State.INSTALLED).anyTimes(); sch1.setDesiredSecurityState(SecurityState.UNSECURED); expect(expectLastCall()).once(); sch1.setSecurityState(SecurityState.UNSECURING); expect(expectLastCall()).once(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").times(1); expect(sch2.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); expect(sch2.getSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch2.getDesiredSecurityState()).andReturn(SecurityState.SECURED_KERBEROS).anyTimes(); expect(sch2.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch2.getHostName()).andReturn("host1").anyTimes(); expect(sch2.getState()).andReturn(State.INSTALLED).anyTimes(); sch2.setDesiredSecurityState(SecurityState.UNSECURED); expect(expectLastCall()).once(); sch2.setSecurityState(SecurityState.UNSECURING); expect(expectLastCall()).once(); final Host host = createMockHost("host1"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createNiceMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .anyTimes(); serviceKerberos.setSecurityState(SecurityState.UNSECURED); expectLastCall().once(); final Service service1 = createNiceMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .anyTimes(); service1.setSecurityState(SecurityState.UNSECURED); expectLastCall().once(); final Service service2 = createNiceMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .anyTimes(); service2.setSecurityState(SecurityState.UNSECURED); expectLastCall().once(); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Collections.singleton(host), SecurityType.NONE, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); add(sch1); add(sch2); } }) .once(); expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(Collections.singletonList(schKerberosClient)) .once(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor2 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getService("KERBEROS")).andReturn(null).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).atLeastOnce(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); expect(cluster.getService("ZOOKEEPER")).andReturn(service1).anyTimes(); // Hook Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); // StopZk Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); // Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Update Configs Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Destroy Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Delete Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Cleanup Stage expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); replayAll(); // Needed by infrastructure metaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.toggleKerberos(cluster, SecurityType.NONE, requestStageContainer, true); verifyAll(); } private void testRegenerateKeytabs(final PrincipalKeyCredential PrincipalKeyCredential, boolean mockRequestStageContainer, final boolean testInvalidHost) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final StackId stackVersion = createMock(StackId.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); expect(sch2.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch2.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch2.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch2.getHostName()).andReturn("host1").anyTimes(); final Host host = createMockHost("host1"); final ServiceComponentHost schKerberosClientInvalid; final ServiceComponentHost sch1a; final Host hostInvalid; if (testInvalidHost) { schKerberosClientInvalid = createMock(ServiceComponentHost.class); expect(schKerberosClientInvalid.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClientInvalid.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClientInvalid.getHostName()).andReturn("host2").anyTimes(); expect(schKerberosClientInvalid.getState()).andReturn(State.INIT).anyTimes(); sch1a = createMock(ServiceComponentHost.class); expect(sch1a.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1a.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1a.getSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1a.getDesiredSecurityState()).andReturn(SecurityState.UNSECURED).anyTimes(); expect(sch1a.getStackVersion()).andReturn(stackVersion).anyTimes(); expect(sch1a.getHostName()).andReturn("host2").anyTimes(); hostInvalid = createMockHost("host1"); } else { schKerberosClientInvalid = null; hostInvalid = null; } Map<String, ServiceComponentHost> map = new HashMap<>(); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); map.put("host1", schKerberosClient); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); if (testInvalidHost) { map.put("host2", schKerberosClientInvalid); } expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(map).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(1); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); expect(kerberosEnvProperties.get("create_ambari_principal")).andReturn("false").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Collection<Host> hosts = (testInvalidHost) ? Arrays.asList(host, hostInvalid) : Collections.singleton(host); final Cluster cluster = createMockCluster("c1", hosts, SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); add(sch1); add(sch2); } }) .atLeastOnce(); expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(Collections.singletonList(schKerberosClient)) .once(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor2 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getService("KERBEROS")).andReturn(null).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).atLeastOnce(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); final RequestStageContainer requestStageContainer; if (mockRequestStageContainer) { // This is a STRICT mock to help ensure that the end result is what we want. requestStageContainer = createStrictMock(RequestStageContainer.class); // Create Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(0L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Distribute Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Update Configurations Stage expect(requestStageContainer.getLastStageId()).andReturn(1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(3L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); } else { requestStageContainer = null; } replayAll(); // Needed by infrastructure metaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); Assert.assertNotNull(kerberosHelper.executeCustomOperations(cluster, Collections.singletonMap(KerberosHelper.DIRECTIVE_REGENERATE_KEYTABS, "true"), requestStageContainer, true)); verifyAll(); } @Test public void testIsClusterKerberosEnabled_false() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); Cluster cluster = createStrictMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(SecurityType.NONE); replay(cluster); assertFalse(kerberosHelper.isClusterKerberosEnabled(cluster)); verify(cluster); } @Test public void testIsClusterKerberosEnabled_true() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); Cluster cluster = createStrictMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(SecurityType.KERBEROS); replay(cluster); assertTrue(kerberosHelper.isClusterKerberosEnabled(cluster)); verify(cluster); } @Test public void testGetManageIdentitiesDirective_NotSet() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(null, kerberosHelper.getManageIdentitiesDirective(null)); assertEquals(null, kerberosHelper.getManageIdentitiesDirective(Collections.<String, String>emptyMap())); assertEquals(null, kerberosHelper.getManageIdentitiesDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, null); put("some_directive_0", "false"); put("some_directive_1", null); } } )); assertEquals(null, kerberosHelper.getManageIdentitiesDirective( new HashMap<String, String>() { { put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testGetManageIdentitiesDirective_True() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(Boolean.TRUE, kerberosHelper.getManageIdentitiesDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, "true"))); assertEquals(Boolean.TRUE, kerberosHelper.getManageIdentitiesDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, "not_false"))); assertEquals(Boolean.TRUE, kerberosHelper.getManageIdentitiesDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, "true"); put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testGetManageIdentitiesDirective_False() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(Boolean.FALSE, kerberosHelper.getManageIdentitiesDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, "false"))); assertEquals(Boolean.FALSE, kerberosHelper.getManageIdentitiesDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_MANAGE_KERBEROS_IDENTITIES, "false"); put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testGetForceToggleKerberosDirective_NotSet() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective(null)); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective(Collections.<String, String>emptyMap())); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, null); put("some_directive_0", "false"); put("some_directive_1", null); } } )); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective( new HashMap<String, String>() { { put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testGetForceToggleKerberosDirective_True() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(true, kerberosHelper.getForceToggleKerberosDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, "true"))); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, "not_true"))); assertEquals(true, kerberosHelper.getForceToggleKerberosDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, "true"); put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testGetForceToggleKerberosDirective_False() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective(Collections.singletonMap(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, "false"))); assertEquals(false, kerberosHelper.getForceToggleKerberosDirective( new HashMap<String, String>() { { put(KerberosHelper.DIRECTIVE_FORCE_TOGGLE_KERBEROS, "false"); put("some_directive_0", "false"); put("some_directive_1", null); } } )); } @Test public void testSetAuthToLocalRules() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final KerberosPrincipalDescriptor principalDescriptor1 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1.getValue()).andReturn("principal1/host1@EXAMPLE.COM").times(1); expect(principalDescriptor1.getLocalUsername()).andReturn("principal1_user").times(1); final KerberosPrincipalDescriptor principalDescriptor2 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor2.getValue()).andReturn("principal2/host2@EXAMPLE.COM").times(1); expect(principalDescriptor2.getLocalUsername()).andReturn("principal2_user").times(1); final KerberosPrincipalDescriptor principalDescriptor3 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor3.getValue()).andReturn("principal3/host3@EXAMPLE.COM").times(1); expect(principalDescriptor3.getLocalUsername()).andReturn("principal3_user").times(1); final KerberosIdentityDescriptor identityDescriptor1 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1.getPrincipalDescriptor()).andReturn(principalDescriptor1).times(1); expect(identityDescriptor1.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); final KerberosIdentityDescriptor identityDescriptor2 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor2.getPrincipalDescriptor()).andReturn(principalDescriptor2).times(1); expect(identityDescriptor2.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); final KerberosIdentityDescriptor identityDescriptor3 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor3.getPrincipalDescriptor()).andReturn(principalDescriptor3).times(1); expect(identityDescriptor3.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); final KerberosComponentDescriptor componentDescriptor1 = createMockComponentDescriptor( "COMPONENT1", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor3); } }, null); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); expect(serviceDescriptor1.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(Arrays.asList( identityDescriptor1, identityDescriptor2 )).times(1); expect(serviceDescriptor1.getComponent("COMPONENT1")).andReturn(componentDescriptor1).times(1); expect(serviceDescriptor1.getAuthToLocalProperties()).andReturn(new HashSet<>(Arrays.asList( "default", "explicit_multiple_lines|new_lines", "explicit_multiple_lines_escaped|new_lines_escaped", "explicit_single_line|spaces", "service-site/default", "service-site/explicit_multiple_lines|new_lines", "service-site/explicit_multiple_lines_escaped|new_lines_escaped", "service-site/explicit_single_line|spaces" ))).times(1); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperty("additional_realms")).andReturn(null).times(1); expect(kerberosDescriptor.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(null).times(1); expect(kerberosDescriptor.getAuthToLocalProperties()).andReturn(null).times(1); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); Map<String, Set<String>> installedServices = Collections.singletonMap("SERVICE1", Collections.singleton("COMPONENT1")); Map<String, Map<String, String>> kerberosConfigurations = new HashMap<>(); replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); Map existingConfigs = new HashMap<>(); existingConfigs.put("kerberos-env", new HashMap<String, String>()); kerberosHelper.setAuthToLocalRules(kerberosDescriptor, "EXAMPLE.COM", installedServices, existingConfigs, kerberosConfigurations); verifyAll(); Map<String, String> configs; configs = kerberosConfigurations.get(""); assertNotNull(configs); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" + "DEFAULT", configs.get("default")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" + "DEFAULT", configs.get("explicit_multiple_lines")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\\\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\\\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\\\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\\\n" + "DEFAULT", configs.get("explicit_multiple_lines_escaped")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*// " + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/ " + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/ " + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/ " + "DEFAULT", configs.get("explicit_single_line")); configs = kerberosConfigurations.get("service-site"); assertNotNull(configs); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" + "DEFAULT", configs.get("default")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\n" + "DEFAULT", configs.get("explicit_multiple_lines")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*//\\\n" + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/\\\n" + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/\\\n" + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/\\\n" + "DEFAULT", configs.get("explicit_multiple_lines_escaped")); assertEquals("RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*// " + "RULE:[2:$1@$0](principal1@EXAMPLE.COM)s/.*/principal1_user/ " + "RULE:[2:$1@$0](principal2@EXAMPLE.COM)s/.*/principal2_user/ " + "RULE:[2:$1@$0](principal3@EXAMPLE.COM)s/.*/principal3_user/ " + "DEFAULT", configs.get("explicit_single_line")); } @Test public void testGetServiceConfigurationUpdates() throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final Host hostA = createMockHost("hostA"); final Host hostB = createMockHost("hostB"); final Host hostC = createMockHost("hostC"); Collection<Host> hosts = Arrays.asList(hostA, hostB, hostC); final Map<String, String> kerberosEnvProperties = new HashMap<String, String>() { { put("kdc_type", "mit-kdc"); put("realm", "FOOBAR.COM"); put("case_insensitive_username_rules", "false"); put("create_ambari_principal", "false"); } }; final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).atLeastOnce(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).atLeastOnce(); final KerberosPrincipalDescriptor principalDescriptor1 = createMockPrincipalDescriptor( "service1/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service1user", "service1-site/service.kerberos.principal"); final KerberosPrincipalDescriptor principalDescriptor1a = createMockPrincipalDescriptor( "component1a/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service1user", "service1-site/component1a.kerberos.principal"); final KerberosPrincipalDescriptor principalDescriptor1b = createMockPrincipalDescriptor( "component1b/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service1user", "service1-site/component1b.kerberos.principal"); final KerberosPrincipalDescriptor principalDescriptor2a = createMockPrincipalDescriptor( "component2a/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service2user", "service2-site/component2a.kerberos.principal"); final KerberosPrincipalDescriptor principalDescriptor2b = createMockPrincipalDescriptor( "component2b/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service2user", "service2-site/component2b.kerberos.principal"); final KerberosPrincipalDescriptor principalDescriptor3a = createMockPrincipalDescriptor( "component3a/_HOST@${realm}", KerberosPrincipalType.SERVICE, "service3user", "service3-site/component3a.kerberos.principal"); final KerberosKeytabDescriptor keytabDescriptor1 = createMockKeytabDescriptor( "keytab1", "service1-site/service.kerberos.keytab"); final KerberosKeytabDescriptor keytabDescriptor1a = createMockKeytabDescriptor( "keytab1a", "service1-site/component1a.kerberos.keytab"); final KerberosKeytabDescriptor keytabDescriptor1b = createMockKeytabDescriptor( "keytab1b", "service1-site/component1b.kerberos.keytab"); final KerberosKeytabDescriptor keytabDescriptor2a = createMockKeytabDescriptor( "keytab2a", "service2-site/component2a.kerberos.keytab"); final KerberosKeytabDescriptor keytabDescriptor2b = createMockKeytabDescriptor( "keytab2b", "service2-site/component2b.kerberos.keytab"); final KerberosKeytabDescriptor keytabDescriptor3a = createMockKeytabDescriptor( "keytab3a", "service3-site/component3a.kerberos.keytab"); final KerberosIdentityDescriptor identityDescriptor1 = createMockIdentityDescriptor( "identity1", principalDescriptor1, keytabDescriptor1); final KerberosIdentityDescriptor identityDescriptor1a = createMockIdentityDescriptor( "identity1a", principalDescriptor1a, keytabDescriptor1a); final KerberosIdentityDescriptor identityDescriptor1b = createMockIdentityDescriptor( "identity1b", principalDescriptor1b, keytabDescriptor1b); final KerberosIdentityDescriptor identityDescriptor2a = createMockIdentityDescriptor( "identity2a", principalDescriptor2a, keytabDescriptor2a); final KerberosIdentityDescriptor identityDescriptor2b = createMockIdentityDescriptor( "identity2b", principalDescriptor2b, keytabDescriptor2b); final KerberosIdentityDescriptor identityDescriptor3a = createMockIdentityDescriptor( "identity3a", principalDescriptor3a, keytabDescriptor3a); final KerberosComponentDescriptor componentDescriptor1a = createMockComponentDescriptor( "COMPONENT1A", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor1a); } }, new HashMap<String, KerberosConfigurationDescriptor>() { { put("service1-site", createMockConfigurationDescriptor( Collections.singletonMap("component1a.property", "${replacement1}") )); } }); final KerberosComponentDescriptor componentDescriptor1b = createMockComponentDescriptor( "COMPONENT1B", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor1b); } }, new HashMap<String, KerberosConfigurationDescriptor>() { { put("service1-site", createMockConfigurationDescriptor( Collections.singletonMap("component1b.property", "${type1/replacement1}") )); } }); final KerberosComponentDescriptor componentDescriptor2a = createMockComponentDescriptor( "COMPONENT2A", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor2a); } }, new HashMap<String, KerberosConfigurationDescriptor>() { { put("service2-site", createMockConfigurationDescriptor( Collections.singletonMap("component2a.property", "${type1/replacement2}") )); } }); final KerberosComponentDescriptor componentDescriptor2b = createMockComponentDescriptor( "COMPONENT2B", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor2b); } }, new HashMap<String, KerberosConfigurationDescriptor>() { { put("service2-site", createMockConfigurationDescriptor( Collections.singletonMap("component2b.property", "${type2/replacement1}") )); } }); final KerberosComponentDescriptor componentDescriptor3a = createMockComponentDescriptor( "COMPONENT3A", new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor3a); } }, new HashMap<String, KerberosConfigurationDescriptor>() { { put("service3-site", createMockConfigurationDescriptor( Collections.singletonMap("component3a.property", "${type3/replacement1}") )); put("core-site", createMockConfigurationDescriptor( Collections.singletonMap("component3b.property", "${type3/replacement2}") )); } }); final KerberosServiceDescriptor serviceDescriptor1 = createMockServiceDescriptor( "SERVICE1", new HashMap<String, KerberosComponentDescriptor>() { { put("COMPONENT1A", componentDescriptor1a); put("COMPONENT1B", componentDescriptor1b); } }, new ArrayList<KerberosIdentityDescriptor>() { { add(identityDescriptor1); } } ); expect(serviceDescriptor1.getComponent("COMPONENT1A")).andReturn(componentDescriptor1a).times(4); expect(serviceDescriptor1.getComponent("COMPONENT1B")).andReturn(componentDescriptor1b).times(4); final KerberosServiceDescriptor serviceDescriptor2 = createMockServiceDescriptor( "SERVICE2", new HashMap<String, KerberosComponentDescriptor>() { { put("COMPONENT2A", componentDescriptor2a); put("COMPONENT2B", componentDescriptor2b); } }, Collections.<KerberosIdentityDescriptor>emptyList()); expect(serviceDescriptor2.getComponent("COMPONENT2A")).andReturn(componentDescriptor2a).times(2); expect(serviceDescriptor2.getComponent("COMPONENT2B")).andReturn(componentDescriptor2b).times(2); final KerberosServiceDescriptor serviceDescriptor3 = createMockServiceDescriptor( "SERVICE3", new HashMap<String, KerberosComponentDescriptor>() { { put("COMPONENT3A", componentDescriptor3a); } }, Collections.<KerberosIdentityDescriptor>emptyList()); expect(serviceDescriptor3.getComponent("COMPONENT3A")).andReturn(componentDescriptor3a).times(4); final Map<String, String> kerberosDescriptorProperties = new HashMap<>(); kerberosDescriptorProperties.put("realm", "${kerberos-env/realm}"); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(kerberosDescriptorProperties).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).atLeastOnce(); expect(kerberosDescriptor.getService("SERVICE3")).andReturn(serviceDescriptor3).atLeastOnce(); expect(kerberosDescriptor.getProperty("additional_realms")).andReturn(null).atLeastOnce(); expect(kerberosDescriptor.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(null).atLeastOnce(); expect(kerberosDescriptor.getAuthToLocalProperties()).andReturn(Collections.singleton("core-site/auth.to.local")).atLeastOnce(); setupKerberosDescriptor(kerberosDescriptor, 2); RecommendationResponse.BlueprintConfigurations coreSiteRecommendation = createNiceMock(RecommendationResponse .BlueprintConfigurations.class); expect(coreSiteRecommendation.getProperties()).andReturn(Collections.singletonMap("newPropertyRecommendation", "newPropertyRecommendation")); RecommendationResponse.BlueprintConfigurations newTypeRecommendation = createNiceMock(RecommendationResponse.BlueprintConfigurations.class); expect(newTypeRecommendation.getProperties()).andReturn(Collections.singletonMap("newTypeRecommendation", "newTypeRecommendation")); RecommendationResponse.BlueprintConfigurations type1Recommendation = createNiceMock(RecommendationResponse.BlueprintConfigurations.class); expect(type1Recommendation.getProperties()).andReturn(Collections.singletonMap("replacement1", "not replaced")); RecommendationResponse.BlueprintConfigurations service1SiteRecommendation = createNiceMock(RecommendationResponse.BlueprintConfigurations.class); expect(service1SiteRecommendation.getProperties()).andReturn(Collections.singletonMap("component1b.property", "replaced value")); Map<String, RecommendationResponse.BlueprintConfigurations> configurations = new HashMap<>(); configurations.put("core-site", coreSiteRecommendation); configurations.put("new-type", newTypeRecommendation); configurations.put("type1", type1Recommendation); configurations.put("service1-site", service1SiteRecommendation); RecommendationResponse.Blueprint blueprint = createMock(RecommendationResponse.Blueprint.class); expect(blueprint.getConfigurations()).andReturn(configurations).once(); RecommendationResponse.Recommendation recommendations = createMock(RecommendationResponse.Recommendation.class); expect(recommendations.getBlueprint()).andReturn(blueprint).once(); RecommendationResponse recommendationResponse = createMock(RecommendationResponse.class); expect(recommendationResponse.getRecommendations()).andReturn(recommendations).once(); StackAdvisorHelper stackAdvisorHelper = injector.getInstance(StackAdvisorHelper.class); expect(stackAdvisorHelper.recommend(anyObject(StackAdvisorRequest.class))).andReturn(null).once(); expect(stackAdvisorHelper.recommend(anyObject(StackAdvisorRequest.class))).andReturn(recommendationResponse).once(); final Service service1 = createMockService("SERVICE1", new HashMap<String, ServiceComponent>() { { put("COMPONENT1A", createMockComponent("COMPONENT1A", true, new HashMap<String, ServiceComponentHost>() { { put("hostA", createMockServiceComponentHost(State.INSTALLED)); } })); put("COMPONENT1B", createMockComponent("COMPONENT1B", false, new HashMap<String, ServiceComponentHost>() { { put("hostB", createMockServiceComponentHost(State.INSTALLED)); put("hostC", createMockServiceComponentHost(State.INSTALLED)); } })); } }); final Service service2 = createMockService("SERVICE2", new HashMap<String, ServiceComponent>() { { put("COMPONENT2A", createMockComponent("COMPONENT2A", true, new HashMap<String, ServiceComponentHost>() { { put("hostA", createMockServiceComponentHost(State.INSTALLED)); } })); put("COMPONENT2B", createMockComponent("COMPONENT2B", false, new HashMap<String, ServiceComponentHost>() { { put("hostB", createMockServiceComponentHost(State.INSTALLED)); put("hostC", createMockServiceComponentHost(State.INSTALLED)); } })); } }); final Service service3 = createMockService("SERVICE3", new HashMap<String, ServiceComponent>() { { put("COMPONENT3A", createMockComponent("COMPONENT3A", true, new HashMap<String, ServiceComponentHost>() { { put("hostA", createMockServiceComponentHost(State.INSTALLED)); } })); } }); Map<String, Service> services = new HashMap<>(); services.put("SERVICE1", service1); services.put("SERVICE2", service2); services.put("SERVICE3", service3); Map<String, Set<String>> serviceComponentHostMap = new HashMap<>(); serviceComponentHostMap.put("COMPONENT1A", Collections.singleton("hostA")); serviceComponentHostMap.put("COMPONENT1B", new HashSet<>(Arrays.asList("hostB", "hostC"))); serviceComponentHostMap.put("COMPONENT2A", Collections.singleton("hostA")); serviceComponentHostMap.put("COMPONENT2B", new HashSet<>(Arrays.asList("hostB", "hostC"))); serviceComponentHostMap.put("COMPONEN3A", Collections.singleton("hostA")); final Cluster cluster = createMockCluster("c1", hosts, SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()).andReturn(services).anyTimes(); expect(cluster.getServiceComponentHostMap(EasyMock.<Set<String>>anyObject(), EasyMock.<Set<String>>anyObject())).andReturn(serviceComponentHostMap).anyTimes(); final Map<String, Map<String, String>> existingConfigurations = new HashMap<String, Map<String, String>>() { { put("kerberos-env", kerberosEnvProperties); put("", new HashMap<String, String>() { { put("replacement1", "value1"); } }); put("type1", new HashMap<String, String>() { { put("replacement1", "value2"); put("replacement2", "value3"); } }); put("type2", new HashMap<String, String>() { { put("replacement1", "value4"); put("replacement2", "value5"); } }); put("type3", new HashMap<String, String>() { { put("replacement1", "value6"); put("replacement2", "value7"); } }); } }; replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); HashMap<String, Set<String>> installedServices1 = new HashMap<>(); installedServices1.put("SERVICE1", new HashSet<>(Arrays.asList("COMPONENT1A", "COMPONENT1B"))); installedServices1.put("SERVICE2", new HashSet<>(Arrays.asList("COMPONENT2A", "COMPONENT2B"))); installedServices1.put("SERVICE3", Collections.singleton("COMPONENT3A")); Map<String, Map<String, String>> updates1 = kerberosHelper.getServiceConfigurationUpdates( cluster, existingConfigurations, installedServices1, null, null, true, true); HashMap<String, Set<String>> installedServices2 = new HashMap<>(); installedServices2.put("SERVICE1", new HashSet<>(Arrays.asList("COMPONENT1A", "COMPONENT1B"))); installedServices2.put("SERVICE3", Collections.singleton("COMPONENT3A")); Map<String, Collection<String>> serviceFilter2 = new HashMap<>(); serviceFilter2.put("SERVICE1", new HashSet<>(Arrays.asList("COMPONENT1A", "COMPONENT1B"))); serviceFilter2.put("SERVICE3", Collections.singleton("COMPONENT3A")); Map<String, Map<String, String>> updates2 = kerberosHelper.getServiceConfigurationUpdates( cluster, existingConfigurations, installedServices2, serviceFilter2, null, true, true); verifyAll(); Map<String, Map<String, String>> expectedUpdates = new HashMap<String, Map<String, String>>() {{ put("service1-site", new HashMap<String, String>() { { put("service.kerberos.principal", "service1/_HOST@FOOBAR.COM"); put("service.kerberos.keytab", "keytab1"); put("component1a.kerberos.principal", "component1a/_HOST@FOOBAR.COM"); put("component1a.kerberos.keytab", "keytab1a"); put("component1a.property", "value1"); put("component1b.kerberos.principal", "component1b/_HOST@FOOBAR.COM"); put("component1b.kerberos.keytab", "keytab1b"); put("component1b.property", "value2"); } }); put("service2-site", new HashMap<String, String>() { { put("component2a.kerberos.principal", "component2a/_HOST@FOOBAR.COM"); put("component2a.kerberos.keytab", "keytab2a"); put("component2a.property", "value3"); put("component2b.kerberos.principal", "component2b/_HOST@FOOBAR.COM"); put("component2b.kerberos.keytab", "keytab2b"); put("component2b.property", "value4"); } }); put("service3-site", new HashMap<String, String>() { { put("component3a.kerberos.principal", "component3a/_HOST@FOOBAR.COM"); put("component3a.kerberos.keytab", "keytab3a"); put("component3a.property", "value6"); } }); put("core-site", new HashMap<String, String>() { { put("auth.to.local", "RULE:[1:$1@$0](.*@FOOBAR.COM)s/@.*//\n" + "RULE:[2:$1@$0](component1a@FOOBAR.COM)s/.*/service1user/\n" + "RULE:[2:$1@$0](component1b@FOOBAR.COM)s/.*/service1user/\n" + "RULE:[2:$1@$0](component2a@FOOBAR.COM)s/.*/service2user/\n" + "RULE:[2:$1@$0](component2b@FOOBAR.COM)s/.*/service2user/\n" + "RULE:[2:$1@$0](component3a@FOOBAR.COM)s/.*/service3user/\n" + "RULE:[2:$1@$0](service1@FOOBAR.COM)s/.*/service1user/\n" + "DEFAULT"); put("component3b.property", "value7"); } }); }}; assertEquals(expectedUpdates, updates1); expectedUpdates.remove("service2-site"); expectedUpdates.get("core-site").put("newPropertyRecommendation", "newPropertyRecommendation"); expectedUpdates.get("core-site").put("auth.to.local", "RULE:[1:$1@$0](.*@FOOBAR.COM)s/@.*//\n" + "RULE:[2:$1@$0](component1a@FOOBAR.COM)s/.*/service1user/\n" + "RULE:[2:$1@$0](component1b@FOOBAR.COM)s/.*/service1user/\n" + "RULE:[2:$1@$0](component3a@FOOBAR.COM)s/.*/service3user/\n" + "RULE:[2:$1@$0](service1@FOOBAR.COM)s/.*/service1user/\n" + "DEFAULT"); expectedUpdates.get("service1-site").put("component1b.property", "replaced value"); expectedUpdates.put("new-type", new HashMap<String, String>() { { put("newTypeRecommendation", "newTypeRecommendation"); } }); assertEquals(expectedUpdates, updates2); // Make sure the existing configurations remained unchanged Map<String, Map<String, String>> expectedExistingConfigurations = new HashMap<String, Map<String, String>>() { { put("kerberos-env", new HashMap<String, String>() { { put("kdc_type", "mit-kdc"); put("realm", "FOOBAR.COM"); put("case_insensitive_username_rules", "false"); put("create_ambari_principal", "false"); } }); put("", new HashMap<String, String>() { { put("replacement1", "value1"); } }); put("type1", new HashMap<String, String>() { { put("replacement1", "value2"); put("replacement2", "value3"); } }); put("type2", new HashMap<String, String>() { { put("replacement1", "value4"); put("replacement2", "value5"); } }); put("type3", new HashMap<String, String>() { { put("replacement1", "value6"); put("replacement2", "value7"); } }); } }; assertEquals(expectedExistingConfigurations, existingConfigurations); } @Test public void testEnsureHeadlessIdentities() throws Exception { testEnsureHeadlessIdentities(false, false); } @Test public void testEnsureHeadlessAndAmbariIdentitiesAsUser() throws Exception { testEnsureHeadlessIdentities(true, false); } @Test public void testEnsureHeadlessAndAmbariIdentitiesAsService() throws Exception { testEnsureHeadlessIdentities(true, true); } private void testEnsureHeadlessIdentities(boolean createAmbariIdentities, boolean ambariServerPrincipalAsService) throws Exception { String clusterName = "c1"; String realm = "EXAMPLE.COM"; String ambariServerHostname = StageUtils.getHostName(); String ambariServerPrincipalName; String ambariServerKeytabFilePath = new File("ambari.server.keytab").getAbsolutePath(); KerberosPrincipalType ambariServerPrincipalType; String ambariServerPrincipalNameExpected; if(ambariServerPrincipalAsService) { ambariServerPrincipalName = "ambari-server${principal_suffix}/_HOST@${realm}"; ambariServerPrincipalType = KerberosPrincipalType.SERVICE; ambariServerPrincipalNameExpected = String.format("ambari-server-%s/%s@%s", clusterName, ambariServerHostname, realm); } else { ambariServerPrincipalName = "ambari-server${principal_suffix}@${realm}"; ambariServerPrincipalType = KerberosPrincipalType.USER; ambariServerPrincipalNameExpected = String.format("ambari-server-%s@%s", clusterName, realm); } Map<String, String> propertiesKrb5Conf = new HashMap<>(); Map<String, String> propertiesKerberosEnv = new HashMap<>(); propertiesKerberosEnv.put("realm", realm); propertiesKerberosEnv.put("kdc_type", "mit-kdc"); propertiesKerberosEnv.put("password_length", "20"); propertiesKerberosEnv.put("password_min_lowercase_letters", "1"); propertiesKerberosEnv.put("password_min_uppercase_letters", "1"); propertiesKerberosEnv.put("password_min_digits", "1"); propertiesKerberosEnv.put("password_min_punctuation", "0"); propertiesKerberosEnv.put("password_min_whitespace", "0"); propertiesKerberosEnv.put("create_ambari_principal", (createAmbariIdentities) ? "true" : "false"); Config configKrb5Conf = createMock(Config.class); expect(configKrb5Conf.getProperties()).andReturn(propertiesKrb5Conf).times(1); Config configKerberosEnv = createMock(Config.class); expect(configKerberosEnv.getProperties()).andReturn(propertiesKerberosEnv).times(1); Host host1 = createMockHost("host1"); Host host2 = createMockHost("host3"); Host host3 = createMockHost("host2"); Map<String, ServiceComponentHost> service1Component1HostMap = new HashMap<>(); service1Component1HostMap.put("host1", createMockServiceComponentHost(State.INSTALLED)); Map<String, ServiceComponentHost> service2Component1HostMap = new HashMap<>(); service2Component1HostMap.put("host2", createMockServiceComponentHost(State.INSTALLED)); Map<String, ServiceComponent> service1ComponentMap = new HashMap<>(); service1ComponentMap.put("COMPONENT11", createMockComponent("COMPONENT11", true, service1Component1HostMap)); Map<String, ServiceComponent> service2ComponentMap = new HashMap<>(); service2ComponentMap.put("COMPONENT21", createMockComponent("COMPONENT21", true, service2Component1HostMap)); Service service1 = createMockService("SERVICE1", service1ComponentMap); Service service2 = createMockService("SERVICE2", service2ComponentMap); Map<String, Service> servicesMap = new HashMap<>(); servicesMap.put("SERVICE1", service1); servicesMap.put("SERVICE2", service2); Cluster cluster = createMockCluster(clusterName, Arrays.asList(host1, host2, host3), SecurityType.KERBEROS, configKrb5Conf, configKerberosEnv); expect(cluster.getServices()).andReturn(servicesMap).times(1); Map<String, String> kerberosDescriptorProperties = new HashMap<>(); kerberosDescriptorProperties.put("additional_realms", ""); kerberosDescriptorProperties.put("keytab_dir", "/etc/security/keytabs"); kerberosDescriptorProperties.put("realm", "${kerberos-env/realm}"); kerberosDescriptorProperties.put("principal_suffix", "-${cluster_name|toLower()}"); ArrayList<KerberosIdentityDescriptor> service1Component1Identities = new ArrayList<>(); service1Component1Identities.add(createMockIdentityDescriptor( "s1c1_1.user", createMockPrincipalDescriptor("s1c1_1@${realm}", KerberosPrincipalType.USER, "s1c1", null), createMockKeytabDescriptor("s1c1_1.user.keytab", null) )); service1Component1Identities.add(createMockIdentityDescriptor( "s1c1_1.service", createMockPrincipalDescriptor("s1c1_1/_HOST@${realm}", KerberosPrincipalType.SERVICE, "s1c1", null), createMockKeytabDescriptor("s1c1_1.service.keytab", null) )); HashMap<String, KerberosComponentDescriptor> service1ComponentDescriptorMap = new HashMap<>(); service1ComponentDescriptorMap.put("COMPONENT11", createMockComponentDescriptor("COMPONENT11", service1Component1Identities, null)); List<KerberosIdentityDescriptor> service1Identities = new ArrayList<>(); service1Identities.add(createMockIdentityDescriptor( "s1_1.user", createMockPrincipalDescriptor("s1_1@${realm}", KerberosPrincipalType.USER, "s1", null), createMockKeytabDescriptor("s1_1.user.keytab", null) )); service1Identities.add(createMockIdentityDescriptor( "s1_1.service", createMockPrincipalDescriptor("s1/_HOST@${realm}", KerberosPrincipalType.SERVICE, "s1", null), createMockKeytabDescriptor("s1.service.keytab", null) )); KerberosServiceDescriptor service1KerberosDescriptor = createMockServiceDescriptor("SERVICE1", service1ComponentDescriptorMap, service1Identities); ArrayList<KerberosIdentityDescriptor> service2Component1Identities = new ArrayList<>(); service2Component1Identities.add(createMockIdentityDescriptor( "s2_1.user", createMockPrincipalDescriptor("s2_1@${realm}", KerberosPrincipalType.USER, "s2", null), createMockKeytabDescriptor("s2_1.user.keytab", null) )); service2Component1Identities.add(createMockIdentityDescriptor( "s2c1_1.service", createMockPrincipalDescriptor("s2c1_1/_HOST@${realm}", KerberosPrincipalType.SERVICE, "s2c1", null), createMockKeytabDescriptor("s2c1_1.service.keytab", null) )); HashMap<String, KerberosComponentDescriptor> service2ComponentDescriptorMap = new HashMap<>(); service2ComponentDescriptorMap.put("COMPONENT21", createMockComponentDescriptor("COMPONENT21", service2Component1Identities, null)); KerberosServiceDescriptor service2KerberosDescriptor = createMockServiceDescriptor("SERVICE2", service2ComponentDescriptorMap, null); KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(kerberosDescriptorProperties); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(service1KerberosDescriptor).times(1); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(service2KerberosDescriptor).times(1); if (createAmbariIdentities) { String spnegoPrincipalNameExpected = String.format("HTTP/%s@%s", ambariServerHostname, realm); ArrayList<KerberosIdentityDescriptor> ambarServerComponent1Identities = new ArrayList<>(); ambarServerComponent1Identities.add(createMockIdentityDescriptor( KerberosHelper.AMBARI_SERVER_KERBEROS_IDENTITY_NAME, createMockPrincipalDescriptor(ambariServerPrincipalName, ambariServerPrincipalType, "ambari", null), createMockKeytabDescriptor(ambariServerKeytabFilePath, null))); ambarServerComponent1Identities.add(createMockIdentityDescriptor( "spnego", createMockPrincipalDescriptor("HTTP/_HOST@${realm}", KerberosPrincipalType.SERVICE, null, null), createMockKeytabDescriptor("spnego.service.keytab", null))); KerberosComponentDescriptor ambariServerComponentKerberosDescriptor = createMockComponentDescriptor("AMBARI_SERVER", ambarServerComponent1Identities, null); HashMap<String, KerberosComponentDescriptor> ambariServerComponentDescriptorMap = new HashMap<>(); ambariServerComponentDescriptorMap.put("AMBARI_SERVER", ambariServerComponentKerberosDescriptor); KerberosServiceDescriptor ambariServiceKerberosDescriptor = createMockServiceDescriptor("AMBARI", ambariServerComponentDescriptorMap, null); expect(ambariServiceKerberosDescriptor.getComponent("AMBARI_SERVER")).andReturn(ambariServerComponentKerberosDescriptor).once(); expect(kerberosDescriptor.getService("AMBARI")).andReturn(ambariServiceKerberosDescriptor).once(); ConfigureAmbariIdentitiesServerAction configureAmbariIdentitiesServerAction = injector.getInstance(ConfigureAmbariIdentitiesServerAction.class); expect(configureAmbariIdentitiesServerAction.installAmbariServerIdentity(eq(ambariServerPrincipalNameExpected), anyString(), eq(ambariServerKeytabFilePath), eq("user1"), eq(true), eq(true), eq("groupA"), eq(true), eq(false), (ActionLog) eq(null))) .andReturn(true) .once(); expect(configureAmbariIdentitiesServerAction.installAmbariServerIdentity(eq(spnegoPrincipalNameExpected), anyString(), eq("spnego.service.keytab"), eq("user1"), eq(true), eq(true), eq("groupA"), eq(true), eq(false), (ActionLog) eq(null))) .andReturn(true) .once(); configureAmbariIdentitiesServerAction.configureJAAS(ambariServerPrincipalNameExpected, ambariServerKeytabFilePath, null); expectLastCall().once(); } setupKerberosDescriptor(kerberosDescriptor, 1); Map<String, Map<String, String>> existingConfigurations = new HashMap<>(); existingConfigurations.put("kerberos-env", propertiesKerberosEnv); Set<String> services = new HashSet<String>() { { add("SERVICE1"); add("SERVICE2"); } }; Capture<? extends String> capturePrincipal = newCapture(CaptureType.ALL); Capture<? extends String> capturePrincipalForKeytab = newCapture(CaptureType.ALL); CreatePrincipalsServerAction createPrincipalsServerAction = injector.getInstance(CreatePrincipalsServerAction.class); expect(createPrincipalsServerAction.createPrincipal(capture(capturePrincipal), eq(false), EasyMock.<Map<String, String>>anyObject(), anyObject(KerberosOperationHandler.class), eq(false), isNull(ActionLog.class))) .andReturn(new CreatePrincipalsServerAction.CreatePrincipalResult("anything", "password", 1)) .times(3); if(createAmbariIdentities) { if (ambariServerPrincipalAsService) { expect(createPrincipalsServerAction.createPrincipal(capture(capturePrincipal), eq(true), EasyMock.<Map<String, String>>anyObject(), anyObject(KerberosOperationHandler.class), eq(false), isNull(ActionLog.class))) .andReturn(new CreatePrincipalsServerAction.CreatePrincipalResult("anything", "password", 1)) .times(2); } else { expect(createPrincipalsServerAction.createPrincipal(capture(capturePrincipal), eq(true), EasyMock.<Map<String, String>>anyObject(), anyObject(KerberosOperationHandler.class), eq(false), isNull(ActionLog.class))) .andReturn(new CreatePrincipalsServerAction.CreatePrincipalResult("anything", "password", 1)) .times(1); expect(createPrincipalsServerAction.createPrincipal(capture(capturePrincipal), eq(false), EasyMock.<Map<String, String>>anyObject(), anyObject(KerberosOperationHandler.class), eq(false), isNull(ActionLog.class))) .andReturn(new CreatePrincipalsServerAction.CreatePrincipalResult("anything", "password", 1)) .times(1); } } CreateKeytabFilesServerAction createKeytabFilesServerAction = injector.getInstance(CreateKeytabFilesServerAction.class); expect(createKeytabFilesServerAction.createKeytab(capture(capturePrincipalForKeytab), eq("password"), eq(1), anyObject(KerberosOperationHandler.class), eq(true), eq(true), isNull(ActionLog.class))) .andReturn(new Keytab()) .times(createAmbariIdentities ? 5 : 3); replayAll(); AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); ambariMetaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, new PrincipalKeyCredential("principal", "password"), CredentialStoreType.TEMPORARY); KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); kerberosHelper.ensureHeadlessIdentities(cluster, existingConfigurations, services); verifyAll(); List<? extends String> capturedPrincipals = capturePrincipal.getValues(); assertEquals(createAmbariIdentities ? 5 : 3, capturedPrincipals.size()); assertTrue(capturedPrincipals.contains("s1_1@EXAMPLE.COM")); assertTrue(capturedPrincipals.contains("s1c1_1@EXAMPLE.COM")); assertTrue(capturedPrincipals.contains("s2_1@EXAMPLE.COM")); List<? extends String> capturedPrincipalsForKeytab = capturePrincipalForKeytab.getValues(); assertEquals(createAmbariIdentities ? 5 : 3, capturedPrincipalsForKeytab.size()); assertTrue(capturedPrincipalsForKeytab.contains("s1_1@EXAMPLE.COM")); assertTrue(capturedPrincipalsForKeytab.contains("s1c1_1@EXAMPLE.COM")); assertTrue(capturedPrincipalsForKeytab.contains("s2_1@EXAMPLE.COM")); if(createAmbariIdentities) { String spnegoPrincipalName = String.format("HTTP/%s@EXAMPLE.COM", ambariServerHostname); assertTrue(capturedPrincipals.contains(ambariServerPrincipalNameExpected)); assertTrue(capturedPrincipals.contains(spnegoPrincipalName)); assertTrue(capturedPrincipalsForKeytab.contains(ambariServerPrincipalNameExpected)); assertTrue(capturedPrincipalsForKeytab.contains(spnegoPrincipalName)); } } /** * Test that a Kerberos Descriptor that contains a Service with 0 Components does not raise any exceptions. */ @Test public void testServiceWithoutComponents() throws Exception { Map<String, String> propertiesKrb5Conf = new HashMap<>(); Map<String, String> propertiesKerberosEnv = new HashMap<>(); propertiesKerberosEnv.put("realm", "EXAMPLE.COM"); propertiesKerberosEnv.put("kdc_type", "mit-kdc"); propertiesKerberosEnv.put("create_ambari_principal", "false"); Config configKrb5Conf = createMock(Config.class); expect(configKrb5Conf.getProperties()).andReturn(propertiesKrb5Conf).times(1); Config configKerberosEnv = createMock(Config.class); expect(configKerberosEnv.getProperties()).andReturn(propertiesKerberosEnv).times(1); // Create a Service (SERVICE1) with one Component (COMPONENT11) Host host1 = createMockHost("host1"); Map<String, ServiceComponentHost> service1Component1HostMap = new HashMap<>(); service1Component1HostMap.put("host1", createMockServiceComponentHost(State.INSTALLED)); Map<String, ServiceComponent> service1ComponentMap = new HashMap<>(); service1ComponentMap.put("COMPONENT11", createMockComponent("COMPONENT11", true, service1Component1HostMap)); Service service1 = createMockService("SERVICE1", service1ComponentMap); Map<String, Service> servicesMap = new HashMap<>(); servicesMap.put("SERVICE1", service1); Cluster cluster = createMockCluster("c1", Arrays.asList(host1), SecurityType.KERBEROS, configKrb5Conf, configKerberosEnv); expect(cluster.getServices()).andReturn(servicesMap).times(1); Map<String, String> kerberosDescriptorProperties = new HashMap<>(); kerberosDescriptorProperties.put("additional_realms", ""); kerberosDescriptorProperties.put("keytab_dir", "/etc/security/keytabs"); kerberosDescriptorProperties.put("realm", "${kerberos-env/realm}"); // Notice that this map is empty, hence it has 0 Components in the kerberosDescriptor. HashMap<String, KerberosComponentDescriptor> service1ComponentDescriptorMap = new HashMap<>(); List<KerberosIdentityDescriptor> service1Identities = new ArrayList<>(); KerberosServiceDescriptor service1KerberosDescriptor = createMockServiceDescriptor("SERVICE1", service1ComponentDescriptorMap, service1Identities); KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(kerberosDescriptorProperties); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(service1KerberosDescriptor).times(1); setupKerberosDescriptor(kerberosDescriptor, 1); Map<String, Map<String, String>> existingConfigurations = new HashMap<>(); existingConfigurations.put("kerberos-env", propertiesKerberosEnv); Set<String> services = new HashSet<String>() { { add("SERVICE1"); } }; Capture<? extends String> capturePrincipal = newCapture(CaptureType.ALL); Capture<? extends String> capturePrincipalForKeytab = newCapture(CaptureType.ALL); replayAll(); AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); ambariMetaInfo.init(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, new PrincipalKeyCredential("principal", "password"), CredentialStoreType.TEMPORARY); KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); // Validate that it works with 0 Components. kerberosHelper.ensureHeadlessIdentities(cluster, existingConfigurations, services); verifyAll(); List<? extends String> capturedPrincipals = capturePrincipal.getValues(); assertEquals(0, capturedPrincipals.size()); List<? extends String> capturedPrincipalsForKeytab = capturePrincipalForKeytab.getValues(); assertEquals(0, capturedPrincipalsForKeytab.size()); } private void setupKerberosDescriptor(KerberosDescriptor kerberosDescriptor, int expectedCalls) throws Exception { // cluster.getCurrentStackVersion expectation is already specified in main test method expect(metaInfo.getKerberosDescriptor("HDP", "2.2")).andReturn(kerberosDescriptor).times(expectedCalls); } private void setupStageFactory() { final StageFactory stageFactory = injector.getInstance(StageFactory.class); expect(stageFactory.createNew(anyLong(), anyObject(String.class), anyObject(String.class), anyLong(), anyObject(String.class), anyObject(String.class), anyObject(String.class))) .andAnswer(new IAnswer<Stage>() { @Override public Stage answer() throws Throwable { Stage stage = createNiceMock(Stage.class); expect(stage.getHostRoleCommands()) .andReturn(Collections.<String, Map<String, HostRoleCommand>>emptyMap()) .anyTimes(); replay(stage); return stage; } }) .anyTimes(); } private void testEnsureIdentities(final PrincipalKeyCredential PrincipalKeyCredential, Set<String> filteredHosts) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final ServiceComponentHost schKerberosClientA = createMock(ServiceComponentHost.class); expect(schKerberosClientA.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClientA.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClientA.getHostName()).andReturn("hostA").anyTimes(); expect(schKerberosClientA.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost schKerberosClientB = createMock(ServiceComponentHost.class); expect(schKerberosClientB.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClientB.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClientB.getHostName()).andReturn("hostB").anyTimes(); expect(schKerberosClientB.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost schKerberosClientC = createMock(ServiceComponentHost.class); expect(schKerberosClientC.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClientC.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClientC.getHostName()).andReturn("hostC").anyTimes(); expect(schKerberosClientC.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1A = createMock(ServiceComponentHost.class); expect(sch1A.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1A.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1A.getHostName()).andReturn("hostA").anyTimes(); final ServiceComponentHost sch1B = createMock(ServiceComponentHost.class); expect(sch1B.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1B.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1B.getHostName()).andReturn("hostB").anyTimes(); final ServiceComponentHost sch1C = createMock(ServiceComponentHost.class); expect(sch1C.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1C.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1C.getHostName()).andReturn("hostC").anyTimes(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); expect(sch2.getHostName()).andReturn("hostA").anyTimes(); final ServiceComponentHost sch3 = createMock(ServiceComponentHost.class); expect(sch3.getServiceName()).andReturn("SERVICE3").anyTimes(); expect(sch3.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); expect(sch3.getHostName()).andReturn("hostA").anyTimes(); final Host hostA = createMockHost("hostA"); final Host hostB = createMockHost("hostB"); final Host hostC = createMockHost("hostC"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn( new HashMap<String, ServiceComponentHost>() { { put("hostA", schKerberosClientA); put("hostB", schKerberosClientB); put("hostC", schKerberosClientC); } } ).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(1); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Arrays.asList(hostA, hostB, hostC), SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); if ((filteredHosts == null) || filteredHosts.contains("hostA")) { expect(cluster.getServiceComponentHosts("hostA")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(sch1A); add(sch2); add(sch3); add(schKerberosClientA); } }) .once(); } if ((filteredHosts == null) || filteredHosts.contains("hostB")) { expect(cluster.getServiceComponentHosts("hostB")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(sch1B); add(schKerberosClientB); } }) .once(); } if ((filteredHosts == null) || filteredHosts.contains("hostC")) { expect(cluster.getServiceComponentHosts("hostC")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(sch1C); add(schKerberosClientC); } }) .once(); } expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClientA); add(schKerberosClientB); add(schKerberosClientC); } }) .once(); final Clusters clusters = injector.getInstance(Clusters.class); if ((filteredHosts == null) || filteredHosts.contains("hostA")) { expect(clusters.getHost("hostA")) .andReturn(hostA) .once(); } if ((filteredHosts == null) || filteredHosts.contains("hostB")) { expect(clusters.getHost("hostB")) .andReturn(hostB) .once(); } if ((filteredHosts == null) || filteredHosts.contains("hostC")) { expect(clusters.getHost("hostC")) .andReturn(hostC) .once(); } final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .times(3); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosPrincipalDescriptor principalDescriptor1a = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1a.getValue()).andReturn("component1a/_HOST@${realm}").anyTimes(); expect(principalDescriptor1a.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor1a.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor1a.getConfiguration()).andReturn("service1b-site/component1.kerberos.principal").anyTimes(); final KerberosPrincipalDescriptor principalDescriptor1b = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1b.getValue()).andReturn("component1b/_HOST@${realm}").anyTimes(); expect(principalDescriptor1b.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor1b.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor1b.getConfiguration()).andReturn("service1b-site/component1.kerberos.principal").anyTimes(); final KerberosPrincipalDescriptor principalDescriptor3 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor3.getValue()).andReturn("component3/${host}@${realm}").anyTimes(); expect(principalDescriptor3.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor3.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor3.getConfiguration()).andReturn("service3-site/component3.kerberos.principal").anyTimes(); final KerberosKeytabDescriptor keytabDescriptor1 = createMock(KerberosKeytabDescriptor.class); final KerberosKeytabDescriptor keytabDescriptor3 = createMock(KerberosKeytabDescriptor.class); final KerberosIdentityDescriptor identityDescriptor1a = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1a.getName()).andReturn("identity1a").anyTimes(); expect(identityDescriptor1a.getPrincipalDescriptor()).andReturn(principalDescriptor1a).anyTimes(); expect(identityDescriptor1a.getKeytabDescriptor()).andReturn(keytabDescriptor1).anyTimes(); final KerberosIdentityDescriptor identityDescriptor1b = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1b.getName()).andReturn("identity1b").anyTimes(); expect(identityDescriptor1b.getPrincipalDescriptor()).andReturn(principalDescriptor1b).anyTimes(); final KerberosIdentityDescriptor identityDescriptor3 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor3.getName()).andReturn("identity3").anyTimes(); expect(identityDescriptor3.getPrincipalDescriptor()).andReturn(principalDescriptor3).anyTimes(); expect(identityDescriptor3.getKeytabDescriptor()).andReturn(keytabDescriptor3).anyTimes(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor3 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); if ((filteredHosts == null) || filteredHosts.contains("hostA")) { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); expect(kerberosDescriptor.getService("SERVICE3")).andReturn(serviceDescriptor3).times(1); } if ((filteredHosts == null) || filteredHosts.contains("hostB")) { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); } if ((filteredHosts == null) || filteredHosts.contains("hostC")) { expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); } setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); // Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Distribute Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); Map<String, Collection<String>> serviceComponentFilter = new HashMap<>(); Collection<String> identityFilter = Arrays.asList("identity1a", "identity3"); serviceComponentFilter.put("SERVICE3", Collections.singleton("COMPONENT3")); serviceComponentFilter.put("SERVICE1", null); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.ensureIdentities(cluster, serviceComponentFilter, filteredHosts, identityFilter, null, requestStageContainer, true); verifyAll(); } private void testDeleteIdentities(final PrincipalKeyCredential PrincipalKeyCredential) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); final ServiceComponentHost sch2 = createMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); final ServiceComponentHost sch3 = createMock(ServiceComponentHost.class); expect(sch3.getServiceName()).andReturn("SERVICE3").anyTimes(); expect(sch3.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); expect(sch3.getHostName()).andReturn("host1").anyTimes(); final Host host = createMockHost("host1"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(1); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(1); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Collections.singleton(host), SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(sch1); add(sch2); add(sch3); add(schKerberosClient); } }) .once(); expect(cluster.getServiceComponentHosts("KERBEROS", "KERBEROS_CLIENT")) .andReturn(Collections.singletonList(schKerberosClient)) .once(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final KerberosPrincipalDescriptor principalDescriptor1a = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1a.getValue()).andReturn("component1a/_HOST@${realm}").anyTimes(); expect(principalDescriptor1a.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor1a.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor1a.getConfiguration()).andReturn("service1b-site/component1.kerberos.principal").anyTimes(); final KerberosPrincipalDescriptor principalDescriptor1b = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1b.getValue()).andReturn("component1b/_HOST@${realm}").anyTimes(); expect(principalDescriptor1b.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor1b.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor1b.getConfiguration()).andReturn("service1b-site/component1.kerberos.principal").anyTimes(); final KerberosPrincipalDescriptor principalDescriptor3 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor3.getValue()).andReturn("component3/${host}@${realm}").anyTimes(); expect(principalDescriptor3.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor3.getLocalUsername()).andReturn(null).anyTimes(); expect(principalDescriptor3.getConfiguration()).andReturn("service3-site/component3.kerberos.principal").anyTimes(); final KerberosKeytabDescriptor keytabDescriptor1 = createMock(KerberosKeytabDescriptor.class); final KerberosKeytabDescriptor keytabDescriptor3 = createMock(KerberosKeytabDescriptor.class); final KerberosIdentityDescriptor identityDescriptor1a = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1a.getName()).andReturn("identity1a").anyTimes(); expect(identityDescriptor1a.getPrincipalDescriptor()).andReturn(principalDescriptor1a).anyTimes(); expect(identityDescriptor1a.getKeytabDescriptor()).andReturn(keytabDescriptor1).anyTimes(); final KerberosIdentityDescriptor identityDescriptor1b = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1b.getName()).andReturn("identity1b").anyTimes(); expect(identityDescriptor1b.getPrincipalDescriptor()).andReturn(principalDescriptor1b).anyTimes(); final KerberosIdentityDescriptor identityDescriptor3 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor3.getName()).andReturn("identity3").anyTimes(); expect(identityDescriptor3.getPrincipalDescriptor()).andReturn(principalDescriptor3).anyTimes(); expect(identityDescriptor3.getKeytabDescriptor()).andReturn(keytabDescriptor3).anyTimes(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); final KerberosServiceDescriptor serviceDescriptor3 = createMock(KerberosServiceDescriptor.class); final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).times(1); expect(kerberosDescriptor.getService("SERVICE3")).andReturn(serviceDescriptor3).times(1); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); // Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Delete Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Delete Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); Map<String, Collection<String>> serviceComponentFilter = new HashMap<>(); Collection<String> identityFilter = Arrays.asList("identity1a", "identity3"); serviceComponentFilter.put("SERVICE3", Collections.singleton("COMPONENT3")); serviceComponentFilter.put("SERVICE1", null); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.deleteIdentities(cluster, serviceComponentFilter, null, identityFilter, requestStageContainer, true); verifyAll(); } private void testCreateTestIdentity(final PrincipalKeyCredential PrincipalKeyCredential, Boolean manageIdentities) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); boolean managingIdentities = !Boolean.FALSE.equals(manageIdentities); final Map<String, String> kerberosEnvProperties = new HashMap<>(); kerberosEnvProperties.put("kdc_type", "mit-kdc"); kerberosEnvProperties.put("realm", "FOOBAR.COM"); kerberosEnvProperties.put("manage_identities", "FOOBAR.COM"); kerberosEnvProperties.put("manage_identities", (manageIdentities == null) ? null : ((manageIdentities) ? "true" : "false")); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = new HashMap<>(); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Map<String, Object> attributeMap = new HashMap<>(); final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).anyTimes(); expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(kerberosEnvConfig).anyTimes(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); if (managingIdentities) { final Host host = createMockHost("host1"); expect(cluster.getHosts()).andReturn(Collections.singleton(host)).anyTimes(); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(2); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(2); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(2); expect(cluster.getClusterName()).andReturn("c1").anyTimes(); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts(Service.Type.KERBEROS.name(), Role.KERBEROS_CLIENT.name())) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); } }) .anyTimes(); expect(cluster.getCurrentStackVersion()) .andReturn(new StackId("HDP", "2.2")) .anyTimes(); expect(cluster.getSessionAttributes()).andReturn(attributeMap).anyTimes(); cluster.setSessionAttribute(anyObject(String.class), anyObject()); expectLastCall().andAnswer(new IAnswer<Object>() { @Override public Object answer() throws Throwable { Object[] args = getCurrentArguments(); attributeMap.put((String) args[0], args[1]); return null; } }).anyTimes(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final ConfigHelper configHelper = injector.getInstance(ConfigHelper.class); expect(configHelper.getEffectiveConfigProperties(anyObject(Cluster.class), EasyMock.<Map<String, Map<String, String>>>anyObject())) .andReturn(new HashMap<String, Map<String, String>>() { { put("cluster-env", new HashMap<String, String>() {{ put("kerberos_domain", "FOOBAR.COM"); }}); } }) .times(1); final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(null).once(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Create Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Distribute Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); } replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); Map<String, String> commandParamsStage = new HashMap<>(); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.createTestIdentity(cluster, commandParamsStage, requestStageContainer); verifyAll(); if (managingIdentities) { Assert.assertTrue(commandParamsStage.containsKey("principal_name")); Assert.assertEquals("${kerberos-env/service_check_principal_name}@${realm}", commandParamsStage.get("principal_name")); Assert.assertTrue(commandParamsStage.containsKey("keytab_file")); Assert.assertEquals("${keytab_dir}/kerberos.service_check." + new SimpleDateFormat("MMddyy").format(new Date()) + ".keytab", commandParamsStage.get("keytab_file")); } } private void testDeleteTestIdentity(final PrincipalKeyCredential PrincipalKeyCredential) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class); expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes(); expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes(); final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class); expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); expect(sch1.getHostName()).andReturn("host1").anyTimes(); final ServiceComponentHost sch2 = createStrictMock(ServiceComponentHost.class); expect(sch2.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); final ServiceComponentHost sch3 = createStrictMock(ServiceComponentHost.class); expect(sch3.getServiceName()).andReturn("SERVICE3").anyTimes(); expect(sch3.getServiceComponentName()).andReturn("COMPONENT3").anyTimes(); expect(sch3.getHostName()).andReturn("host1").anyTimes(); final Host host = createMockHost("host1"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .times(2); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(2); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .times(2); final Map<String, String> kerberosEnvProperties = createMock(Map.class); expect(kerberosEnvProperties.get("kdc_type")).andReturn("mit-kdc").anyTimes(); expect(kerberosEnvProperties.get("realm")).andReturn("FOOBAR.COM").anyTimes(); expect(kerberosEnvProperties.get("manage_identities")).andReturn(null).anyTimes(); final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); final Cluster cluster = createMockCluster("c1", Collections.singleton(host), SecurityType.KERBEROS, krb5ConfConfig, kerberosEnvConfig); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getServiceComponentHosts(Service.Type.KERBEROS.name(), Role.KERBEROS_CLIENT.name())) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient); } }) .anyTimes(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getHost("host1")) .andReturn(host) .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .once(); expect(ambariManagementController.getRoleCommandOrder(cluster)) .andReturn(createMock(RoleCommandOrder.class)) .once(); final ConfigHelper configHelper = injector.getInstance(ConfigHelper.class); expect(configHelper.getEffectiveConfigProperties(anyObject(Cluster.class), EasyMock.<Map<String, Map<String, String>>>anyObject())) .andReturn(new HashMap<String, Map<String, String>>() { { put("cluster-env", new HashMap<String, String>() { { put("kerberos_domain", "FOOBAR.COM"); } }); } }) .times(1); final KerberosDescriptor kerberosDescriptor = createStrictMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(null).once(); setupKerberosDescriptor(kerberosDescriptor, 1); setupStageFactory(); // This is a STRICT mock to help ensure that the end result is what we want. final RequestStageContainer requestStageContainer = createStrictMock(RequestStageContainer.class); // Preparation Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Delete Principals Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Delete Keytabs Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); // Clean-up/Finalize Stage expect(requestStageContainer.getLastStageId()).andReturn(-1L).anyTimes(); expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.setClusterHostInfo(anyString()); expectLastCall().once(); requestStageContainer.addStages(EasyMock.<List<Stage>>anyObject()); expectLastCall().once(); replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); Map<String, String> commandParamsStage = new HashMap<>(); commandParamsStage.put("principal_name", "${cluster-env/smokeuser}@${realm}"); commandParamsStage.put("keytab_file", "${keytab_dir}/kerberos.service_check.keytab"); CredentialStoreService credentialStoreService = injector.getInstance(CredentialStoreService.class); credentialStoreService.setCredential(cluster.getClusterName(), KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, PrincipalKeyCredential, CredentialStoreType.TEMPORARY); kerberosHelper.deleteTestIdentity(cluster, commandParamsStage, requestStageContainer); verifyAll(); } private Map<String, Collection<KerberosIdentityDescriptor>> testGetActiveIdentities(String clusterName, String hostName, String serviceName, String componentName, boolean replaceHostNames, SecurityType clusterSecurityType) throws Exception { KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class); final ServiceComponentHost schKerberosClient1 = createMock(ServiceComponentHost.class); expect(schKerberosClient1.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient1.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); final ServiceComponentHost schKerberosClient2 = createMock(ServiceComponentHost.class); expect(schKerberosClient2.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(schKerberosClient2.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); final ServiceComponentHost sch1a = createMock(ServiceComponentHost.class); expect(sch1a.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch1a.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); final ServiceComponentHost sch1b = createMock(ServiceComponentHost.class); expect(sch1b.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch1b.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); final ServiceComponentHost sch2a = createMock(ServiceComponentHost.class); expect(sch2a.getServiceName()).andReturn("SERVICE1").anyTimes(); expect(sch2a.getServiceComponentName()).andReturn("COMPONENT1").anyTimes(); final ServiceComponentHost sch2b = createMock(ServiceComponentHost.class); expect(sch2b.getServiceName()).andReturn("SERVICE2").anyTimes(); expect(sch2b.getServiceComponentName()).andReturn("COMPONENT2").anyTimes(); final Host host1 = createMockHost("host1"); final Host host2 = createMockHost("host2"); final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class); expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes(); expect(serviceComponentKerberosClient.getServiceComponentHosts()).andReturn(Collections.singletonMap("host1", schKerberosClient1)).anyTimes(); final Service serviceKerberos = createStrictMock(Service.class); expect(serviceKerberos.getName()).andReturn(Service.Type.KERBEROS.name()).anyTimes(); expect(serviceKerberos.getServiceComponents()) .andReturn(Collections.singletonMap(Role.KERBEROS_CLIENT.name(), serviceComponentKerberosClient)) .anyTimes(); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); expect(service1.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .anyTimes(); final Service service2 = createStrictMock(Service.class); expect(service2.getName()).andReturn("SERVICE2").anyTimes(); expect(service2.getServiceComponents()) .andReturn(Collections.<String, ServiceComponent>emptyMap()) .anyTimes(); final Map<String, Host> hostMap = new HashMap<String, Host>() { { put("host1", host1); put("host2", host2); } }; final Collection<Host> hosts = hostMap.values(); final Cluster cluster = createMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(clusterSecurityType).anyTimes(); expect(cluster.getClusterName()).andReturn(clusterName).anyTimes(); expect(cluster.getClusterId()).andReturn(2L).anyTimes(); expect(cluster.getServiceComponentHosts("host1")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient1); add(sch1a); add(sch1b); } }) .anyTimes(); expect(cluster.getServiceComponentHosts("host2")) .andReturn(new ArrayList<ServiceComponentHost>() { { add(schKerberosClient2); add(sch2a); add(sch2b); } }) .anyTimes(); expect(cluster.getServiceComponentHosts(InetAddress.getLocalHost().getCanonicalHostName().toLowerCase())) .andReturn(new ArrayList<ServiceComponentHost>()) .anyTimes(); final Map<String, String> kerberosEnvProperties = new HashMap<String, String>() { { put("kdc_type", "mit-kdc"); put("realm", "FOOBAR.COM"); put("case_insensitive_username_rules", "false"); put("create_ambari_principal", "false"); } }; final Config kerberosEnvConfig = createMock(Config.class); expect(kerberosEnvConfig.getProperties()).andReturn(kerberosEnvProperties).anyTimes(); final Map<String, String> krb5ConfProperties = createMock(Map.class); final Config krb5ConfConfig = createMock(Config.class); expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).anyTimes(); expect(cluster.getDesiredConfigByType("krb5-conf")) .andReturn(krb5ConfConfig) .anyTimes(); expect(cluster.getDesiredConfigByType("kerberos-env")) .andReturn(kerberosEnvConfig) .anyTimes(); expect(cluster.getCurrentStackVersion()) .andReturn(new StackId("HDP", "2.2")) .anyTimes(); expect(cluster.getServices()) .andReturn(new HashMap<String, Service>() { { put(Service.Type.KERBEROS.name(), serviceKerberos); put("SERVICE1", service1); put("SERVICE2", service2); } }) .anyTimes(); expect(cluster.getHosts()) .andReturn(hosts) .anyTimes(); final Clusters clusters = injector.getInstance(Clusters.class); expect(clusters.getCluster(clusterName)).andReturn(cluster).times(1); if (hostName == null) { expect(clusters.getHostsForCluster(clusterName)) .andReturn(hostMap) .once(); } final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, "host1")) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .anyTimes(); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, "host2")) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .anyTimes(); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, null)) .andReturn(Collections.<String, Map<String, String>>emptyMap()) .anyTimes(); final ConfigHelper configHelper = injector.getInstance(ConfigHelper.class); expect(configHelper.getEffectiveConfigProperties(anyObject(Cluster.class), EasyMock.<Map<String, Map<String, String>>>anyObject())) .andReturn(new HashMap<String, Map<String, String>>() { { put("cluster-env", new HashMap<String, String>() {{ put("kerberos_domain", "FOOBAR.COM"); }}); } }) .anyTimes(); final KerberosPrincipalDescriptor principalDescriptor1 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor1.getValue()).andReturn("service1/_HOST@${realm}").anyTimes(); expect(principalDescriptor1.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor1.getConfiguration()).andReturn("service1-site/component1.kerberos.principal").anyTimes(); expect(principalDescriptor1.getLocalUsername()).andReturn("service1").anyTimes(); final KerberosPrincipalDescriptor principalDescriptor2 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptor2.getValue()).andReturn("component2/${host}@${realm}").anyTimes(); expect(principalDescriptor2.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptor2.getConfiguration()).andReturn("service2-site/component2.kerberos.principal").anyTimes(); expect(principalDescriptor2.getLocalUsername()).andReturn("service2").anyTimes(); final KerberosPrincipalDescriptor principalDescriptorService1 = createMock(KerberosPrincipalDescriptor.class); expect(principalDescriptorService1.getValue()).andReturn("service1/_HOST@${realm}").anyTimes(); expect(principalDescriptorService1.getType()).andReturn(KerberosPrincipalType.SERVICE).anyTimes(); expect(principalDescriptorService1.getConfiguration()).andReturn("service1-site/service1.kerberos.principal").anyTimes(); expect(principalDescriptorService1.getLocalUsername()).andReturn("service1").anyTimes(); final KerberosKeytabDescriptor keytabDescriptor1 = createMock(KerberosKeytabDescriptor.class); expect(keytabDescriptor1.getFile()).andReturn("${keytab_dir}/service1.keytab").anyTimes(); expect(keytabDescriptor1.getOwnerName()).andReturn("service1").anyTimes(); expect(keytabDescriptor1.getOwnerAccess()).andReturn("rw").anyTimes(); expect(keytabDescriptor1.getGroupName()).andReturn("hadoop").anyTimes(); expect(keytabDescriptor1.getGroupAccess()).andReturn("").anyTimes(); expect(keytabDescriptor1.getConfiguration()).andReturn("service1-site/component1.keytab.file").anyTimes(); expect(keytabDescriptor1.isCachable()).andReturn(false).anyTimes(); final KerberosKeytabDescriptor keytabDescriptor2 = createMock(KerberosKeytabDescriptor.class); expect(keytabDescriptor2.getFile()).andReturn("${keytab_dir}/service2.keytab").anyTimes(); expect(keytabDescriptor2.getOwnerName()).andReturn("service2").anyTimes(); expect(keytabDescriptor2.getOwnerAccess()).andReturn("rw").anyTimes(); expect(keytabDescriptor2.getGroupName()).andReturn("hadoop").anyTimes(); expect(keytabDescriptor2.getGroupAccess()).andReturn("").anyTimes(); expect(keytabDescriptor2.getConfiguration()).andReturn("service2-site/component2.keytab.file").anyTimes(); expect(keytabDescriptor2.isCachable()).andReturn(false).anyTimes(); final KerberosKeytabDescriptor keytabDescriptorService1 = createMock(KerberosKeytabDescriptor.class); expect(keytabDescriptorService1.getFile()).andReturn("${keytab_dir}/service1.service.keytab").anyTimes(); expect(keytabDescriptorService1.getOwnerName()).andReturn("service1").anyTimes(); expect(keytabDescriptorService1.getOwnerAccess()).andReturn("rw").anyTimes(); expect(keytabDescriptorService1.getGroupName()).andReturn("hadoop").anyTimes(); expect(keytabDescriptorService1.getGroupAccess()).andReturn("").anyTimes(); expect(keytabDescriptorService1.getConfiguration()).andReturn("service1-site/service1.keytab.file").anyTimes(); expect(keytabDescriptorService1.isCachable()).andReturn(false).anyTimes(); final KerberosIdentityDescriptor identityDescriptor1 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor1.getName()).andReturn("identity1").anyTimes(); expect(identityDescriptor1.getReference()).andReturn(null).anyTimes(); expect(identityDescriptor1.getPrincipalDescriptor()).andReturn(principalDescriptor1).anyTimes(); expect(identityDescriptor1.getKeytabDescriptor()).andReturn(keytabDescriptor1).anyTimes(); expect(identityDescriptor1.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); expect(identityDescriptor1.getWhen()).andReturn(null).anyTimes(); final KerberosIdentityDescriptor identityDescriptor2 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptor2.getName()).andReturn("identity2").anyTimes(); expect(identityDescriptor2.getReference()).andReturn(null).anyTimes(); expect(identityDescriptor2.getPrincipalDescriptor()).andReturn(principalDescriptor2).anyTimes(); expect(identityDescriptor2.getKeytabDescriptor()).andReturn(keytabDescriptor2).anyTimes(); expect(identityDescriptor2.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); expect(identityDescriptor2.getWhen()).andReturn(null).anyTimes(); final KerberosIdentityDescriptor identityDescriptorService1 = createMock(KerberosIdentityDescriptor.class); expect(identityDescriptorService1.getName()).andReturn("identity3").anyTimes(); expect(identityDescriptorService1.getReference()).andReturn(null).anyTimes(); expect(identityDescriptorService1.getPrincipalDescriptor()).andReturn(principalDescriptorService1).anyTimes(); expect(identityDescriptorService1.getKeytabDescriptor()).andReturn(keytabDescriptorService1).anyTimes(); expect(identityDescriptorService1.shouldInclude(EasyMock.<Map<String, Object>>anyObject())).andReturn(true).anyTimes(); expect(identityDescriptorService1.getWhen()).andReturn(null).anyTimes(); final KerberosComponentDescriptor componentDescriptor1 = createMock(KerberosComponentDescriptor.class); expect(componentDescriptor1.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(Collections.singletonList(identityDescriptor1)).anyTimes(); final KerberosComponentDescriptor componentDescriptor2 = createMock(KerberosComponentDescriptor.class); expect(componentDescriptor2.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(Collections.singletonList(identityDescriptor2)).anyTimes(); final KerberosServiceDescriptor serviceDescriptor1 = createMock(KerberosServiceDescriptor.class); expect(serviceDescriptor1.getComponent("COMPONENT1")).andReturn(componentDescriptor1).anyTimes(); expect(serviceDescriptor1.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(Collections.singletonList(identityDescriptorService1)).anyTimes(); final KerberosServiceDescriptor serviceDescriptor2 = createMock(KerberosServiceDescriptor.class); expect(serviceDescriptor2.getComponent("COMPONENT2")).andReturn(componentDescriptor2).anyTimes(); expect(serviceDescriptor2.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(null).anyTimes(); final KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); expect(kerberosDescriptor.getProperties()).andReturn(new HashMap<String, String>() { { put("realm", "EXAMPLE.COM"); } }).anyTimes(); expect(kerberosDescriptor.getService("KERBEROS")).andReturn(null).anyTimes(); expect(kerberosDescriptor.getService("SERVICE1")).andReturn(serviceDescriptor1).anyTimes(); expect(kerberosDescriptor.getService("SERVICE2")).andReturn(serviceDescriptor2).anyTimes(); setupKerberosDescriptor(kerberosDescriptor, 1); replayAll(); // Needed by infrastructure metaInfo.init(); Map<String, Collection<KerberosIdentityDescriptor>> identities; identities = kerberosHelper.getActiveIdentities(clusterName, hostName, serviceName, componentName, replaceHostNames); verifyAll(); return identities; } private void addAmbariServerIdentity(Map<String, String> kerberosEnvProperties) throws Exception { KerberosHelperImpl kerberosHelper = injector.getInstance(KerberosHelperImpl.class); boolean createAmbariIdentities = kerberosHelper.createAmbariIdentities(kerberosEnvProperties); KerberosIdentityDescriptor ambariKerberosIdentity = null; KerberosDescriptor kerberosDescriptor = createMock(KerberosDescriptor.class); if (createAmbariIdentities) { String ambariServerPrincipalName = "ambari-server${principal_suffix}@${realm}"; KerberosPrincipalType ambariServerPrincipalType = KerberosPrincipalType.USER; String ambariServerKeytabFilePath = new File("ambari.server.keytab").getAbsolutePath(); ambariKerberosIdentity = createMockIdentityDescriptor( KerberosHelper.AMBARI_SERVER_KERBEROS_IDENTITY_NAME, createMockPrincipalDescriptor(ambariServerPrincipalName, ambariServerPrincipalType, "ambari", null), createMockKeytabDescriptor(ambariServerKeytabFilePath, null)); ArrayList<KerberosIdentityDescriptor> ambarServerComponent1Identities = new ArrayList<>(); ambarServerComponent1Identities.add(ambariKerberosIdentity); ambarServerComponent1Identities.add(createMockIdentityDescriptor( "ambari-server_spnego", createMockPrincipalDescriptor("HTTP/_HOST@${realm}", KerberosPrincipalType.SERVICE, null, null), createMockKeytabDescriptor("spnego.service.keytab", null))); HashMap<String, KerberosComponentDescriptor> ambariServerComponentDescriptorMap = new HashMap<>(); KerberosComponentDescriptor componentDescrptor = createMockComponentDescriptor("AMBARI_SERVER", ambarServerComponent1Identities, null); ambariServerComponentDescriptorMap.put("AMBARI_SERVER", componentDescrptor); KerberosServiceDescriptor ambariServiceKerberosDescriptor = createMockServiceDescriptor("AMBARI", ambariServerComponentDescriptorMap, null); expect(ambariServiceKerberosDescriptor.getComponent("AMBARI_SERVER")).andReturn(componentDescrptor).once(); expect(kerberosDescriptor.getService("AMBARI")).andReturn(ambariServiceKerberosDescriptor).once(); } replayAll(); // Needed by infrastructure injector.getInstance(AmbariMetaInfo.class).init(); List<KerberosIdentityDescriptor> identities = (createAmbariIdentities) ? kerberosHelper.getAmbariServerIdentities(kerberosDescriptor) : new ArrayList<KerberosIdentityDescriptor>(); verifyAll(); if (createAmbariIdentities) { Assert.assertEquals(2, identities.size()); Assert.assertSame(ambariKerberosIdentity, identities.get(0)); } else { Assert.assertTrue(identities.isEmpty()); } } private KerberosConfigurationDescriptor createMockConfigurationDescriptor(Map<String, String> properties) { KerberosConfigurationDescriptor descriptor = createMock(KerberosConfigurationDescriptor.class); expect(descriptor.getProperties()).andReturn(properties).anyTimes(); return descriptor; } private KerberosKeytabDescriptor createMockKeytabDescriptor(String file, String configuration) { KerberosKeytabDescriptor descriptor = createMock(KerberosKeytabDescriptor.class); expect(descriptor.getFile()).andReturn(file).anyTimes(); expect(descriptor.getConfiguration()).andReturn(configuration).anyTimes(); expect(descriptor.getOwnerName()).andReturn("user1").anyTimes(); expect(descriptor.getOwnerAccess()).andReturn("rw").anyTimes(); expect(descriptor.getGroupName()).andReturn("groupA").anyTimes(); expect(descriptor.getGroupAccess()).andReturn("r").anyTimes(); return descriptor; } private KerberosPrincipalDescriptor createMockPrincipalDescriptor(String value, KerberosPrincipalType type, String localUsername, String configuration) { KerberosPrincipalDescriptor descriptor = createMock(KerberosPrincipalDescriptor.class); expect(descriptor.getValue()).andReturn(value).anyTimes(); expect(descriptor.getType()).andReturn(type).anyTimes(); expect(descriptor.getLocalUsername()).andReturn(localUsername).anyTimes(); expect(descriptor.getConfiguration()).andReturn(configuration).anyTimes(); return descriptor; } private KerberosServiceDescriptor createMockServiceDescriptor(String serviceName, HashMap<String, KerberosComponentDescriptor> componentMap, List<KerberosIdentityDescriptor> identities) throws AmbariException { KerberosServiceDescriptor descriptor = createMock(KerberosServiceDescriptor.class); expect(descriptor.getName()).andReturn(serviceName).anyTimes(); expect(descriptor.getComponents()).andReturn(componentMap).anyTimes(); expect(descriptor.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(identities).anyTimes(); expect(descriptor.getAuthToLocalProperties()).andReturn(null).anyTimes(); return descriptor; } private KerberosIdentityDescriptor createMockIdentityDescriptor(String name, KerberosPrincipalDescriptor principalDescriptor, KerberosKeytabDescriptor keytabDescriptor) { KerberosIdentityDescriptor descriptor = createMock(KerberosIdentityDescriptor.class); expect(descriptor.getName()).andReturn(name).anyTimes(); expect(descriptor.getPrincipalDescriptor()).andReturn(principalDescriptor).anyTimes(); expect(descriptor.getKeytabDescriptor()).andReturn(keytabDescriptor).anyTimes(); return descriptor; } private KerberosComponentDescriptor createMockComponentDescriptor(String componentName, ArrayList<KerberosIdentityDescriptor> identities, Map<String, KerberosConfigurationDescriptor> configurations) throws AmbariException { KerberosComponentDescriptor descriptor = createMock(KerberosComponentDescriptor.class); expect(descriptor.getName()).andReturn(componentName).anyTimes(); expect(descriptor.getIdentities(eq(true), EasyMock.<Map<String, Object>>anyObject())).andReturn(identities).anyTimes(); expect(descriptor.getConfigurations(true)).andReturn(configurations).anyTimes(); expect(descriptor.getAuthToLocalProperties()).andReturn(null).anyTimes(); return descriptor; } private ServiceComponentHost createMockServiceComponentHost(State state) { ServiceComponentHost serviceComponentHost = createMock(ServiceComponentHost.class); expect(serviceComponentHost.getDesiredState()).andReturn(state).anyTimes(); return serviceComponentHost; } private ServiceComponent createMockComponent(String componentName, boolean isMasterComponent, Map<String, ServiceComponentHost> hosts) { ServiceComponent component = createMock(ServiceComponent.class); expect(component.getName()).andReturn(componentName).anyTimes(); expect(component.isMasterComponent()).andReturn(isMasterComponent).anyTimes(); expect(component.isClientComponent()).andReturn(!isMasterComponent).anyTimes(); expect(component.getServiceComponentHosts()).andReturn(hosts).anyTimes(); return component; } private Service createMockService(String serviceName, Map<String, ServiceComponent> componentMap) { Service service = createMock(Service.class); expect(service.getName()).andReturn(serviceName).anyTimes(); expect(service.getServiceComponents()).andReturn(componentMap).anyTimes(); return service; } private Host createMockHost(String hostname) { Host host = createMock(Host.class); expect(host.getHostName()).andReturn(hostname).anyTimes(); expect(host.getState()).andReturn(HostState.HEALTHY).anyTimes(); expect(host.getCurrentPingPort()).andReturn(1).anyTimes(); expect(host.getRackInfo()).andReturn("rack1").anyTimes(); expect(host.getIPv4()).andReturn("1.2.3.4").anyTimes(); return host; } private Cluster createMockCluster(String clusterName, Collection<Host> hosts, SecurityType securityType, Config krb5ConfConfig, Config kerberosEnvConfig) { Cluster cluster = createMock(Cluster.class); expect(cluster.getHosts()).andReturn(hosts).anyTimes(); expect(cluster.getClusterId()).andReturn(1L).anyTimes(); expect(cluster.getSecurityType()).andReturn(securityType).anyTimes(); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).anyTimes(); expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(kerberosEnvConfig).anyTimes(); expect(cluster.getClusterName()).andReturn(clusterName).anyTimes(); expect(cluster.getCurrentStackVersion()) .andReturn(new StackId("HDP", "2.2")) .anyTimes(); return cluster; } }