use of org.apache.hadoop.yarn.server.security.MasterKeyData in project hadoop by apache.
the class NMContainerTokenSecretManager method setMasterKey.
/**
* Used by NodeManagers to create a token-secret-manager with the key obtained
* from the RM. This can happen during registration or when the RM rolls the
* master-key and signals the NM.
*
* @param masterKeyRecord
*/
@Private
public synchronized void setMasterKey(MasterKey masterKeyRecord) {
// Update keys only if the key has changed.
if (super.currentMasterKey == null || super.currentMasterKey.getMasterKey().getKeyId() != masterKeyRecord.getKeyId()) {
LOG.info("Rolling master-key for container-tokens, got key with id " + masterKeyRecord.getKeyId());
if (super.currentMasterKey != null) {
updatePreviousMasterKey(super.currentMasterKey);
}
updateCurrentMasterKey(new MasterKeyData(masterKeyRecord, createSecretKey(masterKeyRecord.getBytes().array())));
}
}
use of org.apache.hadoop.yarn.server.security.MasterKeyData in project hadoop by apache.
the class NMContainerTokenSecretManager method recover.
public synchronized void recover() throws IOException {
RecoveredContainerTokensState state = stateStore.loadContainerTokensState();
MasterKey key = state.getCurrentMasterKey();
if (key != null) {
super.currentMasterKey = new MasterKeyData(key, createSecretKey(key.getBytes().array()));
}
key = state.getPreviousMasterKey();
if (key != null) {
previousMasterKey = new MasterKeyData(key, createSecretKey(key.getBytes().array()));
}
// restore the serial number from the current master key
if (super.currentMasterKey != null) {
super.serialNo = super.currentMasterKey.getMasterKey().getKeyId() + 1;
}
for (Entry<ContainerId, Long> entry : state.getActiveTokens().entrySet()) {
ContainerId containerId = entry.getKey();
Long expTime = entry.getValue();
List<ContainerId> containerList = recentlyStartedContainerTracker.get(expTime);
if (containerList == null) {
containerList = new ArrayList<ContainerId>();
recentlyStartedContainerTracker.put(expTime, containerList);
}
if (!containerList.contains(containerId)) {
containerList.add(containerId);
}
}
}
use of org.apache.hadoop.yarn.server.security.MasterKeyData in project hadoop by apache.
the class NMTokenSecretManagerInNM method appAttemptStartContainer.
/**
* This will be called by startContainer. It will add the master key into
* the cache used for starting this container. This should be called before
* validating the startContainer request.
*/
public synchronized void appAttemptStartContainer(NMTokenIdentifier identifier) throws org.apache.hadoop.security.token.SecretManager.InvalidToken {
ApplicationAttemptId appAttemptId = identifier.getApplicationAttemptId();
if (!appToAppAttemptMap.containsKey(appAttemptId.getApplicationId())) {
// First application attempt for the given application
appToAppAttemptMap.put(appAttemptId.getApplicationId(), new ArrayList<ApplicationAttemptId>());
}
MasterKeyData oldKey = oldMasterKeys.get(appAttemptId);
if (oldKey == null) {
// This is a new application attempt.
appToAppAttemptMap.get(appAttemptId.getApplicationId()).add(appAttemptId);
}
if (oldKey == null || oldKey.getMasterKey().getKeyId() != identifier.getKeyId()) {
// Update key only if it is modified.
if (LOG.isDebugEnabled()) {
LOG.debug("NMToken key updated for application attempt : " + identifier.getApplicationAttemptId().toString());
}
if (identifier.getKeyId() == currentMasterKey.getMasterKey().getKeyId()) {
updateAppAttemptKey(appAttemptId, currentMasterKey);
} else if (previousMasterKey != null && identifier.getKeyId() == previousMasterKey.getMasterKey().getKeyId()) {
updateAppAttemptKey(appAttemptId, previousMasterKey);
} else {
throw new InvalidToken("Older NMToken should not be used while starting the container.");
}
}
}
use of org.apache.hadoop.yarn.server.security.MasterKeyData in project hadoop by apache.
the class ApplicationMasterService method allocate.
@Override
public AllocateResponse allocate(AllocateRequest request) throws YarnException, IOException {
AMRMTokenIdentifier amrmTokenIdentifier = YarnServerSecurityUtils.authorizeRequest();
ApplicationAttemptId appAttemptId = amrmTokenIdentifier.getApplicationAttemptId();
this.amLivelinessMonitor.receivedPing(appAttemptId);
/* check if its in cache */
AllocateResponseLock lock = responseMap.get(appAttemptId);
if (lock == null) {
String message = "Application attempt " + appAttemptId + " doesn't exist in ApplicationMasterService cache.";
LOG.error(message);
throw new ApplicationAttemptNotFoundException(message);
}
synchronized (lock) {
AllocateResponse lastResponse = lock.getAllocateResponse();
if (!hasApplicationMasterRegistered(appAttemptId)) {
String message = "AM is not registered for known application attempt: " + appAttemptId + " or RM had restarted after AM registered. " + " AM should re-register.";
throw new ApplicationMasterNotRegisteredException(message);
}
if ((request.getResponseId() + 1) == lastResponse.getResponseId()) {
/* old heartbeat */
return lastResponse;
} else if (request.getResponseId() + 1 < lastResponse.getResponseId()) {
String message = "Invalid responseId in AllocateRequest from application attempt: " + appAttemptId + ", expect responseId to be " + (lastResponse.getResponseId() + 1);
throw new InvalidApplicationMasterRequestException(message);
}
AllocateResponse response = recordFactory.newRecordInstance(AllocateResponse.class);
allocateInternal(amrmTokenIdentifier.getApplicationAttemptId(), request, response);
// update AMRMToken if the token is rolled-up
MasterKeyData nextMasterKey = this.rmContext.getAMRMTokenSecretManager().getNextMasterKeyData();
if (nextMasterKey != null && nextMasterKey.getMasterKey().getKeyId() != amrmTokenIdentifier.getKeyId()) {
RMApp app = this.rmContext.getRMApps().get(appAttemptId.getApplicationId());
RMAppAttempt appAttempt = app.getRMAppAttempt(appAttemptId);
RMAppAttemptImpl appAttemptImpl = (RMAppAttemptImpl) appAttempt;
Token<AMRMTokenIdentifier> amrmToken = appAttempt.getAMRMToken();
if (nextMasterKey.getMasterKey().getKeyId() != appAttemptImpl.getAMRMTokenKeyId()) {
LOG.info("The AMRMToken has been rolled-over. Send new AMRMToken back" + " to application: " + appAttemptId.getApplicationId());
amrmToken = rmContext.getAMRMTokenSecretManager().createAndGetAMRMToken(appAttemptId);
appAttemptImpl.setAMRMToken(amrmToken);
}
response.setAMRMToken(org.apache.hadoop.yarn.api.records.Token.newInstance(amrmToken.getIdentifier(), amrmToken.getKind().toString(), amrmToken.getPassword(), amrmToken.getService().toString()));
}
/*
* As we are updating the response inside the lock object so we don't
* need to worry about unregister call occurring in between (which
* removes the lock object).
*/
response.setResponseId(lastResponse.getResponseId() + 1);
lock.setAllocateResponse(response);
return response;
}
}
Aggregations