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

API conventions: add more on defaulting #6764

Merged
merged 1 commit into from
Aug 16, 2022

Conversation

thockin
Copy link
Member

@thockin thockin commented Jul 28, 2022

In reviewing an issue/PR I realized this lesson had not been documented
anywhere. This is not the ideal mechanism, IMO, but better than
nothing.

This comes out of Service ClusterIP and NodePorts, plus #103546

@robscott @aojea @khenidak @liggitt @msau42

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 28, 2022
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: thockin

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added area/developer-guide Issues or PRs related to the developer guide sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jul 28, 2022
@thockin
Copy link
Member Author

thockin commented Jul 28, 2022

Also @apelisse - it might be interesting to denote some fields as +patchOnUnset or something?

@thockin
Copy link
Member Author

thockin commented Jul 28, 2022

Oh, this needs a TOC update - didn't we have a tool for that?

Edit: done

the values applied when using the "v2" API. In most cases, these values are
defined as literal values by the API version (e.g. "if this field is not
specified it defaults to 0"). In some cases, these values may be
deterministically derived from other fields (e.g. "if this field is not
Copy link
Member

Choose a reason for hiding this comment

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

fwiw, deriving a default from another mutable field makes for really confusing semantics on apply update when the other field gets changed, but the derived default sticks. I'd go so far as to call derived defaults an anti-pattern.

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 can note this in the text, but consider even things like:

    if strategy.Type == appsv1.RollingUpdateDeploymentStrategyType {
        if strategy.RollingUpdate == nil {
            rollingUpdate := appsv1.RollingUpdateDeployment{}
            strategy.RollingUpdate = &rollingUpdate
        }   
        if strategy.RollingUpdate.MaxUnavailable == nil {
            // Set default MaxUnavailable as 25% by default.
            maxUnavailable := intstr.FromString("25%")
            strategy.RollingUpdate.MaxUnavailable = &maxUnavailable
        }   
        if strategy.RollingUpdate.MaxSurge == nil {
            // Set default MaxSurge as 25% by default.
            maxSurge := intstr.FromString("25%")
            strategy.RollingUpdate.MaxSurge = &maxSurge
        }   
    }   

contributors/devel/sig-architecture/api-conventions.md Outdated Show resolved Hide resolved
contributors/devel/sig-architecture/api-conventions.md Outdated Show resolved Hide resolved
Comment on lines +905 to +931
considered. If the field is immutable after creation, consider adding logic to
manually "patch" the value from the "old" object into the "new" one when it has
Copy link
Member

@aojea aojea Jul 29, 2022

Choose a reason for hiding this comment

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

for my understanding, you are saying that if my v1 immutable field defaults to false, and my v2 default to true; I have to mutate the field from false to true if the PUT doesn't specify a value on that field?

Copy link
Member Author

Choose a reason for hiding this comment

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

The PUT with v2 will default the unspecified field to the v2 default value. The validate-update code will see the field change from false (v1) to true (v2) and SHOULD fail with an error because the field is immutable.

The only fixes here are:

  1. require RMW
  2. don't use defaults.go, but do it like Service IPs - in registry - and manually patch it

@thockin
Copy link
Member Author

thockin commented Jul 29, 2022

Some care is required when deciding which mechanism to use and managing the
semantics.

### Static Defaults
Copy link
Member

Choose a reason for hiding this comment

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

Would it be worth describing what CEL will now allow? @jpbetz And it's probably a little premature but also possibly in the admission webhook category below.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good question. CEL for admission control (only an idea right now, not even a provisional KEP) would be the best fit and would align with the below "Admission Controlled Defaults". I would just be another mechanism, in addition to admission controllers and admission webhooks to perform the mutation.

Copy link
Member Author

@thockin thockin Aug 12, 2022

Choose a reason for hiding this comment

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

can we take that as a followup (since I myself am not sure what to write..)?

Copy link
Member

Choose a reason for hiding this comment

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

I'm totally fine with that, thanks!

@apelisse
Copy link
Member

apelisse commented Aug 5, 2022

Looks great to me, thanks

@aojea
Copy link
Member

aojea commented Aug 8, 2022

LGTM

defer to @liggitt

@thockin
Copy link
Member Author

thockin commented Aug 12, 2022

solution in the face of version skew.

When an object is updated with a PUT, the API server will see the "old"
object with defaulted values and the "new" object without. For static defaults
Copy link
Member

Choose a reason for hiding this comment

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

This sentence is a bit confusing... the new object is handled with defaults freshly applied to the new object, not without defaults. Maybe something like ... and the "new" object with independently defaulted values.?

Copy link
Member Author

Choose a reason for hiding this comment

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

good point.

When an object is updated with a PUT, the API server will see the "old"
object with defaulted values and the "new" object without. For static defaults
this is mainly a problem if the CREATE and the PUT used different API versions
(and even then it might be semantically correct). For example, "v1" of an API
Copy link
Member

Choose a reason for hiding this comment

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

the parenthetical makes this sentence difficult to understand - "this is a problem ... but might be correct"?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, the next para talks thru this, so removing parens.

In reviewing an issue/PR I realized this lesson had not been documented
anywhere.  This is not the ideal mechanism, IMO, but better than
nothing.
Copy link
Member Author

@thockin thockin left a comment

Choose a reason for hiding this comment

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

New push up with comments addressed.

solution in the face of version skew.

When an object is updated with a PUT, the API server will see the "old"
object with defaulted values and the "new" object without. For static defaults
Copy link
Member Author

Choose a reason for hiding this comment

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

good point.

When an object is updated with a PUT, the API server will see the "old"
object with defaulted values and the "new" object without. For static defaults
this is mainly a problem if the CREATE and the PUT used different API versions
(and even then it might be semantically correct). For example, "v1" of an 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.

Yeah, the next para talks thru this, so removing parens.

@liggitt
Copy link
Member

liggitt commented Aug 16, 2022

/lgtm
/hold in case you wanted other eyes, unhold at will

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 16, 2022
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 16, 2022
@thockin
Copy link
Member Author

thockin commented Aug 16, 2022

/unhold

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 16, 2022
@k8s-ci-robot k8s-ci-robot merged commit 47da91b into kubernetes:master Aug 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. area/developer-guide Issues or PRs related to the developer guide cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants