From 94da8b8e1213e02fdee6a5d5c1284a7a0e65dbda Mon Sep 17 00:00:00 2001 From: galal-hussein Date: Thu, 23 Apr 2020 00:34:19 +0200 Subject: [PATCH] update helm-controller --- go.mod | 7 +- go.sum | 11 + .../helm-controller/pkg/helm/controller.go | 19 +- .../pkg/generated/controllers/apps/factory.go | 35 ++- .../controllers/apps/v1/daemonset.go | 45 +-- .../controllers/apps/v1/deployment.go | 45 +-- .../controllers/apps/v1/statefulset.go | 45 +-- .../generated/controllers/batch/factory.go | 35 ++- .../pkg/generated/controllers/batch/v1/job.go | 45 +-- .../pkg/generated/controllers/core/factory.go | 35 ++- .../controllers/core/v1/namespace.go | 45 +-- .../pkg/generated/controllers/core/v1/node.go | 45 +-- .../core/v1/persistentvolumeclaim.go | 45 +-- .../pkg/generated/controllers/core/v1/pod.go | 45 +-- .../generated/controllers/core/v1/service.go | 45 +-- .../pkg/generated/controllers/rbac/factory.go | 35 ++- .../rancher/wrangler/pkg/apply/apply.go | 60 ++++ .../rancher/wrangler/pkg/apply/desiredset.go | 33 +- .../wrangler/pkg/apply/desiredset_apply.go | 34 +- .../wrangler/pkg/apply/desiredset_compare.go | 35 ++- .../wrangler/pkg/apply/desiredset_owner.go | 152 +++++++++ .../wrangler/pkg/apply/desiredset_process.go | 42 ++- .../wrangler/pkg/condition/condition.go | 12 +- .../controller-gen/generators/factory_go.go | 35 ++- .../pkg/controller-gen/generators/type_go.go | 44 +-- .../rancher/wrangler/pkg/crd/init.go | 128 +++++++- .../rancher/wrangler/pkg/data/merge.go | 24 ++ .../wrangler/pkg/generic/generating.go | 32 ++ .../rancher/wrangler/pkg/generic/handlers.go | 3 +- .../rancher/wrangler/pkg/gvk/get.go | 11 +- .../wrangler/pkg/objectset/objectset.go | 15 +- .../rancher/wrangler/pkg/patch/apply.go | 2 +- .../wrangler/pkg/schemas/openapi/generate.go | 296 +++++++++--------- .../wrangler/pkg/schemas/reflection.go | 35 ++- vendor/modules.txt | 6 +- 35 files changed, 1101 insertions(+), 480 deletions(-) create mode 100644 vendor/github.com/rancher/wrangler/pkg/apply/desiredset_owner.go create mode 100644 vendor/github.com/rancher/wrangler/pkg/data/merge.go diff --git a/go.mod b/go.mod index fc39ed9074..7f332e9eba 100644 --- a/go.mod +++ b/go.mod @@ -61,6 +61,7 @@ replace ( ) require ( + github.com/Azure/go-autorest v14.0.1+incompatible // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e // indirect @@ -100,11 +101,11 @@ require ( github.com/pkg/errors v0.9.1 github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 // indirect github.com/rancher/dynamiclistener v0.2.0 - github.com/rancher/helm-controller v0.4.2-0.20200326195131-eb51d4fa9d8d + github.com/rancher/helm-controller v0.5.0 github.com/rancher/kine v0.3.5 github.com/rancher/remotedialer v0.2.0 - github.com/rancher/wrangler v0.5.4-0.20200326191509-4054411d9736 - github.com/rancher/wrangler-api v0.5.1-0.20200326194427-c13310506d04 + github.com/rancher/wrangler v0.6.1 + github.com/rancher/wrangler-api v0.6.0 github.com/rootless-containers/rootlesskit v0.7.2 github.com/sirupsen/logrus v1.4.2 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index 689e166461..97761283c5 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,10 @@ github.com/Azure/azure-sdk-for-go v35.0.0+incompatible h1:PkmdmQUmeSdQQ5258f4SyC github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v11.1.2+incompatible h1:viZ3tV5l4gE2Sw0xrasFHytCGtzYCrT+um/rrSQ1BfA= +github.com/Azure/go-autorest v11.1.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest v14.0.1+incompatible h1:YhojO9jolWIvvTW7ORhz2ZSNF6Q1TbLqUunKd3jrtyw= +github.com/Azure/go-autorest v14.0.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= @@ -640,6 +644,8 @@ github.com/rancher/flannel v0.11.0-k3s.2 h1:0GVr5ORAIvcri1LYTE8eMQ+NrRbuPeIniPaW github.com/rancher/flannel v0.11.0-k3s.2/go.mod h1:Hn4ZV+eq0LhLZP63xZnxdGwXEoRSxs5sxELxu27M3UA= github.com/rancher/helm-controller v0.4.2-0.20200326195131-eb51d4fa9d8d h1:6w5gCRgJzWEGdGi/0Xv4XXuGZY8wgWduRA9A+4c1N8I= github.com/rancher/helm-controller v0.4.2-0.20200326195131-eb51d4fa9d8d/go.mod h1:3jCGmvjp3bFnbeuHL4HiODje9ZYJ/ujUBNtXHFXrwlM= +github.com/rancher/helm-controller v0.5.0 h1:BY5PG3dz6GWct2O9r8mFv73tZ7E5U9uI89QwMBXV83E= +github.com/rancher/helm-controller v0.5.0/go.mod h1:kEtAI/0AylXIplxWkIRR2xl3nhd4jZ6Wke1nvE/sKUs= github.com/rancher/kine v0.3.5 h1:Tm4eOtejpnzs1WFBrXj76lCLvX9czLlTkgqUk9luCQk= github.com/rancher/kine v0.3.5/go.mod h1:xEMl0tLCva9/9me7mXJ3m9Vo6yqHgC4OU3NiK4CPrGQ= github.com/rancher/kubernetes v1.18.2-k3s.1 h1:LhWNObWF7dL/+T57LkYpuRKtsCBpt0P5G6dRVFG+Ncs= @@ -693,9 +699,14 @@ github.com/rancher/wrangler v0.4.0 h1:iLvuJcZkd38E3RGG74dFMMNEju0PeTzfT1PQiv5okV github.com/rancher/wrangler v0.4.0/go.mod h1:1cR91WLhZgkZ+U4fV9nVuXqKurWbgXcIReU4wnQvTN8= github.com/rancher/wrangler v0.5.4-0.20200326191509-4054411d9736 h1:hqpVLgNUxU5sQUV6SzJPMY8Fy7T9Qht2QkA2Q7O/SH0= github.com/rancher/wrangler v0.5.4-0.20200326191509-4054411d9736/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4= +github.com/rancher/wrangler v0.6.0/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4= +github.com/rancher/wrangler v0.6.1 h1:7tyLk/FV2zCQkYg5SEtT4lSlsHNwa5yMOa797/VJhiQ= +github.com/rancher/wrangler v0.6.1/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4= github.com/rancher/wrangler-api v0.2.0/go.mod h1:zTPdNLZO07KvRaVOx6XQbKBSV55Fnn4s7nqmrMPJqd8= github.com/rancher/wrangler-api v0.5.1-0.20200326194427-c13310506d04 h1:y55e+kUaz/UswjN/oJdqHWMuoCG1FxwZJkxJEUONZZE= github.com/rancher/wrangler-api v0.5.1-0.20200326194427-c13310506d04/go.mod h1:R3nemXoECcrDqXDSHdY7yJay4j42TeEkU79Hep0rdJ8= +github.com/rancher/wrangler-api v0.6.0 h1:d/b0AkgZ+x41EYLIcUJiogtU3Y11Mqss2zr9VEKycRk= +github.com/rancher/wrangler-api v0.6.0/go.mod h1:RbuDkPNHhxcXuwAbLVvEAhH+UPAh+MIkpEd2fcGc0MM= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY= github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= diff --git a/vendor/github.com/rancher/helm-controller/pkg/helm/controller.go b/vendor/github.com/rancher/helm-controller/pkg/helm/controller.go index cc589b4e74..3bbf5df4a2 100644 --- a/vendor/github.com/rancher/helm-controller/pkg/helm/controller.go +++ b/vendor/github.com/rancher/helm-controller/pkg/helm/controller.go @@ -39,9 +39,10 @@ type Controller struct { } const ( - image = "rancher/klipper-helm:v0.2.3" - label = "helmcharts.helm.cattle.io/chart" - name = "helm-controller" + image = "rancher/klipper-helm:v0.2.5" + Label = "helmcharts.helm.cattle.io/chart" + CRDName = "helmcharts.helm.cattle.io" + Name = "helm-controller" ) func Register(ctx context.Context, apply apply.Apply, @@ -50,7 +51,7 @@ func Register(ctx context.Context, apply apply.Apply, crbs rbaccontroller.ClusterRoleBindingController, sas corecontroller.ServiceAccountController, cm corecontroller.ConfigMapController) { - apply = apply.WithSetID(name). + apply = apply.WithSetID(Name). WithCacheTypes(helms, jobs, crbs, sas, cm). WithStrictCaching().WithPatcher(batch.SchemeGroupVersion.WithKind("Job"), func(namespace, name string, pt types.PatchType, data []byte) (runtime.Object, error) { err := jobs.Delete(namespace, name, &metav1.DeleteOptions{}) @@ -63,7 +64,7 @@ func Register(ctx context.Context, apply apply.Apply, relatedresource.Watch(ctx, "helm-pod-watch", func(namespace, name string, obj runtime.Object) ([]relatedresource.Key, error) { if job, ok := obj.(*batch.Job); ok { - name := job.Labels[label] + name := job.Labels[Label] if name != "" { return []relatedresource.Key{ { @@ -84,8 +85,8 @@ func Register(ctx context.Context, apply apply.Apply, apply: apply, } - helms.OnChange(ctx, name, controller.OnHelmChanged) - helms.OnRemove(ctx, name, controller.OnHelmRemove) + helms.OnChange(ctx, Name, controller.OnHelmChanged) + helms.OnRemove(ctx, Name, controller.OnHelmRemove) } func (c *Controller) OnHelmChanged(key string, chart *helmv1.HelmChart) (*helmv1.HelmChart, error) { @@ -163,7 +164,7 @@ func job(chart *helmv1.HelmChart) (*batch.Job, *core.ConfigMap) { Name: fmt.Sprintf("helm-%s-%s", action, chart.Name), Namespace: chart.Namespace, Labels: map[string]string{ - label: chart.Name, + Label: chart.Name, }, }, Spec: batch.JobSpec{ @@ -171,7 +172,7 @@ func job(chart *helmv1.HelmChart) (*batch.Job, *core.ConfigMap) { Template: core.PodTemplateSpec{ ObjectMeta: meta.ObjectMeta{ Labels: map[string]string{ - label: chart.Name, + Label: chart.Name, }, }, Spec: core.PodSpec{ diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/factory.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/factory.go index f39d11a8cc..9c7261ec78 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/factory.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/factory.go @@ -52,18 +52,23 @@ func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { } func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { - cs, err := clientset.NewForConfig(config) - if err != nil { - return nil, err - } - - informerFactory := informers.NewSharedInformerFactory(cs, 2*time.Hour) - return NewFactory(cs, informerFactory), nil + return NewFactoryFromConfigWithOptions(config, nil) } func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { - if namespace == "" { - return NewFactoryFromConfig(config) + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions struct { + Namespace string + Resync time.Duration +} + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + if opts == nil { + opts = &FactoryOptions{} } cs, err := clientset.NewForConfig(config) @@ -71,7 +76,17 @@ func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (* return nil, err } - informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, 2*time.Hour, informers.WithNamespace(namespace)) + resync := opts.Resync + if resync == 0 { + resync = 2 * time.Hour + } + + if opts.Namespace == "" { + informerFactory := informers.NewSharedInformerFactory(cs, resync) + return NewFactory(cs, informerFactory), nil + } + + informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, resync, informers.WithNamespace(opts.Namespace)) return NewFactory(cs, informerFactory), nil } diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/daemonset.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/daemonset.go index ce97564c28..c7c5378a6e 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/daemonset.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/daemonset.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterDaemonSetGeneratingHandler(ctx context.Context, controller DaemonSe if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterDaemonSetStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *daemonSetStatusHandler) sync(key string, obj *v1.DaemonSet) (*v1.Daemon return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *daemonSetStatusHandler) sync(key string, obj *v1.DaemonSet) (*v1.Daemon newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type daemonSetGeneratingHandler struct { name string } +func (a *daemonSetGeneratingHandler) Remove(key string, obj *v1.DaemonSet) (*v1.DaemonSet, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.DaemonSet{} + 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 *daemonSetGeneratingHandler) Handle(obj *v1.DaemonSet, status v1.DaemonSetStatus) (v1.DaemonSetStatus, error) { objs, newStatus, err := a.DaemonSetGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/deployment.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/deployment.go index 3527d4f6f4..4f405391eb 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/deployment.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/deployment.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterDeploymentGeneratingHandler(ctx context.Context, controller Deploym if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterDeploymentStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *deploymentStatusHandler) sync(key string, obj *v1.Deployment) (*v1.Depl return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *deploymentStatusHandler) sync(key string, obj *v1.Deployment) (*v1.Depl newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type deploymentGeneratingHandler struct { name string } +func (a *deploymentGeneratingHandler) Remove(key string, obj *v1.Deployment) (*v1.Deployment, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Deployment{} + 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 *deploymentGeneratingHandler) Handle(obj *v1.Deployment, status v1.DeploymentStatus) (v1.DeploymentStatus, error) { objs, newStatus, err := a.DeploymentGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/statefulset.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/statefulset.go index fffb67f9ec..5b1b403635 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/statefulset.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1/statefulset.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/apps/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterStatefulSetGeneratingHandler(ctx context.Context, controller Statef if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterStatefulSetStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *statefulSetStatusHandler) sync(key string, obj *v1.StatefulSet) (*v1.St return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *statefulSetStatusHandler) sync(key string, obj *v1.StatefulSet) (*v1.St newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type statefulSetGeneratingHandler struct { name string } +func (a *statefulSetGeneratingHandler) Remove(key string, obj *v1.StatefulSet) (*v1.StatefulSet, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.StatefulSet{} + 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 *statefulSetGeneratingHandler) Handle(obj *v1.StatefulSet, status v1.StatefulSetStatus) (v1.StatefulSetStatus, error) { objs, newStatus, err := a.StatefulSetGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/factory.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/factory.go index c52a7a40c8..c3a8c56498 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/factory.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/factory.go @@ -52,18 +52,23 @@ func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { } func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { - cs, err := clientset.NewForConfig(config) - if err != nil { - return nil, err - } - - informerFactory := informers.NewSharedInformerFactory(cs, 2*time.Hour) - return NewFactory(cs, informerFactory), nil + return NewFactoryFromConfigWithOptions(config, nil) } func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { - if namespace == "" { - return NewFactoryFromConfig(config) + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions struct { + Namespace string + Resync time.Duration +} + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + if opts == nil { + opts = &FactoryOptions{} } cs, err := clientset.NewForConfig(config) @@ -71,7 +76,17 @@ func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (* return nil, err } - informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, 2*time.Hour, informers.WithNamespace(namespace)) + resync := opts.Resync + if resync == 0 { + resync = 2 * time.Hour + } + + if opts.Namespace == "" { + informerFactory := informers.NewSharedInformerFactory(cs, resync) + return NewFactory(cs, informerFactory), nil + } + + informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, resync, informers.WithNamespace(opts.Namespace)) return NewFactory(cs, informerFactory), nil } diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/v1/job.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/v1/job.go index 985b07d062..09b1e3ac75 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/v1/job.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/batch/v1/job.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterJobGeneratingHandler(ctx context.Context, controller JobController, if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterJobStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *jobStatusHandler) sync(key string, obj *v1.Job) (*v1.Job, error) { return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *jobStatusHandler) sync(key string, obj *v1.Job) (*v1.Job, error) { newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type jobGeneratingHandler struct { name string } +func (a *jobGeneratingHandler) Remove(key string, obj *v1.Job) (*v1.Job, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Job{} + 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 *jobGeneratingHandler) Handle(obj *v1.Job, status v1.JobStatus) (v1.JobStatus, error) { objs, newStatus, err := a.JobGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/factory.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/factory.go index d6afba9dca..e4d841ea64 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/factory.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/factory.go @@ -52,18 +52,23 @@ func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { } func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { - cs, err := clientset.NewForConfig(config) - if err != nil { - return nil, err - } - - informerFactory := informers.NewSharedInformerFactory(cs, 2*time.Hour) - return NewFactory(cs, informerFactory), nil + return NewFactoryFromConfigWithOptions(config, nil) } func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { - if namespace == "" { - return NewFactoryFromConfig(config) + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions struct { + Namespace string + Resync time.Duration +} + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + if opts == nil { + opts = &FactoryOptions{} } cs, err := clientset.NewForConfig(config) @@ -71,7 +76,17 @@ func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (* return nil, err } - informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, 2*time.Hour, informers.WithNamespace(namespace)) + resync := opts.Resync + if resync == 0 { + resync = 2 * time.Hour + } + + if opts.Namespace == "" { + informerFactory := informers.NewSharedInformerFactory(cs, resync) + return NewFactory(cs, informerFactory), nil + } + + informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, resync, informers.WithNamespace(opts.Namespace)) return NewFactory(cs, informerFactory), nil } diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/namespace.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/namespace.go index e215655a4a..14f4a090dd 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/namespace.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/namespace.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterNamespaceGeneratingHandler(ctx context.Context, controller Namespac if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterNamespaceStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *namespaceStatusHandler) sync(key string, obj *v1.Namespace) (*v1.Namesp return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *namespaceStatusHandler) sync(key string, obj *v1.Namespace) (*v1.Namesp newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type namespaceGeneratingHandler struct { name string } +func (a *namespaceGeneratingHandler) Remove(key string, obj *v1.Namespace) (*v1.Namespace, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Namespace{} + 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 *namespaceGeneratingHandler) Handle(obj *v1.Namespace, status v1.NamespaceStatus) (v1.NamespaceStatus, error) { objs, newStatus, err := a.NamespaceGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/node.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/node.go index 1165200cd4..1ef583d47d 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/node.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/node.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterNodeGeneratingHandler(ctx context.Context, controller NodeControlle if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterNodeStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *nodeStatusHandler) sync(key string, obj *v1.Node) (*v1.Node, error) { return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *nodeStatusHandler) sync(key string, obj *v1.Node) (*v1.Node, error) { newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type nodeGeneratingHandler struct { name string } +func (a *nodeGeneratingHandler) Remove(key string, obj *v1.Node) (*v1.Node, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Node{} + 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 *nodeGeneratingHandler) Handle(obj *v1.Node, status v1.NodeStatus) (v1.NodeStatus, error) { objs, newStatus, err := a.NodeGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/persistentvolumeclaim.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/persistentvolumeclaim.go index ce6a4e5249..be41b9acd1 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/persistentvolumeclaim.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/persistentvolumeclaim.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterPersistentVolumeClaimGeneratingHandler(ctx context.Context, control if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterPersistentVolumeClaimStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *persistentVolumeClaimStatusHandler) sync(key string, obj *v1.Persistent return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *persistentVolumeClaimStatusHandler) sync(key string, obj *v1.Persistent newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type persistentVolumeClaimGeneratingHandler struct { name string } +func (a *persistentVolumeClaimGeneratingHandler) Remove(key string, obj *v1.PersistentVolumeClaim) (*v1.PersistentVolumeClaim, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.PersistentVolumeClaim{} + 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 *persistentVolumeClaimGeneratingHandler) Handle(obj *v1.PersistentVolumeClaim, status v1.PersistentVolumeClaimStatus) (v1.PersistentVolumeClaimStatus, error) { objs, newStatus, err := a.PersistentVolumeClaimGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/pod.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/pod.go index 72a56b6024..e808414d49 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/pod.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/pod.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterPodGeneratingHandler(ctx context.Context, controller PodController, if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterPodStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *podStatusHandler) sync(key string, obj *v1.Pod) (*v1.Pod, error) { return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *podStatusHandler) sync(key string, obj *v1.Pod) (*v1.Pod, error) { newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type podGeneratingHandler struct { name string } +func (a *podGeneratingHandler) Remove(key string, obj *v1.Pod) (*v1.Pod, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Pod{} + 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 *podGeneratingHandler) Handle(obj *v1.Pod, status v1.PodStatus) (v1.PodStatus, error) { objs, newStatus, err := a.PodGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/service.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/service.go index 1cb578862a..28fba8f794 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/service.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1/service.go @@ -25,6 +25,7 @@ import ( "github.com/rancher/wrangler/pkg/apply" "github.com/rancher/wrangler/pkg/condition" "github.com/rancher/wrangler/pkg/generic" + "github.com/rancher/wrangler/pkg/kv" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/errors" @@ -267,6 +268,7 @@ func RegisterServiceGeneratingHandler(ctx context.Context, controller ServiceCon if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) RegisterServiceStatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -281,7 +283,7 @@ func (a *serviceStatusHandler) sync(key string, obj *v1.Service) (*v1.Service, e return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -289,16 +291,16 @@ func (a *serviceStatusHandler) sync(key string, obj *v1.Service) (*v1.Service, e newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -315,29 +317,28 @@ type serviceGeneratingHandler struct { name string } +func (a *serviceGeneratingHandler) Remove(key string, obj *v1.Service) (*v1.Service, error) { + if obj != nil { + return obj, nil + } + + obj = &v1.Service{} + 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 *serviceGeneratingHandler) Handle(obj *v1.Service, status v1.ServiceStatus) (v1.ServiceStatus, error) { objs, newStatus, err := a.ServiceGeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/rbac/factory.go b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/rbac/factory.go index 002d1a78fc..1ae7c9f52e 100644 --- a/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/rbac/factory.go +++ b/vendor/github.com/rancher/wrangler-api/pkg/generated/controllers/rbac/factory.go @@ -52,18 +52,23 @@ func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { } func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { - cs, err := clientset.NewForConfig(config) - if err != nil { - return nil, err - } - - informerFactory := informers.NewSharedInformerFactory(cs, 2*time.Hour) - return NewFactory(cs, informerFactory), nil + return NewFactoryFromConfigWithOptions(config, nil) } func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { - if namespace == "" { - return NewFactoryFromConfig(config) + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions struct { + Namespace string + Resync time.Duration +} + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + if opts == nil { + opts = &FactoryOptions{} } cs, err := clientset.NewForConfig(config) @@ -71,7 +76,17 @@ func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (* return nil, err } - informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, 2*time.Hour, informers.WithNamespace(namespace)) + resync := opts.Resync + if resync == 0 { + resync = 2 * time.Hour + } + + if opts.Namespace == "" { + informerFactory := informers.NewSharedInformerFactory(cs, resync) + return NewFactory(cs, informerFactory), nil + } + + informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, resync, informers.WithNamespace(opts.Namespace)) return NewFactory(cs, informerFactory), nil } diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/apply.go b/vendor/github.com/rancher/wrangler/pkg/apply/apply.go index f3e3d26d54..372cd44e42 100644 --- a/vendor/github.com/rancher/wrangler/pkg/apply/apply.go +++ b/vendor/github.com/rancher/wrangler/pkg/apply/apply.go @@ -28,18 +28,45 @@ type Reconciler func(oldObj runtime.Object, newObj runtime.Object) (bool, error) type ClientFactory func(gvr schema.GroupVersionResource) (dynamic.NamespaceableResourceInterface, error) +type InformerFactory interface { + Get(gvk schema.GroupVersionKind, gvr schema.GroupVersionResource) (cache.SharedIndexInformer, error) +} + type InformerGetter interface { Informer() cache.SharedIndexInformer GroupVersionKind() schema.GroupVersionKind } +type PatchByGVK map[schema.GroupVersionKind]map[objectset.ObjectKey]string + +func (p PatchByGVK) Add(gvk schema.GroupVersionKind, namespace, name, patch string) { + d, ok := p[gvk] + if !ok { + d = map[objectset.ObjectKey]string{} + p[gvk] = d + } + d[objectset.ObjectKey{ + Name: name, + Namespace: namespace, + }] = patch +} + +type Plan struct { + Create objectset.ObjectKeyByGVK + Delete objectset.ObjectKeyByGVK + Update PatchByGVK + Objects []runtime.Object +} + type Apply interface { Apply(set *objectset.ObjectSet) error ApplyObjects(objs ...runtime.Object) error WithContext(ctx context.Context) Apply WithCacheTypes(igs ...InformerGetter) Apply + WithCacheTypeFactory(factory InformerFactory) Apply WithSetID(id string) Apply WithOwner(obj runtime.Object) Apply + WithOwnerKey(key string, gvk schema.GroupVersionKind) Apply WithInjector(injs ...injectors.ConfigInjector) Apply WithInjectorName(injs ...string) Apply WithPatcher(gvk schema.GroupVersionKind, patchers Patcher) Apply @@ -53,6 +80,10 @@ type Apply interface { WithNoDelete() Apply WithGVK(gvks ...schema.GroupVersionKind) Apply WithSetOwnerReference(controller, block bool) Apply + + FindOwner(obj runtime.Object) (runtime.Object, error) + PurgeOrphan(obj runtime.Object) error + DryRun(objs ...runtime.Object) (Plan, error) } func NewForConfig(cfg *rest.Config) (Apply, error) { @@ -70,6 +101,7 @@ func New(discovery discovery.DiscoveryInterface, cf ClientFactory, igs ...Inform clientFactory: cf, discovery: discovery, namespaced: map[schema.GroupVersionKind]bool{}, + gvkToGVR: map[schema.GroupVersionKind]schema.GroupVersionResource{}, clients: map[schema.GroupVersionKind]dynamic.NamespaceableResourceInterface{}, }, informers: map[schema.GroupVersionKind]cache.SharedIndexInformer{}, @@ -93,6 +125,7 @@ type clients struct { clientFactory ClientFactory discovery discovery.DiscoveryInterface namespaced map[schema.GroupVersionKind]bool + gvkToGVR map[schema.GroupVersionKind]schema.GroupVersionResource clients map[schema.GroupVersionKind]dynamic.NamespaceableResourceInterface } @@ -102,6 +135,12 @@ func (c *clients) IsNamespaced(gvk schema.GroupVersionKind) bool { return c.namespaced[gvk] } +func (c *clients) gvr(gvk schema.GroupVersionKind) schema.GroupVersionResource { + c.Lock() + defer c.Unlock() + return c.gvkToGVR[gvk] +} + func (c *clients) client(gvk schema.GroupVersionKind) (dynamic.NamespaceableResourceInterface, error) { c.Lock() defer c.Unlock() @@ -127,6 +166,7 @@ func (c *clients) client(gvk schema.GroupVersionKind) (dynamic.NamespaceableReso c.namespaced[gvk] = resource.Namespaced c.clients[gvk] = client + c.gvkToGVR[gvk] = gvk.GroupVersion().WithResource(resource.Name) return client, nil } @@ -144,6 +184,10 @@ func (a *apply) newDesiredSet() desiredSet { } } +func (a *apply) DryRun(objs ...runtime.Object) (Plan, error) { + return a.newDesiredSet().DryRun(objs...) +} + func (a *apply) Apply(set *objectset.ObjectSet) error { return a.newDesiredSet().Apply(set) } @@ -162,6 +206,10 @@ func (a *apply) WithOwner(obj runtime.Object) Apply { return a.newDesiredSet().WithOwner(obj) } +func (a *apply) WithOwnerKey(key string, gvk schema.GroupVersionKind) Apply { + return a.newDesiredSet().WithOwnerKey(key, gvk) +} + func (a *apply) WithInjector(injs ...injectors.ConfigInjector) Apply { return a.newDesiredSet().WithInjector(injs...) } @@ -174,6 +222,10 @@ func (a *apply) WithCacheTypes(igs ...InformerGetter) Apply { return a.newDesiredSet().WithCacheTypes(igs...) } +func (a *apply) WithCacheTypeFactory(factory InformerFactory) Apply { + return a.newDesiredSet().WithCacheTypeFactory(factory) +} + func (a *apply) WithGVK(gvks ...schema.GroupVersionKind) Apply { return a.newDesiredSet().WithGVK(gvks...) } @@ -221,3 +273,11 @@ func (a *apply) WithSetOwnerReference(controller, block bool) Apply { func (a *apply) WithContext(ctx context.Context) Apply { return a.newDesiredSet().WithContext(ctx) } + +func (a *apply) FindOwner(obj runtime.Object) (runtime.Object, error) { + return a.newDesiredSet().FindOwner(obj) +} + +func (a *apply) PurgeOrphan(obj runtime.Object) error { + return a.newDesiredSet().PurgeOrphan(obj) +} diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset.go b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset.go index 09abdbaba5..8cc6da4cfc 100644 --- a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset.go +++ b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset.go @@ -3,8 +3,10 @@ package apply import ( "context" "github.com/rancher/wrangler/pkg/apply/injectors" + "github.com/rancher/wrangler/pkg/kv" "github.com/rancher/wrangler/pkg/merr" "github.com/rancher/wrangler/pkg/objectset" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/tools/cache" @@ -12,7 +14,7 @@ import ( type desiredSet struct { a *apply - ctx context.Context + ctx context.Context defaultNamespace string listerNamespace string setOwnerReference bool @@ -23,6 +25,7 @@ type desiredSet struct { pruneTypes map[schema.GroupVersionKind]cache.SharedIndexInformer patchers map[schema.GroupVersionKind]Patcher reconcilers map[schema.GroupVersionKind]Reconciler + informerFactory InformerFactory remove bool noDelete bool setID string @@ -33,6 +36,9 @@ type desiredSet struct { ratelimitingQps float32 injectorNames []string errs []error + + createPlan bool + plan Plan } func (o *desiredSet) err(err error) error { @@ -44,6 +50,12 @@ func (o desiredSet) Err() error { return merr.NewErrors(append(o.errs, o.objs.Err())...) } +func (o desiredSet) DryRun(objs ...runtime.Object) (Plan, error) { + o.objs = objectset.NewObjectSet() + o.objs.Add(objs...) + return o.dryRun() +} + func (o desiredSet) Apply(set *objectset.ObjectSet) error { if set == nil { set = objectset.NewObjectSet() @@ -76,6 +88,14 @@ func (o desiredSet) WithSetID(id string) Apply { return o } +func (o desiredSet) WithOwnerKey(key string, gvk schema.GroupVersionKind) Apply { + obj := &v1.PartialObjectMetadata{} + obj.Namespace, obj.Name = kv.RSplit(key, "/") + obj.SetGroupVersionKind(gvk) + o.owner = obj + return o +} + func (o desiredSet) WithOwner(obj runtime.Object) Apply { o.owner = obj return o @@ -98,6 +118,11 @@ func (o desiredSet) WithInjectorName(injs ...string) Apply { return o } +func (o desiredSet) WithCacheTypeFactory(factory InformerFactory) Apply { + o.informerFactory = factory + return o +} + func (o desiredSet) WithCacheTypes(igs ...InformerGetter) Apply { pruneTypes := make(map[schema.GroupVersionKind]cache.SharedIndexInformer, len(igs)) for k, v := range o.pruneTypes { @@ -147,7 +172,11 @@ func (o desiredSet) WithRestrictClusterScoped() Apply { } func (o desiredSet) WithDefaultNamespace(ns string) Apply { - o.defaultNamespace = ns + if ns == "" { + o.defaultNamespace = defaultNamespace + } else { + o.defaultNamespace = ns + } return o } diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_apply.go b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_apply.go index f56a300584..e297fc795d 100644 --- a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_apply.go +++ b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_apply.go @@ -27,6 +27,7 @@ const ( LabelName = "objectset.rio.cattle.io/owner-name" LabelNamespace = "objectset.rio.cattle.io/owner-namespace" LabelHash = "objectset.rio.cattle.io/hash" + LabelPrefix = "objectset.rio.cattle.io/" ) var ( @@ -58,6 +59,15 @@ func (o *desiredSet) getRateLimit(labelHash string) flowcontrol.RateLimiter { return rl } +func (o *desiredSet) dryRun() (Plan, error) { + o.createPlan = true + o.plan.Create = objectset.ObjectKeyByGVK{} + o.plan.Update = PatchByGVK{} + o.plan.Delete = objectset.ObjectKeyByGVK{} + err := o.apply() + return o.plan, err +} + func (o *desiredSet) apply() error { if o.objs == nil || o.objs.Len() == 0 { o.remove = true @@ -67,7 +77,7 @@ func (o *desiredSet) apply() error { return err } - labelSet, annotationSet, err := o.getLabelsAndAnnotations() + labelSet, annotationSet, err := GetLabelsAndAnnotations(o.setID, o.owner) if err != nil { return o.err(err) } @@ -90,13 +100,13 @@ func (o *desiredSet) apply() error { objs := o.collect(objList) debugID := o.debugID() - req, err := labels.NewRequirement(LabelHash, selection.Equals, []string{labelSet[LabelHash]}) + sel, err := GetSelector(labelSet) if err != nil { return o.err(err) } for _, gvk := range o.objs.GVKOrder(o.knownGVK()...) { - o.process(debugID, labels.NewSelector().Add(*req), gvk, objs[gvk]) + o.process(debugID, sel, gvk, objs[gvk]) } return o.Err() @@ -161,18 +171,26 @@ func (o *desiredSet) runInjectors(objList []runtime.Object) ([]runtime.Object, e return objList, nil } -func (o *desiredSet) getLabelsAndAnnotations() (map[string]string, map[string]string, error) { +func GetSelector(labelSet map[string]string) (labels.Selector, error) { + req, err := labels.NewRequirement(LabelHash, selection.Equals, []string{labelSet[LabelHash]}) + if err != nil { + return nil, err + } + return labels.NewSelector().Add(*req), nil +} + +func GetLabelsAndAnnotations(setID string, owner runtime.Object) (map[string]string, map[string]string, error) { annotations := map[string]string{ - LabelID: o.setID, + LabelID: setID, } - if o.owner != nil { - gvk, err := gvk2.Get(o.owner) + if owner != nil { + gvk, err := gvk2.Get(owner) if err != nil { return nil, nil, err } annotations[LabelGVK] = gvk.String() - metadata, err := meta.Accessor(o.owner) + metadata, err := meta.Accessor(owner) if err != nil { return nil, nil, fmt.Errorf("failed to get metadata for %s", gvk) } diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_compare.go b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_compare.go index 903f3e6f90..892fc36ede 100644 --- a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_compare.go +++ b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_compare.go @@ -5,6 +5,9 @@ import ( "compress/gzip" "encoding/base64" "io/ioutil" + "strings" + + data2 "github.com/rancher/wrangler/pkg/data" "github.com/pkg/errors" "github.com/rancher/wrangler/pkg/data/convert" @@ -95,7 +98,7 @@ func emptyMaps(data map[string]interface{}, keys ...string) bool { return true } -func sanitizePatch(patch []byte) ([]byte, error) { +func sanitizePatch(patch []byte, removeObjectSetAnnotation bool) ([]byte, error) { mod := false data := map[string]interface{}{} err := json.Unmarshal(patch, &data) @@ -117,6 +120,23 @@ func sanitizePatch(patch []byte) ([]byte, error) { mod = true } + if removeObjectSetAnnotation { + metadata := convert.ToMapInterface(data2.GetValueN(data, "metadata")) + annotations := convert.ToMapInterface(data2.GetValueN(data, "metadata", "annotations")) + for k := range annotations { + if strings.HasPrefix(k, LabelPrefix) { + mod = true + delete(annotations, k) + } + } + if mod && len(annotations) == 0 { + delete(metadata, "annotations") + if len(metadata) == 0 { + delete(data, "metadata") + } + } + } + if emptyMaps(data, "metadata", "annotations") { return []byte("{}"), nil } @@ -152,7 +172,7 @@ func applyPatch(gvk schema.GroupVersionKind, reconciler Reconciler, patcher Patc return false, nil } - patch, err = sanitizePatch(patch) + patch, err = sanitizePatch(patch, false) if err != nil { return false, err } @@ -172,6 +192,9 @@ func applyPatch(gvk schema.GroupVersionKind, reconciler Reconciler, patcher Patc if err != nil { return false, err } + if originalObject == nil { + originalObject = oldObject + } handled, err := reconciler(originalObject, newObject) if err != nil { return false, err @@ -187,13 +210,17 @@ func applyPatch(gvk schema.GroupVersionKind, reconciler Reconciler, patcher Patc return true, err } -func (o *desiredSet) compareObjects(gvk schema.GroupVersionKind, patcher Patcher, client dynamic.NamespaceableResourceInterface, debugID string, oldObject, newObject runtime.Object, force bool) error { +func (o *desiredSet) compareObjects(gvk schema.GroupVersionKind, reconciler Reconciler, patcher Patcher, client dynamic.NamespaceableResourceInterface, debugID string, oldObject, newObject runtime.Object, force bool) error { oldMetadata, err := meta.Accessor(oldObject) if err != nil { return err } - if ran, err := applyPatch(gvk, o.reconcilers[gvk], patcher, debugID, oldObject, newObject); err != nil { + if o.createPlan { + o.plan.Objects = append(o.plan.Objects, oldObject) + } + + if ran, err := applyPatch(gvk, reconciler, patcher, debugID, oldObject, newObject); err != nil { return err } else if !ran { logrus.Debugf("DesiredSet - No change(2) %s %s/%s for %s", gvk, oldMetadata.GetNamespace(), oldMetadata.GetName(), debugID) diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_owner.go b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_owner.go new file mode 100644 index 0000000000..126fe02be5 --- /dev/null +++ b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_owner.go @@ -0,0 +1,152 @@ +package apply + +import ( + "fmt" + "strings" + + "github.com/rancher/wrangler/pkg/gvk" + + "github.com/rancher/wrangler/pkg/kv" + + "github.com/pkg/errors" + namer "github.com/rancher/wrangler/pkg/name" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" + "k8s.io/client-go/tools/cache" +) + +var ( + ErrOwnerNotFound = errors.New("owner not found") +) + +func notFound(name string, gvk schema.GroupVersionKind) error { + // this is not proper, but does it really matter that much? If you find this + // line while researching a bug, then the answer is probably yes. + resource := namer.GuessPluralName(strings.ToLower(gvk.Kind)) + return apierrors.NewNotFound(schema.GroupResource{ + Group: gvk.Group, + Resource: resource, + }, name) +} + +func getGVK(gvkLabel string, gvk *schema.GroupVersionKind) error { + parts := strings.Split(gvkLabel, ", Kind=") + if len(parts) != 2 { + return fmt.Errorf("invalid GVK format: %s", gvkLabel) + } + gvk.Group, gvk.Version = kv.Split(parts[0], "/") + gvk.Kind = parts[1] + return nil +} + +func (o desiredSet) FindOwner(obj runtime.Object) (runtime.Object, error) { + if obj == nil { + return nil, ErrOwnerNotFound + } + meta, err := meta.Accessor(obj) + if err != nil { + return nil, err + } + + var ( + debugID = fmt.Sprintf("%s/%s", meta.GetNamespace(), meta.GetName()) + gvkLabel = meta.GetAnnotations()[LabelGVK] + namespace = meta.GetAnnotations()[LabelNamespace] + name = meta.GetAnnotations()[LabelName] + gvk schema.GroupVersionKind + ) + + if gvkLabel == "" { + return nil, ErrOwnerNotFound + } + + if err := getGVK(gvkLabel, &gvk); err != nil { + return nil, err + } + + cache, client, err := o.getControllerAndClient(debugID, gvk) + if err != nil { + return nil, err + } + + if cache != nil { + return o.fromCache(cache, namespace, name, gvk) + } + + return o.fromClient(client, namespace, name, gvk) +} + +func (o *desiredSet) fromClient(client dynamic.NamespaceableResourceInterface, namespace, name string, gvk schema.GroupVersionKind) (runtime.Object, error) { + var ( + err error + obj interface{} + ) + if namespace == "" { + obj, err = client.Get(o.ctx, name, metav1.GetOptions{}) + } else { + obj, err = client.Namespace(namespace).Get(o.ctx, name, metav1.GetOptions{}) + } + if err != nil { + return nil, err + } + if ro, ok := obj.(runtime.Object); ok { + return ro, nil + } + return nil, notFound(name, gvk) +} + +func (o *desiredSet) fromCache(cache cache.SharedInformer, namespace, name string, gvk schema.GroupVersionKind) (runtime.Object, error) { + var key string + if namespace == "" { + key = name + } else { + key = namespace + "/" + name + } + item, ok, err := cache.GetStore().GetByKey(key) + if err != nil { + return nil, err + } else if !ok { + return nil, notFound(name, gvk) + } else if ro, ok := item.(runtime.Object); ok { + return ro, nil + } + return nil, notFound(name, gvk) +} + +func (o desiredSet) PurgeOrphan(obj runtime.Object) error { + if obj == nil { + return nil + } + + meta, err := meta.Accessor(obj) + if err != nil { + return err + } + + if _, err := o.FindOwner(obj); apierrors.IsNotFound(err) { + gvk, err := gvk.Get(obj) + if err != nil { + return err + } + + o.strictCaching = false + _, client, err := o.getControllerAndClient(meta.GetName(), gvk) + if err != nil { + return err + } + if meta.GetNamespace() == "" { + return client.Delete(o.ctx, meta.GetName(), metav1.DeleteOptions{}) + } else { + return client.Namespace(meta.GetNamespace()).Delete(o.ctx, meta.GetName(), metav1.DeleteOptions{}) + } + } else if err == ErrOwnerNotFound { + return nil + } else if err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_process.go b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_process.go index 2ef41c9e77..459de8ff8d 100644 --- a/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_process.go +++ b/vendor/github.com/rancher/wrangler/pkg/apply/desiredset_process.go @@ -28,19 +28,27 @@ var ( ) func (o *desiredSet) getControllerAndClient(debugID string, gvk schema.GroupVersionKind) (cache.SharedIndexInformer, dynamic.NamespaceableResourceInterface, error) { + // client needs to be accessed first so that the gvk->gvr mapping gets cached + client, err := o.a.clients.client(gvk) + if err != nil { + return nil, nil, err + } + informer, ok := o.pruneTypes[gvk] if !ok { informer = o.a.informers[gvk] } + if informer == nil && o.informerFactory != nil { + newInformer, err := o.informerFactory.Get(gvk, o.a.clients.gvr(gvk)) + if err != nil { + return nil, nil, errors.Wrapf(err, "failed to construct informer for %v for %s", gvk, debugID) + } + informer = newInformer + } if informer == nil && o.strictCaching { return nil, nil, fmt.Errorf("failed to find informer for %s for %s", gvk, debugID) } - client, err := o.a.clients.client(gvk) - if err != nil { - return nil, nil, err - } - return informer, client, nil } @@ -206,6 +214,8 @@ func (o *desiredSet) process(debugID string, set labels.Selector, gvk schema.Gro patcher = o.createPatcher(client) } + reconciler := o.reconcilers[gvk] + existing, err := o.list(controller, client, set) if err != nil { o.err(errors.Wrapf(err, "failed to list %s for %s", gvk, debugID)) @@ -214,6 +224,26 @@ func (o *desiredSet) process(debugID string, set labels.Selector, gvk schema.Gro toCreate, toDelete, toUpdate := compareSets(existing, objs) + if o.createPlan { + o.plan.Create[gvk] = toCreate + o.plan.Delete[gvk] = toDelete + + reconciler = nil + patcher = func(namespace, name string, pt types2.PatchType, data []byte) (runtime.Object, error) { + data, err := sanitizePatch(data, true) + if err != nil { + return nil, err + } + if string(data) != "{}" { + o.plan.Update.Add(gvk, namespace, name, string(data)) + } + return nil, nil + } + + toCreate = nil + toDelete = nil + } + createF := func(k objectset.ObjectKey) { obj := objs[k] obj, err := prepareObjectForCreate(gvk, obj) @@ -248,7 +278,7 @@ func (o *desiredSet) process(debugID string, set labels.Selector, gvk schema.Gro } updateF := func(k objectset.ObjectKey) { - err := o.compareObjects(gvk, patcher, client, debugID, existing[k], objs[k], len(toCreate) > 0 || len(toDelete) > 0) + err := o.compareObjects(gvk, reconciler, patcher, client, debugID, existing[k], objs[k], len(toCreate) > 0 || len(toDelete) > 0) if err == ErrReplace { deleteF(k, true) o.err(fmt.Errorf("DesiredSet - Replace Wait %s %s for %s", gvk, k, debugID)) diff --git a/vendor/github.com/rancher/wrangler/pkg/condition/condition.go b/vendor/github.com/rancher/wrangler/pkg/condition/condition.go index 8f8e6cf518..906a4213eb 100644 --- a/vendor/github.com/rancher/wrangler/pkg/condition/condition.go +++ b/vendor/github.com/rancher/wrangler/pkg/condition/condition.go @@ -4,6 +4,7 @@ import ( "reflect" "time" + "github.com/rancher/wrangler/pkg/generic" "github.com/sirupsen/logrus" ) @@ -14,7 +15,7 @@ func (c Cond) GetStatus(obj interface{}) string { } func (c Cond) SetError(obj interface{}, reason string, err error) { - if err == nil { + if err == nil || err == generic.ErrSkip { c.True(obj) c.Message(obj, "") c.Reason(obj, reason) @@ -153,6 +154,9 @@ func getTS(obj interface{}, condName string) string { } func setStatus(obj interface{}, condName, status string) { + if reflect.TypeOf(obj).Kind() != reflect.Ptr { + panic("obj passed must be a pointer") + } cond := findOrCreateCond(obj, condName) setValue(cond, "Status", status) } @@ -167,6 +171,9 @@ func setValue(cond reflect.Value, fieldName, newValue string) { func findOrNotCreateCond(obj interface{}, condName string) *reflect.Value { condSlice := getValue(obj, "Status", "Conditions") + if !condSlice.IsValid() { + condSlice = getValue(obj, "Conditions") + } return findCond(obj, condSlice, condName) } @@ -224,6 +231,9 @@ func getValue(obj interface{}, name ...string) reflect.Value { } func getFieldValue(v reflect.Value, name ...string) reflect.Value { + if !v.IsValid() { + return v + } field := v.FieldByName(name[0]) if len(name) == 1 { return field diff --git a/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/factory_go.go b/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/factory_go.go index 3c28bcf434..723f030c33 100644 --- a/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/factory_go.go +++ b/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/factory_go.go @@ -85,18 +85,23 @@ func NewFactoryFromConfigOrDie(config *rest.Config) *Factory { } func NewFactoryFromConfig(config *rest.Config) (*Factory, error) { - cs, err := clientset.NewForConfig(config) - if err != nil { - return nil, err - } - - informerFactory := informers.NewSharedInformerFactory(cs, 2*time.Hour) - return NewFactory(cs, informerFactory), nil + return NewFactoryFromConfigWithOptions(config, nil) } func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (*Factory, error) { - if namespace == "" { - return NewFactoryFromConfig(config) + return NewFactoryFromConfigWithOptions(config, &FactoryOptions{ + Namespace: namespace, + }) +} + +type FactoryOptions struct { + Namespace string + Resync time.Duration +} + +func NewFactoryFromConfigWithOptions(config *rest.Config, opts *FactoryOptions) (*Factory, error) { + if opts == nil { + opts = &FactoryOptions{} } cs, err := clientset.NewForConfig(config) @@ -104,7 +109,17 @@ func NewFactoryFromConfigWithNamespace(config *rest.Config, namespace string) (* return nil, err } - informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, 2*time.Hour, informers.WithNamespace(namespace)) + resync := opts.Resync + if resync == 0 { + resync = 2*time.Hour + } + + if opts.Namespace == "" { + informerFactory := informers.NewSharedInformerFactory(cs, resync) + return NewFactory(cs, informerFactory), nil + } + + informerFactory := informers.NewSharedInformerFactoryWithOptions(cs, resync, informers.WithNamespace(opts.Namespace)) return NewFactory(cs, informerFactory), nil } diff --git a/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/type_go.go b/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/type_go.go index 8d4dcacf0e..4d96c0b5c1 100644 --- a/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/type_go.go +++ b/vendor/github.com/rancher/wrangler/pkg/controller-gen/generators/type_go.go @@ -333,6 +333,7 @@ func Register{{.type}}GeneratingHandler(ctx context.Context, controller {{.type} if opts != nil { statusHandler.opts = *opts } + controller.OnChange(ctx, name, statusHandler.Remove) Register{{.type}}StatusHandler(ctx, controller, condition, name, statusHandler.Handle) } @@ -347,7 +348,7 @@ func (a *{{.lowerName}}StatusHandler) sync(key string, obj *{{.version}}.{{.type return obj, nil } - origStatus := obj.Status + origStatus := obj.Status.DeepCopy() obj = obj.DeepCopy() newStatus, err := a.handler(obj, obj.Status) if err != nil { @@ -355,16 +356,16 @@ func (a *{{.lowerName}}StatusHandler) sync(key string, obj *{{.version}}.{{.type newStatus = *origStatus.DeepCopy() } - obj.Status = newStatus if a.condition != "" { if errors.IsConflict(err) { - a.condition.SetError(obj, "", nil) + a.condition.SetError(&newStatus, "", nil) } else { - a.condition.SetError(obj, "", err) + a.condition.SetError(&newStatus, "", err) } } - if !equality.Semantic.DeepEqual(origStatus, obj.Status) { + if !equality.Semantic.DeepEqual(origStatus, &newStatus) { var newErr error + obj.Status = newStatus obj, newErr = a.client.UpdateStatus(obj) if err == nil { err = newErr @@ -381,29 +382,28 @@ type {{.lowerName}}GeneratingHandler struct { name string } +func (a *{{.lowerName}}GeneratingHandler) Remove(key string, obj *{{.version}}.{{.type}}) (*{{.version}}.{{.type}}, error) { + if obj != nil { + return obj, nil + } + + obj = &{{.version}}.{{.type}}{} + 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 *{{.lowerName}}GeneratingHandler) Handle(obj *{{.version}}.{{.type}}, status {{.version}}.{{.statusType}}) ({{.version}}.{{.statusType}}, error) { objs, newStatus, err := a.{{.type}}GeneratingHandler(obj, status) if err != nil { return newStatus, err } - apply := a.apply - - if !a.opts.DynamicLookup { - apply = apply.WithStrictCaching() - } - - if !a.opts.AllowCrossNamespace && !a.opts.AllowClusterScoped { - apply = apply.WithSetOwnerReference(true, false). - WithDefaultNamespace(obj.GetNamespace()). - WithListerNamespace(obj.GetNamespace()) - } - - if !a.opts.AllowClusterScoped { - apply = apply.WithRestrictClusterScoped() - } - - return newStatus, apply. + return newStatus, generic.ConfigureApplyForObject(a.apply, obj, &a.opts). WithOwner(obj). WithSetID(a.name). ApplyObjects(objs...) diff --git a/vendor/github.com/rancher/wrangler/pkg/crd/init.go b/vendor/github.com/rancher/wrangler/pkg/crd/init.go index 1c6a70a89d..a5c9095282 100644 --- a/vendor/github.com/rancher/wrangler/pkg/crd/init.go +++ b/vendor/github.com/rancher/wrangler/pkg/crd/init.go @@ -3,6 +3,7 @@ package crd import ( "context" "reflect" + "strconv" "strings" "sync" "time" @@ -16,7 +17,7 @@ import ( apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" @@ -52,8 +53,107 @@ func (c CRD) WithSchemaFromStruct(obj interface{}) CRD { return c } -func (c CRD) WithCustomColumn(columns []v1beta1.CustomResourceColumnDefinition) CRD { - c.Columns = columns +func (c CRD) WithColumn(name, path string) CRD { + c.Columns = append(c.Columns, v1beta1.CustomResourceColumnDefinition{ + Name: name, + Type: "string", + Priority: 0, + JSONPath: path, + }) + return c +} + +func getType(obj interface{}) reflect.Type { + if t, ok := obj.(reflect.Type); ok { + return t + } + + t := reflect.TypeOf(obj) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + +func (c CRD) WithColumnsFromStruct(obj interface{}) CRD { + c.Columns = append(c.Columns, readCustomColumns(getType(obj), ".")...) + return c +} + +func fieldName(f reflect.StructField) string { + jsonTag := f.Tag.Get("json") + if jsonTag == "-" { + return "" + } + name := strings.Split(jsonTag, ",")[0] + if name == "" { + return f.Name + } + return name +} + +func tagToColumn(f reflect.StructField) (v1beta1.CustomResourceColumnDefinition, bool) { + c := v1beta1.CustomResourceColumnDefinition{ + Name: f.Name, + Type: "string", + } + + columnDef, ok := f.Tag.Lookup("column") + if !ok { + return c, false + } + + for k, v := range kv.SplitMap(columnDef, ",") { + switch k { + case "name": + c.Name = v + case "type": + c.Type = v + case "format": + c.Format = v + case "description": + c.Description = v + case "priority": + p, _ := strconv.Atoi(v) + c.Priority = int32(p) + case "jsonpath": + c.JSONPath = v + } + } + + return c, true +} + +func readCustomColumns(t reflect.Type, path string) (result []v1beta1.CustomResourceColumnDefinition) { + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + fieldName := fieldName(f) + if fieldName == "" { + continue + } + + t := f.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() == reflect.Struct { + if f.Anonymous { + result = append(result, readCustomColumns(t, path)...) + } else { + result = append(result, readCustomColumns(t, path+"."+fieldName)...) + } + } else { + if col, ok := tagToColumn(f); ok { + result = append(result, col) + } + } + } + + return result +} + +func (c CRD) WithCustomColumn(columns ...v1beta1.CustomResourceColumnDefinition) CRD { + c.Columns = append(c.Columns, columns...) return c } @@ -79,10 +179,7 @@ func (c CRD) WithShortNames(shortNames ...string) CRD { func (c CRD) ToCustomResourceDefinition() (apiext.CustomResourceDefinition, error) { if c.SchemaObject != nil && c.GVK.Kind == "" { - t := reflect.TypeOf(c.SchemaObject) - if t.Kind() == reflect.Ptr { - t = t.Elem() - } + t := getType(c.SchemaObject) c.GVK.Kind = t.Name() } @@ -250,6 +347,13 @@ func (f *Factory) CreateCRDs(ctx context.Context, crds ...CRD) (map[schema.Group return nil, nil } + if ok, err := f.ensureAccess(ctx); err != nil { + return nil, err + } else if !ok { + logrus.Infof("No access to list CRDs, assuming CRDs are pre-created.") + return nil, err + } + crdStatus := map[schema.GroupVersionKind]*apiext.CustomResourceDefinition{} ready, err := f.getReadyCRDs(ctx) @@ -341,7 +445,7 @@ func (f *Factory) createCRD(ctx context.Context, crdDef CRD, ready map[string]*a } logrus.Infof("Creating CRD %s", crd.Name) - if newCrd, err := f.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(ctx, &crd, metav1.CreateOptions{}); errors.IsAlreadyExists(err) { + if newCrd, err := f.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(ctx, &crd, metav1.CreateOptions{}); apierrors.IsAlreadyExists(err) { return f.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(ctx, crd.Name, metav1.GetOptions{}) } else if err != nil { return nil, err @@ -350,6 +454,14 @@ func (f *Factory) createCRD(ctx context.Context, crdDef CRD, ready map[string]*a } } +func (f *Factory) ensureAccess(ctx context.Context) (bool, error) { + _, err := f.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{}) + if apierrors.IsForbidden(err) { + return false, nil + } + return true, err +} + func (f *Factory) getReadyCRDs(ctx context.Context) (map[string]*apiext.CustomResourceDefinition, error) { list, err := f.CRDClient.ApiextensionsV1beta1().CustomResourceDefinitions().List(ctx, metav1.ListOptions{}) if err != nil { diff --git a/vendor/github.com/rancher/wrangler/pkg/data/merge.go b/vendor/github.com/rancher/wrangler/pkg/data/merge.go new file mode 100644 index 0000000000..76970aa0a6 --- /dev/null +++ b/vendor/github.com/rancher/wrangler/pkg/data/merge.go @@ -0,0 +1,24 @@ +package data + +func MergeMaps(base, overlay map[string]interface{}) map[string]interface{} { + result := map[string]interface{}{} + for k, v := range base { + result[k] = v + } + for k, v := range overlay { + if baseMap, overlayMap, bothMaps := bothMaps(result[k], v); bothMaps { + v = MergeMaps(baseMap, overlayMap) + } + result[k] = v + } + return result +} + +func bothMaps(left, right interface{}) (map[string]interface{}, map[string]interface{}, bool) { + leftMap, ok := left.(map[string]interface{}) + if !ok { + return nil, nil, false + } + rightMap, ok := right.(map[string]interface{}) + return leftMap, rightMap, ok +} diff --git a/vendor/github.com/rancher/wrangler/pkg/generic/generating.go b/vendor/github.com/rancher/wrangler/pkg/generic/generating.go index 4ae27bebb3..9ac9fae863 100644 --- a/vendor/github.com/rancher/wrangler/pkg/generic/generating.go +++ b/vendor/github.com/rancher/wrangler/pkg/generic/generating.go @@ -1,7 +1,39 @@ package generic +import ( + "github.com/rancher/wrangler/pkg/apply" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + type GeneratingHandlerOptions struct { AllowCrossNamespace bool AllowClusterScoped bool + NoOwnerReference bool DynamicLookup bool } + +func ConfigureApplyForObject(apply apply.Apply, obj metav1.Object, opts *GeneratingHandlerOptions) apply.Apply { + if opts == nil { + opts = &GeneratingHandlerOptions{} + } + + if opts.DynamicLookup { + apply = apply.WithDynamicLookup() + } + + if opts.NoOwnerReference { + apply = apply.WithSetOwnerReference(true, false) + } + + if opts.AllowCrossNamespace && !opts.AllowClusterScoped { + apply = apply. + WithDefaultNamespace(obj.GetNamespace()). + WithListerNamespace(obj.GetNamespace()) + } + + if !opts.AllowClusterScoped { + apply = apply.WithRestrictClusterScoped() + } + + return apply +} diff --git a/vendor/github.com/rancher/wrangler/pkg/generic/handlers.go b/vendor/github.com/rancher/wrangler/pkg/generic/handlers.go index dad472fc34..9af89ae45e 100644 --- a/vendor/github.com/rancher/wrangler/pkg/generic/handlers.go +++ b/vendor/github.com/rancher/wrangler/pkg/generic/handlers.go @@ -5,6 +5,7 @@ import ( "reflect" "strings" + errors2 "github.com/pkg/errors" "k8s.io/apimachinery/pkg/runtime" ) @@ -25,7 +26,7 @@ func (h *Handlers) Handle(key string, obj runtime.Object) (runtime.Object, error for _, handler := range h.handlers { newObj, err := handler.handler(key, obj) - if err != nil { + if err != nil && errors2.Cause(err) != ErrSkip { errs = append(errs, &handlerError{ HandlerName: handler.name, Err: err, diff --git a/vendor/github.com/rancher/wrangler/pkg/gvk/get.go b/vendor/github.com/rancher/wrangler/pkg/gvk/get.go index 3392c545ba..743dc00b1c 100644 --- a/vendor/github.com/rancher/wrangler/pkg/gvk/get.go +++ b/vendor/github.com/rancher/wrangler/pkg/gvk/get.go @@ -27,7 +27,16 @@ func Get(obj runtime.Object) (schema.GroupVersionKind, error) { return gvks[0], nil } -func Set(obj runtime.Object) error { +func Set(objs ...runtime.Object) error { + for _, obj := range objs { + if err := setObject(obj); err != nil { + return err + } + } + return nil +} + +func setObject(obj runtime.Object) error { gvk := obj.GetObjectKind().GroupVersionKind() if gvk.Kind != "" { return nil diff --git a/vendor/github.com/rancher/wrangler/pkg/objectset/objectset.go b/vendor/github.com/rancher/wrangler/pkg/objectset/objectset.go index f295497ad2..f8703dfd91 100644 --- a/vendor/github.com/rancher/wrangler/pkg/objectset/objectset.go +++ b/vendor/github.com/rancher/wrangler/pkg/objectset/objectset.go @@ -34,6 +34,8 @@ func (o ObjectKey) String() string { return fmt.Sprintf("%s/%s", o.Namespace, o.Name) } +type ObjectKeyByGVK map[schema.GroupVersionKind][]ObjectKey + type ObjectByGVK map[schema.GroupVersionKind]map[ObjectKey]runtime.Object func (o ObjectByGVK) Add(obj runtime.Object) (schema.GroupVersionKind, error) { @@ -69,14 +71,19 @@ type ObjectSet struct { gvkSeen map[schema.GroupVersionKind]bool } -func NewObjectSet() *ObjectSet { - return &ObjectSet{ +func NewObjectSet(objs ...runtime.Object) *ObjectSet { + os := &ObjectSet{ objects: ObjectByGVK{}, gvkSeen: map[schema.GroupVersionKind]bool{}, } + os.Add(objs...) + return os } func (o *ObjectSet) ObjectsByGVK() ObjectByGVK { + if o == nil { + return nil + } return o.objects } @@ -126,6 +133,10 @@ func (o *ObjectSet) Len() int { return len(o.objects) } +func (o *ObjectSet) GVKs() []schema.GroupVersionKind { + return o.GVKOrder() +} + func (o *ObjectSet) GVKOrder(known ...schema.GroupVersionKind) []schema.GroupVersionKind { var rest []schema.GroupVersionKind diff --git a/vendor/github.com/rancher/wrangler/pkg/patch/apply.go b/vendor/github.com/rancher/wrangler/pkg/patch/apply.go index b7c7a6080e..da9a25d33a 100644 --- a/vendor/github.com/rancher/wrangler/pkg/patch/apply.go +++ b/vendor/github.com/rancher/wrangler/pkg/patch/apply.go @@ -36,7 +36,7 @@ func applyStrategicMergePatch(original, patch []byte, lookup strategicpatch.Look if err := json.Unmarshal(patch, &patchMap); err != nil { return nil, err } - patchedMap, err := strategicpatch.StrategicMergeMapPatch(originalMap, patchMap, lookup) + patchedMap, err := strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(originalMap, patchMap, lookup) if err != nil { return nil, err } diff --git a/vendor/github.com/rancher/wrangler/pkg/schemas/openapi/generate.go b/vendor/github.com/rancher/wrangler/pkg/schemas/openapi/generate.go index ff5af90ad3..5f64e6632e 100644 --- a/vendor/github.com/rancher/wrangler/pkg/schemas/openapi/generate.go +++ b/vendor/github.com/rancher/wrangler/pkg/schemas/openapi/generate.go @@ -1,6 +1,7 @@ package openapi import ( + "encoding/json" "fmt" types "github.com/rancher/wrangler/pkg/schemas" @@ -8,6 +9,14 @@ import ( "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" ) +var ( + blacklistFields = map[string]bool{ + "kind": true, + "apiVersion": true, + "metadata": true, + } +) + func MustGenerate(obj interface{}) *v1beta1.JSONSchemaProps { if obj == nil { return nil @@ -42,178 +51,169 @@ func toOpenAPI(name string, schemas *types.Schemas) (*v1beta1.JSONSchemaProps, e delete(newSchema.ResourceFields, "kind") delete(newSchema.ResourceFields, "apiVersion") delete(newSchema.ResourceFields, "metadata") - return parseSchema(newSchema, schemas) + + return schemaToProps(newSchema, schemas, map[string]bool{}) } -func parseSchema(schema *types.Schema, schemas *types.Schemas) (*v1beta1.JSONSchemaProps, error) { - jsp := &v1beta1.JSONSchemaProps{ - Description: schema.Description, - Type: "object", - Properties: map[string]v1beta1.JSONSchemaProps{}, +func populateField(fieldJSP *v1beta1.JSONSchemaProps, f *types.Field) error { + fieldJSP.Description = f.Description + // don't reset this to not nullable + if f.Nullable { + fieldJSP.Nullable = f.Nullable + } + fieldJSP.MinLength = f.MinLength + fieldJSP.MaxLength = f.MaxLength + + if f.Type == "string" && len(f.Options) > 0 { + for _, opt := range append(f.Options, "") { + bytes, err := json.Marshal(&opt) + if err != nil { + return err + } + fieldJSP.Enum = append(fieldJSP.Enum, v1beta1.JSON{ + Raw: bytes, + }) + } } - for name, f := range schema.ResourceFields { - fieldJSP := v1beta1.JSONSchemaProps{ - Description: f.Description, - Nullable: f.Nullable, - MinLength: f.MinLength, - MaxLength: f.MaxLength, + if len(f.InvalidChars) > 0 { + fieldJSP.Pattern = fmt.Sprintf("^[^%s]*$", f.InvalidChars) + } + + if len(f.ValidChars) > 0 { + fieldJSP.Pattern = fmt.Sprintf("^[%s]*$", f.ValidChars) + } + + if f.Min != nil { + fl := float64(*f.Min) + fieldJSP.Minimum = &fl + } + + if f.Max != nil { + fl := float64(*f.Max) + fieldJSP.Maximum = &fl + } + + return nil +} + +func typeToProps(typeName string, schemas *types.Schemas, inflight map[string]bool) (*v1beta1.JSONSchemaProps, error) { + t, subType, schema, err := typeAndSchema(typeName, schemas) + if err != nil { + return nil, err + } + + if schema != nil { + return schemaToProps(schema, schemas, inflight) + } + + jsp := &v1beta1.JSONSchemaProps{} + + switch t { + case "map": + additionalProps, err := typeToProps(subType, schemas, inflight) + if err != nil { + return nil, err } - - if len(f.Options) > 0 { - for _, opt := range f.Options { - fieldJSP.Enum = append(fieldJSP.Enum, v1beta1.JSON{ - Raw: []byte(opt), - }) - } + jsp.Type = "object" + jsp.Nullable = true + jsp.AdditionalProperties = &v1beta1.JSONSchemaPropsOrBool{ + Schema: additionalProps, } - - if len(f.InvalidChars) > 0 { - fieldJSP.Pattern = fmt.Sprintf("^[^%s]*$", f.InvalidChars) + case "array": + items, err := typeToProps(subType, schemas, inflight) + if err != nil { + return nil, err } - - if len(f.ValidChars) > 0 { - fieldJSP.Pattern = fmt.Sprintf("^[%s]*$", f.ValidChars) + jsp.Type = "array" + jsp.Nullable = true + jsp.Items = &v1beta1.JSONSchemaPropsOrArray{ + Schema: items, } - - if f.Min != nil { - fl := float64(*f.Min) - fieldJSP.Minimum = &fl - } - - if f.Max != nil { - fl := float64(*f.Max) - fieldJSP.Maximum = &fl - } - - // default is not support by k8s - // - //if f.Default != nil { - // bytes, err := json.Marshal(f.Default) - // if err != nil { - // return nil, err - // } - // fieldJSP.Default = &v1beta1.JSON{ - // Raw: bytes, - // } - //} - - if f.Required { - fieldJSP.Required = append(fieldJSP.Required, name) - } - - if definition.IsMapType(f.Type) { - fieldJSP.Type = "object" - subType := definition.SubType(f.Type) - - subType, schema, err := typeAndSchema(subType, schemas) - if err != nil { - return nil, err - } - - if schema == nil { - fieldJSP.AdditionalProperties = &v1beta1.JSONSchemaPropsOrBool{ - Schema: &v1beta1.JSONSchemaProps{ - Type: subType, - }, - } - } else { - subObject, err := parseSchema(schema, schemas) - if err != nil { - return nil, err - } - - fieldJSP.AdditionalProperties = &v1beta1.JSONSchemaPropsOrBool{ - Schema: subObject, - } - } - } else if definition.IsArrayType(f.Type) { - fieldJSP.Type = "array" - subType := definition.SubType(f.Type) - - subType, schema, err := typeAndSchema(subType, schemas) - if err != nil { - return nil, err - } - - if schema == nil { - fieldJSP.Items = &v1beta1.JSONSchemaPropsOrArray{ - Schema: &v1beta1.JSONSchemaProps{ - Type: subType, - }, - } - } else { - subObject, err := parseSchema(schema, schemas) - if err != nil { - return nil, err - } - - fieldJSP.Items = &v1beta1.JSONSchemaPropsOrArray{ - Schema: subObject, - } - } - } else { - typeName, schema, err := typeAndSchema(f.Type, schemas) - if err != nil { - return nil, err - } - if schema == nil { - fieldJSP.Type = typeName - } else { - fieldJSP.Type = "object" - subObject, err := parseSchema(schema, schemas) - if err != nil { - return nil, err - } - fieldJSP.Properties = subObject.Properties - } - } - - jsp.Properties[name] = fieldJSP + default: + jsp.Type = t } return jsp, nil } -func typeAndSchema(typeName string, schemas *types.Schemas) (string, *types.Schema, error) { - switch typeName { - // TODO: in v1 set the x- header for this - case "intOrString": - return "string", nil, nil - case "int": - return "integer", nil, nil - case "float": - return "number", nil, nil - case "string": - return "string", nil, nil - case "date": - return "string", nil, nil - case "enum": - return "string", nil, nil - case "password": - return "string", nil, nil - case "hostname": - return "string", nil, nil - case "boolean": - return "boolean", nil, nil - case "json": - return "object", nil, nil +func schemaToProps(schema *types.Schema, schemas *types.Schemas, inflight map[string]bool) (*v1beta1.JSONSchemaProps, error) { + jsp := &v1beta1.JSONSchemaProps{ + Description: schema.Description, + Type: "object", } + if inflight[schema.ID] { + return jsp, nil + } + + inflight[schema.ID] = true + defer delete(inflight, schema.ID) + + jsp.Properties = map[string]v1beta1.JSONSchemaProps{} + + for name, f := range schema.ResourceFields { + fieldJSP, err := typeToProps(f.Type, schemas, inflight) + if err != nil { + return nil, err + } + if err := populateField(fieldJSP, &f); err != nil { + return nil, err + } + if f.Required { + jsp.Required = append(jsp.Required, name) + } + jsp.Properties[name] = *fieldJSP + } + + return jsp, nil +} + +func typeAndSchema(typeName string, schemas *types.Schemas) (string, string, *types.Schema, error) { if definition.IsReferenceType(typeName) { - return "string", nil, nil + return "string", "", nil, nil } if definition.IsArrayType(typeName) { - return "array", nil, nil + return "array", definition.SubType(typeName), nil, nil + } + + if definition.IsMapType(typeName) { + return "map", definition.SubType(typeName), nil, nil + } + + switch typeName { + // TODO: in v1 set the x- header for this + case "intOrString": + return "string", "", nil, nil + case "int": + return "integer", "", nil, nil + case "float": + return "number", "", nil, nil + case "string": + return "string", "", nil, nil + case "date": + return "string", "", nil, nil + case "enum": + return "string", "", nil, nil + case "base64": + return "string", "", nil, nil + case "password": + return "string", "", nil, nil + case "hostname": + return "string", "", nil, nil + case "boolean": + return "boolean", "", nil, nil + case "json": + return "object", "", nil, nil } schema := schemas.Schema(typeName) if schema == nil { - return "", nil, fmt.Errorf("failed to find schema %s", typeName) + return "", "", nil, fmt.Errorf("failed to find schema %s", typeName) } if schema.InternalSchema != nil { - return "", schema.InternalSchema, nil + return "", "", schema.InternalSchema, nil } - return "", schema, nil + return "", "", schema, nil } diff --git a/vendor/github.com/rancher/wrangler/pkg/schemas/reflection.go b/vendor/github.com/rancher/wrangler/pkg/schemas/reflection.go index 1b665e8cb7..d1efeaa83f 100644 --- a/vendor/github.com/rancher/wrangler/pkg/schemas/reflection.go +++ b/vendor/github.com/rancher/wrangler/pkg/schemas/reflection.go @@ -64,23 +64,25 @@ func (s *Schemas) MustImportAndCustomize(obj interface{}, f func(*Schema), exter MustCustomizeType(obj, f) } +func getType(obj interface{}) reflect.Type { + if t, ok := obj.(reflect.Type); ok { + return t + } + + t := reflect.TypeOf(obj) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + func (s *Schemas) Import(obj interface{}, externalOverrides ...interface{}) (*Schema, error) { var types []reflect.Type for _, override := range externalOverrides { - types = append(types, reflect.TypeOf(override)) - } - - var ( - v = reflect.ValueOf(obj) - t reflect.Type - ) - - if v.Kind() == reflect.Ptr { - t = v.Elem().Type() - } else { - t = v.Type() + types = append(types, getType(override)) } + t := getType(obj) return s.importType(t, types...) } @@ -320,6 +322,9 @@ func (s *Schemas) readFields(schema *Schema, t reflect.Type) error { } if hasType && hasMeta { + delete(schema.ResourceFields, "kind") + delete(schema.ResourceFields, "apiVersion") + delete(schema.ResourceFields, "metadata") schema.CollectionMethods = []string{"GET", "POST"} schema.ResourceMethods = []string{"GET", "PUT", "DELETE"} } @@ -357,7 +362,11 @@ func (s *Schemas) processFieldsMappers(t reflect.Type, fieldName string, schema } func applyTag(structField *reflect.StructField, field *Field) error { - for _, part := range strings.Split(structField.Tag.Get("norman"), ",") { + t, ok := structField.Tag.Lookup("wrangler") + if !ok { + t = structField.Tag.Get("norman") + } + for _, part := range strings.Split(t, ",") { if part == "" { continue } diff --git a/vendor/modules.txt b/vendor/modules.txt index 353e79dadb..8ee935bcbf 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -716,7 +716,7 @@ github.com/rancher/dynamiclistener/factory github.com/rancher/dynamiclistener/storage/file github.com/rancher/dynamiclistener/storage/kubernetes github.com/rancher/dynamiclistener/storage/memory -# github.com/rancher/helm-controller v0.4.2-0.20200326195131-eb51d4fa9d8d +# github.com/rancher/helm-controller v0.5.0 github.com/rancher/helm-controller/pkg/apis/helm.cattle.io github.com/rancher/helm-controller/pkg/apis/helm.cattle.io/v1 github.com/rancher/helm-controller/pkg/generated/clientset/versioned @@ -745,7 +745,7 @@ github.com/rancher/kine/pkg/server github.com/rancher/kine/pkg/tls # github.com/rancher/remotedialer v0.2.0 github.com/rancher/remotedialer -# github.com/rancher/wrangler v0.5.4-0.20200326191509-4054411d9736 +# github.com/rancher/wrangler v0.6.1 github.com/rancher/wrangler/pkg/apply github.com/rancher/wrangler/pkg/apply/injectors github.com/rancher/wrangler/pkg/cleanup @@ -773,7 +773,7 @@ github.com/rancher/wrangler/pkg/schemes github.com/rancher/wrangler/pkg/signals github.com/rancher/wrangler/pkg/slice github.com/rancher/wrangler/pkg/start -# github.com/rancher/wrangler-api v0.5.1-0.20200326194427-c13310506d04 +# github.com/rancher/wrangler-api v0.6.0 github.com/rancher/wrangler-api/pkg/generated/controllers/apps github.com/rancher/wrangler-api/pkg/generated/controllers/apps/v1 github.com/rancher/wrangler-api/pkg/generated/controllers/batch