-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unstructured support in different functions #112
Changes from all commits
24073d9
9f56540
c3a2e08
5ae7327
1a49843
9e95327
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ package status | |
import ( | ||
"context" | ||
"fmt" | ||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
"reflect" | ||
|
||
appsv1 "k8s.io/api/apps/v1" | ||
|
@@ -46,50 +47,94 @@ type aggregator struct { | |
func (a *aggregator) Reconciled(ctx context.Context, src declarative.DeclarativeObject, objs *manifest.Objects) error { | ||
log := log.Log | ||
|
||
instance, ok := src.(addonv1alpha1.CommonObject) | ||
if !ok { | ||
return fmt.Errorf("object %T was not an addonv1alpha1.CommonObject", src) | ||
} | ||
|
||
status := addonv1alpha1.CommonStatus{Healthy: true} | ||
statusHealthy := true | ||
statusErrors := []string{} | ||
|
||
for _, o := range objs.Items { | ||
gk := o.Group + "/" + o.Kind | ||
healthy := true | ||
var err error | ||
switch gk { | ||
case "/Service": | ||
healthy, err = a.service(ctx, instance, o.Name) | ||
healthy, err = a.service(ctx, src, o.Name) | ||
case "extensions/Deployment", "apps/Deployment": | ||
healthy, err = a.deployment(ctx, instance, o.Name) | ||
healthy, err = a.deployment(ctx, src, o.Name) | ||
default: | ||
log.WithValues("type", gk).V(2).Info("type not implemented for status aggregation, skipping") | ||
} | ||
|
||
status.Healthy = status.Healthy && healthy | ||
statusHealthy = statusHealthy && healthy | ||
if err != nil { | ||
status.Errors = append(status.Errors, fmt.Sprintf("%v", err)) | ||
statusErrors = append(statusErrors, fmt.Sprintf("%v", err)) | ||
} | ||
} | ||
|
||
log.WithValues("object", src).WithValues("status", status).V(2).Info("built status") | ||
log.WithValues("object", src).WithValues("status", statusHealthy).V(2).Info("built status") | ||
|
||
if !reflect.DeepEqual(status, instance.GetCommonStatus()) { | ||
instance.SetCommonStatus(status) | ||
unstruct, ok := src.(*unstructured.Unstructured) | ||
instance, commonOkay := src.(addonv1alpha1.CommonObject) | ||
|
||
log.WithValues("name", instance.GetName()).WithValues("status", status).Info("updating status") | ||
unstructStatus := make(map[string]interface{}) | ||
var status addonv1alpha1.CommonStatus | ||
|
||
if ok { | ||
unstructStatus["Healthy"] = true | ||
} else if commonOkay { | ||
status = addonv1alpha1.CommonStatus{Healthy: true} | ||
} else { | ||
return fmt.Errorf("object %T was not an addonv1alpha1.CommonObject", src) | ||
} | ||
|
||
err := a.client.Update(ctx, instance) | ||
if commonOkay { | ||
status.Errors = statusErrors | ||
status.Healthy = statusHealthy | ||
|
||
if !reflect.DeepEqual(status, instance.GetCommonStatus()) { | ||
instance.SetCommonStatus(status) | ||
|
||
log.WithValues("name", instance.GetName()).WithValues("status", status).Info("updating status") | ||
|
||
err := a.client.Update(ctx, instance) | ||
if err != nil { | ||
log.Error(err, "updating status") | ||
return err | ||
} | ||
} | ||
} else { | ||
unstructStatus["Healthy"] = true | ||
unstructStatus["Errors"] = statusErrors | ||
s, _, err := unstructured.NestedMap(unstruct.Object, "status") | ||
if err != nil { | ||
log.Error(err, "updating status") | ||
return err | ||
log.Error(err, "getting status") | ||
return fmt.Errorf("unable to get status from unstructured: %v", err) | ||
} | ||
if !reflect.DeepEqual(status, s) { | ||
err = unstructured.SetNestedField(unstruct.Object, statusHealthy, "status", "healthy") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missed error-check here |
||
if err != nil { | ||
log.Error(err, "updating status") | ||
return fmt.Errorf("unable to set status in unstructured: %v", err) | ||
} | ||
|
||
err = unstructured.SetNestedStringSlice(unstruct.Object, statusErrors, "status", "errors") | ||
if err != nil { | ||
log.Error(err, "updating status") | ||
return fmt.Errorf("unable to set status in unstructured: %v", err) | ||
} | ||
|
||
log.WithValues("name", unstruct.GetName()).WithValues("status", status).Info("updating status") | ||
|
||
err = a.client.Update(ctx, unstruct) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you make this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if this would work as the status wasn't changed on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we know where we don't change (Also, if we're changing status we might have to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems every time we run the update function, |
||
if err != nil { | ||
log.Error(err, "updating status") | ||
return err | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (a *aggregator) deployment(ctx context.Context, src addonv1alpha1.CommonObject, name string) (bool, error) { | ||
func (a *aggregator) deployment(ctx context.Context, src declarative.DeclarativeObject, name string) (bool, error) { | ||
key := client.ObjectKey{Namespace: src.GetNamespace(), Name: name} | ||
dep := &appsv1.Deployment{} | ||
|
||
|
@@ -106,7 +151,7 @@ func (a *aggregator) deployment(ctx context.Context, src addonv1alpha1.CommonObj | |
return false, fmt.Errorf("deployment (%s) does not meet condition: %s", key, successfulDeployment) | ||
} | ||
|
||
func (a *aggregator) service(ctx context.Context, src addonv1alpha1.CommonObject, name string) (bool, error) { | ||
func (a *aggregator) service(ctx context.Context, src declarative.DeclarativeObject, name string) (bool, error) { | ||
key := client.ObjectKey{Namespace: src.GetNamespace(), Name: name} | ||
svc := &corev1.Service{} | ||
err := a.client.Get(ctx, key, svc) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the other PRs, we might want to create helper functions here. e.g.
GetVersion
andGetHealthy
(or maybeGetCommonSpec
andGetCommonStatus
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could definitely work on this. I think it is a good idea