You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2015/01/08 00:56:07 UTC
[1/2] ambari git commit: AMBARI-8984. Ambari user+group sync does not
work with Active Directory. (Yurii Shylov via mahadev)
Repository: ambari
Updated Branches:
refs/heads/trunk 07a3078cc -> 6b1eef55e
AMBARI-8984. Ambari user+group sync does not work with Active Directory. (Yurii Shylov via mahadev)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d7a293bf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d7a293bf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d7a293bf
Branch: refs/heads/trunk
Commit: d7a293bfe384989ab1a6b3556a459752f7d46efa
Parents: 07a3078
Author: Mahadev Konar <ma...@apache.org>
Authored: Wed Jan 7 14:14:40 2015 -0800
Committer: Mahadev Konar <ma...@apache.org>
Committed: Wed Jan 7 15:48:54 2015 -0800
----------------------------------------------------------------------
.../server/configuration/Configuration.java | 4 +
.../authorization/LdapServerProperties.java | 12 ++
.../security/ldap/AmbariLdapDataPopulator.java | 113 +++++++++++--------
ambari-server/src/main/python/ambari-server.py | 29 ++---
.../ldap/AmbariLdapDataPopulatorTest.java | 63 +++++++++++
.../src/test/python/TestAmbariServer.py | 8 +-
6 files changed, 168 insertions(+), 61 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 4bbe255..e5b4cc4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -142,6 +142,8 @@ public class Configuration {
"authentication.ldap.managerDn";
public static final String LDAP_MANAGER_PASSWORD_KEY =
"authentication.ldap.managerPassword";
+ public static final String LDAP_DN_ATTRIBUTE_KEY =
+ "authentication.ldap.dnAttribute";
public static final String LDAP_USERNAME_ATTRIBUTE_KEY =
"authentication.ldap.usernameAttribute";
public static final String LDAP_USER_BASE_KEY =
@@ -295,6 +297,7 @@ public class Configuration {
private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
private static final String LDAP_USERNAME_ATTRIBUTE_DEFAULT = "uid";
+ private static final String LDAP_DN_ATTRIBUTE_DEFAULT = "dn";
private static final String LDAP_USER_BASE_DEFAULT =
"ou=people,dc=ambari,dc=apache,dc=org";
private static final String LDAP_USER_OBJECT_CLASS_DEFAULT = "person";
@@ -910,6 +913,7 @@ public class Configuration {
ldapServerProperties.setUserBase(properties.getProperty(LDAP_USER_BASE_KEY, LDAP_USER_BASE_DEFAULT));
ldapServerProperties.setUserObjectClass(properties.getProperty(LDAP_USER_OBJECT_CLASS_KEY, LDAP_USER_OBJECT_CLASS_DEFAULT));
+ ldapServerProperties.setDnAttribute(properties.getProperty(LDAP_DN_ATTRIBUTE_KEY, LDAP_DN_ATTRIBUTE_DEFAULT));
ldapServerProperties.setGroupBase(properties.
getProperty(LDAP_GROUP_BASE_KEY, LDAP_GROUP_BASE_DEFAULT));
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
index 758523b..ddb3670 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
@@ -35,6 +35,7 @@ public class LdapServerProperties {
private String managerDn;
private String managerPassword;
private String baseDN;
+ private String dnAttribute;
//LDAP group properties
private String groupBase;
@@ -216,6 +217,14 @@ public class LdapServerProperties {
return userObjectClass;
}
+ public String getDnAttribute() {
+ return dnAttribute;
+ }
+
+ public void setDnAttribute(String dnAttribute) {
+ this.dnAttribute = dnAttribute;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -249,6 +258,8 @@ public class LdapServerProperties {
that.adminGroupMappingRules) : that.adminGroupMappingRules != null) return false;
if (groupSearchFilter != null ? !groupSearchFilter.equals(
that.groupSearchFilter) : that.groupSearchFilter != null) return false;
+ if (dnAttribute != null ? !dnAttribute.equals(
+ that.dnAttribute) : that.dnAttribute != null) return false;
return true;
}
@@ -271,6 +282,7 @@ public class LdapServerProperties {
result = 31 * result + (groupNamingAttr != null ? groupNamingAttr.hashCode() : 0);
result = 31 * result + (adminGroupMappingRules != null ? adminGroupMappingRules.hashCode() : 0);
result = 31 * result + (groupSearchFilter != null ? groupSearchFilter.hashCode() : 0);
+ result = 31 * result + (dnAttribute != null ? dnAttribute.hashCode() : 0);
return result;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
index 62e2966..05494e3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
@@ -82,7 +82,6 @@ public class AmbariLdapDataPopulator {
// Constants
private static final String UID_ATTRIBUTE = "uid";
- private static final String DN_ATTRIBUTE = "dn";
private static final String OBJECT_CLASS_ATTRIBUTE = "objectClass";
/**
@@ -459,6 +458,7 @@ public class AmbariLdapDataPopulator {
private Filter getMemberFilter(String memberAttribute) {
String usernameAttribute = ldapServerProperties.getUsernameAttribute();
+ String dnAttribute = ldapServerProperties.getDnAttribute();
OrFilter memberFilter = null;
String[] filters = memberAttribute.split(",");
@@ -468,7 +468,7 @@ public class AmbariLdapDataPopulator {
String lOperand = operands[0];
- if (lOperand.equals(usernameAttribute) || lOperand.equals(UID_ATTRIBUTE) || lOperand.equals(DN_ATTRIBUTE)) {
+ if (lOperand.equals(usernameAttribute) || lOperand.equals(UID_ATTRIBUTE) || lOperand.equals(dnAttribute)) {
if (memberFilter == null) {
memberFilter = new OrFilter();
}
@@ -477,7 +477,7 @@ public class AmbariLdapDataPopulator {
}
}
return memberFilter == null ?
- new OrFilter().or(new EqualsFilter(DN_ATTRIBUTE, memberAttribute)).
+ new OrFilter().or(new EqualsFilter(dnAttribute, memberAttribute)).
or(new EqualsFilter(UID_ATTRIBUTE, memberAttribute)) :
memberFilter;
}
@@ -494,29 +494,7 @@ public class AmbariLdapDataPopulator {
final Set<LdapGroupDto> groups = new HashSet<LdapGroupDto>();
final LdapTemplate ldapTemplate = loadLdapTemplate();
String baseDn = ldapServerProperties.getBaseDN();
- ldapTemplate.search(baseDn, filter.encode(), new ContextMapper() {
-
- @Override
- public Object mapFromContext(Object ctx) {
- final DirContextAdapter adapter = (DirContextAdapter) ctx;
-
- final LdapGroupDto group = new LdapGroupDto();
- final String groupNameAttribute = adapter.getStringAttribute(ldapServerProperties.getGroupNamingAttr());
-
- if (groupNameAttribute != null) {
- group.setGroupName(groupNameAttribute.toLowerCase());
-
- final String[] uniqueMembers = adapter.getStringAttributes(ldapServerProperties.getGroupMembershipAttr());
- if (uniqueMembers != null) {
- for (String uniqueMember: uniqueMembers) {
- group.getMemberAttributes().add(uniqueMember.toLowerCase());
- }
- }
- groups.add(group);
- }
- return null;
- }
- });
+ ldapTemplate.search(baseDn, filter.encode(), new LdapGroupContextMapper(groups, ldapServerProperties));
return groups;
}
@@ -543,26 +521,7 @@ public class AmbariLdapDataPopulator {
final Set<LdapUserDto> users = new HashSet<LdapUserDto>();
final LdapTemplate ldapTemplate = loadLdapTemplate();
String baseDn = ldapServerProperties.getBaseDN();
- ldapTemplate.search(baseDn, filter.encode(), new ContextMapper() {
-
- @Override
- public Object mapFromContext(Object ctx) {
- final LdapUserDto user = new LdapUserDto();
- final DirContextAdapter adapter = (DirContextAdapter) ctx;
- final String usernameAttribute = adapter.getStringAttribute(ldapServerProperties.getUsernameAttribute());
- final String uidAttribute = adapter.getStringAttribute(UID_ATTRIBUTE);
- if (usernameAttribute != null && uidAttribute != null) {
- user.setUserName(usernameAttribute.toLowerCase());
- user.setUid(uidAttribute.toLowerCase());
- user.setDn(adapter.getNameInNamespace().toLowerCase());
- users.add(user);
- } else {
- LOG.warn("Ignoring LDAP user " + adapter.getNameInNamespace() + " as it doesn't have required" +
- " attributes uid and " + ldapServerProperties.getUsernameAttribute());
- }
- return null;
- }
- });
+ ldapTemplate.search(baseDn, filter.encode(), new LdapUserContextMapper(users, ldapServerProperties));
return users;
}
@@ -644,4 +603,66 @@ public class AmbariLdapDataPopulator {
}
return ldapTemplate;
}
+
+ //
+ // ContextMapper implementations
+ //
+
+ protected static class LdapGroupContextMapper implements ContextMapper {
+
+ private final Set<LdapGroupDto> groups;
+ private final LdapServerProperties ldapServerProperties;
+
+ public LdapGroupContextMapper(Set<LdapGroupDto> groups, LdapServerProperties ldapServerProperties) {
+ this.groups = groups;
+ this.ldapServerProperties = ldapServerProperties;
+ }
+
+ @Override
+ public Object mapFromContext(Object ctx) {
+ final DirContextAdapter adapter = (DirContextAdapter) ctx;
+ final String groupNameAttribute = adapter.getStringAttribute(ldapServerProperties.getGroupNamingAttr());
+ if (groupNameAttribute != null) {
+ final LdapGroupDto group = new LdapGroupDto();
+ group.setGroupName(groupNameAttribute.toLowerCase());
+ final String[] uniqueMembers = adapter.getStringAttributes(ldapServerProperties.getGroupMembershipAttr());
+ if (uniqueMembers != null) {
+ for (String uniqueMember: uniqueMembers) {
+ group.getMemberAttributes().add(uniqueMember.toLowerCase());
+ }
+ }
+ groups.add(group);
+ }
+ return null;
+ }
+ }
+
+ protected static class LdapUserContextMapper implements ContextMapper {
+
+ private final Set<LdapUserDto> users;
+ private final LdapServerProperties ldapServerProperties;
+
+ public LdapUserContextMapper(Set<LdapUserDto> users, LdapServerProperties ldapServerProperties) {
+ this.users = users;
+ this.ldapServerProperties = ldapServerProperties;
+ }
+
+ @Override
+ public Object mapFromContext(Object ctx) {
+ final DirContextAdapter adapter = (DirContextAdapter) ctx;
+ final String usernameAttribute = adapter.getStringAttribute(ldapServerProperties.getUsernameAttribute());
+ final String uidAttribute = adapter.getStringAttribute(UID_ATTRIBUTE);
+ if (usernameAttribute != null || uidAttribute != null) {
+ final LdapUserDto user = new LdapUserDto();
+ user.setUserName(usernameAttribute != null ? usernameAttribute.toLowerCase() : null);
+ user.setUid(uidAttribute != null ? uidAttribute.toLowerCase() : null);
+ user.setDn(adapter.getNameInNamespace().toLowerCase());
+ users.add(user);
+ } else {
+ LOG.warn("Ignoring LDAP user " + adapter.getNameInNamespace() + " as it doesn't have required" +
+ " attributes uid and " + ldapServerProperties.getUsernameAttribute());
+ }
+ return null;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index 89caa2e..af27f5f 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -3226,6 +3226,7 @@ def setup_ldap():
"authentication.ldap.groupObjectClass",
"authentication.ldap.groupNamingAttr",
"authentication.ldap.groupMembershipAttr",
+ "authentication.ldap.dnAttribute",
"authentication.ldap.baseDn",
"authentication.ldap.bindAnonymously"]
@@ -3250,8 +3251,9 @@ def setup_ldap():
LDAP_GROUP_CLASS_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[5], "posixGroup")
LDAP_GROUP_ATT_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[6], "cn")
LDAP_GROUP_MEMBER_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[7], "memberUid")
- LDAP_BASE_DN_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[8])
- LDAP_BIND_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[9], "false")
+ LDAP_DN_ATT_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[8], "dn")
+ LDAP_BASE_DN_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[9])
+ LDAP_BIND_DEFAULT = get_value_from_properties(properties, ldap_property_list_reqd[10], "false")
LDAP_MGR_DN_DEFAULT = get_value_from_properties(properties, ldap_property_list_opt[0])
SSL_TRUSTSTORE_TYPE_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_TYPE_PROPERTY, "jks")
SSL_TRUSTSTORE_PATH_DEFAULT = get_value_from_properties(properties, SSL_TRUSTSTORE_PATH_PROPERTY)
@@ -3259,23 +3261,24 @@ def setup_ldap():
ldap_properties_map_reqd =\
{
- ldap_property_list_reqd[0]:(LDAP_PRIMARY_URL_DEFAULT, "Primary URL* {{host:port}} {0}: ".format(get_prompt_default(LDAP_PRIMARY_URL_DEFAULT)), False),\
- ldap_property_list_reqd[1]:(LDAP_SECONDARY_URL_DEFAULT, "Secondary URL {{host:port}} {0}: ".format(get_prompt_default(LDAP_SECONDARY_URL_DEFAULT)), True),\
- ldap_property_list_reqd[2]:(LDAP_USE_SSL_DEFAULT, "Use SSL* [true/false] {0}: ".format(get_prompt_default(LDAP_USE_SSL_DEFAULT)), False),\
- ldap_property_list_reqd[3]:(LDAP_USER_CLASS_DEFAULT, "User object class* {0}: ".format(get_prompt_default(LDAP_USER_CLASS_DEFAULT)), False),\
- ldap_property_list_reqd[4]:(LDAP_USER_ATT_DEFAULT, "User name attribute* {0}: ".format(get_prompt_default(LDAP_USER_ATT_DEFAULT)), False),\
- ldap_property_list_reqd[5]:(LDAP_GROUP_CLASS_DEFAULT, "Group object class* {0}: ".format(get_prompt_default(LDAP_GROUP_CLASS_DEFAULT)), False),\
- ldap_property_list_reqd[6]:(LDAP_GROUP_ATT_DEFAULT, "Group name attribute* {0}: ".format(get_prompt_default(LDAP_GROUP_ATT_DEFAULT)), False),\
- ldap_property_list_reqd[7]:(LDAP_GROUP_MEMBER_DEFAULT, "Group member attribute* {0}: ".format(get_prompt_default(LDAP_GROUP_MEMBER_DEFAULT)), False),\
- ldap_property_list_reqd[8]:(LDAP_BASE_DN_DEFAULT, "Base DN* {0}: ".format(get_prompt_default(LDAP_BASE_DN_DEFAULT)), False),\
- ldap_property_list_reqd[9]:(LDAP_BIND_DEFAULT, "Bind anonymously* [true/false] {0}: ".format(get_prompt_default(LDAP_BIND_DEFAULT)), False),\
+ ldap_property_list_reqd[0]:(LDAP_PRIMARY_URL_DEFAULT, "Primary URL* {{host:port}} {0}: ".format(get_prompt_default(LDAP_PRIMARY_URL_DEFAULT)), False),
+ ldap_property_list_reqd[1]:(LDAP_SECONDARY_URL_DEFAULT, "Secondary URL {{host:port}} {0}: ".format(get_prompt_default(LDAP_SECONDARY_URL_DEFAULT)), True),
+ ldap_property_list_reqd[2]:(LDAP_USE_SSL_DEFAULT, "Use SSL* [true/false] {0}: ".format(get_prompt_default(LDAP_USE_SSL_DEFAULT)), False),
+ ldap_property_list_reqd[3]:(LDAP_USER_CLASS_DEFAULT, "User object class* {0}: ".format(get_prompt_default(LDAP_USER_CLASS_DEFAULT)), False),
+ ldap_property_list_reqd[4]:(LDAP_USER_ATT_DEFAULT, "User name attribute* {0}: ".format(get_prompt_default(LDAP_USER_ATT_DEFAULT)), False),
+ ldap_property_list_reqd[5]:(LDAP_GROUP_CLASS_DEFAULT, "Group object class* {0}: ".format(get_prompt_default(LDAP_GROUP_CLASS_DEFAULT)), False),
+ ldap_property_list_reqd[6]:(LDAP_GROUP_ATT_DEFAULT, "Group name attribute* {0}: ".format(get_prompt_default(LDAP_GROUP_ATT_DEFAULT)), False),
+ ldap_property_list_reqd[7]:(LDAP_GROUP_MEMBER_DEFAULT, "Group member attribute* {0}: ".format(get_prompt_default(LDAP_GROUP_MEMBER_DEFAULT)), False),
+ ldap_property_list_reqd[8]:(LDAP_DN_ATT_DEFAULT, "Distinguished name attribute* {0}: ".format(get_prompt_default(LDAP_DN_ATT_DEFAULT)), False),
+ ldap_property_list_reqd[9]:(LDAP_BASE_DN_DEFAULT, "Base DN* {0}: ".format(get_prompt_default(LDAP_BASE_DN_DEFAULT)), False),
+ ldap_property_list_reqd[10]:(LDAP_BIND_DEFAULT, "Bind anonymously* [true/false] {0}: ".format(get_prompt_default(LDAP_BIND_DEFAULT)), False),
}
ldap_property_value_map = {}
for idx, key in enumerate(ldap_property_list_reqd):
if idx in [0, 1]:
pattern = REGEX_HOSTNAME_PORT
- elif idx in [2, 9]:
+ elif idx in [2, 10]:
pattern = REGEX_TRUE_FALSE
else:
pattern = REGEX_ANYTHING
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
index fc399ac..ea5570e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
@@ -45,6 +45,7 @@ import org.easymock.IAnswer;
import org.junit.Test;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.core.LdapTemplate;
import static junit.framework.Assert.*;
@@ -1417,6 +1418,7 @@ public class AmbariLdapDataPopulatorTest {
expect(configuration.getLdapServerProperties()).andReturn(ldapServerProperties).anyTimes();
expect(ldapServerProperties.getUserObjectClass()).andReturn("objectClass").anyTimes();
+ expect(ldapServerProperties.getDnAttribute()).andReturn("dn").anyTimes();
expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes();
expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(|(dn=foo)(uid=foo)))"), capture(contextMapperCapture))).andReturn(list);
@@ -1434,6 +1436,67 @@ public class AmbariLdapDataPopulatorTest {
verify(ldapTemplate, ldapServerProperties, users, configuration);
}
+ @Test
+ public void testLdapUserContextMapper_uidIsNull() throws Exception {
+ LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
+ expect(ldapServerProperties.getUsernameAttribute()).andReturn("cn").once();
+ DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
+ expect(adapter.getStringAttribute("cn")).andReturn("testUser");
+ expect(adapter.getStringAttribute("uid")).andReturn(null);
+ expect(adapter.getNameInNamespace()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com");
+
+ replay(ldapServerProperties, adapter);
+
+ Set<LdapUserDto> userResultSet = new HashSet<LdapUserDto>();
+ AmbariLdapDataPopulator.LdapUserContextMapper ldapUserContextMapper = new AmbariLdapDataPopulator.LdapUserContextMapper(userResultSet, ldapServerProperties);
+ ldapUserContextMapper.mapFromContext(adapter);
+
+ assertEquals(1, userResultSet.size());
+ LdapUserDto userDto = userResultSet.iterator().next();
+ assertNull(userDto.getUid());
+ assertEquals("testuser", userDto.getUserName());
+ assertEquals("cn=testuser,ou=ambari,dc=sme,dc=support,dc=com", userDto.getDn());
+ }
+
+ @Test
+ public void testLdapUserContextMapper_uidAndUsernameAreNull() throws Exception {
+ LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
+ expect(ldapServerProperties.getUsernameAttribute()).andReturn("cn").once();
+ DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
+ expect(adapter.getStringAttribute("cn")).andReturn(null);
+ expect(adapter.getStringAttribute("uid")).andReturn(null);
+
+ replay(ldapServerProperties, adapter);
+
+ Set<LdapUserDto> userResultSet = new HashSet<LdapUserDto>();
+ AmbariLdapDataPopulator.LdapUserContextMapper ldapUserContextMapper = new AmbariLdapDataPopulator.LdapUserContextMapper(userResultSet, ldapServerProperties);
+ ldapUserContextMapper.mapFromContext(adapter);
+
+ assertEquals(0, userResultSet.size());
+ }
+
+ @Test
+ public void testLdapUserContextMapper() throws Exception {
+ LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
+ expect(ldapServerProperties.getUsernameAttribute()).andReturn("cn").once();
+ DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
+ expect(adapter.getStringAttribute("cn")).andReturn("testUser");
+ expect(adapter.getStringAttribute("uid")).andReturn("UID1");
+ expect(adapter.getNameInNamespace()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com");
+
+ replay(ldapServerProperties, adapter);
+
+ Set<LdapUserDto> userResultSet = new HashSet<LdapUserDto>();
+ AmbariLdapDataPopulator.LdapUserContextMapper ldapUserContextMapper = new AmbariLdapDataPopulator.LdapUserContextMapper(userResultSet, ldapServerProperties);
+ ldapUserContextMapper.mapFromContext(adapter);
+
+ assertEquals(1, userResultSet.size());
+ LdapUserDto userDto = userResultSet.iterator().next();
+ assertEquals("uid1", userDto.getUid());
+ assertEquals("testuser", userDto.getUserName());
+ assertEquals("cn=testuser,ou=ambari,dc=sme,dc=support,dc=com", userDto.getDn());
+ }
+
private static int userIdCounter = 1;
private User createUser(String name, boolean ldapUser, GroupEntity group) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d7a293bf/ambari-server/src/test/python/TestAmbariServer.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestAmbariServer.py b/ambari-server/src/test/python/TestAmbariServer.py
index 0eae33b..9290558 100644
--- a/ambari-server/src/test/python/TestAmbariServer.py
+++ b/ambari-server/src/test/python/TestAmbariServer.py
@@ -4672,7 +4672,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
}
get_ambari_properties_method.return_value = configs
- raw_input_mock.side_effect = ['a:3', 'b:b', 'hody', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'base', 'true']
+ raw_input_mock.side_effect = ['a:3', 'b:b', 'hody', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'true']
ambari_server.SILENT = False
get_YN_input_method.return_value = True
@@ -4688,6 +4688,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
"authentication.ldap.groupObjectClass": "group",
"authentication.ldap.groupNamingAttr": "cn",
"authentication.ldap.groupMembershipAttr": "member",
+ "authentication.ldap.dnAttribute": "dn",
"authentication.ldap.baseDn": "base",
"authentication.ldap.bindAnonymously": "true",
"client.security": "ldap",
@@ -4702,7 +4703,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
self.assertTrue(8, raw_input_mock.call_count)
raw_input_mock.reset_mock()
- raw_input_mock.side_effect = ['a:3', '', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'base', 'true']
+ raw_input_mock.side_effect = ['a:3', '', 'b:2', 'false', 'user', 'uid', 'group', 'cn', 'member', 'dn', 'base', 'true']
ambari_server.setup_ldap()
@@ -4715,6 +4716,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
"authentication.ldap.groupObjectClass": "group",
"authentication.ldap.groupNamingAttr": "cn",
"authentication.ldap.groupMembershipAttr": "member",
+ "authentication.ldap.dnAttribute": "dn",
"authentication.ldap.baseDn": "base",
"authentication.ldap.bindAnonymously": "true",
"client.security": "ldap",
@@ -4813,6 +4815,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
"authentication.ldap.groupObjectClass": "test",
"authentication.ldap.groupMembershipAttr": "test",
"authentication.ldap.groupNamingAttr": "test",
+ "authentication.ldap.dnAttribute": "test",
"client.security": "ldap", \
ambari_server.LDAP_MGR_PASSWORD_PROPERTY: "ldap-password.dat",
"ambari.ldap.isConfigured": "true"
@@ -4873,6 +4876,7 @@ MIIFHjCCAwYCCQDpHKOBI+Lt0zANBgkqhkiG9w0BAQUFADBRMQswCQYDVQQGEwJV
"authentication.ldap.useSSL": "true",
"authentication.ldap.usernameAttribute": "test",
"authentication.ldap.baseDn": "test",
+ "authentication.ldap.dnAttribute": "test",
"authentication.ldap.bindAnonymously": "false",
"authentication.ldap.managerDn": "test",
"client.security": "ldap",
[2/2] ambari git commit: AMBARI-9012. Add Nagios-SNMP contrib to
Ambari. (Cabir Zounaidou via mahadev)
Posted by ma...@apache.org.
AMBARI-9012. Add Nagios-SNMP contrib to Ambari. (Cabir Zounaidou via mahadev)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6b1eef55
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6b1eef55
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6b1eef55
Branch: refs/heads/trunk
Commit: 6b1eef55ec692db337233c8f676b8725eae10652
Parents: d7a293b
Author: Mahadev Konar <ma...@apache.org>
Authored: Wed Jan 7 15:55:52 2015 -0800
Committer: Mahadev Konar <ma...@apache.org>
Committed: Wed Jan 7 15:55:52 2015 -0800
----------------------------------------------------------------------
contrib/nagios-snmp/README.md | 99 ++++++++++++++++++++
.../src/nagios/objects/snmp-commands.cfg | 33 +++++++
.../src/nagios/objects/snmp-contacts.cfg | 31 ++++++
contrib/nagios-snmp/src/scripts/send-host-trap | 29 ++++++
.../nagios-snmp/src/scripts/send-service-trap | 30 ++++++
5 files changed, 222 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6b1eef55/contrib/nagios-snmp/README.md
----------------------------------------------------------------------
diff --git a/contrib/nagios-snmp/README.md b/contrib/nagios-snmp/README.md
new file mode 100644
index 0000000..dd76f46
--- /dev/null
+++ b/contrib/nagios-snmp/README.md
@@ -0,0 +1,99 @@
+<!--
+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](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.
+-->
+
+Ambari Server integration with SNMP traps
+=========================================
+Ambari uses nagios to manage alerts in the cluster. When a node goes down or a service state changes in the cluster, nagios
+will handle those events and is monitored using Ambari-web. This document describes how to integrate alerts with remote
+SNMP management station by sending SNMP traps. By enabling SNMP traps, Ambari & Hadoop cluster alerts can be monitored
+using remote management station (like OpenNMS, HP OpenView, etc.,).
+
+ This will work with Ambari Server 1.7.0 and below. In Ambari 2.0.0, this feature will be
+ replaced by alert framework.
+
+Prerequisites:
+--------------
+1. Nagios server should be running in one of the hadoop cluster node. (Need not to be same node as Ambari server).
+2. SNMP should be installed in the node where nagios server is running. Run the following command to install net-snmp
+and net-snmp-utils.
+> yum install net-snmp net-snmp-utils net-snmp-devel
+3. There should be connectivity between the hadoop node running nagios server and the management station. The snmptrap
+command will use 162/udp to send trap to the management station.
+
+Instructions:
+-------------
+1. Copy the file src/nagios/objects/snmp-commands.cfg to {nagios\_home\_dir}/objects/snmp-commands.cfg in the node where nagios is running.
+This file defines the command to send traps for service and host failures.
+
+ The default home directory (nagios_home_dir) for nagios is /etc/nagios
+
+2. Copy the file src/nagios/objects/snmp-contacts.cfg to {nagios\_home\_dir}/objects/snmp-contacts.cfg in the node where nagios is running.
+This file defines the **snmp-management-station** contact.
+
+3. In the node where ambari-server is running, edit file /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/nagios.cfg.j2
+and add below lines just before the {{nagios\_host\_cfg}}
+
+ <pre><code>#Definitions for SNMP traps
+ cfg_file=/etc/nagios/objects/snmp-commands.cfg
+ cfg_file=/etc/nagios/objects/snmp-contacts.cfg</code></pre>
+
+ Note: If the home directory is different than /etc/nagios, use the updated home directory. The updated configuration will be automatically
+ pushed to the nagios server when ambari-server restarted.
+
+4. To enable SNMP trap, edit file /var/lib/ambari-server/resources/stacks/HDP/2.0.6/services/NAGIOS/package/templates/contacts.cfg.j2
+in the ambari-server and add **snmp-management-station** to the contract group **admins**
+
+ > members {{nagios\_web\_login}},sys_logger,**snmp-management-station**
+
+5. Copy the file src/scripts/send-service-trap to /usr/local/bin/send-service-trap in the node where nagios is running.
+Also, run the following command
+
+ > chmod +x /usr/local/bin/send-service-trap
+
+ > chown nagios:nagios /usr/local/bin/send-service-trap
+
+6. Copy the file src/scripts/send-host-trap to /usr/local/bin/send-host-trap in the node where nagios is running.
+Also, run the following command
+
+ > chmod +x /usr/local/bin/send-service-trap
+
+ > chown nagios:nagios /usr/local/bin/send-service-trap
+
+7. Download nagios MIBS from *http://ftp.cc.uoc.gr/mirrors/monitoring-plugins/mib/nagiosmib-1.0.0.tar.gz* and
+extract the files to /usr/share/snmp/mibs/ directory.
+
+8. Restart ambari-server
+ > ambari-server restart
+
+9. Launch ambari-web (or GUI) in the browser and login. Select Nagios server and restart the service.
+
+10. Configure management station by editing file /etc/hosts and add the below line
+
+ <MGMT_STATION_IP> snmp-manager
+
+11. For integrating with existing management station or NMS system,
+ 1. Download the nagios MIB's from *http://ftp.cc.uoc.gr/mirrors/monitoring-plugins/mib/nagiosmib-1.0.0.tar.gz*
+ 2. Extract and copy the files under MIB directory of the management station's (or NMS) mib directory.
+ 3. Import the mibs if required.
+
+Testing:
+-------
+To test whether the snmptraps are triggered, use the following procedure.
+
+1. Load the MIB in the snmp management system.
+2. Make sure the snmp management system IP (or FQDN) is configured in the /etc/hosts file in the node where
+nagios server is running.
+3. Open the ambari-web in the browser and login. Try to stop some services from ambari-web and check the snmptraps
+are received by the snmp management station.
http://git-wip-us.apache.org/repos/asf/ambari/blob/6b1eef55/contrib/nagios-snmp/src/nagios/objects/snmp-commands.cfg
----------------------------------------------------------------------
diff --git a/contrib/nagios-snmp/src/nagios/objects/snmp-commands.cfg b/contrib/nagios-snmp/src/nagios/objects/snmp-commands.cfg
new file mode 100644
index 0000000..81087bf
--- /dev/null
+++ b/contrib/nagios-snmp/src/nagios/objects/snmp-commands.cfg
@@ -0,0 +1,33 @@
+#
+#
+# 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.
+#
+#
+#
+
+# 'send-service-trap' command definition
+define command {
+ command_name send-service-trap
+ command_line /usr/local/bin/send-service-trap snmp-manager public "$HOSTNAME$" "$SERVICEDESC$" $SERVICESTATEID$ "$SERVICEOUTPUT$"
+}
+
+# 'send-host-trap' command definition
+define command {
+ command_name send-host-trap
+ command_line /usr/local/bin/send-host-trap snmp-manager public "$HOSTNAME$" $HOSTSTATEID$ "$HOSTOUTPUT$"
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6b1eef55/contrib/nagios-snmp/src/nagios/objects/snmp-contacts.cfg
----------------------------------------------------------------------
diff --git a/contrib/nagios-snmp/src/nagios/objects/snmp-contacts.cfg b/contrib/nagios-snmp/src/nagios/objects/snmp-contacts.cfg
new file mode 100644
index 0000000..cf44858
--- /dev/null
+++ b/contrib/nagios-snmp/src/nagios/objects/snmp-contacts.cfg
@@ -0,0 +1,31 @@
+#
+#
+# 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.
+#
+#
+#
+
+define contact {
+ contact_name snmp-management-station
+ use generic-contact
+ alias Management Station
+ service_notification_options w,u,c,r
+ host_notification_options d,u,r
+ service_notification_commands send-service-trap
+ host_notification_commands send-host-trap
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/6b1eef55/contrib/nagios-snmp/src/scripts/send-host-trap
----------------------------------------------------------------------
diff --git a/contrib/nagios-snmp/src/scripts/send-host-trap b/contrib/nagios-snmp/src/scripts/send-host-trap
new file mode 100644
index 0000000..388cc6f
--- /dev/null
+++ b/contrib/nagios-snmp/src/scripts/send-host-trap
@@ -0,0 +1,29 @@
+#!/bin/sh
+# 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
+
+#
+# Inputs:
+# $1 - Management station host name (example: snmp-manager).
+# $2 - Community string (example: public, default, etc.,).
+# $3 - Host name where the trap originated.
+# $4 - Current state of the host (0=UP, 1=DOWN, 2=UNREACHABLE)
+# $5 - Host specific description
+#
+# For more details, refer to NAGIOS-ROOT-MIB.txt and NAGIOS-NOTIFY-MIB.txt
+#
+
+# Sending trap to the management station
+/usr/bin/snmptrap -v 2c -c $2 $1 '' NAGIOS-NOTIFY-MIB::nHostEvent nHostname s "$3" nHostStateID i $4 nHostOutput s "$5"
http://git-wip-us.apache.org/repos/asf/ambari/blob/6b1eef55/contrib/nagios-snmp/src/scripts/send-service-trap
----------------------------------------------------------------------
diff --git a/contrib/nagios-snmp/src/scripts/send-service-trap b/contrib/nagios-snmp/src/scripts/send-service-trap
new file mode 100644
index 0000000..fc7ffe4
--- /dev/null
+++ b/contrib/nagios-snmp/src/scripts/send-service-trap
@@ -0,0 +1,30 @@
+#!/bin/sh
+# 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
+
+#
+# Inputs:
+# $1 - Management station host name (example: snmp-manager).
+# $2 - Community string (example: public, default, etc.,).
+# $3 - Host name where the trap originated.
+# $4 - Description of the service.
+# $5 - Severity ( 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN).
+# $6 - Service specific description.
+#
+# For more details, refer to NAGIOS-ROOT-MIB.txt and NAGIOS-NOTIFY-MIB.txt
+#
+
+# Sending trap to the management station
+/usr/bin/snmptrap -v 2c -c $2 $1 '' NAGIOS-NOTIFY-MIB::nSvcEvent nSvcHostname s "$3" nSvcDesc s "$4" nSvcStateID i $5 nSvcOutput s "$6"