import { type AddonInfo, DescribeAddonVersionsCommand, type DescribeAddonVersionsResponse, EKSClient, } from '@aws-sdk/client-eks'; import { mockClient } from 'aws-sdk-client-mock'; import { logger } from '../../../../test/util.ts'; import * as hostRules from '../../../util/host-rules.ts'; import { getPkgReleases } from '../index.ts'; import { AwsEKSAddonDataSource } from './index.ts'; const datasource = AwsEKSAddonDataSource.id; const eksMock = mockClient(EKSClient); function mockDescribeAddonVersionsCommand( result: DescribeAddonVersionsResponse, ): void { eksMock.reset(); eksMock.on(DescribeAddonVersionsCommand).resolves(result); } function mockDescribeAddonVersionsCommandWithRegion( result: DescribeAddonVersionsResponse, ): void { eksMock.reset(); eksMock .on(DescribeAddonVersionsCommand) .callsFake(async (input, getClient) => { const client = getClient(); const region = await client.config.region(); return { ...result, // put the client region as nextToken // so that when we assert on the snapshot, we also verify that region from packageName is // passed to aws client. nextToken: region, }; }); } const addonInfo: AddonInfo = { addonName: 'vpc-cni', type: 'networking', addonVersions: [ { addonVersion: 'v1.19.0-eksbuild.1', architecture: ['amd64', 'arm64'], compatibilities: [ { clusterVersion: '1.31', defaultVersion: true, }, { clusterVersion: '1.30', defaultVersion: true, }, { clusterVersion: '1.29', defaultVersion: true, }, ], }, { addonVersion: 'v1.18.1-eksbuild.1', architecture: ['amd64', 'arm64'], compatibilities: [ { clusterVersion: '1.30', defaultVersion: false, }, ], }, { addonVersion: 'v1.18.2-eksbuild.1', architecture: ['amd64', 'arm64'], compatibilities: [ { clusterVersion: '1.30', platformVersions: ['*'], defaultVersion: true, }, ], }, ], publisher: 'eks', owner: 'aws', }; describe('modules/datasource/aws-eks-addon/index', () => { beforeEach(() => { hostRules.clear(); }); describe('getPkgReleases()', () => { it.each` des | req ${'null'} | ${{}} ${'empty'} | ${{ addons: [] }} ${'emptyVersion'} | ${{ addons: [{}] }} `('returned $des addons to be null', async ({ req }) => { mockDescribeAddonVersionsCommand(req); const res = await getPkgReleases({ datasource, packageName: '{"kubernetesVersion":"1.30","addonName":"non-existing-addon"}', }); expect(res).toBeNull(); expect(eksMock.calls()).toHaveLength(1); expect(eksMock.call(0).args[0].input).toEqual({ kubernetesVersion: '1.30', addonName: 'non-existing-addon', maxResults: 1, }); }); it('with addonName not supplied', async () => { const res = await getPkgReleases({ datasource, packageName: '{"kubernetesVersion":"1.30"}', }); expect(res).toBeNull(); expect(logger.logger.warn).toHaveBeenCalledWith( { err: expect.anything(), serializedFilter: '{"kubernetesVersion":"1.30"}', }, 'Error parsing eks-addons config.', ); }); it('with addonName only', async () => { mockDescribeAddonVersionsCommand({ addons: [addonInfo] }); const res = await getPkgReleases({ datasource, packageName: '{"addonName":"vpc-cni"}', }); expect(res).toEqual({ releases: [ { version: 'v1.18.1-eksbuild.1', compatibleWith: ['1.30'], default: false, }, { version: 'v1.18.2-eksbuild.1', compatibleWith: ['1.30'], default: true, }, { version: 'v1.19.0-eksbuild.1', compatibleWith: ['1.31', '1.30', '1.29'], default: true, }, ], }); expect(eksMock.call(0).args[0].input).toEqual({ addonName: 'vpc-cni', maxResults: 1, }); }); it('with addon and profile', async () => { mockDescribeAddonVersionsCommand({ addons: [] }); await getPkgReleases({ datasource, packageName: '{"addonName":"vpc-cni-not-exist", "profile":"paradox"}', }); expect(eksMock.calls()).toHaveLength(1); }); it('prefers host rule credentials over the configured profile', async () => { hostRules.add({ hostType: datasource, username: 'access-key-id', password: 'secret-access-key', token: 'session-token', }); mockDescribeAddonVersionsCommand({ addons: [] }); const awsEksAddonDatasource = new AwsEKSAddonDataSource(); await awsEksAddonDatasource.getReleases({ packageName: '{"addonName":"host-rule-credentials","profile":"ignored-profile"}', }); const eks = eksMock.call(0).thisValue as EKSClient; await expect(eks.config.credentials()).resolves.toEqual({ accessKeyId: 'access-key-id', secretAccessKey: 'secret-access-key', sessionToken: 'session-token', $source: { CREDENTIALS_CODE: 'e', }, }); }); it('with addon and region', async () => { mockDescribeAddonVersionsCommand({ addons: [] }); await getPkgReleases({ datasource, packageName: '{"addonName":"vpc-cni-not-exist", "region":"usa"}', }); expect(eksMock.calls()).toHaveLength(1); }); it('with addonName and default only config', async () => { mockDescribeAddonVersionsCommand({ addons: [addonInfo] }); const res = await getPkgReleases({ datasource, packageName: '{"addonName":"vpc-cni", "default":true}', }); expect(eksMock.call(0).args[0].input).toEqual({ addonName: 'vpc-cni', maxResults: 1, }); expect(res).toEqual({ releases: [ { version: 'v1.18.2-eksbuild.1', compatibleWith: ['1.30'], default: true, }, { version: 'v1.19.0-eksbuild.1', compatibleWith: ['1.31', '1.30', '1.29'], default: true, }, ], }); }); it('with matched addon to return all versions of the addon', async () => { const vpcCniAddonInfo: AddonInfo = { addonName: 'vpc-cni', type: 'networking', addonVersions: [ { addonVersion: 'v1.18.1-eksbuild.1', architecture: ['amd64', 'arm64'], compatibilities: [ { clusterVersion: '1.30', platformVersions: ['*'], defaultVersion: false, }, ], requiresConfiguration: false, }, { addonVersion: 'v1.18.2-eksbuild.1', architecture: ['amd64', 'arm64'], compatibilities: [ { clusterVersion: '1.30', platformVersions: ['*'], defaultVersion: false, }, ], requiresConfiguration: false, }, // a bad addonVersion that's missing the basic fields. {}, ], publisher: 'eks', owner: 'aws', }; mockDescribeAddonVersionsCommandWithRegion({ addons: [vpcCniAddonInfo], }); const res = await getPkgReleases({ datasource, packageName: '{"kubernetesVersion":"1.30","addonName":"vpc-cni","region":"mars-east-1"}', }); expect(res).toEqual({ releases: [ { version: 'v1.18.1-eksbuild.1', compatibleWith: ['1.30'], default: false, }, { version: 'v1.18.2-eksbuild.1', compatibleWith: ['1.30'], default: false, }, ], }); expect(eksMock.call(0).args[0].input).toEqual({ kubernetesVersion: '1.30', addonName: 'vpc-cni', maxResults: 1, }); }); }); });