in functions/source/nic-attachment/lib/aws/index.js [2582:2729]
async handleGetConfig() {
logger.info('calling handleGetConfig');
let config,
primaryInfo,
params = {},
primaryIp,
duplicatedGetConfigCall;
let promiseEmitter = this.checkPrimaryElection.bind(this),
validator = result => {
// TODO: remove the workaround if mantis item: #0534971 is resolved
// if i am the primary, don't wait, continue, if not, wait
// this if-condition is to work around the double GET config calls.
if (
this._primaryRecord &&
this._primaryRecord.voteState === 'pending' &&
this._selfInstance &&
this._primaryRecord.instanceId === this._selfInstance.instanceId &&
this._primaryRecord.scalingGroupName === this.scalingGroupName
) {
duplicatedGetConfigCall = true;
primaryIp = this._primaryRecord.ip;
return true;
}
// if neither a pending primary nor a primary instance is found on the primary
// scaling group. and if primary-election-no-wait is enabled, allow this fgt
// to wake up without a primary ip.
// this also implies this instance cannot be elected as the next primary which
// means it should be a secondary.
// primary info exists
if (result) {
// i am the elected primary
if (
result.primaryPrivateIpAddress ===
this._selfInstance.primaryPrivateIpAddress
) {
primaryIp = this._selfInstance.primaryPrivateIpAddress;
return true;
} else if (this._primaryRecord) {
// i am not the elected primary, how is the primary election going?
if (this._primaryRecord.voteState === 'done') {
// primary election done
return true;
} else if (this._primaryRecord.voteState === 'pending') {
// primary is still pending
// if not wait for the primary election to complete,
if (this._settings['primary-election-no-wait'] === 'true') {
return true;
} else {
// primary election not done, wait for a moment
// clear the current primary record cache and get a new one
// in the next call
this._primaryRecord = null;
return false;
}
}
} else {
// primary info exists but no primary record?
// this looks like a case that shouldn't happen. do the election again?
logger.warn('primary info found but primary record not found. retry.');
return false;
}
} else {
// primary cannot be elected but I cannot be the next elected primary either
// if not wait for the primary election to complete, let me become headless
return this._settings['primary-election-no-wait'] === 'true';
}
},
counter = () => {
if (Date.now() < process.env.SCRIPT_EXECUTION_EXPIRE_TIME - 3000) {
return false;
}
logger.warn('script execution is about to expire');
return true;
};
try {
primaryInfo = await AutoScaleCore.Functions.waitFor(
promiseEmitter,
validator,
5000,
counter
);
} catch (error) {
// if error occurs, check who is holding a primary election, if it is this instance,
// terminates this election. then tear down this instance whether it's primary or not.
this._primaryRecord = this._primaryRecord || (await this.platform.getPrimaryRecord());
if (
this._primaryRecord.instanceId === this._selfInstance.instanceId &&
this._primaryRecord.scalingGroupName === this._selfInstance.scalingGroupName
) {
await this.platform.removePrimaryRecord();
}
await this.removeInstance(this._selfInstance);
throw new Error(
'Failed to determine the primary instance. This instance is unable' +
' to bootstrap. Please report this to' +
' administrators.'
);
}
// get TGW_VPN record
if (this._settings['enable-transit-gateway-vpn'] === 'true') {
let vpnAttachmentRecord = await this.platform.getTgwVpnAttachmentRecord(
this._selfInstance
);
if (vpnAttachmentRecord) {
params.vpnConfigSetName = 'setuptgwvpn';
params.vpnConfiguration =
vpnAttachmentRecord.customerGatewayConfiguration.vpn_connection;
params.vpnConfiguration.id = params.vpnConfiguration.$.id;
}
}
// the primary ip same as mine? (diagram: primary IP same as mine?)
// this checking for 'duplicatedGetConfigCall' is to work around
// the double GET config calls.
// TODO: remove the workaround if mantis item: #0534971 is resolved
if (duplicatedGetConfigCall || primaryIp === this._selfInstance.primaryPrivateIpAddress) {
this._step = 'handler:getConfig:getPrimaryConfig';
params.callbackUrl = await this.platform.getCallbackEndpointUrl();
config = await this.getPrimaryConfig(params);
logger.info(
'called handleGetConfig: returning primary config' +
`(master-ip: ${primaryIp}):\n ${config}`
);
return config;
} else {
this._step = 'handler:getConfig:getSecondaryConfig';
let getPendingPrimaryIp = !(
this._settings['primary-election-no-wait'] === 'true' &&
this._primaryRecord &&
this._primaryRecord.voteState === 'pending'
);
params.callbackUrl = await this.platform.getCallbackEndpointUrl();
params.primaryIp =
(getPendingPrimaryIp && primaryInfo && primaryInfo.primaryPrivateIpAddress) || null;
params.allowHeadless = this._settings['primary-election-no-wait'] === 'true';
config = await this.getSecondaryConfig(params);
logger.info(
'called handleGetConfig: returning secondary config' +
`(master-ip: ${params.primaryIp || 'undetermined'}):\n ${config}`
);
return config;
}
}