Repository: ambari Updated Branches: refs/heads/trunk 5a3a1f56a -> c775c6071
http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java index a83d26d..1de7103 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog200.java @@ -66,6 +66,8 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog { private static final String ALERT_TARGET_STATES_TABLE = "alert_target_states"; private static final String ALERT_CURRENT_TABLE = "alert_current"; private static final String ARTIFACT_TABLE = "artifact"; + private static final String KERBEROS_PRINCIPAL_TABLE = "kerberos_principal"; + private static final String KERBEROS_PRINCIPAL_HOST_TABLE = "kerberos_principal_host"; /** * {@inheritDoc} @@ -111,6 +113,7 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog { prepareRollingUpgradesDDL(); executeAlertDDLUpdates(); createArtifactTable(); + createKerberosPrincipalTables(); // add security_type to clusters dbAccessor.addColumn("clusters", new DBColumnInfo( @@ -272,6 +275,23 @@ public class UpgradeCatalog200 extends AbstractUpgradeCatalog { dbAccessor.createTable(ARTIFACT_TABLE, columns, "artifact_name", "foreign_keys"); } + private void createKerberosPrincipalTables() throws SQLException { + ArrayList<DBColumnInfo> columns; + + columns = new ArrayList<DBColumnInfo>(); + columns.add(new DBColumnInfo("principal_name", String.class, 255, null, false)); + columns.add(new DBColumnInfo("is_service", Short.class, 1, 1, false)); + columns.add(new DBColumnInfo("cached_keytab_path", String.class, 255, null, true)); + dbAccessor.createTable(KERBEROS_PRINCIPAL_TABLE, columns, "principal_name"); + + columns = new ArrayList<DBColumnInfo>(); + columns.add(new DBColumnInfo("principal_name", String.class, 255, null, false)); + columns.add(new DBColumnInfo("host_name", String.class, 255, null, false)); + dbAccessor.createTable(KERBEROS_PRINCIPAL_HOST_TABLE, columns, "principal_name", "host_name"); + dbAccessor.addFKConstraint(KERBEROS_PRINCIPAL_HOST_TABLE, "FK_kerberosprincipalhost_hostname", "host_name", "hosts", "host_name", false); + dbAccessor.addFKConstraint(KERBEROS_PRINCIPAL_HOST_TABLE, "FK_kerberosprincipalhost_principalname", "principal_name", KERBEROS_PRINCIPAL_TABLE, "principal_name", false); + } + // ----- UpgradeCatalog ---------------------------------------------------- /** http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql index 3e0d39e..e46e567 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql @@ -598,6 +598,29 @@ ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); +-- Kerberos +CREATE TABLE kerberos_principal ( + principal_name VARCHAR(255) NOT NULL, + is_service SMALLINT NOT NULL DEFAULT 1, + cached_keytab_path VARCHAR(255), + PRIMARY KEY(principal_name) +); + +CREATE TABLE kerberos_principal_host ( + principal_name VARCHAR(255) NOT NULL, + host_name VARCHAR(255) NOT NULL, + PRIMARY KEY(principal_name, host_name) +); + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_hostname +FOREIGN KEY (host_name) REFERENCES hosts (host_name) ON DELETE CASCADE; + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_principalname +FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name) ON DELETE CASCADE; +-- Kerberos (end) + -- Alerting Framework CREATE TABLE alert_definition ( definition_id BIGINT NOT NULL, http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql index 2c33b37..3b62a7b 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql @@ -588,6 +588,29 @@ ALTER TABLE users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (principal_id ALTER TABLE groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES adminprincipal(principal_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); +-- Kerberos +CREATE TABLE kerberos_principal ( + principal_name VARCHAR2(255) NOT NULL, + is_service NUMBER(1) DEFAULT 1 NOT NULL, + cached_keytab_path VARCHAR2(255), + PRIMARY KEY(principal_name) +); + +CREATE TABLE kerberos_principal_host ( + principal_name VARCHAR2(255) NOT NULL, + host_name VARCHAR2(255) NOT NULL, + PRIMARY KEY(principal_name, host_name) +); + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_hostname +FOREIGN KEY (host_name) REFERENCES hosts (host_name) ON DELETE CASCADE; + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_principalname +FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name) ON DELETE CASCADE; +-- Kerberos (end) + -- Alerting Framework CREATE TABLE alert_definition ( definition_id NUMBER(19) NOT NULL, http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql index ff42074..5cd6ce3 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql @@ -585,6 +585,29 @@ ALTER TABLE serviceconfigmapping ADD CONSTRAINT FK_scvm_config FOREIGN KEY (conf ALTER TABLE serviceconfighosts ADD CONSTRAINT FK_scvhosts_scv FOREIGN KEY (service_config_id) REFERENCES serviceconfig(service_config_id); ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id); +-- Kerberos +CREATE TABLE kerberos_principal ( + principal_name VARCHAR(255) NOT NULL, + is_service SMALLINT NOT NULL DEFAULT 1, + cached_keytab_path VARCHAR(255), + PRIMARY KEY(principal_name) +); + +CREATE TABLE kerberos_principal_host ( + principal_name VARCHAR(255) NOT NULL, + host_name VARCHAR(255) NOT NULL, + PRIMARY KEY(principal_name, host_name) +); + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_hostname +FOREIGN KEY (host_name) REFERENCES hosts (host_name) ON DELETE CASCADE; + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_principalname +FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name) ON DELETE CASCADE; +-- Kerberos (end) + -- Alerting Framework CREATE TABLE alert_definition ( definition_id BIGINT NOT NULL, http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql index 8f7a6ea..cc015ab 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql @@ -659,6 +659,31 @@ ALTER TABLE ambari.users ADD CONSTRAINT FK_users_principal_id FOREIGN KEY (princ ALTER TABLE ambari.groups ADD CONSTRAINT FK_groups_principal_id FOREIGN KEY (principal_id) REFERENCES ambari.adminprincipal(principal_id); ALTER TABLE ambari.clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES ambari.adminresource(resource_id); +-- Kerberos +CREATE TABLE ambari.kerberos_principal ( + principal_name VARCHAR(255) NOT NULL, + is_service SMALLINT NOT NULL DEFAULT 1, + cached_keytab_path VARCHAR(255), + PRIMARY KEY(principal_name) +); +GRANT ALL PRIVILEGES ON TABLE ambari.kerberos_principal TO :username; + +CREATE TABLE ambari.kerberos_principal_host ( + principal_name VARCHAR(255) NOT NULL, + host_name VARCHAR(255) NOT NULL, + PRIMARY KEY(principal_name, host_name) +); +GRANT ALL PRIVILEGES ON TABLE ambari.kerberos_principal_host TO :username; + +ALTER TABLE ambari.kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_hostname +FOREIGN KEY (host_name) REFERENCES ambari.hosts (host_name) ON DELETE CASCADE; + +ALTER TABLE ambari.kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_principalname +FOREIGN KEY (principal_name) REFERENCES ambari.kerberos_principal (principal_name) ON DELETE CASCADE; +-- Kerberos (end) + -- Alerting Framework CREATE TABLE ambari.alert_definition ( definition_id BIGINT NOT NULL, http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql index 7c72037..ca842a4 100644 --- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql +++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql @@ -163,6 +163,29 @@ ALTER TABLE clusters ADD CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resourc ALTER TABLE host_version ADD CONSTRAINT FK_host_version_host_name FOREIGN KEY (host_name) REFERENCES hosts (host_name); ALTER TABLE host_version ADD CONSTRAINT FK_host_version_repovers_id FOREIGN KEY (repo_version_id) REFERENCES repo_version (repo_version_id); +-- Kerberos +CREATE TABLE kerberos_principal ( + principal_name VARCHAR(255) NOT NULL, + is_service SMALLINT NOT NULL DEFAULT 1, + cached_keytab_path VARCHAR(255), + PRIMARY KEY(principal_name) +); + +CREATE TABLE kerberos_principal_host ( + principal_name VARCHAR(255) NOT NULL, + host_name VARCHAR(255) NOT NULL, + PRIMARY KEY(principal_name, host_name) +); + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_hostname +FOREIGN KEY (host_name) REFERENCES hosts (host_name) ON DELETE CASCADE; + +ALTER TABLE kerberos_principal_host +ADD CONSTRAINT FK_kerberosprincipalhost_principalname +FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name) ON DELETE CASCADE; +-- Kerberos (end) + -- Alerting Framework CREATE TABLE alert_definition ( definition_id BIGINT NOT NULL, http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml index 07bd67d..d89f5d5 100644 --- a/ambari-server/src/main/resources/META-INF/persistence.xml +++ b/ambari-server/src/main/resources/META-INF/persistence.xml @@ -43,6 +43,8 @@ <class>org.apache.ambari.server.orm.entities.HostRoleCommandEntity</class> <class>org.apache.ambari.server.orm.entities.HostStateEntity</class> <class>org.apache.ambari.server.orm.entities.HostVersionEntity</class> + <class>org.apache.ambari.server.orm.entities.KerberosPrincipalEntity</class> + <class>org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity</class> <class>org.apache.ambari.server.orm.entities.KeyValueEntity</class> <class>org.apache.ambari.server.orm.entities.MemberEntity</class> <class>org.apache.ambari.server.orm.entities.MetainfoEntity</class> http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py index 8e171c8..2c3505c 100644 --- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py +++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py @@ -42,7 +42,7 @@ class KerberosClient(KerberosScript): cached_kinit_executor(status_params.kinit_path_local, status_params.smoke_user, status_params.smoke_user_keytab, - status_params.smoke_user, + status_params.smoke_user_principal, status_params.hostname, status_params.tmp_dir) self.put_structured_out({"securityState": "SECURED_KERBEROS"}) @@ -56,7 +56,7 @@ class KerberosClient(KerberosScript): self.put_structured_out({"securityState": "UNSECURED"}) def set_keytab(self, env): - KerberosScript.write_keytab_file() + self.write_keytab_file() if __name__ == "__main__": KerberosClient().execute() http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py index 6af6d05..703be52 100644 --- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py +++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py @@ -351,8 +351,7 @@ class KerberosScript(Script): return 0, '' - @staticmethod - def write_keytab_file(): + def write_keytab_file(self): import params import stat @@ -393,3 +392,9 @@ class KerberosScript(Script): mode=mode, owner=owner, group=group) + + principal = get_property_value(item, 'principal') + if principal is not None: + self.put_structured_out({ + principal.replace("_HOST", params.hostname): keytab_file_path + }) http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py index c624dd5..83dd016 100644 --- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py +++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/params.py @@ -49,6 +49,8 @@ cluster_env = None kdc_server_host = None cluster_host_info = None +hostname = config['hostname'] + kdb5_util_path = 'kdb5_util' kdamin_pid_path = '/var/run/kadmind.pid' http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/status_params.py ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/status_params.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/status_params.py new file mode 100644 index 0000000..4fabf6c --- /dev/null +++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/status_params.py @@ -0,0 +1,32 @@ +""" +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. + +""" + +from resource_management import * + +config = Script.get_config() +tmp_dir = Script.get_tmp_dir() + +hostname = config['hostname'] +kinit_path_local = functions.get_kinit_path(["/usr/bin", "/usr/kerberos/bin", "/usr/sbin"]) + +security_enabled = config['configurations']['cluster-env']['security_enabled'] + +smoke_user_keytab = config['configurations']['cluster-env']['smokeuser_keytab'] +smoke_user = config['configurations']['cluster-env']['smokeuser'] +smoke_user_principal = config['configurations']['cluster-env']['smokeuser_principal_name'] http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartBeatHandlerInjectKeytabTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartBeatHandlerInjectKeytabTest.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartBeatHandlerInjectKeytabTest.java deleted file mode 100644 index d613669..0000000 --- a/ambari-server/src/test/java/org/apache/ambari/server/agent/HeartBeatHandlerInjectKeytabTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.ambari.server.agent; - - -import org.apache.ambari.server.AmbariException; -import org.apache.ambari.server.serveraction.kerberos.KerberosActionDataFile; -import org.apache.ambari.server.serveraction.kerberos.KerberosActionDataFileBuilder; -import org.apache.ambari.server.serveraction.kerberos.KerberosServerAction; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Tests injectKeytab method of HeartBeatHandler - */ -public class HeartBeatHandlerInjectKeytabTest { - - String dataDir; - - @Before - public void setup() throws Exception { - File temporaryDirectory; - File indexFile; - KerberosActionDataFileBuilder kerberosActionDataFileBuilder = null; - - try { - temporaryDirectory = File.createTempFile(".ambari_", ".d"); - } catch (IOException e) { - throw new AmbariException("Unexpected error", e); - } - - // Convert the temporary file into a temporary directory... - if (!temporaryDirectory.delete() || !temporaryDirectory.mkdirs()) { - throw new AmbariException("Failed to create temporary directory"); - } - - dataDir = temporaryDirectory.getAbsolutePath(); - - indexFile = new File(temporaryDirectory, KerberosActionDataFile.DATA_FILE_NAME); - kerberosActionDataFileBuilder = new KerberosActionDataFileBuilder(indexFile); - - kerberosActionDataFileBuilder.addRecord("c6403.ambari.apache.org", "HDFS", "DATANODE", - "dn/_HOST@_REALM", "service", "hdfs-site/dfs.namenode.kerberos.principal", - "/etc/security/keytabs/dn.service.keytab", - "hdfs", "r", "hadoop", "", "hdfs-site/dfs.namenode.keytab.file"); - - kerberosActionDataFileBuilder.close(); - File hostDirectory = new File(dataDir, "c6403.ambari.apache.org"); - - // Ensure the host directory exists... - if (hostDirectory.exists() || hostDirectory.mkdirs()) { - File file = new File(hostDirectory, DigestUtils.sha1Hex("/etc/security/keytabs/dn.service.keytab")); - if (!file.exists()) { - file.createNewFile(); - } - - FileWriter fw = new FileWriter(file.getAbsoluteFile()); - BufferedWriter bw = new BufferedWriter(fw); - bw.write("hello"); - bw.close(); - } - } - - @Test - public void testInjectKeytabApplicableHost() throws Exception { - - ExecutionCommand executionCommand = new ExecutionCommand(); - - Map<String, String> hlp = new HashMap<String, String>(); - hlp.put("custom_command", "SET_KEYTAB"); - executionCommand.setHostLevelParams(hlp); - - Map<String, String> commandparams = new HashMap<String, String>(); - commandparams.put(KerberosServerAction.DATA_DIRECTORY, dataDir); - executionCommand.setCommandParams(commandparams); - - HeartBeatHandler.injectKeytab(executionCommand, "c6403.ambari.apache.org"); - - List<Map<String, String>> kcp = executionCommand.getKerberosCommandParams(); - - Assert.assertEquals("c6403.ambari.apache.org", kcp.get(0).get(KerberosActionDataFile.HOSTNAME)); - Assert.assertEquals("HDFS", kcp.get(0).get(KerberosActionDataFile.SERVICE)); - Assert.assertEquals("DATANODE", kcp.get(0).get(KerberosActionDataFile.COMPONENT)); - Assert.assertEquals("dn/_HOST@_REALM", kcp.get(0).get(KerberosActionDataFile.PRINCIPAL)); - Assert.assertEquals("hdfs-site/dfs.namenode.kerberos.principal", kcp.get(0).get(KerberosActionDataFile.PRINCIPAL_CONFIGURATION)); - Assert.assertEquals("/etc/security/keytabs/dn.service.keytab", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_PATH)); - Assert.assertEquals("hdfs", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_OWNER_NAME)); - Assert.assertEquals("r", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_OWNER_ACCESS)); - Assert.assertEquals("hadoop", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_GROUP_NAME)); - Assert.assertEquals("", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_GROUP_ACCESS)); - Assert.assertEquals("hdfs-site/dfs.namenode.keytab.file", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_CONFIGURATION)); - - Assert.assertEquals(Base64.encodeBase64String("hello".getBytes()), kcp.get(0).get(KerberosServerAction.KEYTAB_CONTENT_BASE64)); - - } - - @Test - public void testInjectKeytabNotApplicableHost() throws Exception { - ExecutionCommand executionCommand = new ExecutionCommand(); - - Map<String, String> hlp = new HashMap<String, String>(); - hlp.put("custom_command", "SET_KEYTAB"); - executionCommand.setHostLevelParams(hlp); - - Map<String, String> commandparams = new HashMap<String, String>(); - commandparams.put(KerberosServerAction.DATA_DIRECTORY, dataDir); - executionCommand.setCommandParams(commandparams); - - HeartBeatHandler.injectKeytab(executionCommand, "c6400.ambari.apache.org"); - - List<Map<String, String>> kcp = executionCommand.getKerberosCommandParams(); - Assert.assertTrue(kcp.isEmpty()); - - } - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java index 3140128..abee322 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java @@ -46,6 +46,9 @@ import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -81,6 +84,9 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.OrmTestHelper; import org.apache.ambari.server.orm.dao.RepositoryVersionDAO; import org.apache.ambari.server.orm.entities.RepositoryVersionEntity; +import org.apache.ambari.server.serveraction.kerberos.KerberosActionDataFile; +import org.apache.ambari.server.serveraction.kerberos.KerberosActionDataFileBuilder; +import org.apache.ambari.server.serveraction.kerberos.KerberosServerAction; import org.apache.ambari.server.state.Alert; import org.apache.ambari.server.state.AlertState; import org.apache.ambari.server.state.Cluster; @@ -100,10 +106,14 @@ import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEve import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent; import org.apache.ambari.server.state.svccomphost.ServiceComponentHostUpgradeEvent; import org.apache.ambari.server.utils.StageUtils; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; import org.codehaus.jackson.JsonGenerationException; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -133,6 +143,9 @@ public class TestHeartbeatHandler { private UnitOfWork unitOfWork; + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Before public void setup() throws Exception { @@ -2468,6 +2481,93 @@ public class TestHeartbeatHandler { entity = dao.findByStackAndVersion("HDP-0.1", "2.2.1.0-2222"); Assert.assertNotNull(entity); + } + + @Test + public void testInjectKeytabApplicableHost() throws Exception { + List<Map<String, String>> kcp = testInjectKeytab("c6403.ambari.apache.org"); + + Assert.assertNotNull(kcp); + Assert.assertEquals(1, kcp.size()); + Assert.assertEquals("c6403.ambari.apache.org", kcp.get(0).get(KerberosActionDataFile.HOSTNAME)); + Assert.assertEquals("HDFS", kcp.get(0).get(KerberosActionDataFile.SERVICE)); + Assert.assertEquals("DATANODE", kcp.get(0).get(KerberosActionDataFile.COMPONENT)); + Assert.assertEquals("dn/_HOST@_REALM", kcp.get(0).get(KerberosActionDataFile.PRINCIPAL)); + Assert.assertEquals("hdfs-site/dfs.namenode.kerberos.principal", kcp.get(0).get(KerberosActionDataFile.PRINCIPAL_CONFIGURATION)); + Assert.assertEquals("/etc/security/keytabs/dn.service.keytab", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_PATH)); + Assert.assertEquals("hdfs", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_OWNER_NAME)); + Assert.assertEquals("r", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_OWNER_ACCESS)); + Assert.assertEquals("hadoop", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_GROUP_NAME)); + Assert.assertEquals("", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_GROUP_ACCESS)); + Assert.assertEquals("hdfs-site/dfs.namenode.keytab.file", kcp.get(0).get(KerberosActionDataFile.KEYTAB_FILE_CONFIGURATION)); + + Assert.assertEquals(Base64.encodeBase64String("hello".getBytes()), kcp.get(0).get(KerberosServerAction.KEYTAB_CONTENT_BASE64)); } + + @Test + public void testInjectKeytabNotApplicableHost() throws Exception { + List<Map<String, String>> kcp = testInjectKeytab("c6401.ambari.apache.org"); + Assert.assertNotNull(kcp); + Assert.assertTrue(kcp.isEmpty()); + } + + private List<Map<String, String>> testInjectKeytab(String targetHost) throws Exception { + + ExecutionCommand executionCommand = new ExecutionCommand(); + + Map<String, String> hlp = new HashMap<String, String>(); + hlp.put("custom_command", "SET_KEYTAB"); + executionCommand.setHostLevelParams(hlp); + + Map<String, String> commandparams = new HashMap<String, String>(); + commandparams.put(KerberosServerAction.DATA_DIRECTORY, createTestKeytabData().getAbsolutePath()); + executionCommand.setCommandParams(commandparams); + + ActionQueue aq = new ActionQueue(); + + final HostRoleCommand command = new HostRoleCommand(DummyHostname1, + Role.DATANODE, null, null); + + ActionManager am = getMockActionManager(); + expect(am.getTasks(anyObject(List.class))).andReturn( + new ArrayList<HostRoleCommand>() {{ + add(command); + }}); + replay(am); + + getHeartBeatHandler(am, aq).injectKeytab(executionCommand, targetHost); + + return executionCommand.getKerberosCommandParams(); + } + + + private File createTestKeytabData() throws Exception { + File dataDirectory = temporaryFolder.newFolder(); + File indexFile = new File(dataDirectory, KerberosActionDataFile.DATA_FILE_NAME); + KerberosActionDataFileBuilder kerberosActionDataFileBuilder = new KerberosActionDataFileBuilder(indexFile); + File hostDirectory = new File(dataDirectory, "c6403.ambari.apache.org"); + + File keytabFile; + if(hostDirectory.mkdirs()) + keytabFile = new File(hostDirectory, DigestUtils.sha1Hex("/etc/security/keytabs/dn.service.keytab")); + else + throw new Exception("Failed to create " + hostDirectory.getAbsolutePath()); + + kerberosActionDataFileBuilder.addRecord("c6403.ambari.apache.org", "HDFS", "DATANODE", + "dn/_HOST@_REALM", "service", "hdfs-site/dfs.namenode.kerberos.principal", + "/etc/security/keytabs/dn.service.keytab", + "hdfs", "r", "hadoop", "", "hdfs-site/dfs.namenode.keytab.file"); + + kerberosActionDataFileBuilder.close(); + + // Ensure the host directory exists... + FileWriter fw = new FileWriter(keytabFile); + BufferedWriter bw = new BufferedWriter(fw); + bw.write("hello"); + bw.close(); + + return dataDirectory; + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java index 472178b..ad6128c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java @@ -50,7 +50,6 @@ 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.MaintenanceState; import org.apache.ambari.server.state.SecurityState; import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.Service; @@ -160,7 +159,6 @@ public class KerberosHelperTest extends EasyMockSupport { bind(SecurityHelper.class).toInstance(createNiceMock(SecurityHelper.class)); bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); bind(AmbariCustomCommandExecutionHelper.class).toInstance(createNiceMock(AmbariCustomCommandExecutionHelper.class)); - bind(MaintenanceStateHelper.class).toInstance(createNiceMock(MaintenanceStateHelper.class)); bind(AmbariManagementController.class).toInstance(createNiceMock(AmbariManagementController.class)); bind(AmbariMetaInfo.class).toInstance(metaInfo); bind(ActionManager.class).toInstance(createNiceMock(ActionManager.class)); @@ -401,10 +399,6 @@ public class KerberosHelperTest extends EasyMockSupport { // TODO: (rlevas) Remove when AMBARI 9121 is complete expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).once(); - final MaintenanceStateHelper maintenanceStateHelper = injector.getInstance(MaintenanceStateHelper.class); - expect(maintenanceStateHelper.getEffectiveState(anyObject(ServiceComponentHost.class))) - .andReturn(MaintenanceState.OFF).anyTimes(); - final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(SecurityType.KERBEROS).once(); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).once(); @@ -445,6 +439,9 @@ public class KerberosHelperTest extends EasyMockSupport { } }) .once(); + expect(clusters.getHost("host1")) + .andReturn(host) + .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, "host1")) @@ -621,7 +618,6 @@ public class KerberosHelperTest extends EasyMockSupport { final Host host = createNiceMock(Host.class); expect(host.getHostName()).andReturn("host1").once(); - expect(host.getState()).andReturn(HostState.HEALTHY).once(); final Service service1 = createStrictMock(Service.class); expect(service1.getName()).andReturn("SERVICE1").anyTimes(); @@ -654,10 +650,6 @@ public class KerberosHelperTest extends EasyMockSupport { // TODO: (rlevas) Remove when AMBARI 9121 is complete expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).once(); - final MaintenanceStateHelper maintenanceStateHelper = injector.getInstance(MaintenanceStateHelper.class); - expect(maintenanceStateHelper.getEffectiveState(anyObject(ServiceComponentHost.class))) - .andReturn(MaintenanceState.OFF).anyTimes(); - final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(SecurityType.NONE).once(); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).once(); @@ -809,6 +801,11 @@ public class KerberosHelperTest extends EasyMockSupport { expect(requestStageContainer.getId()).andReturn(1L).once(); requestStageContainer.addStages(anyObject(List.class)); expectLastCall().once(); + // Destroy Principals Stage + expect(requestStageContainer.getLastStageId()).andReturn(2L).anyTimes(); + expect(requestStageContainer.getId()).andReturn(1L).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(); @@ -879,10 +876,6 @@ public class KerberosHelperTest extends EasyMockSupport { // TODO: (rlevas) Remove when AMBARI 9121 is complete expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).once(); - final MaintenanceStateHelper maintenanceStateHelper = injector.getInstance(MaintenanceStateHelper.class); - expect(maintenanceStateHelper.getEffectiveState(anyObject(ServiceComponentHost.class))) - .andReturn(MaintenanceState.OFF).anyTimes(); - final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getSecurityType()).andReturn(SecurityType.KERBEROS).once(); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).once(); @@ -923,6 +916,9 @@ public class KerberosHelperTest extends EasyMockSupport { } }) .once(); + expect(clusters.getHost("host1")) + .andReturn(host) + .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, "host1")) @@ -1161,10 +1157,6 @@ public class KerberosHelperTest extends EasyMockSupport { // TODO: (rlevas) Remove when AMBARI 9121 is complete expect(krb5ConfConfig.getProperties()).andReturn(krb5ConfProperties).once(); - final MaintenanceStateHelper maintenanceStateHelper = injector.getInstance(MaintenanceStateHelper.class); - expect(maintenanceStateHelper.getEffectiveState(anyObject(ServiceComponentHost.class))) - .andReturn(MaintenanceState.OFF).anyTimes(); - final Cluster cluster = createNiceMock(Cluster.class); expect(cluster.getDesiredConfigByType("krb5-conf")).andReturn(krb5ConfConfig).once(); expect(cluster.getDesiredConfigByType("kerberos-env")).andReturn(kerberosEnvConfig).once(); @@ -1205,6 +1197,9 @@ public class KerberosHelperTest extends EasyMockSupport { } }) .once(); + expect(clusters.getHost("host1")) + .andReturn(host) + .once(); final AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class); expect(ambariManagementController.findConfigurationTagsWithOverrides(cluster, "host1")) http://git-wip-us.apache.org/repos/asf/ambari/blob/c775c607/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java index b935c29..cdb5380 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog200Test.java @@ -135,6 +135,8 @@ public class UpgradeCatalog200Test { Capture<DBAccessor.DBColumnInfo> dataValueColumnCapture = new Capture<DBAccessor.DBColumnInfo>(); Capture<List<DBAccessor.DBColumnInfo>> alertTargetStatesCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); Capture<List<DBAccessor.DBColumnInfo>> artifactCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); + Capture<List<DBAccessor.DBColumnInfo>> kerberosPrincipalCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); + Capture<List<DBAccessor.DBColumnInfo>> kerberosPrincipalHostCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); Capture<List<DBAccessor.DBColumnInfo>> upgradeCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); Capture<List<DBAccessor.DBColumnInfo>> upgradeGroupCapture = new Capture<List<DBAccessor.DBColumnInfo>>(); @@ -211,6 +213,18 @@ public class UpgradeCatalog200Test { dbAccessor.createTable(eq("artifact"), capture(artifactCapture), eq("artifact_name"), eq("foreign_keys")); + // kerberos_principal + dbAccessor.createTable(eq("kerberos_principal"), capture(kerberosPrincipalCapture), + eq("principal_name")); + + // kerberos_principal_host + dbAccessor.createTable(eq("kerberos_principal_host"), capture(kerberosPrincipalHostCapture), + eq("principal_name"), eq("host_name")); + dbAccessor.addFKConstraint(eq("kerberos_principal_host"), eq("FK_kerberosprincipalhost_hostname"), + eq("host_name"), eq("hosts"), eq("host_name"), eq(false)); + dbAccessor.addFKConstraint(eq("kerberos_principal_host"), eq("FK_kerberosprincipalhost_principalname"), + eq("principal_name"), eq("kerberos_principal"), eq("principal_name"), eq(false)); + setViewInstancePropertyExpectations(dbAccessor, valueColumnCapture); setViewInstanceDataExpectations(dbAccessor, dataValueColumnCapture); @@ -282,6 +296,11 @@ public class UpgradeCatalog200Test { List<DBAccessor.DBColumnInfo> artifactColumns = artifactCapture.getValue(); testCreateArtifactTable(artifactColumns); + // verify kerberos_principal columns + testCreateKerberosPrincipalTable(kerberosPrincipalCapture.getValue()); + + // verify kerberos_principal_host columns + testCreateKerberosPrincipalHostTable(kerberosPrincipalHostCapture.getValue()); // Verify capture group sizes assertEquals(7, clusterVersionCapture.getValue().size()); @@ -606,4 +625,47 @@ public class UpgradeCatalog200Test { } } } + + private void testCreateKerberosPrincipalTable(List<DBColumnInfo> columns) { + assertEquals(3, columns.size()); + for (DBColumnInfo column : columns) { + if (column.getName().equals("principal_name")) { + assertNull(column.getDefaultValue()); + assertEquals(String.class, column.getType()); + assertEquals(255, (int) column.getLength()); + assertEquals(false, column.isNullable()); + } else if (column.getName().equals("is_service")) { + assertEquals(1, column.getDefaultValue()); + assertEquals(Short.class, column.getType()); + assertEquals(1, (int) column.getLength()); + assertEquals(false, column.isNullable()); + } else if (column.getName().equals("cached_keytab_path")) { + assertNull(column.getDefaultValue()); + assertEquals(String.class, column.getType()); + assertEquals(255, (int) column.getLength()); + assertEquals(true, column.isNullable()); + } else { + fail("unexpected column name"); + } + } + } + + private void testCreateKerberosPrincipalHostTable(List<DBColumnInfo> columns) { + assertEquals(2, columns.size()); + for (DBColumnInfo column : columns) { + if (column.getName().equals("principal_name")) { + assertNull(column.getDefaultValue()); + assertEquals(String.class, column.getType()); + assertEquals(255, (int) column.getLength()); + assertEquals(false, column.isNullable()); + } else if (column.getName().equals("host_name")) { + assertNull(column.getDefaultValue()); + assertEquals(String.class, column.getType()); + assertEquals(255, (int) column.getLength()); + assertEquals(false, column.isNullable()); + } else { + fail("unexpected column name"); + } + } + } }