@@ -19,6 +19,7 @@ package status
19
19
import (
20
20
"context"
21
21
"fmt"
22
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22
23
"reflect"
23
24
24
25
appsv1 "k8s.io/api/apps/v1"
@@ -46,50 +47,94 @@ type aggregator struct {
46
47
func (a * aggregator ) Reconciled (ctx context.Context , src declarative.DeclarativeObject , objs * manifest.Objects ) error {
47
48
log := log .Log
48
49
49
- instance , ok := src .(addonv1alpha1.CommonObject )
50
- if ! ok {
51
- return fmt .Errorf ("object %T was not an addonv1alpha1.CommonObject" , src )
52
- }
53
-
54
- status := addonv1alpha1.CommonStatus {Healthy : true }
50
+ statusHealthy := true
51
+ statusErrors := []string {}
55
52
56
53
for _ , o := range objs .Items {
57
54
gk := o .Group + "/" + o .Kind
58
55
healthy := true
59
56
var err error
60
57
switch gk {
61
58
case "/Service" :
62
- healthy , err = a .service (ctx , instance , o .Name )
59
+ healthy , err = a .service (ctx , src , o .Name )
63
60
case "extensions/Deployment" , "apps/Deployment" :
64
- healthy , err = a .deployment (ctx , instance , o .Name )
61
+ healthy , err = a .deployment (ctx , src , o .Name )
65
62
default :
66
63
log .WithValues ("type" , gk ).V (2 ).Info ("type not implemented for status aggregation, skipping" )
67
64
}
68
65
69
- status . Healthy = status . Healthy && healthy
66
+ statusHealthy = statusHealthy && healthy
70
67
if err != nil {
71
- status . Errors = append (status . Errors , fmt .Sprintf ("%v" , err ))
68
+ statusErrors = append (statusErrors , fmt .Sprintf ("%v" , err ))
72
69
}
73
70
}
74
71
75
- log .WithValues ("object" , src ).WithValues ("status" , status ).V (2 ).Info ("built status" )
72
+ log .WithValues ("object" , src ).WithValues ("status" , statusHealthy ).V (2 ).Info ("built status" )
76
73
77
- if ! reflect . DeepEqual ( status , instance . GetCommonStatus ()) {
78
- instance . SetCommonStatus ( status )
74
+ unstruct , ok := src .( * unstructured. Unstructured )
75
+ instance , commonOkay := src .(addonv1alpha1. CommonObject )
79
76
80
- log .WithValues ("name" , instance .GetName ()).WithValues ("status" , status ).Info ("updating status" )
77
+ unstructStatus := make (map [string ]interface {})
78
+ var status addonv1alpha1.CommonStatus
79
+
80
+ if ok {
81
+ unstructStatus ["Healthy" ] = true
82
+ } else if commonOkay {
83
+ status = addonv1alpha1.CommonStatus {Healthy : true }
84
+ } else {
85
+ return fmt .Errorf ("object %T was not an addonv1alpha1.CommonObject" , src )
86
+ }
81
87
82
- err := a .client .Update (ctx , instance )
88
+ if commonOkay {
89
+ status .Errors = statusErrors
90
+ status .Healthy = statusHealthy
91
+
92
+ if ! reflect .DeepEqual (status , instance .GetCommonStatus ()) {
93
+ instance .SetCommonStatus (status )
94
+
95
+ log .WithValues ("name" , instance .GetName ()).WithValues ("status" , status ).Info ("updating status" )
96
+
97
+ err := a .client .Update (ctx , instance )
98
+ if err != nil {
99
+ log .Error (err , "updating status" )
100
+ return err
101
+ }
102
+ }
103
+ } else {
104
+ unstructStatus ["Healthy" ] = true
105
+ unstructStatus ["Errors" ] = statusErrors
106
+ s , _ , err := unstructured .NestedMap (unstruct .Object , "status" )
83
107
if err != nil {
84
- log .Error (err , "updating status" )
85
- return err
108
+ log .Error (err , "getting status" )
109
+ return fmt .Errorf ("unable to get status from unstructured: %v" , err )
110
+ }
111
+ if ! reflect .DeepEqual (status , s ) {
112
+ err = unstructured .SetNestedField (unstruct .Object , statusHealthy , "status" , "healthy" )
113
+ if err != nil {
114
+ log .Error (err , "updating status" )
115
+ return fmt .Errorf ("unable to set status in unstructured: %v" , err )
116
+ }
117
+
118
+ err = unstructured .SetNestedStringSlice (unstruct .Object , statusErrors , "status" , "errors" )
119
+ if err != nil {
120
+ log .Error (err , "updating status" )
121
+ return fmt .Errorf ("unable to set status in unstructured: %v" , err )
122
+ }
123
+
124
+ log .WithValues ("name" , unstruct .GetName ()).WithValues ("status" , status ).Info ("updating status" )
125
+
126
+ err = a .client .Update (ctx , unstruct )
127
+ if err != nil {
128
+ log .Error (err , "updating status" )
129
+ return err
130
+ }
86
131
}
87
132
}
88
133
89
134
return nil
90
135
}
91
136
92
- func (a * aggregator ) deployment (ctx context.Context , src addonv1alpha1. CommonObject , name string ) (bool , error ) {
137
+ func (a * aggregator ) deployment (ctx context.Context , src declarative. DeclarativeObject , name string ) (bool , error ) {
93
138
key := client.ObjectKey {Namespace : src .GetNamespace (), Name : name }
94
139
dep := & appsv1.Deployment {}
95
140
@@ -106,7 +151,7 @@ func (a *aggregator) deployment(ctx context.Context, src addonv1alpha1.CommonObj
106
151
return false , fmt .Errorf ("deployment (%s) does not meet condition: %s" , key , successfulDeployment )
107
152
}
108
153
109
- func (a * aggregator ) service (ctx context.Context , src addonv1alpha1. CommonObject , name string ) (bool , error ) {
154
+ func (a * aggregator ) service (ctx context.Context , src declarative. DeclarativeObject , name string ) (bool , error ) {
110
155
key := client.ObjectKey {Namespace : src .GetNamespace (), Name : name }
111
156
svc := & corev1.Service {}
112
157
err := a .client .Get (ctx , key , svc )
0 commit comments