From 8cbe186706f187929e6619abfe5eeaf3b114fa6d Mon Sep 17 00:00:00 2001 From: Guangbo Chen Date: Mon, 26 Oct 2020 10:58:06 +0800 Subject: [PATCH] Add default network setting and conditions --- .../crds/harvester.cattle.io_settings.yaml | 31 +++++ .../harvester.cattle.io/v1alpha1/settings.go | 7 ++ .../v1alpha1/zz_generated_deepcopy.go | 22 ++++ .../v1alpha1/fake/fake_setting.go | 11 ++ .../harvester.cattle.io/v1alpha1/setting.go | 16 +++ .../harvester.cattle.io/v1alpha1/setting.go | 110 +++++++++++++++++- 6 files changed, 196 insertions(+), 1 deletion(-) diff --git a/deploy/charts/harvester/crds/harvester.cattle.io_settings.yaml b/deploy/charts/harvester/crds/harvester.cattle.io_settings.yaml index f2062322301..06ccc80bd70 100644 --- a/deploy/charts/harvester/crds/harvester.cattle.io_settings.yaml +++ b/deploy/charts/harvester/crds/harvester.cattle.io_settings.yaml @@ -36,6 +36,37 @@ spec: type: object source: type: string + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + lastUpdateTime: + description: The last time this condition was updated. + type: string + message: + description: Human-readable message indicating details about last + transition + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of the condition. + type: string + required: + - status + - type + type: object + type: array + type: object value: type: string type: object diff --git a/pkg/apis/harvester.cattle.io/v1alpha1/settings.go b/pkg/apis/harvester.cattle.io/v1alpha1/settings.go index 5bda611860e..1a4a98845f9 100644 --- a/pkg/apis/harvester.cattle.io/v1alpha1/settings.go +++ b/pkg/apis/harvester.cattle.io/v1alpha1/settings.go @@ -24,4 +24,11 @@ type Setting struct { // +optional Source string `json:"source,omitempty"` + + Status SettingStatus `json:"status,omitempty"` +} + +type SettingStatus struct { + // +optional + Conditions []Condition `json:"conditions,omitempty"` } diff --git a/pkg/apis/harvester.cattle.io/v1alpha1/zz_generated_deepcopy.go b/pkg/apis/harvester.cattle.io/v1alpha1/zz_generated_deepcopy.go index b5091462558..a6ec2a3d4b4 100644 --- a/pkg/apis/harvester.cattle.io/v1alpha1/zz_generated_deepcopy.go +++ b/pkg/apis/harvester.cattle.io/v1alpha1/zz_generated_deepcopy.go @@ -217,6 +217,7 @@ func (in *Setting) DeepCopyInto(out *Setting) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Status.DeepCopyInto(&out.Status) return } @@ -271,6 +272,27 @@ func (in *SettingList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SettingStatus) DeepCopyInto(out *SettingStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingStatus. +func (in *SettingStatus) DeepCopy() *SettingStatus { + if in == nil { + return nil + } + out := new(SettingStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TokenResponse) DeepCopyInto(out *TokenResponse) { *out = *in diff --git a/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/fake/fake_setting.go b/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/fake/fake_setting.go index 13cd802ca45..140d656f068 100644 --- a/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/fake/fake_setting.go +++ b/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/fake/fake_setting.go @@ -96,6 +96,17 @@ func (c *FakeSettings) Update(ctx context.Context, setting *v1alpha1.Setting, op return obj.(*v1alpha1.Setting), err } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeSettings) UpdateStatus(ctx context.Context, setting *v1alpha1.Setting, opts v1.UpdateOptions) (*v1alpha1.Setting, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(settingsResource, "status", setting), &v1alpha1.Setting{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Setting), err +} + // Delete takes name of the setting and deletes it. Returns an error if one occurs. func (c *FakeSettings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. diff --git a/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/setting.go b/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/setting.go index aa332b0fb2b..1e282965337 100644 --- a/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/setting.go +++ b/pkg/generated/clientset/versioned/typed/harvester.cattle.io/v1alpha1/setting.go @@ -40,6 +40,7 @@ type SettingsGetter interface { type SettingInterface interface { Create(ctx context.Context, setting *v1alpha1.Setting, opts v1.CreateOptions) (*v1alpha1.Setting, error) Update(ctx context.Context, setting *v1alpha1.Setting, opts v1.UpdateOptions) (*v1alpha1.Setting, error) + UpdateStatus(ctx context.Context, setting *v1alpha1.Setting, opts v1.UpdateOptions) (*v1alpha1.Setting, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.Setting, error) @@ -128,6 +129,21 @@ func (c *settings) Update(ctx context.Context, setting *v1alpha1.Setting, opts v return } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *settings) UpdateStatus(ctx context.Context, setting *v1alpha1.Setting, opts v1.UpdateOptions) (result *v1alpha1.Setting, err error) { + result = &v1alpha1.Setting{} + err = c.client.Put(). + Resource("settings"). + Name(setting.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(setting). + Do(ctx). + Into(result) + return +} + // Delete takes name of the setting and deletes it. Returns an error if one occurs. func (c *settings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). diff --git a/pkg/generated/controllers/harvester.cattle.io/v1alpha1/setting.go b/pkg/generated/controllers/harvester.cattle.io/v1alpha1/setting.go index 280a89c26c0..e5fe9938072 100644 --- a/pkg/generated/controllers/harvester.cattle.io/v1alpha1/setting.go +++ b/pkg/generated/controllers/harvester.cattle.io/v1alpha1/setting.go @@ -25,7 +25,10 @@ import ( v1alpha1 "github.com/rancher/harvester/pkg/apis/harvester.cattle.io/v1alpha1" "github.com/rancher/lasso/pkg/client" "github.com/rancher/lasso/pkg/controller" + "github.com/rancher/wrangler/pkg/apply" + "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -55,7 +58,7 @@ type SettingController interface { type SettingClient interface { Create(*v1alpha1.Setting) (*v1alpha1.Setting, error) Update(*v1alpha1.Setting) (*v1alpha1.Setting, error) - + UpdateStatus(*v1alpha1.Setting) (*v1alpha1.Setting, error) Delete(name string, options *metav1.DeleteOptions) error Get(name string, options metav1.GetOptions) (*v1alpha1.Setting, error) List(opts metav1.ListOptions) (*v1alpha1.SettingList, error) @@ -184,6 +187,11 @@ func (c *settingController) Update(obj *v1alpha1.Setting) (*v1alpha1.Setting, er return result, c.client.Update(context.TODO(), "", obj, result, metav1.UpdateOptions{}) } +func (c *settingController) UpdateStatus(obj *v1alpha1.Setting) (*v1alpha1.Setting, error) { + result := &v1alpha1.Setting{} + return result, c.client.UpdateStatus(context.TODO(), "", obj, result, metav1.UpdateOptions{}) +} + func (c *settingController) Delete(name string, options *metav1.DeleteOptions) error { if options == nil { options = &metav1.DeleteOptions{} @@ -254,3 +262,103 @@ func (c *settingCache) GetByIndex(indexName, key string) (result []*v1alpha1.Set } return result, nil } + +type SettingStatusHandler func(obj *v1alpha1.Setting, status v1alpha1.SettingStatus) (v1alpha1.SettingStatus, error) + +type SettingGeneratingHandler func(obj *v1alpha1.Setting, status v1alpha1.SettingStatus) ([]runtime.Object, v1alpha1.SettingStatus, error) + +func RegisterSettingStatusHandler(ctx context.Context, controller SettingController, condition condition.Cond, name string, handler SettingStatusHandler) { + statusHandler := &settingStatusHandler{ + client: controller, + condition: condition, + handler: handler, + } + controller.AddGenericHandler(ctx, name, FromSettingHandlerToHandler(statusHandler.sync)) +} + +func RegisterSettingGeneratingHandler(ctx context.Context, controller SettingController, apply apply.Apply, + condition condition.Cond, name string, handler SettingGeneratingHandler, opts *generic.GeneratingHandlerOptions) { + statusHandler := &settingGeneratingHandler{ + SettingGeneratingHandler: handler, + apply: apply, + name: name, + gvk: controller.GroupVersionKind(), + } + if opts != nil { + statusHandler.opts = *opts + } + controller.OnChange(ctx, name, statusHandler.Remove) + RegisterSettingStatusHandler(ctx, controller, condition, name, statusHandler.Handle) +} + +type settingStatusHandler struct { + client SettingClient + condition condition.Cond + handler SettingStatusHandler +} + +func (a *settingStatusHandler) sync(key string, obj *v1alpha1.Setting) (*v1alpha1.Setting, error) { + if obj == nil { + return obj, nil + } + + origStatus := obj.Status.DeepCopy() + obj = obj.DeepCopy() + newStatus, err := a.handler(obj, obj.Status) + if err != nil { + // Revert to old status on error + newStatus = *origStatus.DeepCopy() + } + + if a.condition != "" { + if errors.IsConflict(err) { + a.condition.SetError(&newStatus, "", nil) + } else { + a.condition.SetError(&newStatus, "", err) + } + } + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { + var newErr error + obj.Status = newStatus + obj, newErr = a.client.UpdateStatus(obj) + if err == nil { + err = newErr + } + } + return obj, err +} + +type settingGeneratingHandler struct { + SettingGeneratingHandler + apply apply.Apply + opts generic.GeneratingHandlerOptions + gvk schema.GroupVersionKind + name string +} + +func (a *settingGeneratingHandler) Remove(key string, obj *v1alpha1.Setting) (*v1alpha1.Setting, error) { + if obj != nil { + return obj, nil + } + + obj = &v1alpha1.Setting{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(a.gvk) + + return nil, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects() +} + +func (a *settingGeneratingHandler) Handle(obj *v1alpha1.Setting, status v1alpha1.SettingStatus) (v1alpha1.SettingStatus, error) { + objs, newStatus, err := a.SettingGeneratingHandler(obj, status) + if err != nil { + return newStatus, err + } + + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). + WithOwner(obj). + WithSetID(a.name). + ApplyObjects(objs...) +}