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

Relax validations on eks.Cluster instance_roles #1227

Merged
merged 11 commits into from
Jul 16, 2024
Merged

Relax validations on eks.Cluster instance_roles #1227

merged 11 commits into from
Jul 16, 2024

Conversation

t0yv0
Copy link
Member

@t0yv0 t0yv0 commented Jul 3, 2024

Proposed changes

This change allows a program to set empty instance_roles=[] on an eks.Cluster with custom authentication_mode without triggering a warning on these properties being incompatible.

roleMappings and userMappings are treated symmetrically.

Related issues (optional)

Fixes #1220

@t0yv0
Copy link
Member Author

t0yv0 commented Jul 3, 2024

I've confirmed this fixes preview of the following program. Checking if it fixes pulumi up as well.

import pulumi
import pulumi_aws as aws
import pulumi_awsx as awsx
import pulumi_eks as eks

vpc = awsx.ec2.Vpc("vpc")

cluster = eks.Cluster(
    "zd-5423",
    vpc_id=vpc.vpc_id,
    public_subnet_ids=vpc.public_subnet_ids,
    private_subnet_ids=vpc.private_subnet_ids,
    authentication_mode=eks.AuthenticationMode.API,
    skip_default_node_group=True,
    instance_roles=[],
    use_default_vpc_cni=False,
)

Copy link

github-actions bot commented Jul 3, 2024

Does the PR have any schema changes?

Looking good! No breaking changes found.
No new resources/functions.

@t0yv0 t0yv0 requested a review from flostadler July 4, 2024 00:23
Copy link

github-actions bot commented Jul 4, 2024

Does the PR have any schema changes?

Looking good! No breaking changes found.
No new resources/functions.

// Validate promptly if possible, otherwise validate in the Promise chain underlying the Output and ensure that the
// input is gated on the validation. Unfortunately since apply always unwraps, the validate function required here needs
// to be able to handle both unwrapped and normal forms.
function validatedInput<T>(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trick didn't work as neatly as I hoped. I hoped to make a pulumi.Input<T> that is gated on the validation. Unfortunately I couldn't wrestle the jest framework to be able to assert against failing pulumi.Output values :/ so simply coercing pulumi.Input<T> to pulumi.Output<T> does not cut it because I couldn't fix the unit tests. Instead this is further refined to handle immediately available T on the stack and only jump into an apply chain if that is not possible. Unfortunately since apply always unwraps and there doesn't seem to be a non-unwrapping variant available, the validate function has this signature:

 validate: (value: T|pulumi.Unwrap<T>|undefined) => void

where the ideal signature would be:

 validate: (value: T|undefined) => void

@@ -70,10 +70,20 @@ describe("validateAuthenticationMode", () => {
};

expect(() => validateAuthenticationMode(args)).toThrowError(
"The 'instanceRoles' property is not supported when 'authenticationMode' is set to 'API'.",
"The 'instanceRoles' property does not support non-empty values when 'authenticationMode' is set to 'API'.",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually something must be of as this test shouldn't compile.

 const args = {
            authenticationMode: "API",
            instanceRoles: ["roleArn"],
        };

"roleArn" is not a valid aws.eks.Role.

Copy link
Contributor

@flostadler flostadler Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test isn't type checked because it's executed as js. If you'd like to satisfy the type checker you could pass the args as ClusterOptions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added it to tsconfig.json and fixed it up, it now is type-checked.

@t0yv0
Copy link
Member Author

t0yv0 commented Jul 4, 2024

Wish list for the Node SDK here.

  • should be a simple way to assert that Output<T> values are failing in jest, such as transforming Output<T> to Promise<OutputResult<T>> and asserting that this promise resolves with an exception

  • should be a way to apply (x: T)=>U to an Output<T> and receive Output<U> and not Output<Unwrap<U>> opting out of the unwrapping

if (!supportsConfigMap(args.authenticationMode)) {
configMapOnlyProperties.forEach((prop) => {
if (args[prop]) {
const check: (prop: string) => (propertyValue: any|undefined) => void = (prop) => (pv) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: prop could be keyof ClusterOptions. What do you think about renaming this to checkIsUndefined? That way it's clearer what it is actually checking

throw new Error(
`The '${prop}' property is not supported when 'authenticationMode' is set to '${args.authenticationMode}'.`,
);
}
};

args.roleMappings = validatedInput(args.roleMappings, check("roleMappings"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we extend this to roleMappings and userMappings as well? Would be a nice improvement and it's a bit odd imho if roleMappings/userMappings don't allow empty arrays while instanceRoles does

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

it("should not throw an error for instanceRoles=[] when authentication mode is set to API", () => {
const args = {
authenticationMode: "API",
instanceRoles: [],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also test passing instanceRoles as a Promise and Output?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be great but I was running into limitations that seem to make failing outputs un-testable. I can ask around for help.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth adding an integration test tif that doesn't work

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed pulumi/pulumi#16665 - there's something odd, possibly a bug in Node SDK that makes it extra difficult. I'll look into an integration test.

Copy link

Does the PR have any schema changes?

Looking good! No breaking changes found.
No new resources/functions.

@t0yv0 t0yv0 requested a review from flostadler July 15, 2024 18:26
Copy link
Contributor

@flostadler flostadler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one comment about CI

describe("validateAuthenticationMode", () => {

const testRole: aws.iam.Role = (<any>{"arn": "testRole"});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

@@ -89,6 +90,50 @@ func TestReportUpgradeCoverage(t *testing.T) {
providertest.ReportUpgradeCoverage(t)
}

func TestEksClusterInputValidations(t *testing.T) {
Copy link
Contributor

@flostadler flostadler Jul 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is executed as part of the upgrade tests right now in CI. What do you think about moving it to it's own job?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, interesting, I thought that we're trying to put tests that are not useful as examples to end-users now under provider/* instead of under examples/*, I can backlog cleaning this up.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@t0yv0 t0yv0 merged commit 986c528 into master Jul 16, 2024
43 checks passed
@t0yv0 t0yv0 deleted the t0yv0/fix-1220 branch July 16, 2024 14:31
@pulumi-bot
Copy link
Contributor

This PR has been shipped in release v2.7.4.

@pulumi-bot
Copy link
Contributor

This PR has been shipped in release v2.7.5.

@pulumi-bot
Copy link
Contributor

This PR has been shipped in release v2.7.6.

@mjeffryes mjeffryes added this to the 0.107 milestone Jul 24, 2024
flostadler pushed a commit that referenced this pull request Sep 4, 2024
<!--Thanks for your contribution. See [CONTRIBUTING](CONTRIBUTING.md)
    for Pulumi's contribution guidelines.

    Help us merge your changes more quickly by adding more details such
    as labels, milestones, and reviewers.-->

### Proposed changes

<!--Give us a brief description of what you've done and what it solves.
-->

This change allows a program to set empty `instance_roles=[]` on an
eks.Cluster with custom `authentication_mode` without triggering a
warning on these properties being incompatible.

roleMappings and userMappings are treated symmetrically.

### Related issues (optional)

<!--Refer to related PRs or issues: #1234, or 'Fixes #1234' or 'Closes
#1234'.
Or link to full URLs to issues or pull requests in other GitHub
repositories. -->

Fixes #1220
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cluster with auth mode API can not be created with workaround that prevents instance role creation
4 participants