YARN-7777. Fix user name format in YARN Registry DNS name. Contributed by Jian He
This commit is contained in:
parent
fa8cf4d1b4
commit
0c559b2782
@ -392,14 +392,9 @@ private void initGlobalTokensForSubstitute(ServiceContext context) {
|
|||||||
// ZK
|
// ZK
|
||||||
globalTokens.put(ServiceApiConstants.CLUSTER_ZK_QUORUM, getConfig()
|
globalTokens.put(ServiceApiConstants.CLUSTER_ZK_QUORUM, getConfig()
|
||||||
.getTrimmed(KEY_REGISTRY_ZK_QUORUM, DEFAULT_REGISTRY_ZK_QUORUM));
|
.getTrimmed(KEY_REGISTRY_ZK_QUORUM, DEFAULT_REGISTRY_ZK_QUORUM));
|
||||||
String user = null;
|
String user = RegistryUtils.currentUser();
|
||||||
try {
|
globalTokens.put(SERVICE_ZK_PATH,
|
||||||
user = UserGroupInformation.getCurrentUser().getShortUserName();
|
ServiceRegistryUtils.mkServiceHomePath(user, app.getName()));
|
||||||
} catch (IOException e) {
|
|
||||||
LOG.error("Failed to get user.", e);
|
|
||||||
}
|
|
||||||
globalTokens
|
|
||||||
.put(SERVICE_ZK_PATH, ServiceRegistryUtils.mkServiceHomePath(user, app.getName()));
|
|
||||||
|
|
||||||
globalTokens.put(ServiceApiConstants.USER, user);
|
globalTokens.put(ServiceApiConstants.USER, user);
|
||||||
String dnsDomain = getConfig().getTrimmed(KEY_DNS_DOMAIN);
|
String dnsDomain = getConfig().getTrimmed(KEY_DNS_DOMAIN);
|
||||||
|
@ -61,6 +61,9 @@ public class ServiceApiUtil {
|
|||||||
private static final PatternValidator namePattern
|
private static final PatternValidator namePattern
|
||||||
= new PatternValidator("[a-z][a-z0-9-]*");
|
= new PatternValidator("[a-z][a-z0-9-]*");
|
||||||
|
|
||||||
|
private static final PatternValidator userNamePattern
|
||||||
|
= new PatternValidator("[a-z][a-z0-9-.]*");
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static void setJsonSerDeser(JsonSerDeser jsd) {
|
public static void setJsonSerDeser(JsonSerDeser jsd) {
|
||||||
jsonSerDeser = jsd;
|
jsonSerDeser = jsd;
|
||||||
@ -72,11 +75,15 @@ public static void validateAndResolveService(Service service,
|
|||||||
IOException {
|
IOException {
|
||||||
boolean dnsEnabled = conf.getBoolean(RegistryConstants.KEY_DNS_ENABLED,
|
boolean dnsEnabled = conf.getBoolean(RegistryConstants.KEY_DNS_ENABLED,
|
||||||
RegistryConstants.DEFAULT_DNS_ENABLED);
|
RegistryConstants.DEFAULT_DNS_ENABLED);
|
||||||
if (dnsEnabled && RegistryUtils.currentUser().length() > RegistryConstants
|
if (dnsEnabled) {
|
||||||
.MAX_FQDN_LABEL_LENGTH) {
|
if (RegistryUtils.currentUser().length()
|
||||||
throw new IllegalArgumentException(RestApiErrorMessages
|
> RegistryConstants.MAX_FQDN_LABEL_LENGTH) {
|
||||||
.ERROR_USER_NAME_INVALID);
|
throw new IllegalArgumentException(
|
||||||
|
RestApiErrorMessages.ERROR_USER_NAME_INVALID);
|
||||||
}
|
}
|
||||||
|
userNamePattern.validate(RegistryUtils.currentUser());
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isEmpty(service.getName())) {
|
if (StringUtils.isEmpty(service.getName())) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
RestApiErrorMessages.ERROR_APPLICATION_NAME_INVALID);
|
RestApiErrorMessages.ERROR_APPLICATION_NAME_INVALID);
|
||||||
|
@ -24,11 +24,13 @@
|
|||||||
import org.apache.hadoop.fs.PathNotFoundException;
|
import org.apache.hadoop.fs.PathNotFoundException;
|
||||||
import org.apache.hadoop.registry.client.exceptions.InvalidPathnameException;
|
import org.apache.hadoop.registry.client.exceptions.InvalidPathnameException;
|
||||||
import org.apache.hadoop.registry.client.impl.zk.RegistryInternalConstants;
|
import org.apache.hadoop.registry.client.impl.zk.RegistryInternalConstants;
|
||||||
|
import org.apache.hadoop.registry.server.dns.BaseServiceRecordProcessor;
|
||||||
import org.apache.zookeeper.common.PathUtils;
|
import org.apache.zookeeper.common.PathUtils;
|
||||||
|
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,6 +47,9 @@ public class RegistryPathUtils {
|
|||||||
private static final Pattern PATH_ENTRY_VALIDATION_PATTERN =
|
private static final Pattern PATH_ENTRY_VALIDATION_PATTERN =
|
||||||
Pattern.compile(RegistryInternalConstants.VALID_PATH_ENTRY_PATTERN);
|
Pattern.compile(RegistryInternalConstants.VALID_PATH_ENTRY_PATTERN);
|
||||||
|
|
||||||
|
private static final Pattern USER_NAME =
|
||||||
|
Pattern.compile("/users/([a-z][a-z0-9-.]*)");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate ZK path with the path itself included in
|
* Validate ZK path with the path itself included in
|
||||||
* the exception text
|
* the exception text
|
||||||
@ -215,4 +220,19 @@ public static String encodeForRegistry(String element) {
|
|||||||
public static String encodeYarnID(String yarnId) {
|
public static String encodeYarnID(String yarnId) {
|
||||||
return yarnId.replace("container", "ctr").replace("_", "-");
|
return yarnId.replace("container", "ctr").replace("_", "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the username found in the ZK path.
|
||||||
|
*
|
||||||
|
* @param recPath the ZK recPath.
|
||||||
|
* @return the user name.
|
||||||
|
*/
|
||||||
|
public static String getUsername(String recPath) {
|
||||||
|
String user = "anonymous";
|
||||||
|
Matcher matcher = USER_NAME.matcher(recPath);
|
||||||
|
if (matcher.find()) {
|
||||||
|
user = matcher.group(1);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,10 @@ public static String getCurrentUsernameUnencoded(String env_hadoop_username) {
|
|||||||
*/
|
*/
|
||||||
public static String currentUser() {
|
public static String currentUser() {
|
||||||
String shortUserName = currentUsernameUnencoded();
|
String shortUserName = currentUsernameUnencoded();
|
||||||
return encodeForRegistry(shortUserName);
|
String encodedName = encodeForRegistry(shortUserName);
|
||||||
|
// DNS name doesn't allow "_", replace it with "-"
|
||||||
|
encodedName = RegistryUtils.convertUsername(encodedName);
|
||||||
|
return encodedName.replace("_", "-");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides common service record processing logic.
|
* Provides common service record processing logic.
|
||||||
@ -51,7 +49,6 @@ public abstract class BaseServiceRecordProcessor
|
|||||||
private String path;
|
private String path;
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
private static final Pattern USER_NAME = Pattern.compile("/users/(\\w*)/?");
|
|
||||||
private static final String YARN_SERVICE_API_PREFIX =
|
private static final String YARN_SERVICE_API_PREFIX =
|
||||||
"classpath:org.apache.hadoop.yarn.service.";
|
"classpath:org.apache.hadoop.yarn.service.";
|
||||||
private static final String HTTP_API_TYPE = "http://";
|
private static final String HTTP_API_TYPE = "http://";
|
||||||
@ -75,21 +72,6 @@ public BaseServiceRecordProcessor(ServiceRecord record, String path,
|
|||||||
initTypeToInfoMapping(record);
|
initTypeToInfoMapping(record);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the username found in the ZK path.
|
|
||||||
*
|
|
||||||
* @param recPath the ZK recPath.
|
|
||||||
* @return the user name.
|
|
||||||
*/
|
|
||||||
protected String getUsername(String recPath) {
|
|
||||||
String user = "anonymous";
|
|
||||||
Matcher matcher = USER_NAME.matcher(recPath);
|
|
||||||
if (matcher.find()) {
|
|
||||||
user = matcher.group(1);
|
|
||||||
}
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the IPv6 mapped address for the provided IPv4 address. Utilized
|
* Return the IPv6 mapped address for the provided IPv4 address. Utilized
|
||||||
* to create corresponding AAAA records.
|
* to create corresponding AAAA records.
|
||||||
@ -300,7 +282,7 @@ protected Name getContainerName()
|
|||||||
String service = RegistryPathUtils.lastPathEntry(
|
String service = RegistryPathUtils.lastPathEntry(
|
||||||
RegistryPathUtils.parentOf(RegistryPathUtils.parentOf(getPath())));
|
RegistryPathUtils.parentOf(RegistryPathUtils.parentOf(getPath())));
|
||||||
String description = getRecord().description.toLowerCase();
|
String description = getRecord().description.toLowerCase();
|
||||||
String user = getUsername(getPath());
|
String user = RegistryPathUtils.getUsername(getPath());
|
||||||
return Name.fromString(MessageFormat.format("{0}.{1}.{2}.{3}",
|
return Name.fromString(MessageFormat.format("{0}.{1}.{2}.{3}",
|
||||||
description,
|
description,
|
||||||
service,
|
service,
|
||||||
@ -352,7 +334,7 @@ public ApplicationRecordDescriptor(ServiceRecord record,
|
|||||||
* @throws TextParseException
|
* @throws TextParseException
|
||||||
*/
|
*/
|
||||||
protected Name getServiceName() throws TextParseException {
|
protected Name getServiceName() throws TextParseException {
|
||||||
String user = getUsername(getPath());
|
String user = RegistryPathUtils.getUsername(getPath());
|
||||||
String service =
|
String service =
|
||||||
String.format("%s.%s.%s",
|
String.format("%s.%s.%s",
|
||||||
RegistryPathUtils.lastPathEntry(getPath()),
|
RegistryPathUtils.lastPathEntry(getPath()),
|
||||||
|
@ -80,7 +80,15 @@ public void testPaths() throws Throwable {
|
|||||||
assertCreatedPathEquals("/alice", "/alice", "/");
|
assertCreatedPathEquals("/alice", "/alice", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUserFromPath() throws Exception {
|
||||||
|
assertEquals("bob", RegistryPathUtils
|
||||||
|
.getUsername("/registry/users/bob/services/yarn-service/test1/"));
|
||||||
|
assertEquals("bob-dev", RegistryPathUtils
|
||||||
|
.getUsername("/registry/users/bob-dev/services/yarn-service/test1"));
|
||||||
|
assertEquals("bob.dev", RegistryPathUtils
|
||||||
|
.getUsername("/registry/users/bob.dev/services/yarn-service/test1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -155,7 +155,7 @@ where `regionserver-0` is the actual component instance name assigned by the sys
|
|||||||
| Name | Description |
|
| Name | Description |
|
||||||
| ------------ | ------------- |
|
| ------------ | ------------- |
|
||||||
| SERVICE_NAME | name of the service defined by the user
|
| SERVICE_NAME | name of the service defined by the user
|
||||||
| USER | user who submits the service |
|
| USER | user who submits the service. Note that user name which has "\_" will be converted to use "-", to conform with DNS hostname RFC format which doesn't allow "\_", and all characters will be lowercased E.g. "Bob_dev" will be converted to "bob-dev" |
|
||||||
| DOMAIN | the domain name for the cluster |
|
| DOMAIN | the domain name for the cluster |
|
||||||
| COMPONENT_NAME | the name for a given component |
|
| COMPONENT_NAME | the name for a given component |
|
||||||
| COMPONENT_INSTANCE_NAME | the name for a given component instance (i.e. container) |
|
| COMPONENT_INSTANCE_NAME | the name for a given component instance (i.e. container) |
|
||||||
|
Loading…
Reference in New Issue
Block a user