Skip to content

Commit 1b07d87

Browse files
committed
Base preflight check function
1 parent a32c56c commit 1b07d87

File tree

5 files changed

+131
-9
lines changed

5 files changed

+131
-9
lines changed

go.sum

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34
124124
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
125125
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
126126
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
127-
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
128127
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
129128
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
130129
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
@@ -214,7 +213,6 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
214213
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
215214
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
216215
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
217-
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
218216
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
219217
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
220218
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -289,7 +287,6 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN
289287
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
290288
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
291289
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
292-
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
293290
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
294291
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
295292
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
@@ -324,12 +321,10 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
324321
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
325322
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
326323
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
327-
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
328324
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
329325
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
330326
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
331327
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
332-
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
333328
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
334329
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
335330
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
@@ -346,23 +341,19 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
346341
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
347342
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
348343
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
349-
github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
350344
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
351345
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
352346
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
353347
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
354-
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
355348
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
356349
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
357350
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
358351
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
359352
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
360-
github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
361353
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
362354
github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw=
363355
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
364356
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
365-
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
366357
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
367358
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
368359
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=

pkg/patterns/addon/pkg/status/basic.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,13 @@ func NewBasic(client client.Client) declarative.Status {
2929
// no preflight checks
3030
}
3131
}
32+
33+
// NewBasicVersionCheck provides an implementation of declarative.Status that
34+
// performs version checks for the version of the operator that the manifest requires.
35+
func NewBasicVersionChecks(client client.Client, version string) declarative.Status {
36+
return &declarative.StatusBuilder{
37+
ReconciledImpl: NewAggregator(client),
38+
VersionCheckImpl: NewVersionCheck(client, version),
39+
// no preflight checks
40+
}
41+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package status
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"github.com/blang/semver"
7+
"sigs.k8s.io/controller-runtime/pkg/client"
8+
"sigs.k8s.io/controller-runtime/pkg/log"
9+
addonsv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
10+
11+
//"sigs.k8s.io/controller-runtime/pkg/log"
12+
13+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
14+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative/pkg/manifest"
15+
)
16+
17+
// NewVersionCheck provides an implementation of declarative.Reconciled that
18+
// checks the version of the operator if it is up to the version required by the manifest
19+
func NewVersionCheck(client client.Client, version string) *versionCheck {
20+
return &versionCheck{client, version}
21+
}
22+
23+
type versionCheck struct {
24+
client client.Client
25+
version string
26+
}
27+
28+
func (p *versionCheck) VersionCheck(
29+
ctx context.Context,
30+
src declarative.DeclarativeObject,
31+
objs *manifest.Objects,
32+
) (bool, error) {
33+
log := log.Log
34+
zeroVersion := semver.Version{}
35+
var versionNeededStr string
36+
maxVersion := zeroVersion
37+
38+
// Look for annotation from any resource with the max version
39+
for _, obj := range objs.Items {
40+
unstruct := obj.UnstructuredObject().Object
41+
metadata := unstruct["metadata"].(map[string]interface{})
42+
annotations, ok := metadata["annotations"].(map[string]interface{})
43+
if ok {
44+
versionNeededStr, _ = annotations["addons.k8s.io/operator-version"].(string)
45+
log.WithValues("version", versionNeededStr).Info("Got version, %v")
46+
47+
versionActual, err := semver.Make(versionNeededStr)
48+
if err != nil {
49+
log.WithValues("version", versionNeededStr).Info("Unable to convert string to version, skipping this object")
50+
continue
51+
}
52+
53+
if versionActual.GT(maxVersion) {
54+
maxVersion = versionActual
55+
}
56+
}
57+
}
58+
59+
// TODO(somtochi): Do we want to return an error when the version is invalid or just skip and use the operator?
60+
operatorVersion, err := semver.Make(p.version)
61+
if err != nil {
62+
log.WithValues("version", p.version).Info("Unable to convert string to version, skipping check")
63+
return true, nil
64+
}
65+
66+
if maxVersion.Equals(zeroVersion) || !maxVersion.GT(operatorVersion) {
67+
return true, nil
68+
}
69+
70+
addonObject, ok := src.(addonsv1alpha1.CommonObject)
71+
if !ok {
72+
return false, fmt.Errorf("object %T was not an addonsv1alpha1.CommonObject", src)
73+
}
74+
75+
status := addonsv1alpha1.CommonStatus{
76+
Healthy: false,
77+
Errors: []string{
78+
fmt.Sprintf("Addons needs version %v, this operator is version %v", maxVersion.String(), operatorVersion.String()),
79+
},
80+
}
81+
log.WithValues("name", addonObject.GetName()).WithValues("status", status).Info("updating status")
82+
addonObject.SetCommonStatus(status)
83+
84+
return false, fmt.Errorf("operator not qualified, manifest needs operator >= %v", maxVersion.String())
85+
}

pkg/patterns/declarative/reconciler.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ func (r *Reconciler) Reconcile(request reconcile.Request) (result reconcile.Resu
115115
}
116116

117117
if r.options.status != nil {
118+
<<<<<<< HEAD
118119
if err = r.options.status.Preflight(ctx, instance); err != nil {
120+
=======
121+
if err := r.options.status.Preflight(ctx, instance); err != nil {
122+
>>>>>>> 3128f67... Changes preflight to version checks
119123
log.Error(err, "preflight check failed, not reconciling")
120124
return reconcile.Result{}, err
121125
}
@@ -140,6 +144,22 @@ func (r *Reconciler) reconcileExists(ctx context.Context, name types.NamespacedN
140144
}
141145
log.WithValues("objects", fmt.Sprintf("%d", len(objects.Items))).Info("built deployment objects")
142146

147+
if r.options.status != nil {
148+
bool, err := r.options.status.VersionCheck(ctx, instance, objects)
149+
if err != nil {
150+
if !bool {
151+
// r.client isn't exported so can't be updated in version check function
152+
r.client.Status().Update(ctx, instance)
153+
recorder := r.mgr.GetEventRecorderFor(fmt.Sprintf("%v", instance.GetName()))
154+
recorder.Event(instance, "Warning", "Failed version check", err.Error())
155+
log.Error(err, "Version check failed, not reconciling")
156+
return reconcile.Result{}, nil
157+
}
158+
log.Error(err, "Version check failed, trying to reconcile")
159+
return reconcile.Result{}, err
160+
}
161+
}
162+
143163
defer func() {
144164
if r.options.status != nil {
145165
if err := r.options.status.Reconciled(ctx, instance, objects); err != nil {

pkg/patterns/declarative/status.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
type Status interface {
2727
Reconciled
2828
Preflight
29+
VersionCheck
2930
}
3031

3132
type Reconciled interface {
@@ -42,10 +43,18 @@ type Preflight interface {
4243
Preflight(context.Context, DeclarativeObject) error
4344
}
4445

46+
type VersionCheck interface {
47+
// VersionCheck checks if the version of the operator is greater than or equal to the
48+
//version requested by objects in the manifest, if it isn't it updates the status and
49+
// events and stops reconciling
50+
VersionCheck(context.Context, DeclarativeObject, *manifest.Objects) (bool, error)
51+
}
52+
4553
// StatusBuilder provides a pluggable implementation of Status
4654
type StatusBuilder struct {
4755
ReconciledImpl Reconciled
4856
PreflightImpl Preflight
57+
VersionCheckImpl VersionCheck
4958
}
5059

5160
func (s *StatusBuilder) Reconciled(ctx context.Context, src DeclarativeObject, objs *manifest.Objects) error {
@@ -62,4 +71,11 @@ func (s *StatusBuilder) Preflight(ctx context.Context, src DeclarativeObject) er
6271
return nil
6372
}
6473

74+
func (s *StatusBuilder) VersionCheck(ctx context.Context, src DeclarativeObject,objs *manifest.Objects) (bool, error) {
75+
if s.VersionCheckImpl != nil {
76+
return s.VersionCheckImpl.VersionCheck(ctx, src, objs)
77+
}
78+
return true, nil
79+
}
80+
6581
var _ Status = &StatusBuilder{}

0 commit comments

Comments
 (0)