Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(versioning): aws-eks-addon versioning added #33301

Merged
merged 14 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/modules/versioning/api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as awsEksAddon from './aws-eks-addon';
import * as amazonMachineImage from './aws-machine-image';
import * as azureRestApi from './azure-rest-api';
import * as bazelModule from './bazel-module';
Expand Down Expand Up @@ -45,6 +46,7 @@ import * as unity3d from './unity3d';
const api = new Map<string, VersioningApi | VersioningApiConstructor>();
export default api;

api.set(awsEksAddon.id, awsEksAddon.api);
api.set(amazonMachineImage.id, amazonMachineImage.api);
api.set(azureRestApi.id, azureRestApi.api);
api.set(bazelModule.id, bazelModule.api);
Expand Down
146 changes: 146 additions & 0 deletions lib/modules/versioning/aws-eks-addon/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import aws from '.';

describe('modules/versioning/aws-eks-addon/index', () => {
describe('parse(version)', () => {
it('should return 1.23.7 and release version', () => {
expect(aws.getMajor('v1.20.7-eksbuild.1')).toBe(1);
expect(aws.getMinor('v1.23.7-eksbuild.1')).toBe(23);
expect(aws.getPatch('v1.20.7-eksbuild.1')).toBe(7);
});
});

describe('isValid(version)', () => {
it.each`
input | expected
${''} | ${false}
${'.1..'} | ${false}
${'abrakadabra'} | ${false}
${'v1'} | ${false}
${'v1.'} | ${false}
${'v1...-eksbuild.1'} | ${false}
${'v1-eksbuild.1'} | ${false}
${'v1.a-eksbuild.1'} | ${false}
${'v1.23-eksbuild.1'} | ${false}
${'1.23.1-eksbuild.a'} | ${false}
${'v1.11.7'} | ${false}
${'v1.11.7.6'} | ${false}
${'v1.11.7-noneksbuild'} | ${false}
${'v1.11.7-noneksbuild.1'} | ${false}
${'v1.11.7-eksbuild'} | ${false}
${'v1.11.7.3-eksbuild.1'} | ${false}
${'v1.23.1-eksbuild.1'} | ${true}
${'1.23.1-eksbuild.1'} | ${true}
${'v1.23.1-eksbuild.11'} | ${true}
`('isValid("$input") === $expected', ({ input, expected }) => {
const actual = aws.isValid(input);
expect(actual).toBe(expected);
});
});

describe('isVersion(version)', () => {
it.each`
input | expected
${''} | ${false}
${'abrakadabra'} | ${false}
${'v1'} | ${false}
${'v1.'} | ${false}
${'v1-eksbuild.1'} | ${false}
${'v1.a-eksbuild.1'} | ${false}
${'v1.23-eksbuild.1'} | ${false}
${'1.23.1-eksbuild.a'} | ${false}
${'v1.11.7'} | ${false}
${'v1.11.7.6'} | ${false}
${'v1.11.7-noneksbuild'} | ${false}
${'v1.11.7-noneksbuild.1'} | ${false}
${'v1.11.7-eksbuild'} | ${false}
${'v1.11.7.3-eksbuild.1'} | ${false}
${'v1.23.1-eksbuild.1'} | ${true}
${'1.23.1-eksbuild.1'} | ${true}
${'v1.23.1-eksbuild.11'} | ${true}
`('isValid("$input") === $expected', ({ input, expected }) => {
const actual = aws.isVersion(input);
expect(actual).toBe(expected);
});
});

describe('isCompatible(version)', () => {
it.each`
input | expected
${''} | ${false}
${'abrakadabra'} | ${false}
${'v1'} | ${false}
${'v1.'} | ${false}
${'v1-eksbuild.1'} | ${false}
${'v1.a-eksbuild.1'} | ${false}
${'v1.23-eksbuild.1'} | ${false}
${'1.23.1-eksbuild.1'} | ${false}
${'1.23.1-eksbuild.a'} | ${false}
${'v1.11.7'} | ${false}
${'v1.11.7.6'} | ${false}
${'v1.11.7-noneksbuild'} | ${false}
${'v1.11.7-noneksbuild.1'} | ${false}
${'v1.11.7-eksbuild'} | ${false}
${'v1.11.7.3-eksbuild.1'} | ${false}
`('isCompatible("$input") === $expected', ({ input, expected }) => {
const actual = aws.isCompatible(input);
expect(actual).toBe(expected);
});
});

describe('isCompatible(version,range)', () => {
it.each`
version | current | expected
${'1.23.1-eksbuild.1'} | ${'1.23.1-eksbuild.2'} | ${true}
${'v1.23.1-eksbuild.1'} | ${'1.23.1-eksbuild.2'} | ${true}
${'v1.23.1-eksbuild.1'} | ${'1.23.1-eksbuild.21'} | ${true}
${'v1.11.7-eksbuild.1'} | ${'v1.11.7-noneksbuild.1'} | ${false}
${'v1.11.7'} | ${'v1.11.7-noneksbuild.1'} | ${false}
${'v1-eksbuild.1'} | ${'artful'} | ${false}
${'v1.11.7.1-eksbuild.1'} | ${'v1.11.7-eksbuild.1'} | ${false}
`(
'isCompatible($version, $current) === $expected',
({ version, current, expected }) => {
const actual = aws.isCompatible(version, current);
expect(actual).toBe(expected);
},
);
});

describe('isGreaterThan(version1, version2)', () => {
it.each`
version | other | expected
${'v1.11.7-eksbuild.1'} | ${'v1.11.7-eksbuild.0'} | ${true}
${'v1.11.7-eksbuild.11'} | ${'v1.11.7-eksbuild.1'} | ${true}
${'v1.22.7-eksbuild.2'} | ${'v1.20.7-eksbuild.1'} | ${true}
${'v1.22.7-eksbuild.2'} | ${'v1.22.7'} | ${true}
${'v1.20.7-eksbuild.1'} | ${'v2.0.0'} | ${true}
${'v1.20.7-eksbuild.1'} | ${'v1.20.7-eksbuild.2'} | ${false}
${'v1.20.6-eksbuild.1'} | ${'v1.20.7-eksbuild.2'} | ${false}
${'v1.20.7-eksbuild.1'} | ${'v2.0.0-eksbuild.1'} | ${false}
`(
'isGreaterThan($version, $other) === $expected',
({ version, other, expected }) => {
const actual = aws.isGreaterThan(version, other);
expect(actual).toBe(expected);
},
);
});

it('getSatisfyingVersion', () => {
expect(
aws.getSatisfyingVersion(['v1.20.7-eksbuild.1'], 'v1.20.7-eksbuild.1'),
).toBe('v1.20.7-eksbuild.1');
expect(
aws.getSatisfyingVersion(
['v1.20.7-eksbuild.1', 'v1.20.7-eksbuild.2', 'v1.20.7-eksbuild.7'],
'v1.20.7-eksbuild.3',
),
).toBeNull();
expect(
aws.getSatisfyingVersion(
['v1.20.7-eksbuild.1', 'v1.20.7-eksbuild.2'],
'v1.20.7-eksbuild.3',
),
).toBeNull();
});
});
20 changes: 20 additions & 0 deletions lib/modules/versioning/aws-eks-addon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { RegExpVersioningApi } from '../regex';
import type { VersioningApi } from '../types';

export const id = 'aws-eks-addon';
export const displayName = 'aws-eks-addon';

export const supportsRanges = false;

export class AwsEKSAddonVersioningApi extends RegExpVersioningApi {
static versionRegex =
'^v?(?<major>\\d+)\\.(?<minor>\\d+)\\.(?<patch>\\d+)(?<compatibility>-eksbuild\\.)(?<build>\\d+)$';

public constructor() {
super(AwsEKSAddonVersioningApi.versionRegex);
}
}

export const api: VersioningApi = new AwsEKSAddonVersioningApi();

export default api;
18 changes: 18 additions & 0 deletions lib/modules/versioning/aws-eks-addon/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
AWS versioning syntax is used for EKS Addon updates.

It is based off [Semantic Versioning 2.0](https://semver.org) but with a subset of addon `build metadata` syntax.

At the moment every ESK Addon that matches the regex `^[v]?(\d+(?:\.\d+)*)(-eksbuild\.\d+)$` is considered a valid "release".

**Key Points about EKS Addon Versioning**

1. Versioning Scheme: Add-ons typically follow a semantic versioning scheme (e.g., Major.Minor.Patch). This helps in understanding the significance of changes between versions:

- `Major`: Indicates significant changes or breaking API changes for plugin version.
- `Minor`: Introduces new features or enhancements for plugin version.
- `Patch`: Includes bug fixes and minor improvements for plugin version.
- `Build Metadata` : It helps differentiate this particular release from others that might have been built independently.

2. Default Versions: When creating a new EKS cluster, AWS often selects a default version for each addon based on the cluster's Kubernetes version and other factors. This default version is usually the most stable and recommended for the specific cluster configuration

3. Build metadata. Example `eksbuild.1`. The `eksbuild.1` part signifies a specific build or release within the `1.19.0` version, likely managed by the EKS build system. It helps differentiate this particular release from others that might have been built independently. The build metadata provides additional context about the specific release, which can be useful for tracking and troubleshooting.
Loading