Skip to content

Commit 045672b

Browse files
authored
Merge pull request #118 from SomtochiAma/helper-functions
Refactors code to set and get status from object
2 parents 46c90d1 + 462d6f7 commit 045672b

File tree

6 files changed

+88
-143
lines changed

6 files changed

+88
-143
lines changed

pkg/patterns/addon/application.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package addon
1919
import (
2020
"context"
2121
"errors"
22-
"fmt"
2322

2423
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/utils"
2524
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
@@ -42,15 +41,17 @@ const (
4241

4342
// TransformApplicationFromStatus modifies the Application in the deployment based off the CommonStatus
4443
func TransformApplicationFromStatus(ctx context.Context, instance declarative.DeclarativeObject, objects *manifest.Objects) error {
45-
version, err := utils.GetCommonVersion(instance)
44+
status, err := utils.GetCommonStatus(instance)
4645
if err != nil {
47-
return fmt.Errorf("unable to get version from object: %v", err)
46+
return err
4847
}
48+
healthy := status.Healthy
4949

50-
healthy, err := utils.GetCommonHealth(instance)
50+
spec, err := utils.GetCommonSpec(instance)
5151
if err != nil {
52-
return fmt.Errorf("unable to get health from object: %v", err)
52+
return err
5353
}
54+
version := spec.Version
5455

5556
app, err := declarative.ExtractApplication(objects)
5657
if err != nil {

pkg/patterns/addon/pkg/loaders/fs.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,18 @@ func (c *ManifestLoader) ResolveManifest(ctx context.Context, object runtime.Obj
6565
componentName string
6666
)
6767

68-
version, err := utils.GetCommonVersion(object)
68+
spec, err := utils.GetCommonSpec(object)
6969
if err != nil {
7070
return nil, err
7171
}
72+
version = spec.Version
73+
channelName = spec.Channel
7274

7375
componentName, err = utils.GetCommonName(object)
7476
if err != nil {
7577
return nil, err
7678
}
7779

78-
channelName, err = utils.GetCommonChannel(object)
79-
if err != nil {
80-
return nil, err
81-
}
82-
8380
// TODO: We should actually do id (1.1.2-aws or 1.1.1-nginx). But maybe YAGNI
8481
id := version
8582

pkg/patterns/addon/pkg/status/aggregate.go

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ import (
2121
"fmt"
2222
"reflect"
2323

24-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
24+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/utils"
2525

2626
appsv1 "k8s.io/api/apps/v1"
2727
corev1 "k8s.io/api/core/v1"
2828
"sigs.k8s.io/controller-runtime/pkg/client"
2929
"sigs.k8s.io/controller-runtime/pkg/log"
30-
addonv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
3130
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
3231
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative/pkg/manifest"
3332
)
@@ -80,54 +79,23 @@ func (a *aggregator) Reconciled(ctx context.Context, src declarative.Declarative
8079

8180
log.WithValues("object", src).WithValues("status", statusHealthy).V(2).Info("built status")
8281

83-
unstruct, ok := src.(*unstructured.Unstructured)
84-
instance, commonOkay := src.(addonv1alpha1.CommonObject)
85-
changed := false
86-
87-
if commonOkay {
88-
var status = instance.GetCommonStatus()
89-
status.Errors = statusErrors
90-
status.Healthy = statusHealthy
91-
92-
if !reflect.DeepEqual(status, instance.GetCommonStatus()) {
93-
status.Healthy = statusHealthy
82+
currentStatus, err := utils.GetCommonStatus(src)
83+
if err != nil {
84+
return err
85+
}
9486

95-
log.WithValues("name", instance.GetName()).WithValues("status", status).Info("updating status")
96-
changed = true
97-
}
98-
} else if ok {
99-
unstructStatus := make(map[string]interface{})
87+
status := currentStatus
88+
status.Healthy = statusHealthy
89+
status.Errors = statusErrors
10090

101-
s, _, err := unstructured.NestedMap(unstruct.Object, "status")
91+
if !reflect.DeepEqual(status, currentStatus) {
92+
err := utils.SetCommonStatus(src, status)
10293
if err != nil {
103-
log.Error(err, "getting status")
104-
return fmt.Errorf("unable to get status from unstructured: %v", err)
105-
}
106-
107-
unstructStatus = s
108-
unstructStatus["Healthy"] = statusHealthy
109-
unstructStatus["Errors"] = statusErrors
110-
if !reflect.DeepEqual(unstruct, s) {
111-
err = unstructured.SetNestedField(unstruct.Object, statusHealthy, "status", "healthy")
112-
if err != nil {
113-
log.Error(err, "updating status")
114-
return fmt.Errorf("unable to set status in unstructured: %v", err)
115-
}
116-
117-
err = unstructured.SetNestedStringSlice(unstruct.Object, statusErrors, "status", "errors")
118-
if err != nil {
119-
log.Error(err, "updating status")
120-
return fmt.Errorf("unable to set status in unstructured: %v", err)
121-
}
122-
changed = true
94+
return err
12395
}
124-
} else {
125-
return fmt.Errorf("instance %T was not an addonsv1alpha1.CommonObject or unstructured.Unstructured", src)
126-
}
12796

128-
if changed == true {
129-
log.WithValues("name", src.GetName()).WithValues("status", statusHealthy).Info("updating status")
130-
err := a.client.Status().Update(ctx, src)
97+
log.WithValues("name", src.GetName()).WithValues("status", status).Info("updating status")
98+
err = a.client.Status().Update(ctx, src)
13199
if err != nil {
132100
log.Error(err, "updating status")
133101
return err

pkg/patterns/addon/pkg/status/kstatus.go

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import (
44
"context"
55
"fmt"
66

7-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
87
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
98
"sigs.k8s.io/controller-runtime/pkg/client"
109
"sigs.k8s.io/controller-runtime/pkg/log"
11-
addonsv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
10+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/utils"
1211
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
1312
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative/pkg/manifest"
1413
)
@@ -47,41 +46,21 @@ func (k *kstatusAggregator) Reconciled(ctx context.Context, src declarative.Decl
4746
}
4847
}
4948

50-
addonObject, ok := src.(addonsv1alpha1.CommonObject)
51-
unstruct, unstructOk := src.(*unstructured.Unstructured)
5249
aggregatedPhase := string(aggregateStatus(statusMap))
53-
changed := false
54-
if ok {
55-
addonStatus := addonObject.GetCommonStatus()
56-
if addonStatus.Phase != aggregatedPhase {
57-
addonStatus.Phase = aggregatedPhase
58-
addonObject.SetCommonStatus(addonStatus)
59-
changed = true
60-
}
61-
} else if unstructOk {
62-
statusPhase, _, err := unstructured.NestedString(unstruct.Object, "status", "phase")
50+
51+
currentStatus, err := utils.GetCommonStatus(src)
52+
if err != nil {
53+
log.Error(err, "error retrieving status")
54+
return err
55+
}
56+
if currentStatus.Phase != aggregatedPhase {
57+
currentStatus.Phase = aggregatedPhase
58+
err := utils.SetCommonStatus(src, currentStatus)
6359
if err != nil {
64-
log.Error(err, "error retrieving status")
6560
return err
6661
}
67-
68-
if statusPhase != aggregatedPhase {
69-
err := unstructured.SetNestedField(unstruct.Object, aggregatedPhase, "status", "phase")
70-
if err != nil {
71-
log.Error(err, "error retrieving status")
72-
return err
73-
}
74-
changed = true
75-
}
76-
} else {
77-
return fmt.Errorf("instance %T was not an addonsv1alpha1.CommonObject or unstructured."+
78-
"Unstructured",
79-
src)
80-
}
81-
82-
if changed == true {
8362
log.WithValues("name", src.GetName()).WithValues("phase", aggregatedPhase).Info("updating status")
84-
err := k.client.Status().Update(ctx, src)
63+
err = k.client.Status().Update(ctx, src)
8564
if err != nil {
8665
log.Error(err, "error updating status")
8766
return fmt.Errorf("error error status: %v", err)

pkg/patterns/addon/pkg/status/version.go

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ import (
66
"reflect"
77

88
"github.com/blang/semver"
9-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
109
"sigs.k8s.io/controller-runtime/pkg/client"
1110
"sigs.k8s.io/controller-runtime/pkg/log"
12-
addonsv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
11+
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/utils"
1312

1413
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative"
1514
"sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/declarative/pkg/manifest"
@@ -64,44 +63,22 @@ func (p *versionCheck) VersionCheck(
6463
fmt.Sprintf("manifest needs operator version >= %v, this operator is version %v", minOperatorVersion.String(),
6564
p.operatorVersion.String()),
6665
}
67-
unstruct, ok := src.(*unstructured.Unstructured)
68-
addonObject, commonOkay := src.(addonsv1alpha1.CommonObject)
6966

70-
if ok {
71-
unstructStatus := make(map[string]interface{})
72-
73-
s, _, err := unstructured.NestedMap(unstruct.Object, "status")
74-
if err != nil {
75-
log.Error(err, "getting status")
76-
return false, fmt.Errorf("unable to get status from unstructured: %v", err)
77-
}
78-
79-
unstructStatus = s
80-
unstructStatus["Healthy"] = false
81-
unstructStatus["Errors"] = errors
67+
currentStatus, err := utils.GetCommonStatus(src)
68+
if err != nil {
69+
log.Error(err, "getting status")
70+
return false, err
71+
}
8272

83-
if !reflect.DeepEqual(unstruct, s) {
84-
err = unstructured.SetNestedField(unstruct.Object, false, "status", "healthy")
85-
if err != nil {
86-
log.Error(err, "unable to updating status in unstructured")
87-
}
73+
status := currentStatus
74+
status.Healthy = false
75+
status.Errors = errors
8876

89-
err = unstructured.SetNestedStringSlice(unstruct.Object, errors, "status", "errors")
90-
if err != nil {
91-
log.Error(err, "unable to updating status in unstructured")
92-
}
93-
}
94-
} else if commonOkay {
95-
status := addonObject.GetCommonStatus()
96-
status.Healthy = false
97-
status.Errors = errors
98-
if !reflect.DeepEqual(status, addonObject.GetCommonStatus()) {
99-
status.Healthy = false
100-
status.Errors = errors
101-
addonObject.SetCommonStatus(status)
77+
if !reflect.DeepEqual(status, currentStatus) {
78+
err := utils.SetCommonStatus(src, status)
79+
if err != nil {
80+
log.Error(err, "unable to updating status")
10281
}
103-
} else {
104-
return false, fmt.Errorf("instance %T was not an addonsv1alpha1.CommonObject or unstructured.Unstructured", src)
10582
}
10683

10784
return false, fmt.Errorf("operator not qualified, manifest needs operator version >= %v", minOperatorVersion.String())

pkg/patterns/addon/pkg/utils/helpers.go

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,71 @@ import (
99
addonsv1alpha1 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/apis/v1alpha1"
1010
)
1111

12-
func GetCommonVersion(instance runtime.Object) (string, error) {
12+
func genError(v runtime.Object) error {
13+
return fmt.Errorf("instance %T is not addonsv1alpha1.CommonObject or unstructured", v)
14+
}
15+
16+
func GetCommonStatus(instance runtime.Object) (addonsv1alpha1.CommonStatus, error) {
1317
switch v := instance.(type) {
1418
case addonsv1alpha1.CommonObject:
15-
return v.CommonSpec().Version, nil
19+
return v.GetCommonStatus(), nil
1620
case *unstructured.Unstructured:
17-
version, _, err := unstructured.NestedString(v.Object, "spec", "version")
21+
unstructStatus, _, err := unstructured.NestedMap(v.Object, "status")
22+
if err != nil {
23+
return addonsv1alpha1.CommonStatus{}, fmt.Errorf("unable to get status from unstuctured: %v", err)
24+
}
25+
var addonStatus addonsv1alpha1.CommonStatus
26+
err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructStatus, &addonStatus)
1827
if err != nil {
19-
return "", fmt.Errorf("unable to get version from unstuctured: %v", err)
28+
return addonStatus, err
2029
}
21-
return version, nil
30+
31+
return addonStatus, nil
2232
default:
23-
return "", fmt.Errorf("instance %T is not addonsv1alpha1.CommonObject or unstructured", v)
33+
return addonsv1alpha1.CommonStatus{}, genError(v)
2434
}
2535
}
2636

27-
func GetCommonHealth(instance runtime.Object) (bool, error) {
37+
func SetCommonStatus(instance runtime.Object, status addonsv1alpha1.CommonStatus) error {
2838
switch v := instance.(type) {
2939
case addonsv1alpha1.CommonObject:
30-
return v.GetCommonStatus().Healthy, nil
40+
v.SetCommonStatus(status)
3141
case *unstructured.Unstructured:
32-
version, _, err := unstructured.NestedBool(v.Object, "status", "healthy")
42+
unstructStatus, err := runtime.DefaultUnstructuredConverter.ToUnstructured(status)
43+
if err != nil {
44+
return fmt.Errorf("unable to convert unstructured to addonStatus: %v", err)
45+
}
46+
47+
err = unstructured.SetNestedMap(v.Object, unstructStatus, "status")
3348
if err != nil {
34-
return false, fmt.Errorf("unable to get version from unstuctured: %v", err)
49+
return fmt.Errorf("unable to set status in unstructured: %v", err)
3550
}
36-
return version, nil
51+
52+
return nil
3753
default:
38-
return false, fmt.Errorf("instance %T is not addonsv1alpha1.CommonObject or unstructured", v)
54+
return genError(v)
3955
}
56+
return nil
4057
}
4158

42-
func GetCommonChannel(instance runtime.Object) (string, error) {
59+
func GetCommonSpec(instance runtime.Object) (addonsv1alpha1.CommonSpec, error) {
4360
switch v := instance.(type) {
4461
case addonsv1alpha1.CommonObject:
45-
return v.CommonSpec().Channel, nil
62+
return v.CommonSpec(), nil
4663
case *unstructured.Unstructured:
47-
channel, _, err := unstructured.NestedString(v.Object, "spec", "channel")
64+
unstructSpec, _, err := unstructured.NestedMap(v.Object, "spec")
4865
if err != nil {
49-
return "", fmt.Errorf("unable to get version from unstuctured: %v", err)
66+
return addonsv1alpha1.CommonSpec{}, fmt.Errorf("unable to get spec from unstuctured: %v", err)
5067
}
51-
return channel, nil
68+
var addonSpec addonsv1alpha1.CommonSpec
69+
err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructSpec, &addonSpec)
70+
if err != nil {
71+
return addonSpec, err
72+
}
73+
74+
return addonSpec, nil
5275
default:
53-
return "", fmt.Errorf("instance %T is not addonsv1alpha1.CommonObject or unstructured", v)
76+
return addonsv1alpha1.CommonSpec{}, genError(v)
5477
}
5578
}
5679

@@ -61,6 +84,6 @@ func GetCommonName(instance runtime.Object) (string, error) {
6184
case *unstructured.Unstructured:
6285
return strings.ToLower(v.GetKind()), nil
6386
default:
64-
return "", fmt.Errorf("instance %T is not addonsv1alpha1.CommonObject or unstructured", v)
87+
return "", genError(v)
6588
}
6689
}

0 commit comments

Comments
 (0)