MCPcopy Create free account
hub / github.com/api3dao/airnode / deployAirnode

Function deployAirnode

packages/airnode-deployer/src/infrastructure/index.ts:333–437  ·  view source on GitHub ↗
(config: Config, configPath: string, secretsPath: string, timestamp: number)

Source from the content-addressed store, hash-verified

331}
332
333export const deployAirnode = async (config: Config, configPath: string, secretsPath: string, timestamp: number) => {
334 const { airnodeWalletMnemonic, cloudProvider, stage } = config.nodeSettings;
335 const airnodeAddress = deriveAirnodeAddress(airnodeWalletMnemonic);
336 const { type, region } = cloudProvider as CloudProvider;
337
338 const spinner = logger.getSpinner();
339 spinner.start(`Deploying Airnode ${airnodeAddress} ${stage} to ${type} ${region}`);
340 if (logger.inDebugMode()) {
341 spinner.info();
342 }
343
344 const goDeploy = await go(async () => {
345 logger.debug('Fetching Airnode bucket');
346 let bucket = await cloudProviderLib[type].getAirnodeBucket();
347 if (!bucket) {
348 logger.debug('No Airnode bucket found, creating');
349 bucket = await cloudProviderLib[type].createAirnodeBucket(cloudProvider as any);
350 }
351 logger.debug(`Using Airnode bucket '${bucket.name}'`);
352
353 logger.debug('Fetching Airnode bucket content');
354 const directoryStructure = await cloudProviderLib[type].getBucketDirectoryStructure(bucket);
355
356 const bucketStagePath = `${airnodeAddress}/${stage}`;
357 const bucketDeploymentPath = `${bucketStagePath}/${timestamp}`;
358
359 const stageDirectory = getStageDirectory(directoryStructure, airnodeAddress, stage);
360 if (stageDirectory) {
361 logger.debug(`Deployment '${bucketStagePath}' already exists`);
362
363 const bucketMissingFiles = getMissingBucketFiles(directoryStructure);
364 if (
365 bucketMissingFiles[airnodeAddress] &&
366 bucketMissingFiles[airnodeAddress][stage] &&
367 bucketMissingFiles[airnodeAddress][stage].length !== 0
368 ) {
369 throw new Error(
370 `Can't update an Airnode with missing files: ${bucketMissingFiles[airnodeAddress][stage].join(
371 ', '
372 )}. Deployer commands may fail and manual removal may be necessary.`
373 );
374 }
375
376 const latestDeployment = Object.keys(stageDirectory.children).sort().reverse()[0];
377 const bucketConfigPath = `${bucketStagePath}/${latestDeployment}/config.json`;
378 logger.debug(`Fetching configuration file '${bucketConfigPath}'`);
379 const goGetRemoteConfigFileFromBucket = await go(() =>
380 cloudProviderLib[type].getFileFromBucket(bucket!, bucketConfigPath)
381 );
382 if (!goGetRemoteConfigFileFromBucket.success) {
383 throw new Error(`Failed to fetch configuration file. Error: ${goGetRemoteConfigFileFromBucket.error.message}`);
384 }
385 const goRemoteConfig = goSync(() => JSON.parse(goGetRemoteConfigFileFromBucket.data));
386 if (!goRemoteConfig.success) {
387 throw new Error(`Failed to parse configuration file. Error: ${goRemoteConfig.error.message}`);
388 }
389
390 const remoteNodeSettings = goRemoteConfig.data.nodeSettings;

Callers 1

deployFunction · 0.90

Calls 10

deriveAirnodeAddressFunction · 0.90
getStageDirectoryFunction · 0.90
getMissingBucketFilesFunction · 0.90
terraformAirnodeApplyFunction · 0.85
execTerraformFunction · 0.85
transformTerraformOutputFunction · 0.85
startMethod · 0.80
infoMethod · 0.80
failMethod · 0.80
succeedMethod · 0.80

Tested by

no test coverage detected