Skip to content

Commit

Permalink
Replace Airnode address short with deployment ID
Browse files Browse the repository at this point in the history
  • Loading branch information
amarthadan committed Dec 1, 2022
1 parent aee28b1 commit 042a128
Show file tree
Hide file tree
Showing 24 changed files with 95 additions and 150 deletions.
7 changes: 7 additions & 0 deletions .changeset/unlucky-eggs-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@api3/airnode-deployer': minor
'@api3/airnode-node': minor
'@api3/airnode-validator': minor
---

Replace Airnode's short address with deployment ID
45 changes: 16 additions & 29 deletions packages/airnode-deployer/src/infrastructure/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,7 @@ describe('prepareCloudProviderAirnodeApplyDestoryArguments', () => {

describe('prepareAirnodeApplyDestroyArguments', () => {
const variables = {
airnodeAddressShort: 'd0624e6',
stage: 'dev',
deploymentId: 'aws7195b548',
configPath: '/some/path/config.json',
secretsPath: '/some/path/secrets.env',
handlerDir: '/some/path/handlers',
Expand All @@ -257,8 +256,7 @@ describe('prepareAirnodeApplyDestroyArguments', () => {

it('returns cloud provider agnostic Terraform variables', () => {
const expectedArguments = [
['var', 'airnode_address_short', variables.airnodeAddressShort],
['var', 'stage', variables.stage],
['var', 'deployment_id', variables.deploymentId],
['var', 'configuration_file', variables.configPath],
['var', 'secrets_file', variables.secretsPath],
['var', 'handler_dir', variables.handlerDir],
Expand All @@ -272,14 +270,11 @@ describe('prepareAirnodeApplyDestroyArguments', () => {

it('sets the missing optional arguments correctly', () => {
const onlyRequiredVariables = pick(variables, [
'airnodeAddressShort',
'stage',
'handlerDir',
'disableConcurrencyReservations',
]) as infrastructure.AirnodeApplyDestroyVariables;
const expectedArguments = [
['var', 'airnode_address_short', onlyRequiredVariables.airnodeAddressShort],
['var', 'stage', onlyRequiredVariables.stage],
['var', 'deployment_id', onlyRequiredVariables.deploymentId],
['var', 'configuration_file', 'NULL'],
['var', 'secrets_file', 'NULL'],
['var', 'handler_dir', onlyRequiredVariables.handlerDir],
Expand Down Expand Up @@ -354,7 +349,7 @@ describe('terraformAirnodeApply', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform apply -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
`terraform apply -var="aws_region=us-east-1" -var="deployment_id=aws40207f25" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
execOptions
);
});
Expand All @@ -380,12 +375,12 @@ describe('terraformAirnodeApply', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform import -var="gcp_region=us-east1" -var="gcp_project=airnode-test-123456" -var="airnode_bucket=airnode-123456789" -var="deployment_bucket_dir=airnode-address/stage/timestamp" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" module.startCoordinator.google_app_engine_application.app[0] airnode-test-123456`,
`terraform import -var="gcp_region=us-east1" -var="gcp_project=airnode-test-123456" -var="airnode_bucket=airnode-123456789" -var="deployment_bucket_dir=airnode-address/stage/timestamp" -var="deployment_id=gcp1fc73e56" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" module.startCoordinator.google_app_engine_application.app[0] airnode-test-123456`,
{ ignoreError: true }
);
expect(exec).toHaveBeenNthCalledWith(
3,
`terraform apply -var="gcp_region=us-east1" -var="gcp_project=airnode-test-123456" -var="airnode_bucket=airnode-123456789" -var="deployment_bucket_dir=airnode-address/stage/timestamp" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
`terraform apply -var="gcp_region=us-east1" -var="gcp_project=airnode-test-123456" -var="airnode_bucket=airnode-123456789" -var="deployment_bucket_dir=airnode-address/stage/timestamp" -var="deployment_id=gcp1fc73e56" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
execOptions
);
});
Expand Down Expand Up @@ -419,7 +414,7 @@ describe('terraformAirnodeApply', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform apply -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -auto-approve`,
`terraform apply -var="aws_region=us-east-1" -var="deployment_id=aws40207f25" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -auto-approve`,
execOptions
);
});
Expand Down Expand Up @@ -487,7 +482,7 @@ describe('deployAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform apply -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
`terraform apply -var="aws_region=us-east-1" -var="deployment_id=aws40207f25" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(exec).toHaveBeenNthCalledWith(3, 'terraform output -json -no-color', { cwd: 'tmpDir' });
Expand Down Expand Up @@ -527,7 +522,7 @@ describe('deployAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform apply -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
`terraform apply -var="aws_region=us-east-1" -var="deployment_id=aws40207f25" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(exec).toHaveBeenNthCalledWith(3, 'terraform output -json -no-color', { cwd: 'tmpDir' });
Expand Down Expand Up @@ -570,7 +565,7 @@ describe('deployAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform apply -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
`terraform apply -var="aws_region=us-east-1" -var="deployment_id=aws40207f25" -var="configuration_file=${configPath}" -var="secrets_file=${secretsPath}" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=0xd627c727db73ed7067cbc1e15295f7004b83c01d243aa90711d549cda6bd5bca" -input=false -no-color -var="max_concurrency=100" -var="http_gateway_enabled=true" -var="http_max_concurrency=20" -var="http_signed_data_gateway_enabled=true" -var="http_signed_data_max_concurrency=20" -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(exec).toHaveBeenNthCalledWith(3, 'terraform output -json -no-color', { cwd: 'tmpDir' });
Expand Down Expand Up @@ -638,8 +633,7 @@ describe('terraformAirnodeDestroy', () => {
region: 'europe-central-1',
} as AwsCloudProvider;
const handlerDir = path.resolve(`${__dirname}/../../.webpack`);
const airnodeAddressShort = 'a30ca71';
const stage = 'dev';
const deploymentId = 'aws7195b548';
const bucket = {
name: 'airnode-123456789',
region: 'us-east-1',
Expand All @@ -650,22 +644,15 @@ describe('terraformAirnodeDestroy', () => {
const commandOutput = 'example command output';
exec.mockImplementation(() => ({ stdout: commandOutput }));

await infrastructure.terraformAirnodeDestroy(
execOptions,
cloudProvider,
airnodeAddressShort,
stage,
bucket,
bucketPath
);
await infrastructure.terraformAirnodeDestroy(execOptions, cloudProvider, deploymentId, bucket, bucketPath);
expect(exec).toHaveBeenNthCalledWith(
1,
`terraform init -backend-config="region=us-east-1" -backend-config="bucket=airnode-123456789" -backend-config="key=airnode-address/stage/timestamp/default.tfstate" -from-module=${terraformDir}/aws`,
execOptions
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform destroy -var="aws_region=europe-central-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
`terraform destroy -var="aws_region=europe-central-1" -var="deployment_id=aws7195b548" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
execOptions
);
});
Expand Down Expand Up @@ -734,7 +721,7 @@ describe('removeAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform destroy -var="aws_region=us-east-1" -var="airnode_address_short=d0624e6" -var="stage=dev" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
`terraform destroy -var="aws_region=us-east-1" -var="deployment_id=${happyPathDeploymentId}" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(awsGetBucketDirectoryStructureSpy).toHaveBeenNthCalledWith(2, bucket.name);
Expand Down Expand Up @@ -765,7 +752,7 @@ describe('removeAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform destroy -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
`terraform destroy -var="aws_region=us-east-1" -var="deployment_id=${deploymentId}" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(awsGetBucketDirectoryStructureSpy).toHaveBeenNthCalledWith(2, bucket.name);
Expand Down Expand Up @@ -805,7 +792,7 @@ describe('removeAirnode', () => {
);
expect(exec).toHaveBeenNthCalledWith(
2,
`terraform destroy -var="aws_region=us-east-1" -var="airnode_address_short=a30ca71" -var="stage=dev" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
`terraform destroy -var="aws_region=us-east-1" -var="deployment_id=${deploymentId}" -var="configuration_file=NULL" -var="secrets_file=NULL" -var="handler_dir=${handlerDir}" -var="disable_concurrency_reservation=false" -var="airnode_wallet_private_key=NULL" -input=false -no-color -auto-approve`,
{ cwd: 'tmpDir' }
);
expect(awsGetBucketDirectoryStructureSpy).toHaveBeenNthCalledWith(2, bucket.name);
Expand Down
48 changes: 17 additions & 31 deletions packages/airnode-deployer/src/infrastructure/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
Bucket,
} from '../utils/infrastructure';
import { version as nodeVersion } from '../../package.json';
import { deriveAirnodeAddress, shortenAirnodeAddress } from '../utils';
import { deriveAirnodeAddress } from '../utils';
import { airnodeAddressReadable, cloudProviderReadable, timestampReadable } from '../utils/cli';

export const TF_STATE_FILENAME = 'default.tfstate';
Expand Down Expand Up @@ -188,8 +188,7 @@ export function prepareCloudProviderAirnodeApplyDestoryArguments(
}

export type AirnodeApplyDestroyVariables = {
airnodeAddressShort: string;
stage: string;
deploymentId: string;
configPath?: string;
secretsPath?: string;
handlerDir: string;
Expand All @@ -198,19 +197,11 @@ export type AirnodeApplyDestroyVariables = {
};

export function prepareAirnodeApplyDestroyArguments(variables: AirnodeApplyDestroyVariables): CommandArg[] {
const {
airnodeAddressShort,
stage,
configPath,
secretsPath,
handlerDir,
disableConcurrencyReservations,
airnodeWalletPrivateKey,
} = variables;
const { deploymentId, configPath, secretsPath, handlerDir, disableConcurrencyReservations, airnodeWalletPrivateKey } =
variables;

return [
['var', 'airnode_address_short', airnodeAddressShort],
['var', 'stage', stage],
['var', 'deployment_id', deploymentId],
['var', 'configuration_file', configPath ? path.resolve(configPath) : 'NULL'],
['var', 'secrets_file', secretsPath ? path.resolve(secretsPath) : 'NULL'],
['var', 'handler_dir', handlerDir],
Expand Down Expand Up @@ -245,17 +236,22 @@ export async function terraformAirnodeApply(
configPath: string,
secretsPath: string
) {
const { airnodeWalletMnemonic, stage, httpGateway, httpSignedDataGateway } = config.nodeSettings;
const {
airnodeWalletMnemonic,
stage,
httpGateway,
httpSignedDataGateway,
nodeVersion: configNodeVersion,
} = config.nodeSettings;
const cloudProvider = config.nodeSettings.cloudProvider as CloudProvider;
const airnodeAddressShort = shortenAirnodeAddress(deriveAirnodeAddress(airnodeWalletMnemonic));
const airnodeAddress = deriveAirnodeAddress(airnodeWalletMnemonic);
const airnodeWalletPrivateKey = evm.getAirnodeWallet(config).privateKey;
const maxConcurrency = config.chains.reduce((concurrency: number, chain) => concurrency + chain.maxConcurrency, 0);

await terraformAirnodeInit(execOptions, cloudProvider, bucket, bucketDeploymentPath);

const commonArguments = prepareAirnodeApplyDestroyArguments({
airnodeAddressShort,
stage,
deploymentId: deriveDeploymentId(cloudProvider, airnodeAddress, stage, configNodeVersion),
configPath,
secretsPath,
handlerDir,
Expand Down Expand Up @@ -395,16 +391,14 @@ export const deployAirnode = async (config: Config, configPath: string, secretsP
export async function terraformAirnodeDestroy(
execOptions: child.ExecOptions,
cloudProvider: CloudProvider,
airnodeAddressShort: string,
stage: string,
deploymentId: string,
bucket: Bucket,
bucketDeploymentPath: string
) {
await terraformAirnodeInit(execOptions, cloudProvider, bucket, bucketDeploymentPath);

const commonArguments = prepareAirnodeApplyDestroyArguments({
airnodeAddressShort,
stage,
deploymentId,
handlerDir,
disableConcurrencyReservations: cloudProvider.disableConcurrencyReservations,
});
Expand Down Expand Up @@ -560,17 +554,9 @@ export async function removeAirnode(deploymentId: string) {
}

logger.debug('Removing Airnode via Terraform recipes');
const airnodeAddressShort = shortenAirnodeAddress(airnodeAddress);
const airnodeTmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'airnode'));
const execOptions = { cwd: airnodeTmpDir };
await terraformAirnodeDestroy(
execOptions,
cloudProvider,
airnodeAddressShort,
stage,
bucket,
bucketLatestDeploymentPath
);
await terraformAirnodeDestroy(execOptions, cloudProvider, deploymentId, bucket, bucketLatestDeploymentPath);
fs.rmSync(airnodeTmpDir, { recursive: true });

// Refreshing the bucket content because the source code archives were removed by Terraform
Expand Down
Loading

0 comments on commit 042a128

Please sign in to comment.