Skip to content

Commit

Permalink
Teach go codegen to emit yaml struct tags (#504)
Browse files Browse the repository at this point in the history
We have command-line tooling that reads Kinds from multi-document yaml
files. Unmarshalling will not work on the yaml side without the correct
tags.
  • Loading branch information
bcotton authored Dec 2, 2024
1 parent 1beac10 commit bbd0371
Show file tree
Hide file tree
Showing 40 changed files with 406 additions and 387 deletions.
2 changes: 1 addition & 1 deletion codegen/templates/lineage.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var LacunaResolver func(*LineageType, []thema.Lacuna) error = nil
// and Object has extra fields for metadata (which necessarily cannot be rendered in the Lineage/Schema,
// but must exist for the Object). This is essentially an "intermediate step" struct.
type LineageType struct { {{ range .Subresources }}
{{.TypeName}} {{.TypeName}} `json:"{{.JSONName}}"`{{ end }}
{{.TypeName}} {{.TypeName}} `json:"{{.JSONName}}" yaml:"{{.JSONName}}"`{{ end }}
}

func init() {
Expand Down
14 changes: 7 additions & 7 deletions codegen/templates/resourceobject.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import ({{ range .CustomMetadataFields }}{{ range $imp := .GoType.AdditionalImpo

// +k8s:openapi-gen=true
type {{.TypeName}} struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec {{.SpecTypeName}} `json:"spec"`{{ range .Subresources }}{{ if ne .Comment "" }}
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
Spec {{.SpecTypeName}} `json:"spec" yaml:"spec"`{{ range .Subresources }}{{ if ne .Comment "" }}
// {{.Comment }}{{end}}
{{ .TypeName }} {{.TypeName}} `json:"{{.JSONName}}"`{{ end }}
{{ .TypeName }} {{.TypeName}} `json:"{{.JSONName}}" yaml:"{{.JSONName}}"`{{ end }}
}

func ({{.ObjectShortName}} *{{.TypeName}}) GetSpec() any {
Expand Down Expand Up @@ -196,9 +196,9 @@ var _ resource.Object = &{{.TypeName}}{}

// +k8s:openapi-gen=true
type {{.TypeName}}List struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []{{.TypeName}} `json:"items"`
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []{{.TypeName}} `json:"items" yaml:"items"`
}

func ({{.ObjectShortName}} *{{.TypeName}}List) DeepCopyObject() runtime.Object {
Expand Down
2 changes: 1 addition & 1 deletion codegen/templates/secure/data.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package secure

// Data is the go model of the plugin's secureJsonData
type Data struct {
AuthHeaderContent string `json:"auth_header_content"`
AuthHeaderContent string `json:"auth_header_content" yaml:"auth_header_content"`
}

// ParseRaw parses secure settings from a raw string map.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ import (

// CustomKindMetadata defines model for CustomKindMetadata.
type CustomKindMetadata struct {
CreatedBy string `json:"createdBy"`
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
Generation int64 `json:"generation"`
Labels map[string]string `json:"labels"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
UpdateTimestamp time.Time `json:"updateTimestamp"`
UpdatedBy string `json:"updatedBy"`
CreatedBy string `json:"createdBy" yaml:"createdBy"`
CreationTimestamp time.Time `json:"creationTimestamp" yaml:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty" yaml:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers" yaml:"finalizers"`
Generation int64 `json:"generation" yaml:"generation"`
Labels map[string]string `json:"labels" yaml:"labels"`
ResourceVersion string `json:"resourceVersion" yaml:"resourceVersion"`
Uid string `json:"uid" yaml:"uid"`
UpdateTimestamp time.Time `json:"updateTimestamp" yaml:"updateTimestamp"`
UpdatedBy string `json:"updatedBy" yaml:"updatedBy"`
}

// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
// It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
// As it is also intended to be generic enough to function with any API Server.
type CustomKindKubeObjectMetadata struct {
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
Generation int64 `json:"generation"`
Labels map[string]string `json:"labels"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
CreationTimestamp time.Time `json:"creationTimestamp" yaml:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty" yaml:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers" yaml:"finalizers"`
Generation int64 `json:"generation" yaml:"generation"`
Labels map[string]string `json:"labels" yaml:"labels"`
ResourceVersion string `json:"resourceVersion" yaml:"resourceVersion"`
Uid string `json:"uid" yaml:"uid"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (

// +k8s:openapi-gen=true
type CustomKind struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec CustomKindSpec `json:"spec"`
CustomKindStatus CustomKindStatus `json:"status"`
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
Spec CustomKindSpec `json:"spec" yaml:"spec"`
CustomKindStatus CustomKindStatus `json:"status" yaml:"status"`
}

func (o *CustomKind) GetSpec() any {
Expand Down Expand Up @@ -224,9 +224,9 @@ var _ resource.Object = &CustomKind{}

// +k8s:openapi-gen=true
type CustomKindList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []CustomKind `json:"items"`
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []CustomKind `json:"items" yaml:"items"`
}

func (o *CustomKindList) DeepCopyObject() runtime.Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ package v0_0
// CustomKindSpec defines model for CustomKindSpec.
// +k8s:openapi-gen=true
type CustomKindSpec struct {
DeprecatedField string `json:"deprecatedField"`
Field1 string `json:"field1"`
DeprecatedField string `json:"deprecatedField" yaml:"deprecatedField"`
Field1 string `json:"field1" yaml:"field1"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ const (
// +k8s:openapi-gen=true
type CustomKindOperatorState struct {
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
DescriptiveState *string `json:"descriptiveState,omitempty" yaml:"descriptiveState,omitempty"`

// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
Details map[string]interface{} `json:"details,omitempty" yaml:"details,omitempty"`

// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
LastEvaluation string `json:"lastEvaluation" yaml:"lastEvaluation"`

// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State CustomKindOperatorStateState `json:"state"`
State CustomKindOperatorStateState `json:"state" yaml:"state"`
}

// CustomKindOperatorStateState state describes the state of the lastEvaluation.
Expand All @@ -40,28 +40,28 @@ type CustomKindOperatorStateState string
// +k8s:openapi-gen=true
type CustomKindStatus struct {
// additionalFields is reserved for future use
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty" yaml:"additionalFields,omitempty"`

// operatorStates is a map of operator ID to operator state evaluations.
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
OperatorStates map[string]CustomKindstatusOperatorState `json:"operatorStates,omitempty"`
OperatorStates map[string]CustomKindstatusOperatorState `json:"operatorStates,omitempty" yaml:"operatorStates,omitempty"`
}

// CustomKindstatusOperatorState defines model for CustomKindstatus.#OperatorState.
// +k8s:openapi-gen=true
type CustomKindstatusOperatorState struct {
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
DescriptiveState *string `json:"descriptiveState,omitempty" yaml:"descriptiveState,omitempty"`

// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
Details map[string]interface{} `json:"details,omitempty" yaml:"details,omitempty"`

// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
LastEvaluation string `json:"lastEvaluation" yaml:"lastEvaluation"`

// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State CustomKindstatusOperatorStateState `json:"state"`
State CustomKindstatusOperatorStateState `json:"state" yaml:"state"`
}

// CustomKindstatusOperatorStateState state describes the state of the lastEvaluation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ import (

// CustomKindMetadata defines model for CustomKindMetadata.
type CustomKindMetadata struct {
CreatedBy string `json:"createdBy"`
CreationTimestamp time.Time `json:"creationTimestamp"`
CustomMetadataField string `json:"customMetadataField"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
Generation int64 `json:"generation"`
Labels map[string]string `json:"labels"`
OtherMetadataField string `json:"otherMetadataField"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
UpdateTimestamp time.Time `json:"updateTimestamp"`
UpdatedBy string `json:"updatedBy"`
CreatedBy string `json:"createdBy" yaml:"createdBy"`
CreationTimestamp time.Time `json:"creationTimestamp" yaml:"creationTimestamp"`
CustomMetadataField string `json:"customMetadataField" yaml:"customMetadataField"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty" yaml:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers" yaml:"finalizers"`
Generation int64 `json:"generation" yaml:"generation"`
Labels map[string]string `json:"labels" yaml:"labels"`
OtherMetadataField string `json:"otherMetadataField" yaml:"otherMetadataField"`
ResourceVersion string `json:"resourceVersion" yaml:"resourceVersion"`
Uid string `json:"uid" yaml:"uid"`
UpdateTimestamp time.Time `json:"updateTimestamp" yaml:"updateTimestamp"`
UpdatedBy string `json:"updatedBy" yaml:"updatedBy"`
}

// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field.
// It is not exhaustive and only includes fields which may be relevant to a kind's implementation,
// As it is also intended to be generic enough to function with any API Server.
type CustomKindKubeObjectMetadata struct {
CreationTimestamp time.Time `json:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers"`
Generation int64 `json:"generation"`
Labels map[string]string `json:"labels"`
ResourceVersion string `json:"resourceVersion"`
Uid string `json:"uid"`
CreationTimestamp time.Time `json:"creationTimestamp" yaml:"creationTimestamp"`
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty" yaml:"deletionTimestamp,omitempty"`
Finalizers []string `json:"finalizers" yaml:"finalizers"`
Generation int64 `json:"generation" yaml:"generation"`
Labels map[string]string `json:"labels" yaml:"labels"`
ResourceVersion string `json:"resourceVersion" yaml:"resourceVersion"`
Uid string `json:"uid" yaml:"uid"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (

// +k8s:openapi-gen=true
type CustomKind struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec CustomKindSpec `json:"spec"`
CustomKindStatus CustomKindStatus `json:"status"`
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
Spec CustomKindSpec `json:"spec" yaml:"spec"`
CustomKindStatus CustomKindStatus `json:"status" yaml:"status"`
}

func (o *CustomKind) GetSpec() any {
Expand Down Expand Up @@ -256,9 +256,9 @@ var _ resource.Object = &CustomKind{}

// +k8s:openapi-gen=true
type CustomKindList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`
Items []CustomKind `json:"items"`
metav1.TypeMeta `json:",inline" yaml:",inline"`
metav1.ListMeta `json:"metadata" yaml:"metadata"`
Items []CustomKind `json:"items" yaml:"items"`
}

func (o *CustomKindList) DeepCopyObject() runtime.Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,31 @@ const (
// CustomKindInnerObject1 defines model for CustomKindInnerObject1.
// +k8s:openapi-gen=true
type CustomKindInnerObject1 struct {
InnerField1 string `json:"innerField1"`
InnerField2 []string `json:"innerField2"`
InnerField3 []CustomKindInnerObject2 `json:"innerField3"`
InnerField1 string `json:"innerField1" yaml:"innerField1"`
InnerField2 []string `json:"innerField2" yaml:"innerField2"`
InnerField3 []CustomKindInnerObject2 `json:"innerField3" yaml:"innerField3"`
}

// CustomKindInnerObject2 defines model for CustomKindInnerObject2.
// +k8s:openapi-gen=true
type CustomKindInnerObject2 struct {
Details map[string]interface{} `json:"details"`
Name string `json:"name"`
Details map[string]interface{} `json:"details" yaml:"details"`
Name string `json:"name" yaml:"name"`
}

// CustomKindSpec defines model for CustomKindSpec.
// +k8s:openapi-gen=true
type CustomKindSpec struct {
BoolField bool `json:"boolField"`
Enum CustomKindSpecEnum `json:"enum"`
Field1 string `json:"field1"`
FloatField float64 `json:"floatField"`
I32 int `json:"i32"`
I64 int `json:"i64"`
Inner CustomKindInnerObject1 `json:"inner"`
Map map[string]CustomKindType2 `json:"map"`
Timestamp time.Time `json:"timestamp"`
Union interface{} `json:"union"`
BoolField bool `json:"boolField" yaml:"boolField"`
Enum CustomKindSpecEnum `json:"enum" yaml:"enum"`
Field1 string `json:"field1" yaml:"field1"`
FloatField float64 `json:"floatField" yaml:"floatField"`
I32 int `json:"i32" yaml:"i32"`
I64 int `json:"i64" yaml:"i64"`
Inner CustomKindInnerObject1 `json:"inner" yaml:"inner"`
Map map[string]CustomKindType2 `json:"map" yaml:"map"`
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
Union interface{} `json:"union" yaml:"union"`
}

// CustomKindSpecEnum defines model for CustomKindSpec.Enum.
Expand All @@ -50,13 +50,13 @@ type CustomKindSpecEnum string
// CustomKindType1 defines model for CustomKindType1.
// +k8s:openapi-gen=true
type CustomKindType1 struct {
Group string `json:"group"`
Options []string `json:"options,omitempty"`
Group string `json:"group" yaml:"group"`
Options []string `json:"options,omitempty" yaml:"options,omitempty"`
}

// CustomKindType2 defines model for CustomKindType2.
// +k8s:openapi-gen=true
type CustomKindType2 struct {
Details map[string]interface{} `json:"details"`
Group string `json:"group"`
Details map[string]interface{} `json:"details" yaml:"details"`
Group string `json:"group" yaml:"group"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ const (
// +k8s:openapi-gen=true
type CustomKindOperatorState struct {
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
DescriptiveState *string `json:"descriptiveState,omitempty" yaml:"descriptiveState,omitempty"`

// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
Details map[string]interface{} `json:"details,omitempty" yaml:"details,omitempty"`

// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
LastEvaluation string `json:"lastEvaluation" yaml:"lastEvaluation"`

// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State CustomKindOperatorStateState `json:"state"`
State CustomKindOperatorStateState `json:"state" yaml:"state"`
}

// CustomKindOperatorStateState state describes the state of the lastEvaluation.
Expand All @@ -40,29 +40,29 @@ type CustomKindOperatorStateState string
// +k8s:openapi-gen=true
type CustomKindStatus struct {
// additionalFields is reserved for future use
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty" yaml:"additionalFields,omitempty"`

// operatorStates is a map of operator ID to operator state evaluations.
// Any operator which consumes this kind SHOULD add its state evaluation information to this field.
OperatorStates map[string]CustomKindstatusOperatorState `json:"operatorStates,omitempty"`
StatusField1 string `json:"statusField1"`
OperatorStates map[string]CustomKindstatusOperatorState `json:"operatorStates,omitempty" yaml:"operatorStates,omitempty"`
StatusField1 string `json:"statusField1" yaml:"statusField1"`
}

// CustomKindstatusOperatorState defines model for CustomKindstatus.#OperatorState.
// +k8s:openapi-gen=true
type CustomKindstatusOperatorState struct {
// descriptiveState is an optional more descriptive state field which has no requirements on format
DescriptiveState *string `json:"descriptiveState,omitempty"`
DescriptiveState *string `json:"descriptiveState,omitempty" yaml:"descriptiveState,omitempty"`

// details contains any extra information that is operator-specific
Details map[string]interface{} `json:"details,omitempty"`
Details map[string]interface{} `json:"details,omitempty" yaml:"details,omitempty"`

// lastEvaluation is the ResourceVersion last evaluated
LastEvaluation string `json:"lastEvaluation"`
LastEvaluation string `json:"lastEvaluation" yaml:"lastEvaluation"`

// state describes the state of the lastEvaluation.
// It is limited to three possible states for machine evaluation.
State CustomKindstatusOperatorStateState `json:"state"`
State CustomKindstatusOperatorStateState `json:"state" yaml:"state"`
}

// CustomKindstatusOperatorStateState state describes the state of the lastEvaluation.
Expand Down
Loading

0 comments on commit bbd0371

Please sign in to comment.