-
Notifications
You must be signed in to change notification settings - Fork 209
Fix declarative defaults using aliases #246
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
Fix declarative defaults using aliases #246
Conversation
alexzielenski
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annotated some changes to give context to reviewer
| var defaultString string | ||
| if len(defaultMap) == 1 { | ||
| defaultString = defaultMap[0] | ||
| } else if len(defaultMap) > 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved this line up from below since defaultMap is not ever mutated
| klog.Fatalf("Found more than one default tag for %v", t.Kind) | ||
| } else if len(defaultMap) == 0 { | ||
|
|
||
| if len(defaultString) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed len(defaultMap) == 0 -> len(defaultString) == 0` since that seemed to be the original intention to allow nested default to work. Nested default is only used if default map is empty, so the original condition here would block their use.
|
|
||
| t, depth := resolveTypeAndDepth(t) | ||
| if depth > 0 && defaultString == "" { | ||
| baseT, depth := resolveTypeAndDepth(t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed t->baseT since getNestedDefault would always be invoked on the primitive base type like string, int, struct, etc and always yield no nested default string unless base type was struct with default defined. But that case is already unusable due to mustEnforceDefault enforcing all structs use {} or nothing as their default value.
It seems the original intention of the code was to call getNestedDefault on the input argument. This would allow a default declared on an alias to be respected. I've refactored t->baseT usages elsewhere where the base primitive element type was desired.
|
/cc @sttts |
c4967f5 to
7b0b2a6
Compare
14834e1 to
cafd10d
Compare
|
That's great, I still need to continue reviewing, I just want to mention that these defaults won't be included in the OpenAPI. The code that parses the default flags into their OpenAPI components lives in kube-openapi. |
| // Type-level default is not respected unless a pointer | ||
| AliasDefault DefaultedValueItem `json:",omitempty"` | ||
|
|
||
| // Type-level default is not respected unless a pointer | ||
| AliasPointerDefault *DefaultedValueItem `json:",omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My memory on this is blurry, but shouldn't we accept the defaults if it's omitempty, even if it's not a pointer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I would've expected but the source seems explicitly written to only read the default from the struct/alias type if the type is pointer (depth > 0):
gengo/examples/defaulter-gen/generators/defaulter.go
Lines 518 to 528 in ab3349d
| func populateDefaultValue(node *callNode, t *types.Type, tags string, commentLines []string) *callNode { | |
| defaultMap := extractDefaultTag(commentLines) | |
| var defaultString string | |
| if len(defaultMap) == 1 { | |
| defaultString = defaultMap[0] | |
| } | |
| t, depth := resolveTypeAndDepth(t) | |
| if depth > 0 && defaultString == "" { | |
| defaultString = getNestedDefault(t) | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's probably a bug to be honest.
4e747b6 to
22fc851
Compare
apelisse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
/lgtm
| // +default=ref(SomeDefault) | ||
| AliasOverride Item | ||
|
|
||
| // Type-level default is not respected unless a pointer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if that makes sense or not.
22fc851 to
a57114b
Compare
e625bcb to
5d46758
Compare
5d46758 to
ca53d90
Compare
apelisse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
struct was getting very large also adds omitempty tag for non-pointer fields. Openapi-gen would throw error. probably a bug that it is accepted in defaulter-gen test: import package of types that are used for casting cleanup: go mod tidy
also unconditionally cast when using references since we dont know their source type otherwise if you have a `string` field, and provide a `type Value string`-valued default, you get an error trying to assign an alias to a string cleanup and commenting
ca53d90 to
b5ba24c
Compare
apelisse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
|
|
yes those are expected errors from the import boss test |
|
Tested against current k8s master branch with only one minor package naming change due to #247 ( diff --git a/pkg/controller/apis/config/v1alpha1/zz_generated.defaults.go b/pkg/controller/apis/config/v1alpha1/zz_generated.defaults.go
index bd27200c5a4..b441808f2ec 100644
--- a/pkg/controller/apis/config/v1alpha1/zz_generated.defaults.go
+++ b/pkg/controller/apis/config/v1alpha1/zz_generated.defaults.go
@@ -23,7 +23,7 @@ package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
- cloudproviderconfigv1alpha1 "k8s.io/cloud-provider/config/v1alpha1"
+ configv1alpha1 "k8s.io/cloud-provider/config/v1alpha1"
v1alpha1 "k8s.io/kube-controller-manager/config/v1alpha1"
)
@@ -39,5 +39,5 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
func SetObjectDefaults_KubeControllerManagerConfiguration(in *v1alpha1.KubeControllerManagerConfiguration) {
SetDefaults_KubeControllerManagerConfiguration(in)
- cloudproviderconfigv1alpha1.SetDefaults_KubeCloudSharedConfiguration(&in.KubeCloudShared)
+ configv1alpha1.SetDefaults_KubeCloudSharedConfiguration(&in.KubeCloudShared)
} |
1da33ff to
2d1998f
Compare
2d1998f to
be9cf52
Compare
apelisse
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
|
/approve |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: alexzielenski, apelisse, sttts 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 |
#239 seems to have gone stale so I took a stab at fixing this myself.
One distinction this approach taken here has over the original attempt is that it is able to construct arbitrary interleavings of aliases and pointers from any default convertible to the same base type.
Based on #247 since it fixes bug resolving local package names