You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2015/03/12 01:38:40 UTC
ambari git commit: AMBARI-9007. Identity references fail to deference
for service-level references in Kerberos descriptor parser (rlevas)
Repository: ambari
Updated Branches:
refs/heads/trunk 04f54294e -> 6bf7adc5e
AMBARI-9007. Identity references fail to deference for service-level references in Kerberos descriptor parser (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6bf7adc5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6bf7adc5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6bf7adc5
Branch: refs/heads/trunk
Commit: 6bf7adc5e1e9ce2ade3163d50087257d727d830b
Parents: 04f5429
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Mar 11 20:38:28 2015 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Mar 11 20:38:28 2015 -0400
----------------------------------------------------------------------
.../AbstractKerberosDescriptorContainer.java | 127 +++++++++++++------
.../state/kerberos/KerberosDescriptor.java | 20 +++
.../HIVE/0.12.0.2.0/kerberos.json | 54 ++++----
.../state/kerberos/KerberosDescriptorTest.java | 89 +++++++++++++
...test_get_referenced_identity_descriptor.json | 127 +++++++++++++++++++
5 files changed, 350 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6bf7adc5/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
index 2ec2cb5..874e331 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/AbstractKerberosDescriptorContainer.java
@@ -527,10 +527,38 @@ public abstract class AbstractKerberosDescriptorContainer extends AbstractKerber
* <p/>
* The path value is expected to be an "absolute" path through the Kerberos Descriptor hierarchy
* to some specific KerberosIdentityDescriptor. The path must be in one of the following forms:
+ * <ul>
+ * <li>/identity</li>
+ * <li>/service/identity</li>
+ * <li>/service/component/identity</li>
+ * </ul>
* <p/>
- * /identity
- * /service/identity
- * /service/component/identity
+ * If the path starts with "../", the ".." will be translated to the path of the parent item.
+ * In the following example, <code>../service_identity</code> will resolve to
+ * <code>/SERVICE/service_identity</code>:
+ * <pre>
+ * {
+ * "name": "SERVICE",
+ * "identities": [
+ * {
+ * "name": "service_identity",
+ * ...
+ * }
+ * ],
+ * "components" : [
+ * {
+ * "name": "COMPONENT",
+ * "identities": [
+ * {
+ * "name": "./service_identity",
+ * ...
+ * },
+ * ...
+ * ]
+ * }
+ * ]
+ * }
+ * </pre>
*
* @param path a String declaring the path to a KerberosIdentityDescriptor
* @return a KerberosIdentityDescriptor identified by the path or null if not found
@@ -539,50 +567,72 @@ public abstract class AbstractKerberosDescriptorContainer extends AbstractKerber
throws AmbariException {
KerberosIdentityDescriptor identityDescriptor = null;
- if ((path != null) && path.startsWith("/")) {
- // The name indicates it is referencing an identity somewhere in the hierarchy... try to find it.
- // /[<service name>/[<component name>/]]<identity name>
- String[] pathParts = path.split("/");
+ if (path != null) {
+ if(path.startsWith("../")) {
+ // Resolve parent path
+ AbstractKerberosDescriptor parent = getParent();
- String serviceName = null;
- String componentName = null;
- String identityName;
+ path = path.substring(2);
- switch (pathParts.length) {
- case 3:
- serviceName = pathParts[0];
- componentName = pathParts[1];
- identityName = pathParts[2];
- break;
- case 2:
- serviceName = pathParts[0];
- identityName = pathParts[1];
- break;
- case 1:
- identityName = pathParts[0];
- break;
- default:
- throw new AmbariException(String.format("Unexpected path length in %s", path));
+ while(parent != null) {
+ String name = parent.getName();
+
+ if (name != null) {
+ path = String.format("/%s", name) + path;
+ }
+
+ parent = parent.getParent();
+ }
}
- if (identityName != null) {
- // Start at the top of the hierarchy
- AbstractKerberosDescriptor descriptor = getRoot();
+ if (path.startsWith("/")) {
+ // The name indicates it is referencing an identity somewhere in the hierarchy... try to find it.
+ // /[<service name>/[<component name>/]]<identity name>
+ String[] pathParts = path.split("/");
+
+ String serviceName = null;
+ String componentName = null;
+ String identityName;
+
+ switch (pathParts.length) {
+ case 4:
+ serviceName = pathParts[1];
+ componentName = pathParts[2];
+ identityName = pathParts[3];
+ break;
+ case 3:
+ serviceName = pathParts[1];
+ identityName = pathParts[2];
+ break;
+ case 2:
+ identityName = pathParts[1];
+ break;
+ case 1:
+ identityName = pathParts[0];
+ break;
+ default:
+ throw new AmbariException(String.format("Unexpected path length in %s", path));
+ }
+
+ if (identityName != null) {
+ // Start at the top of the hierarchy
+ AbstractKerberosDescriptor descriptor = getRoot();
- if (descriptor != null) {
- if ((serviceName != null) && !serviceName.isEmpty()) {
- descriptor = descriptor.getDescriptor(KerberosDescriptorType.SERVICE, serviceName);
+ if (descriptor != null) {
+ if ((serviceName != null) && !serviceName.isEmpty()) {
+ descriptor = descriptor.getDescriptor(KerberosDescriptorType.SERVICE, serviceName);
- if ((descriptor != null) && (componentName != null) && !componentName.isEmpty()) {
- descriptor = descriptor.getDescriptor(KerberosDescriptorType.COMPONENT, componentName);
+ if ((descriptor != null) && (componentName != null) && !componentName.isEmpty()) {
+ descriptor = descriptor.getDescriptor(KerberosDescriptorType.COMPONENT, componentName);
+ }
}
- }
- if (descriptor != null) {
- descriptor = descriptor.getDescriptor(KerberosDescriptorType.IDENTITY, identityName);
+ if (descriptor != null) {
+ descriptor = descriptor.getDescriptor(KerberosDescriptorType.IDENTITY, identityName);
- if (descriptor instanceof KerberosIdentityDescriptor) {
- identityDescriptor = (KerberosIdentityDescriptor) descriptor;
+ if (descriptor instanceof KerberosIdentityDescriptor) {
+ identityDescriptor = (KerberosIdentityDescriptor) descriptor;
+ }
}
}
}
@@ -590,7 +640,6 @@ public abstract class AbstractKerberosDescriptorContainer extends AbstractKerber
}
return identityDescriptor;
-
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/6bf7adc5/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
index 791b0e6..8cd9718 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptor.java
@@ -256,6 +256,26 @@ public class KerberosDescriptor extends AbstractKerberosDescriptorContainer {
}
/**
+ * Gets the requested AbstractKerberosDescriptor implementation using a type name and a relevant
+ * descriptor name.
+ * <p/>
+ * This implementation handles service descriptors and delegates to the AbstractKerberosDescriptor
+ * implementation to handle component and identity types.
+ *
+ * @param type a String indicating the type of the requested descriptor
+ * @param name a String indicating the name of the requested descriptor
+ * @return a AbstractKerberosDescriptor representing the requested descriptor or null if not found
+ */
+ @Override
+ protected AbstractKerberosDescriptor getDescriptor(KerberosDescriptorType type, String name) {
+ if (KerberosDescriptorType.SERVICE == type) {
+ return getService(name);
+ } else {
+ return super.getDescriptor(type, name);
+ }
+ }
+
+ /**
* Creates a Map of values that can be used to create a copy of this KerberosDescriptor
* or generate the JSON structure described in
* {@link org.apache.ambari.server.state.kerberos.KerberosDescriptor}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6bf7adc5/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/kerberos.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/kerberos.json b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/kerberos.json
index ad5ee3e..e154c02 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/kerberos.json
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/kerberos.json
@@ -8,6 +8,25 @@
},
{
"name": "/smokeuser"
+ },
+ {
+ "name": "hive",
+ "principal": {
+ "value": "hive/_HOST@${realm}",
+ "type": "service",
+ "local_username": "${hive-env/hive_user}"
+ },
+ "keytab": {
+ "file": "${keytab_dir}/hive.service.keytab",
+ "owner": {
+ "name": "${hive-env/hive_user}",
+ "access": "r"
+ },
+ "group": {
+ "name": "${cluster-env/user_group}",
+ "access": ""
+ }
+ }
}
],
"configurations": [
@@ -35,23 +54,11 @@
"name": "HIVE_METASTORE",
"identities": [
{
- "name": "hive_metastore_hive",
+ "name": "../hive",
"principal": {
- "value": "hive/_HOST@${realm}",
- "type" : "service",
- "configuration": "hive-site/hive.metastore.kerberos.principal",
- "local_username": "${hive-env/hive_user}"
+ "configuration": "hive-site/hive.metastore.kerberos.principal"
},
"keytab": {
- "file": "${keytab_dir}/hive.service.keytab",
- "owner": {
- "name": "${hive-env/hive_user}",
- "access": "r"
- },
- "group": {
- "name": "${cluster-env/user_group}",
- "access": ""
- },
"configuration": "hive-site/hive.metastore.kerberos.keytab.file"
}
}
@@ -61,23 +68,11 @@
"name": "HIVE_SERVER",
"identities": [
{
- "name": "hive_server_hive",
+ "name": "../hive",
"principal": {
- "value": "hive/_HOST@${realm}",
- "type" : "service",
- "configuration": "hive-site/hive.server2.authentication.kerberos.principal",
- "local_username": "${hive-env/hive_user}"
+ "configuration": "hive-site/hive.server2.authentication.kerberos.principal"
},
"keytab": {
- "file": "${keytab_dir}/hive.service.keytab",
- "owner": {
- "name": "${hive-env/hive_user}",
- "access": "r"
- },
- "group": {
- "name": "${cluster-env/user_group}",
- "access": ""
- },
"configuration": "hive-site/hive.server2.authentication.kerberos.keytab"
}
},
@@ -105,6 +100,9 @@
}
}
]
+ },
+ {
+ "name": "HIVE_CLIENT"
}
]
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6bf7adc5/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
index 97f8008..637facc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorTest.java
@@ -22,6 +22,9 @@ import junit.framework.Assert;
import org.apache.ambari.server.AmbariException;
import org.junit.Test;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -435,4 +438,90 @@ public class KerberosDescriptorTest {
Assert.assertEquals("$c6401.ambari.apache.org",
KerberosDescriptor.replaceVariables("$${host}", configurations));
}
+
+ @Test
+ public void testGetReferencedIdentityDescriptor() throws IOException {
+ URL systemResourceURL = ClassLoader.getSystemResource("kerberos/test_get_referenced_identity_descriptor.json");
+ Assert.assertNotNull(systemResourceURL);
+ KerberosDescriptor descriptor = KERBEROS_DESCRIPTOR_FACTORY.createInstance(new File(systemResourceURL.getFile()));
+
+ KerberosIdentityDescriptor identity;
+
+ // Stack-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/stack_identity");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("stack_identity", identity.getName());
+
+ // Service-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/SERVICE1/service1_identity");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("service1_identity", identity.getName());
+ Assert.assertNotNull(identity.getParent());
+ Assert.assertEquals("SERVICE1", identity.getParent().getName());
+
+ // Component-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/SERVICE2/SERVICE2_COMPONENT1/service2_component1_identity");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("service2_component1_identity", identity.getName());
+ Assert.assertNotNull(identity.getParent());
+ Assert.assertEquals("SERVICE2_COMPONENT1", identity.getParent().getName());
+ Assert.assertNotNull(identity.getParent().getParent());
+ Assert.assertEquals("SERVICE2", identity.getParent().getParent().getName());
+ }
+
+ @Test
+ public void testGetReferencedIdentityDescriptor_NameCollisions() throws IOException {
+ URL systemResourceURL = ClassLoader.getSystemResource("kerberos/test_get_referenced_identity_descriptor.json");
+ Assert.assertNotNull(systemResourceURL);
+ KerberosDescriptor descriptor = KERBEROS_DESCRIPTOR_FACTORY.createInstance(new File(systemResourceURL.getFile()));
+
+ KerberosIdentityDescriptor identity;
+
+ // Stack-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/collision");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("collision", identity.getName());
+ Assert.assertNotNull(identity.getParent());
+ Assert.assertEquals(null, identity.getParent().getName());
+
+ // Service-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/SERVICE1/collision");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("collision", identity.getName());
+ Assert.assertNotNull(identity.getParent());
+ Assert.assertEquals("SERVICE1", identity.getParent().getName());
+
+ // Component-level identity
+ identity = descriptor.getReferencedIdentityDescriptor("/SERVICE2/SERVICE2_COMPONENT1/collision");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("collision", identity.getName());
+ Assert.assertNotNull(identity.getParent());
+ Assert.assertEquals("SERVICE2_COMPONENT1", identity.getParent().getName());
+ Assert.assertNotNull(identity.getParent().getParent());
+ Assert.assertEquals("SERVICE2", identity.getParent().getParent().getName());
+ }
+
+ @Test
+ public void testGetReferencedIdentityDescriptor_RelativePath() throws IOException {
+ URL systemResourceURL = ClassLoader.getSystemResource("kerberos/test_get_referenced_identity_descriptor.json");
+ Assert.assertNotNull(systemResourceURL);
+
+ KerberosDescriptor descriptor = KERBEROS_DESCRIPTOR_FACTORY.createInstance(new File(systemResourceURL.getFile()));
+ Assert.assertNotNull(descriptor);
+
+ KerberosServiceDescriptor serviceDescriptor = descriptor.getService("SERVICE2");
+ Assert.assertNotNull(serviceDescriptor);
+
+ KerberosComponentDescriptor componentDescriptor = serviceDescriptor.getComponent("SERVICE2_COMPONENT1");
+ Assert.assertNotNull(componentDescriptor);
+
+ KerberosIdentityDescriptor identity;
+ identity = componentDescriptor.getReferencedIdentityDescriptor("../service2_identity");
+ Assert.assertNotNull(identity);
+ Assert.assertEquals("service2_identity", identity.getName());
+ Assert.assertEquals(serviceDescriptor, identity.getParent());
+
+ identity = serviceDescriptor.getReferencedIdentityDescriptor("../service2_identity");
+ Assert.assertNull(identity);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/6bf7adc5/ambari-server/src/test/resources/kerberos/test_get_referenced_identity_descriptor.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/kerberos/test_get_referenced_identity_descriptor.json b/ambari-server/src/test/resources/kerberos/test_get_referenced_identity_descriptor.json
new file mode 100644
index 0000000..307a1e1
--- /dev/null
+++ b/ambari-server/src/test/resources/kerberos/test_get_referenced_identity_descriptor.json
@@ -0,0 +1,127 @@
+{
+ "properties": {
+ "realm": "${kerberos-env/realm}",
+ "keytab_dir": "/etc/security/keytabs"
+ },
+ "identities": [
+ {
+ "name": "stack_identity",
+ "principal": {
+ "value": "stack@${realm}",
+ "type": "user"
+ },
+ "keytab": {
+ "file": "${keytab_dir}/stack.keytab",
+ "owner": {
+ "name": "root",
+ "access": "r"
+ },
+ "group": {
+ "name": "${cluster-env/user_group}",
+ "access": "r"
+ }
+ }
+ },
+ {
+ "name": "collision",
+ "principal": {
+ "value": "stack_collision@${realm}",
+ "type": "user"
+ }
+ }
+ ],
+ "services" : [
+ {
+ "name": "SERVICE1",
+ "identities": [
+ {
+ "name": "service1_identity",
+ "principal": {
+ "value": "service1@${realm}",
+ "type": "user"
+ },
+ "keytab": {
+ "file": "${keytab_dir}/service1.keytab",
+ "owner": {
+ "name": "root",
+ "access": "r"
+ },
+ "group": {
+ "name": "${cluster-env/user_group}",
+ "access": "r"
+ }
+ }
+ },
+ {
+ "name": "collision",
+ "principal": {
+ "value": "service1_collision@${realm}",
+ "type": "user"
+ }
+ }
+ ]
+ },
+ {
+ "name": "SERVICE2",
+ "identities": [
+ {
+ "name": "service2_identity",
+ "principal": {
+ "value": "service2@${realm}",
+ "type": "user"
+ },
+ "keytab": {
+ "file": "${keytab_dir}/service2.keytab",
+ "owner": {
+ "name": "root",
+ "access": "r"
+ },
+ "group": {
+ "name": "${cluster-env/user_group}",
+ "access": "r"
+ }
+ }
+ },
+ {
+ "name": "collision",
+ "principal": {
+ "value": "service2_collision@${realm}",
+ "type": "user"
+ }
+ }
+ ],
+ "components" : [
+ {
+ "name": "SERVICE2_COMPONENT1",
+ "identities": [
+ {
+ "name": "service2_component1_identity",
+ "principal": {
+ "value": "service2_component1@${realm}",
+ "type": "user"
+ },
+ "keytab": {
+ "file": "${keytab_dir}/service2_component1.keytab",
+ "owner": {
+ "name": "root",
+ "access": "r"
+ },
+ "group": {
+ "name": "${cluster-env/user_group}",
+ "access": "r"
+ }
+ }
+ },
+ {
+ "name": "collision",
+ "principal": {
+ "value": "service2_component1_collision@${realm}",
+ "type": "user"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}