Skip to content

Commit 6103636

Browse files
authored
Merge pull request #4897 from camilamacedo86/deploy-image
🐛 (deploy-image/v1alpha): ensure that api scaffold are following k8s api conventions
2 parents 5837b2d + 910bf55 commit 6103636

28 files changed

+911
-221
lines changed

diff.txt

Lines changed: 540 additions & 0 deletions
Large diffs are not rendered by default.

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ require (
2525
github.com/inconshreveable/mousetrap v1.1.0 // indirect
2626
github.com/kr/pretty v0.3.1 // indirect
2727
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
28-
github.com/rogpeppe/go-internal v1.12.0 // indirect
29-
github.com/stretchr/testify v1.9.0 // indirect
28+
github.com/rogpeppe/go-internal v1.14.1 // indirect
29+
github.com/stretchr/testify v1.10.0 // indirect
3030
go.uber.org/automaxprocs v1.6.0 // indirect
3131
go.yaml.in/yaml/v2 v2.4.2 // indirect
3232
golang.org/x/net v0.41.0 // indirect
3333
golang.org/x/sync v0.15.0 // indirect
3434
golang.org/x/sys v0.33.0 // indirect
35+
google.golang.org/protobuf v1.36.6 // indirect
3536
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
3637
gopkg.in/yaml.v3 v3.0.1 // indirect
3738
)

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH
3434
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
3535
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
3636
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
37-
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
38-
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
37+
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
38+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
3939
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
4040
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
4141
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -52,8 +52,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
5252
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5353
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
5454
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
55-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
56-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
55+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
56+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
5757
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
5858
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
5959
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
@@ -73,8 +73,8 @@ golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
7373
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
7474
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
7575
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
76-
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
77-
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
76+
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
77+
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
7878
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
7979
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
8080
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/internal/templates/api/types.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,19 @@ import (
7575
type {{ .Resource.Kind }}Spec struct {
7676
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
7777
// Important: Run "make" to regenerate code after modifying this file
78-
79-
// Size defines the number of {{ .Resource.Kind }} instances
8078
// The following markers will use OpenAPI v3 schema to validate the value
8179
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
82-
// +kubebuilder:validation:Minimum=1
83-
Size int32 ` + "`" + `json:"size,omitempty"` + "`" + `
80+
81+
// size defines the number of {{ .Resource.Kind }} instances
82+
// +kubebuilder:default=1
83+
// +kubebuilder:validation:Minimum=0
84+
// +optional
85+
Size *int32 ` + "`" + `json:"size,omitempty"` + "`" + `
8486
8587
{{ if not (isEmptyStr .Port) -}}
86-
// Port defines the port that will be used to init the container with the image
87-
ContainerPort int32 ` + "`" + `json:"containerPort,omitempty"` + "`" + `
88+
// containerPort defines the port that will be used to init the container with the image
89+
// +required
90+
ContainerPort int32 ` + "`" + `json:"containerPort"` + "`" + `
8891
{{- end }}
8992
}
9093
@@ -97,13 +100,14 @@ type {{ .Resource.Kind }}Status struct {
97100
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
98101
//
99102
// Standard condition types include:
100-
// - "Available": the resource is fully functional.
101-
// - "Progressing": the resource is being created or updated.
102-
// - "Degraded": the resource failed to reach or maintain its desired state.
103+
// - "Available": the resource is fully functional
104+
// - "Progressing": the resource is being created or updated
105+
// - "Degraded": the resource failed to reach or maintain its desired state
103106
//
104107
// The status of each condition is one of True, False, or Unknown.
105108
// +listType=map
106109
// +listMapKey=type
110+
// +optional
107111
Conditions []metav1.Condition ` + "`" + `json:"conditions,omitempty"` + "`" + `
108112
}
109113
@@ -120,10 +124,18 @@ type {{ .Resource.Kind }}Status struct {
120124
// {{ .Resource.Kind }} is the Schema for the {{ .Resource.Plural }} API
121125
type {{ .Resource.Kind }} struct {
122126
metav1.TypeMeta ` + "`" + `json:",inline"` + "`" + `
127+
128+
// metadata is a standard object metadata
129+
// +optional
123130
metav1.ObjectMeta ` + "`" + `json:"metadata,omitempty"` + "`" + `
124131
125-
Spec {{ .Resource.Kind }}Spec ` + "`" + `json:"spec,omitempty"` + "`" + `
126-
Status {{ .Resource.Kind }}Status ` + "`" + `json:"status,omitempty"` + "`" + `
132+
// spec defines the desired state of {{ .Resource.Kind }}
133+
// +required
134+
Spec {{ .Resource.Kind }}Spec ` + "`" + `json:"spec"` + "`" + `
135+
136+
// status defines the observed state of {{ .Resource.Kind }}
137+
// +optional
138+
Status *{{ .Resource.Kind }}Status ` + "`" + `json:"status,omitempty"` + "`" + `
127139
}
128140
129141
// +kubebuilder:object:root=true

pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/internal/templates/controllers/controller-test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import (
7777
"k8s.io/apimachinery/pkg/api/errors"
7878
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7979
"k8s.io/apimachinery/pkg/types"
80+
"k8s.io/utils/ptr"
8081
"sigs.k8s.io/controller-runtime/pkg/reconcile"
8182
8283
{{ if not (isEmptyStr .Resource.Path) -}}
@@ -121,13 +122,13 @@ var _ = Describe("{{ .Resource.Kind }} controller", func() {
121122
if err != nil && errors.IsNotFound(err) {
122123
// Let's mock our custom resource at the same way that we would
123124
// apply on the cluster the manifest under config/samples
124-
{{ lower .Resource.Kind }} := &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{
125+
{{ lower .Resource.Kind }} = &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}{
125126
ObjectMeta: metav1.ObjectMeta{
126127
Name: {{ .Resource.Kind }}Name,
127128
Namespace: namespace.Name,
128129
},
129130
Spec: {{ .Resource.ImportAlias }}.{{ .Resource.Kind }}Spec{
130-
Size: 1,
131+
Size: ptr.To(int32(1)),
131132
{{ if not (isEmptyStr .Port) -}}
132133
ContainerPort: {{ .Port }},
133134
{{- end }}

pkg/plugins/golang/deploy-image/v1alpha1/scaffolds/internal/templates/controllers/controller.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ func (r *{{ .Resource.Kind }}Reconciler) Reconcile(ctx context.Context, req ctrl
155155
}
156156
157157
// Let's just set the status as Unknown when no status is available
158+
if {{ lower .Resource.Kind }}.Status == nil {
159+
{{ lower .Resource.Kind }}.Status = &{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}Status{}
160+
}
161+
158162
if len({{ lower .Resource.Kind }}.Status.Conditions) == 0 {
159163
meta.SetStatusCondition(&{{ lower .Resource.Kind }}.Status.Conditions, metav1.Condition{Type: typeAvailable{{ .Resource.Kind }}, Status: metav1.ConditionUnknown, Reason: "Reconciling", Message: "Starting reconciliation"})
160164
if err = r.Status().Update(ctx, {{ lower .Resource.Kind }}); err != nil {
@@ -283,13 +287,18 @@ func (r *{{ .Resource.Kind }}Reconciler) Reconcile(ctx context.Context, req ctrl
283287
return ctrl.Result{}, err
284288
}
285289
290+
// If the size is not defined in the Custom Resource then we will set the desired replicas to 0
291+
var desiredReplicas int32 = 0
292+
if {{ lower .Resource.Kind }}.Spec.Size != nil {
293+
desiredReplicas = *{{ lower .Resource.Kind }}.Spec.Size
294+
}
295+
286296
// The CRD API defines that the {{ .Resource.Kind }} type have a {{ .Resource.Kind }}Spec.Size field
287297
// to set the quantity of Deployment instances to the desired state on the cluster.
288298
// Therefore, the following code will ensure the Deployment size is the same as defined
289299
// via the Size spec of the Custom Resource which we are reconciling.
290-
size := {{ lower .Resource.Kind }}.Spec.Size
291-
if *found.Spec.Replicas != size {
292-
found.Spec.Replicas = &size
300+
if found.Spec.Replicas == nil || *found.Spec.Replicas != desiredReplicas {
301+
found.Spec.Replicas = ptr.To(desiredReplicas)
293302
if err = r.Update(ctx, found); err != nil {
294303
log.Error(err, "Failed to update Deployment",
295304
"Deployment.Namespace", found.Namespace, "Deployment.Name", found.Name)
@@ -325,7 +334,7 @@ func (r *{{ .Resource.Kind }}Reconciler) Reconcile(ctx context.Context, req ctrl
325334
// The following implementation will update the status
326335
meta.SetStatusCondition(&{{ lower .Resource.Kind }}.Status.Conditions, metav1.Condition{Type: typeAvailable{{ .Resource.Kind }},
327336
Status: metav1.ConditionTrue, Reason: "Reconciling",
328-
Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", {{ lower .Resource.Kind }}.Name, size)})
337+
Message: fmt.Sprintf("Deployment for custom resource (%s) with %d replicas created successfully", {{ lower .Resource.Kind }}.Name, desiredReplicas)})
329338
330339
if err := r.Status().Update(ctx, {{ lower .Resource.Kind }}); err != nil {
331340
log.Error(err, "Failed to update {{ .Resource.Kind }} status")
@@ -359,7 +368,6 @@ func (r *{{ .Resource.Kind }}Reconciler) doFinalizerOperationsFor{{ .Resource.Ki
359368
func (r *{{ .Resource.Kind }}Reconciler) deploymentFor{{ .Resource.Kind }}(
360369
{{ lower .Resource.Kind }} *{{ .Resource.ImportAlias }}.{{ .Resource.Kind }}) (*appsv1.Deployment, error) {
361370
ls := labelsFor{{ .Resource.Kind }}()
362-
replicas := {{ lower .Resource.Kind }}.Spec.Size
363371
364372
// Get the Operand image
365373
image, err := imageFor{{ .Resource.Kind }}()
@@ -373,7 +381,7 @@ func (r *{{ .Resource.Kind }}Reconciler) deploymentFor{{ .Resource.Kind }}(
373381
Namespace: {{ lower .Resource.Kind }}.Namespace,
374382
},
375383
Spec: appsv1.DeploymentSpec{
376-
Replicas: &replicas,
384+
Replicas: {{ lower .Resource.Kind }}.Spec.Size,
377385
Selector: &metav1.LabelSelector{
378386
MatchLabels: ls,
379387
},

testdata/project-v4-multigroup/api/example.com/v1alpha1/busybox_types.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ import (
2727
type BusyboxSpec struct {
2828
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
2929
// Important: Run "make" to regenerate code after modifying this file
30-
31-
// Size defines the number of Busybox instances
3230
// The following markers will use OpenAPI v3 schema to validate the value
3331
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
34-
// +kubebuilder:validation:Minimum=1
35-
Size int32 `json:"size,omitempty"`
32+
33+
// size defines the number of Busybox instances
34+
// +kubebuilder:default=1
35+
// +kubebuilder:validation:Minimum=0
36+
// +optional
37+
Size *int32 `json:"size,omitempty"`
3638
}
3739

3840
// BusyboxStatus defines the observed state of Busybox
@@ -44,13 +46,14 @@ type BusyboxStatus struct {
4446
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
4547
//
4648
// Standard condition types include:
47-
// - "Available": the resource is fully functional.
48-
// - "Progressing": the resource is being created or updated.
49-
// - "Degraded": the resource failed to reach or maintain its desired state.
49+
// - "Available": the resource is fully functional
50+
// - "Progressing": the resource is being created or updated
51+
// - "Degraded": the resource failed to reach or maintain its desired state
5052
//
5153
// The status of each condition is one of True, False, or Unknown.
5254
// +listType=map
5355
// +listMapKey=type
56+
// +optional
5457
Conditions []metav1.Condition `json:"conditions,omitempty"`
5558
}
5659

@@ -59,11 +62,19 @@ type BusyboxStatus struct {
5962

6063
// Busybox is the Schema for the busyboxes API
6164
type Busybox struct {
62-
metav1.TypeMeta `json:",inline"`
65+
metav1.TypeMeta `json:",inline"`
66+
67+
// metadata is a standard object metadata
68+
// +optional
6369
metav1.ObjectMeta `json:"metadata,omitempty"`
6470

65-
Spec BusyboxSpec `json:"spec,omitempty"`
66-
Status BusyboxStatus `json:"status,omitempty"`
71+
// spec defines the desired state of Busybox
72+
// +required
73+
Spec BusyboxSpec `json:"spec"`
74+
75+
// status defines the observed state of Busybox
76+
// +optional
77+
Status *BusyboxStatus `json:"status,omitempty"`
6778
}
6879

6980
// +kubebuilder:object:root=true

testdata/project-v4-multigroup/api/example.com/v1alpha1/memcached_types.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,18 @@ import (
2727
type MemcachedSpec struct {
2828
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
2929
// Important: Run "make" to regenerate code after modifying this file
30-
31-
// Size defines the number of Memcached instances
3230
// The following markers will use OpenAPI v3 schema to validate the value
3331
// More info: https://book.kubebuilder.io/reference/markers/crd-validation.html
34-
// +kubebuilder:validation:Minimum=1
35-
Size int32 `json:"size,omitempty"`
3632

37-
// Port defines the port that will be used to init the container with the image
38-
ContainerPort int32 `json:"containerPort,omitempty"`
33+
// size defines the number of Memcached instances
34+
// +kubebuilder:default=1
35+
// +kubebuilder:validation:Minimum=0
36+
// +optional
37+
Size *int32 `json:"size,omitempty"`
38+
39+
// containerPort defines the port that will be used to init the container with the image
40+
// +required
41+
ContainerPort int32 `json:"containerPort"`
3942
}
4043

4144
// MemcachedStatus defines the observed state of Memcached
@@ -47,13 +50,14 @@ type MemcachedStatus struct {
4750
// Each condition has a unique type and reflects the status of a specific aspect of the resource.
4851
//
4952
// Standard condition types include:
50-
// - "Available": the resource is fully functional.
51-
// - "Progressing": the resource is being created or updated.
52-
// - "Degraded": the resource failed to reach or maintain its desired state.
53+
// - "Available": the resource is fully functional
54+
// - "Progressing": the resource is being created or updated
55+
// - "Degraded": the resource failed to reach or maintain its desired state
5356
//
5457
// The status of each condition is one of True, False, or Unknown.
5558
// +listType=map
5659
// +listMapKey=type
60+
// +optional
5761
Conditions []metav1.Condition `json:"conditions,omitempty"`
5862
}
5963

@@ -62,11 +66,19 @@ type MemcachedStatus struct {
6266

6367
// Memcached is the Schema for the memcacheds API
6468
type Memcached struct {
65-
metav1.TypeMeta `json:",inline"`
69+
metav1.TypeMeta `json:",inline"`
70+
71+
// metadata is a standard object metadata
72+
// +optional
6673
metav1.ObjectMeta `json:"metadata,omitempty"`
6774

68-
Spec MemcachedSpec `json:"spec,omitempty"`
69-
Status MemcachedStatus `json:"status,omitempty"`
75+
// spec defines the desired state of Memcached
76+
// +required
77+
Spec MemcachedSpec `json:"spec"`
78+
79+
// status defines the observed state of Memcached
80+
// +optional
81+
Status *MemcachedStatus `json:"status,omitempty"`
7082
}
7183

7284
// +kubebuilder:object:root=true

testdata/project-v4-multigroup/api/example.com/v1alpha1/zz_generated.deepcopy.go

Lines changed: 22 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)