diff --git a/application/component.go b/application/component.go new file mode 100644 index 0000000000000000000000000000000000000000..244ee4b67b37c93e5cb8aa035c50fffc62f6b384 --- /dev/null +++ b/application/component.go @@ -0,0 +1,60 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package application + +import ( + "github.com/presslabs/controller-util/syncer" + settings "k8s.libre.sh/application/settings" + interfaces "k8s.libre.sh/interfaces" + meta "k8s.libre.sh/meta" + objects "k8s.libre.sh/objects" +) + +type Component interface { + meta.Instance + GetMeta() meta.Instance + SetDefaults() + Init() + GetObjects() map[int]objects.Object + HasDependencies() bool + GetDependencies() settings.Config +} + +func NewSyncer(i Component, r interfaces.Reconcile, owner interfaces.Object) (syncers []syncer.Interface) { + mutators := i.GetObjects() + + for _, m := range mutators { + syncers = append(syncers, objects.NewObjectSyncer(m, owner, r)) + } + + return syncers +} + +func InitComponent(i Instance, c Component) { + + component := c.GetComponent() + + meta.SetObjectMeta(i, c) + + if len(component) > 0 { + c.SetComponent(component) + } + + for _, o := range c.GetObjects() { + meta.SetObjectMeta(c, o) + } + +} diff --git a/application/components/network.go b/application/components/network.go new file mode 100644 index 0000000000000000000000000000000000000000..1c58ec1e0110ea1608ab3a7e6bfb6e367b55c705 --- /dev/null +++ b/application/components/network.go @@ -0,0 +1,174 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package components + +import ( + "fmt" + "strings" + + corev1 "k8s.io/api/core/v1" + networkingv1beta1 "k8s.io/api/networking/v1beta1" + "k8s.io/apimachinery/pkg/util/intstr" + + "k8s.libre.sh/interfaces" + meta "k8s.libre.sh/meta" + ingress "k8s.libre.sh/objects/ingress" + service "k8s.libre.sh/objects/service" +) + +// +kubebuilder:object:generate=true +type Network struct { + IngressMeta *meta.ObjectMeta `json:"ingressMeta,omitempty"` + ServiceMeta *meta.ObjectMeta `json:"serviceMeta,omitempty"` + *Backend `json:",inline"` +} + +type Service struct { + *meta.ObjectMeta `json:"meta,omitempty"` + *Backend `json:"backend,omitempty"` +} + +func (s *Service) Mutate(obj interfaces.Object) error { + service.MutateService(s, obj.(*corev1.Service), s.ObjectMeta) + meta.MutateMeta(s, obj) + return nil +} + +func (s *Service) GetObject() interfaces.Object { + return &corev1.Service{} +} + +type Ingress struct { + *meta.ObjectMeta `json:"commonMeta,omitempty"` + Backends []Backend `json:"backends,omitempty"` +} + +// +kubebuilder:object:generate=true +type Backend struct { + ServiceName string `json:"name,omitempty"` + Hostname string `json:"hostname,omitempty"` + Paths []string `json:"routes,omitempty"` + TLS bool `json:"tls,omitempty"` + TLSSecretRef string `json:"tlsSecretRef,omitempty"` + Port service.Port `json:"port,omitempty"` + ServiceType corev1.ServiceType `json:"type,omitempty"` +} + +func (i *Ingress) Mutate(obj interfaces.Object) error { + ingress.MutateIngress(i, obj.(*networkingv1beta1.Ingress)) + meta.MutateMeta(i, obj) + return nil +} + +func (i *Ingress) GetObject() interfaces.Object { + return &networkingv1beta1.Ingress{} +} + +func (b *Backend) GetServiceType() corev1.ServiceType { return b.ServiceType } + +func (b *Backend) GetServicePorts() []corev1.ServicePort { + + ports := []corev1.ServicePort{} + ports = append(ports, b.GetServicePort()) + + return ports +} + +func (b *Backend) GetServicePort() corev1.ServicePort { + + port := corev1.ServicePort{ + TargetPort: intstr.FromString(b.Port.Name), + Port: b.Port.Port, + Name: b.Port.Name, + } + + if len(b.Port.Protocol) > 0 { + port.Protocol = b.Port.Protocol + } + + return port +} + +func (b *Backend) GetIngressBackendPaths() []networkingv1beta1.HTTPIngressPath { + + bkpaths := []networkingv1beta1.HTTPIngressPath{} + + for _, p := range b.Paths { + path := networkingv1beta1.HTTPIngressPath{ + Path: p, + Backend: networkingv1beta1.IngressBackend{ + // TODO TO FIX + ServiceName: b.ServiceName, + ServicePort: intstr.FromString(b.Port.Name), + }, + } + + bkpaths = append(bkpaths, path) + } + return bkpaths +} + +func (b *Backend) GetIngressRule() networkingv1beta1.IngressRule { + + rule := networkingv1beta1.IngressRule{ + Host: b.Hostname, + IngressRuleValue: networkingv1beta1.IngressRuleValue{ + HTTP: &networkingv1beta1.HTTPIngressRuleValue{ + Paths: b.GetIngressBackendPaths(), + }, + }, + } + + return rule +} + +func (i *Ingress) GetIngressRules() []networkingv1beta1.IngressRule { + + rules := []networkingv1beta1.IngressRule{} + + for _, ing := range i.Backends { + rules = append(rules, ing.GetIngressRule()) + } + + return rules +} + +func (b *Backend) GetIngressTLS() networkingv1beta1.IngressTLS { + tls := networkingv1beta1.IngressTLS{} + if b.TLS { + if len(b.TLSSecretRef) == 0 { + b.TLSSecretRef = fmt.Sprintf("%v-%v", strings.Replace(b.Hostname, ".", "-", -1), "tls") + } + + tls = networkingv1beta1.IngressTLS{ + SecretName: b.TLSSecretRef, + } + + tls.Hosts = append(tls.Hosts, b.Hostname) + } + return tls +} + +func (i *Ingress) GetIngressTLS() []networkingv1beta1.IngressTLS { + + tlsList := []networkingv1beta1.IngressTLS{} + + for _, ing := range i.Backends { + tlsList = append(tlsList, ing.GetIngressTLS()) + } + + return tlsList +} diff --git a/application/components/workload.go b/application/components/workload.go new file mode 100644 index 0000000000000000000000000000000000000000..1ca82da57ad74b7d690ce43007563b57fddff538 --- /dev/null +++ b/application/components/workload.go @@ -0,0 +1,128 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package components + +import ( + settings "k8s.libre.sh/application/settings" + meta "k8s.libre.sh/meta" + "k8s.libre.sh/objects" + deployment "k8s.libre.sh/objects/deployment" + + corev1 "k8s.io/api/core/v1" +) + +const DefaultComponent string = "app" + +// +kubebuilder:object:generate=true +type Workload struct { + *meta.ObjectMeta `json:"commonMeta,omitempty"` + *deployment.Deployment `json:"deployment,omitempty"` + *Network `json:"network,omitempty"` + Dependencies bool `json:"dependencies,omitempty"` +} + +func (w *Workload) HasDependencies() bool { + return w.Dependencies +} + +func (w *Workload) GetMeta() meta.Instance { + return w.ObjectMeta +} + +func (w *Workload) GetObjects() map[int]objects.Object { + + objects := make(map[int]objects.Object) + + ing := &Ingress{ + // TODO TO FIX + ObjectMeta: w.IngressMeta, + Backends: []Backend{ + *w.Backend, + }, + } + + srv := &Service{ + // TODO TO FIX + ObjectMeta: w.ServiceMeta, + Backend: w.Backend, + } + + meta.SetObjectMeta(w.ObjectMeta, ing.ObjectMeta) + meta.SetObjectMeta(w.ObjectMeta, srv.ObjectMeta) + + objects[0] = srv + objects[1] = ing + objects[2] = w.Deployment + + return objects +} + +func (w *Workload) SetDependencies(s *settings.Component) { w.ConfigSpec = s.ConfigSpec } +func (w *Workload) GetDependencies() settings.Config { return w.ConfigSpec } + +func (w *Workload) SetDefaults() { + + // TODO FIXME + w.Dependencies = true + + w.Backend.ServiceName = w.ServiceMeta.GetName() + + containerPort := corev1.ContainerPort{ + Name: w.Backend.Port.Name, + ContainerPort: w.Backend.Port.Port, + Protocol: w.Backend.Port.Protocol, + } + + w.ContainerSpec.Ports = append(w.ContainerSpec.Ports, containerPort) + +} + +func (w *Workload) Init() { + + // TODO improve initialisation of objectMeta, labels... + if w.ObjectMeta == nil { + w.ObjectMeta = &meta.ObjectMeta{} + } + + if len(w.ObjectMeta.Labels) == 0 { + w.ObjectMeta.Labels = make(map[string]string) + } + + // TODO FIXME + if len(w.ObjectMeta.GetComponent()) == 0 { + w.ObjectMeta.SetComponent(DefaultComponent) + } + + if w.Deployment.ObjectMeta == nil { + w.Deployment.ObjectMeta = &meta.ObjectMeta{} + } + + if w.ConfigSpec == nil { + w.ConfigSpec = &settings.ConfigSpec{} + } + + if w.Backend == nil { + w.Backend = &Backend{} + } + + if w.ServiceMeta == nil { + w.ServiceMeta = &meta.ObjectMeta{} + } + + if w.IngressMeta == nil { + w.IngressMeta = &meta.ObjectMeta{} + } +} diff --git a/components/zz_generated.deepcopy.go b/application/components/zz_generated.deepcopy.go similarity index 73% rename from components/zz_generated.deepcopy.go rename to application/components/zz_generated.deepcopy.go index 32b6e11021b650e919e985ee8f0845091f8bb4fa..eff21773870eb342825a8d102f4955d2babeefd5 100644 --- a/components/zz_generated.deepcopy.go +++ b/application/components/zz_generated.deepcopy.go @@ -25,26 +25,22 @@ import ( ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Ingress) DeepCopyInto(out *Ingress) { +func (in *Backend) DeepCopyInto(out *Backend) { *out = *in - if in.ObjectMeta != nil { - in, out := &in.ObjectMeta, &out.ObjectMeta - *out = new(meta.ObjectMeta) - (*in).DeepCopyInto(*out) - } if in.Paths != nil { in, out := &in.Paths, &out.Paths *out = make([]string, len(*in)) copy(*out, *in) } + out.Port = in.Port } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ingress. -func (in *Ingress) DeepCopy() *Ingress { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backend. +func (in *Backend) DeepCopy() *Backend { if in == nil { return nil } - out := new(Ingress) + out := new(Backend) in.DeepCopyInto(out) return out } @@ -52,42 +48,29 @@ func (in *Ingress) DeepCopy() *Ingress { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Network) DeepCopyInto(out *Network) { *out = *in - if in.ObjectMeta != nil { - in, out := &in.ObjectMeta, &out.ObjectMeta + if in.IngressMeta != nil { + in, out := &in.IngressMeta, &out.IngressMeta *out = new(meta.ObjectMeta) (*in).DeepCopyInto(*out) } - in.Service.DeepCopyInto(&out.Service) - in.Ingress.DeepCopyInto(&out.Ingress) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Network. -func (in *Network) DeepCopy() *Network { - if in == nil { - return nil - } - out := new(Network) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Service) DeepCopyInto(out *Service) { - *out = *in - if in.ObjectMeta != nil { - in, out := &in.ObjectMeta, &out.ObjectMeta + if in.ServiceMeta != nil { + in, out := &in.ServiceMeta, &out.ServiceMeta *out = new(meta.ObjectMeta) (*in).DeepCopyInto(*out) } - out.Port = in.Port + if in.Backend != nil { + in, out := &in.Backend, &out.Backend + *out = new(Backend) + (*in).DeepCopyInto(*out) + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service. -func (in *Service) DeepCopy() *Service { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Network. +func (in *Network) DeepCopy() *Network { if in == nil { return nil } - out := new(Service) + out := new(Network) in.DeepCopyInto(out) return out } diff --git a/application/instance.go b/application/instance.go new file mode 100644 index 0000000000000000000000000000000000000000..e1925508fd0aa59575b4cbd4aa2d5ac4b9badad7 --- /dev/null +++ b/application/instance.go @@ -0,0 +1,114 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package application + +import ( + "context" + + "github.com/presslabs/controller-util/syncer" + + settings "k8s.libre.sh/application/settings" + "k8s.libre.sh/interfaces" + "k8s.libre.sh/meta" + "k8s.libre.sh/objects" +) + +type Instance interface { + meta.Instance + GetComponents() map[int]Component + GetOwner() interfaces.Object + GetSettings() settings.Settings + // GetSettings() map[int]settings.Settings + SetDefaults() +} + +func Init(i Instance) { + + i.SetDefaults() + + for _, c := range i.GetComponents() { + c.Init() + + // TODO TOFIX + component := c.GetComponent() + + meta.SetObjectMeta(i, c) + + if len(component) > 0 { + c.SetComponent(component) + } + + for _, o := range c.GetObjects() { + meta.SetObjectMeta(c, o) + } + + c.SetDefaults() + + } +} + +func NewSyncers(app Instance, r interfaces.Reconcile, owner interfaces.Object) (syncers []syncer.Interface, err error) { + + //////////////////// + //// Settings ////// + /////////////////// + + // TODO TO FIX SHOULD BE RUN IN INITIALIZED FUNCTION + // INITIALISE VALUES FROM EXTERNAL RESOURCES, RANDOM & TEMPLATES + // sett := app.GetSettings().GetConfig().(*components.Settings) + sett := app.GetSettings().(*settings.Component) + + err = sett.Init(r.GetClient()) + + if err != nil { + return syncers, err + } + + // Object Syncers + + for _, obj := range sett.GetObjects() { + // meta.SetObjectMeta(sett.CommonMeta, obj) + s := objects.NewObjectSyncer(obj, owner, r) + + if err := syncer.Sync(context.TODO(), s, r.GetRecorder()); err != nil { + return syncers, err + } + + } + + ///////////////////// + //// Components //// + /////////////////// + components := app.GetComponents() + + // TODO TO FIX SHOULD BE RUN IN INITIALIZED FUNCTION + // INITIALIZE + for _, c := range components { + if c.HasDependencies() { + + deps := c.GetDependencies() + deps = settings.MergeSettings(sett, deps) + + } + // GET SYNCERS + mutators := c.GetObjects() + for _, m := range mutators { + syncers = append(syncers, objects.NewObjectSyncer(m, owner, r)) + } + } + return syncers, nil + +} diff --git a/application/settings/component.go b/application/settings/component.go new file mode 100644 index 0000000000000000000000000000000000000000..6e78b4eedd23f9cd97a2c4c28e4b290b59c83668 --- /dev/null +++ b/application/settings/component.go @@ -0,0 +1,303 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "strings" + + corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + "k8s.libre.sh/application/settings/parameters" + "k8s.libre.sh/meta" + "k8s.libre.sh/objects" + "k8s.libre.sh/objects/configmap" + "k8s.libre.sh/objects/secret" +) + +const ( + // Generate settings as env variables in a configMap or Secret + GenEnvFile SettingsGenerate = "envFile" +) + +const ( + // Generate settings as env variables in a configMap or Secret + SecretSettings SettingsType = "secret" +) + +type SettingsGenerate string +type SettingsType string + +// +kubebuilder:object:generate=true +type Component struct { + CommonMeta *meta.ObjectMeta `json:"commonMeta,omitempty"` + SecretMeta *meta.ObjectMeta `json:"secretMeta,omitempty"` + ConfigMeta *meta.ObjectMeta `json:"configMeta,omitempty"` + // DefaultType parameters.ParameterType `json:"defaultType,omitempty"` + // DefaultMountType parameters.MountType `json:"defaultMountType,omitempty"` + // Template string json:"template,omitempty"` + Generate SettingsGenerate `json:"generate,omitempty"` + SettingsType SettingsType `json:"type,omitempty"` + *ConfigSpec `json:",inline"` +} + +// ConfigSpec defines a list of parameters and references to resources from which those parameters can be fetched +// Only secrets and configmaps in the same namespace are supported as references +// +kubebuilder:object:generate=true +type SettingsSpec struct { + Sources []Source `json:"sources,omitempty"` + // Parameters is a list of parameters + *parameters.Parameters `json:"parameters,omitempty"` +} + +type CreateOptions struct { + CommonMeta *meta.ObjectMeta `json:"commonMeta,omitempty"` + SecretMeta *meta.ObjectMeta `json:"secretMeta,omitempty"` + ConfigMeta *meta.ObjectMeta `json:"configMeta,omitempty"` + // DefaultType parameters.ParameterType `json:"defaultType,omitempty"` + // DefaultMountType parameters.MountType `json:"defaultMountType,omitempty"` + // Template string json:"template,omitempty"` + Generate SettingsGenerate `json:"generate,omitempty"` + SettingsType SettingsType `json:"type,omitempty"` +} + +func (s *Component) GetConfig() Config { return s.ConfigSpec } + +func (s *Component) GetMeta() meta.Instance { return s.CommonMeta } + +func (s *Component) GetSecretMeta() meta.Instance { return s.SecretMeta } + +func (s *Component) GetConfigMapMeta() meta.Instance { return s.ConfigMeta } + +func (s *Component) SetDefaults() { + // TODO TO FIX DUPLICATE WITH INIT + meta.SetObjectMeta(s.CommonMeta, s.SecretMeta) + meta.SetObjectMeta(s.CommonMeta, s.ConfigMeta) +} + +func (s *Component) GetObjects() map[int]objects.Object { + + cm := &configmap.ConfigMap{ + ObjectMeta: s.ConfigMeta, + } + + secret := &secret.Secret{ + ObjectMeta: s.SecretMeta, + } + + objs := make(map[int]objects.Object, 2) + + genConfigParams := []string{} + genSecretParams := []string{} + + for _, p := range *s.ConfigSpec.Parameters { + // TODO TO FIX + if p.MountType == parameters.MountEnvFile && + // TODO TO FIX + (p.Type == parameters.SecretParameter || p.Type == "") && + len(p.Value) > 0 { + if p.Generate != parameters.GenerateTemplate && p.Generate != "" { + genSecretParams = append(genSecretParams, p.Key) + } + secret.Parameters = append(secret.Parameters, p) + } + if p.MountType == parameters.MountEnvFile && + p.Type == parameters.ConfigParameter && + len(p.Value) > 0 { + if p.Generate != parameters.GenerateTemplate && p.Generate != "" { + genConfigParams = append(genConfigParams, p.Key) + } + cm.Parameters = append(cm.Parameters, p) + } + } + + if len(genSecretParams) > 0 { + if len(secret.ObjectMeta.Annotations) == 0 { + secret.ObjectMeta.Annotations = make(map[string]string) + } + secret.ObjectMeta.Annotations["settings.k8s.libre.sh/generate"] = strings.Join(genSecretParams, ",") + + } + + if len(genConfigParams) > 0 { + if len(secret.ObjectMeta.Annotations) == 0 { + cm.ObjectMeta.Annotations = make(map[string]string) + } + secret.ObjectMeta.Annotations["settings.k8s.libre.sh/generate"] = strings.Join(genConfigParams, ",") + } + + // TODO IMPROVE + if len(cm.Parameters) > 0 { + objs[0] = cm + } + + if len(secret.Parameters) > 0 { + if objs[0] == nil { + objs[0] = secret + + } else { + objs[1] = secret + } + } + + return objs +} + +func (s *Component) Init(c client.Client) error { + // TODO TO FIX DUPLICATE WITH SETDEFAULTS + meta.SetObjectMeta(s.CommonMeta, s.ConfigMeta) + meta.SetObjectMeta(s.CommonMeta, s.SecretMeta) + + err := InitParametersValueFrom(s, c) + + if err != nil { + return err + } + + s.InitRandValues() + + err = s.InitTemplateValues(parameters.KeyPairValues(s.Parameters)) + + if err != nil { + return err + } + + return nil +} + +// InitParametersValueFrom intialise the parameters with values provided in external resources in the same namespace +// All parameters values are filled from those resources +// Only Secrets and Configmaps are supported +func InitParametersValueFrom(s *Component, c client.Client) error { + + params := parameters.Parameters{} + + paramsByKey := parameters.ParametersByKey(s.Parameters) + paramsBySecretSource, paramsByConfigMapSource := OrderByResourceRef(s.ConfigSpec) + + cm := &corev1.ConfigMap{} + sec := &corev1.Secret{} + + cm.SetNamespace(s.CommonMeta.GetNamespace()) + sec.SetNamespace(s.CommonMeta.GetNamespace()) + + for k, v := range paramsBySecretSource { + sec.SetName(k) + + err := parameters.GetAndMergeParameters(v, paramsByKey, c, sec) + if err != nil { + return err + } + } + + for k, v := range paramsByConfigMapSource { + cm.SetName(k) + err := parameters.GetAndMergeParameters(v, paramsByKey, c, cm) + if err != nil { + return err + } + } + + secretSrc := Source{ + Ref: s.GetSecretMeta().GetName(), + Type: "secret", + } + configSrc := Source{ + Ref: s.GetSecretMeta().GetName(), + Type: "configmap", + } + + if s.Generate == GenEnvFile { + // s.SecretRefs = []string{s.GetSecretMeta().GetName()} + // s.ConfigRefs = []string{s.GetConfigMapMeta().GetName()} + + s.Sources = []Source{} + + if len(paramsByConfigMapSource) > 0 { + s.Sources = append(s.Sources, configSrc) + } + + if len(paramsBySecretSource) > 0 { + s.Sources = append(s.Sources, secretSrc) + } + + for _, v := range paramsByKey { + v.MountType = parameters.MountEnvFile + v.Ref = "" + params = append(params, v) + } + s.Parameters = ¶ms + + return nil + } + + addSecretSrc := false + addConfigSrc := false + + for _, v := range paramsByKey { + if v.MountType == parameters.MountEnvFile { + v.Ref = "" + + if !addConfigSrc && v.Type == parameters.ConfigParameter { + s.Sources = append(s.Sources, configSrc) + addConfigSrc = true + } else if !addSecretSrc && v.Type == parameters.SecretParameter { + s.Sources = append(s.Sources, secretSrc) + addSecretSrc = true + } + } + params = append(params, v) + } + + s.Parameters = ¶ms + + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SettingsSpec) DeepCopyInto(out *SettingsSpec) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]Source, len(*in)) + copy(*out, *in) + } + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = new(parameters.Parameters) + if **in != nil { + in, out := *in, *out + *out = make([]*parameters.Parameter, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(parameters.Parameter) + **out = **in + } + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingsSpec. +func (in *SettingsSpec) DeepCopy() *SettingsSpec { + if in == nil { + return nil + } + out := new(SettingsSpec) + in.DeepCopyInto(out) + return out +} diff --git a/application/settings/config.go b/application/settings/config.go new file mode 100644 index 0000000000000000000000000000000000000000..057ea8eb25c711b41f32af78d0b75f071f146a9c --- /dev/null +++ b/application/settings/config.go @@ -0,0 +1,188 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package settings provides some api types and interfaces to manage settings in kubernetes +// +// Settings can be provided in: +// - The parent CRD with the parameter type +// - ConfigMaps and Secrets +// +// Settings can be passed to a container: +// - As EnvVar in the container spec (name & value) +// - As EnvVarFrom in the container spec with a fromKey and secret/configMap source +// - As EnvVarFrom object +// - As EnvFrom mounting all the data from a secret/configmap as env var +// - As a file configmap/secret +// +// Settings value: +// - can be randomly generate +// - provided in the crd +// - generate by template +package settings + +import ( + "sort" + + corev1 "k8s.io/api/core/v1" + "k8s.libre.sh/application/settings/parameters" +) + +// +kubebuilder:object:generate=true +type Source struct { + // Ref is the name of a resource in the same namespace + Ref string `json:"ref,omitempty"` + // Type is the type of the resource + // Only Secrets and ConfigMaps are supported + Type string `json:"type,omitempty"` +} + +// ConfigSpec defines a list of parameters and references to resources from which those parameters can be fetched +// Only secrets and configmaps in the same namespace are supported as references +// +kubebuilder:object:generate=true +type ConfigSpec struct { + // Sources is a list of sources for the parameters from kubernetes resources in the same namespace + Sources []Source `json:"sources,omitempty"` + // Parameters is a list of parameters + *parameters.Parameters `json:"parameters,omitempty"` +} + +// SetParameters sets the parameters +func (c *ConfigSpec) SetParameters(parameters *parameters.Parameters) { c.Parameters = parameters } + +// GetParameters return the parameters +func (c *ConfigSpec) GetParameters() *parameters.Parameters { + if c.Parameters == nil { + c.Parameters = ¶meters.Parameters{} + } + return c.Parameters +} + +func (c *ConfigSpec) GetSources() []Source { return c.Sources } + +func (c *ConfigSpec) SetSources(sources []Source) { c.Sources = sources } + +// GetEnvFrom returns a list of EnvFromSource to populate environment variables in the container. +func (c *ConfigSpec) GetEnvFrom() []corev1.EnvFromSource { + // envFroms := []corev1.EnvFromSource{} + envFromSecret := []corev1.EnvFromSource{} + envFromConfigMap := []corev1.EnvFromSource{} + + // envFromMap := map[int]corev1.EnvFromSource{} + envFrom := corev1.EnvFromSource{} + src := Source{} + + for _, p := range *c.Parameters { + if p.MountType == parameters.MountEnvFile && len(p.Ref) > 0 { + if p.Type == parameters.ConfigParameter { + src = Source{ + Ref: p.Ref, + Type: string(p.Type), + } + c.Sources = append(c.Sources, src) + } else if p.Type == parameters.SecretParameter { + src = Source{ + Ref: p.Ref, + Type: string(p.Type), + } + c.Sources = append(c.Sources, src) + } + } + } + + if len(c.Sources) > 0 { + for _, source := range c.Sources { + if source.Type == "configmap" { + envFrom = corev1.EnvFromSource{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: source.Ref, + }, + }, + } + // envFromMap[k] = envFrom + envFromConfigMap = append(envFromConfigMap, envFrom) + } else if source.Type == "secret" { + envFrom = corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: source.Ref, + }, + }, + } + // envFromMap[k] = envFrom + envFromSecret = append(envFromSecret, envFrom) + } + } + } + + // We need to sort so the order is always the same and container is not update + // if len(envFromSecret) > 0 { + sort.SliceStable(envFromSecret, func(i, j int) bool { + return envFromSecret[i].SecretRef.Name < envFromSecret[j].SecretRef.Name + }) + sort.SliceStable(envFromConfigMap, func(i, j int) bool { + return envFromConfigMap[i].ConfigMapRef.Name < envFromConfigMap[j].ConfigMapRef.Name + }) + // } + + envFroms := append(envFromSecret, envFromConfigMap...) + + /* if len(envFroms) > 0 { + return envFroms + } + */ + /* for _, v := range envFromMap { + envFroms = append(envFroms, v) + } + */ + return envFroms + + // return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigSpec) DeepCopyInto(out *ConfigSpec) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]Source, len(*in)) + copy(*out, *in) + } + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + *out = new(parameters.Parameters) + if **in != nil { + in, out := *in, *out + *out = make([]*parameters.Parameter, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(parameters.Parameter) + **out = **in + } + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigSpec. +func (in *ConfigSpec) DeepCopy() *ConfigSpec { + if in == nil { + return nil + } + out := new(ConfigSpec) + in.DeepCopyInto(out) + return out +} diff --git a/application/settings/interface.go b/application/settings/interface.go new file mode 100644 index 0000000000000000000000000000000000000000..be8cb086a23e64b5d3f6d018d1a1acd104e4e1c5 --- /dev/null +++ b/application/settings/interface.go @@ -0,0 +1,52 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "k8s.libre.sh/application/settings/parameters" +) + +type Config interface { + GetParameters() *parameters.Parameters + SetParameters(*parameters.Parameters) + InitRandValues() + InitTemplateValues(map[string]string) error + // InitExternaValues(c client.Client) error + SetSources(sources []Source) + GetSources() (sources []Source) +} + +func MergeSettings(src, dest Config) Config { + + if dest == nil { + dest = src + } else { + dest.SetSources(append(dest.GetSources(), src.GetSources()...)) + + params := *dest.GetParameters() + + if params == nil { + params = *src.GetParameters() + } else { + for _, p := range *src.GetParameters() { + params = append(params, p) + } + } + dest.SetParameters(¶ms) + } + + return dest +} diff --git a/application/settings/parameters/parameter.go b/application/settings/parameters/parameter.go new file mode 100644 index 0000000000000000000000000000000000000000..8370b89f452e6aa538dd2e730225d6199f148ff3 --- /dev/null +++ b/application/settings/parameters/parameter.go @@ -0,0 +1,95 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package parameters + +const ( + // Random value + GenerateRand Generate = "rand" + // Random value of size 12 + GenerateRand12 Generate = "rand12" + // Random value of size 24 + GenerateRand24 Generate = "rand24" + // Value is generated from a template + // Value container the template and will be replaced + GenerateTemplate Generate = "template" +) + +const ( + // Parameter is mounted as key/value in the container envVar specs + MountLiteral MountType = "literal" + // Parameter is mounted as as EnvVarSource in the container envVar specs + // no data is transformed in a new resource + MountFrom MountType = "from" + // Parameter is mouned as file in the container path + MountFile MountType = "file" + // Parameter is mounted as EnvFromSource in the container specs + // Data can be retrieved from the crds or external resources specified in the parameter envFrom + // and transformed in a new secret or configmap + MountEnvFile MountType = "envFile" +) + +const ( + ConfigParameter ParameterType = "configmap" + SecretParameter ParameterType = "secret" + ObjectFieldParameter ParameterType = "field" + TemplateValue ParameterType = "templateValue" +) + +type MountType string +type Generate string +type ParameterType string + +// +kubebuilder:object:generate=true +type Parameters []*Parameter + +// +kubebuilder:object:generate=true +type Parameter struct { + // Key of the parameter, can be mounted as as an environment variable, used in template + // or as in the data fied of configmap/secret + // + // Key must be unique + Key string `json:"key,omitempty"` + // Value of the paramater, should not contain secret values + // If it is a template, ParameterType should be template + Value string `json:"value,omitempty"` + // ValueFrom when specified indicates the source of the parameter. + // Cannot be used if value is not empty. + ValueFrom `json:",inline"` + // MountPath specifies where the parameter will be mounted as a file + MountPath MountPath `json:"mountFrom,omitempty"` + // Generate if specified defines how the parameter value will be generated + Generate Generate `json:"generate,omitempty"` + // Type specifies specifies the parameter type + Type ParameterType `json:"type,omitempty"` + // MountType defined how the parameter will be mounted in the pod + // Defaults to EnvFile + MountType MountType `json:"mountType,omitempty"` +} + +type ValueFrom struct { + // Key to select from the source + FromKey string `json:"fromKey,omitempty"` + // Name of the referent. + Ref string `json:"ref,omitempty"` + // Type of the parameter's source + // Defaults to the parameter type if not specified + RefType ParameterType `json:"refType,omitempty"` +} + +type MountPath struct { + Path string `json:"path,omitempty"` + SubPath string `json:"subPath,omitempty"` +} diff --git a/settings/parameter_helper.go b/application/settings/parameters/parameter_helper.go similarity index 90% rename from settings/parameter_helper.go rename to application/settings/parameters/parameter_helper.go index 9406d6f0cef8bbecdeb2edfce602a5ddf1a435dc..36fc17c621200d7fbb66919ca5b73e745f49e5c8 100644 --- a/settings/parameter_helper.go +++ b/application/settings/parameters/parameter_helper.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package settings +package parameters import ( "errors" @@ -21,8 +21,8 @@ import ( corev1 "k8s.io/api/core/v1" ) +// GetEnvVar gets an environment variables to set in the container. func (p *Parameter) GetEnvVar() (envVar corev1.EnvVar, err error) { - switch p.MountType { case MountLiteral: if len(p.Value) > 0 && len(p.Key) > 0 { @@ -50,6 +50,7 @@ func (p *Parameter) GetEnvVar() (envVar corev1.EnvVar, err error) { }, } return envVar, nil + case ConfigParameter: envVar = corev1.EnvVar{ Name: p.Key, @@ -63,6 +64,7 @@ func (p *Parameter) GetEnvVar() (envVar corev1.EnvVar, err error) { }, } return envVar, nil + case ObjectFieldParameter: envVar = corev1.EnvVar{ Name: p.Key, @@ -77,6 +79,7 @@ func (p *Parameter) GetEnvVar() (envVar corev1.EnvVar, err error) { } } return envVar, errors.New("missing arguments") + default: return envVar, errors.New("wrong MountType") } diff --git a/application/settings/parameters/parameters_helpers.go b/application/settings/parameters/parameters_helpers.go new file mode 100644 index 0000000000000000000000000000000000000000..cac6e807d07bac81f899f7dd9f1d2f1adb9efb82 --- /dev/null +++ b/application/settings/parameters/parameters_helpers.go @@ -0,0 +1,128 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package parameters + +import ( + "bytes" + "sort" + "text/template" + + "github.com/presslabs/controller-util/rand" + corev1 "k8s.io/api/core/v1" +) + +func (p *Parameters) InitValues() { + p.InitRandValues() + p.InitTemplateValues(KeyPairValues(p)) +} + +// InitRandValues initialies the parameters random values +func (p *Parameters) InitRandValues() { + for _, param := range *p { + + if len(param.Key) > 0 && len(param.Value) == 0 && param.Generate != GenerateTemplate && param.Type != ObjectFieldParameter { + var size int + switch param.Generate { + case GenerateRand24: + size = 24 + random, err := rand.AlphaNumericString(size) + if err != nil { + } + param.Value = random + + case GenerateRand12: + size = 12 + random, err := rand.AlphaNumericString(size) + if err != nil { + } + param.Value = random + } + } + } +} + +// InitTemplateValues initialies the parameters values from a template and a key pair value set +// The template shoud be in the parameter value when GenerateTemplate is specified and the values +// will be replaced from the result of the template processing. +func (p *Parameters) InitTemplateValues(values map[string]string) error { + + for _, param := range *p { + if param.Generate == GenerateTemplate { + tmpl, err := template.New(param.Key).Parse(param.Value) + + if err != nil { + return err + } + + var tpl bytes.Buffer + err = tmpl.Execute(&tpl, values) + + if err != nil { + return err + } + + param.Value = tpl.String() + } + } + return nil +} + +// GetData get the data for the secret or configmap as a key:values +// This function only returns data which should be either in a secret or a configmap +// It implements the configmap and secret interfaces +func (p *Parameters) GetData() map[string]string { + data := make(map[string]string) + + for _, param := range *p { + // TODO TO FIX + if (param.MountType == MountEnvFile || param.MountType == "") && + param.Type != ObjectFieldParameter && + len(param.Value) > 0 { + data[param.Key] = param.Value + } + } + + return data +} + +// GetEnvVar gets a list of environment variables to set in the container. +func (p *Parameters) GetEnvVar() []corev1.EnvVar { + envVars := []corev1.EnvVar{} + envVar := corev1.EnvVar{} + + var err error + + for _, param := range *p { + envVar, err = param.GetEnvVar() + // TODO TOFIX + if err != nil { + } + + if len(envVar.Name) > 0 { + envVars = append(envVars, envVar) + } + } + + if len(envVars) > 0 { + // Sort var to avoid update of the object if var are not in the same order? + sort.SliceStable(envVars, func(i, j int) bool { + return envVars[i].Name < envVars[j].Name + }) + + return envVars + } + return nil +} diff --git a/settings/parameters_suite_test.go b/application/settings/parameters/parameters_suite_test.go similarity index 88% rename from settings/parameters_suite_test.go rename to application/settings/parameters/parameters_suite_test.go index cae00848a9f282a00db2e5cf1941e5bfadb74565..3ebdba69cfad4b8632158627b577fc754fb6d752 100644 --- a/settings/parameters_suite_test.go +++ b/application/settings/parameters/parameters_suite_test.go @@ -1,4 +1,4 @@ -package settings_test +package parameters_test import ( "testing" diff --git a/settings/parameters_test.go b/application/settings/parameters/parameters_test.go similarity index 69% rename from settings/parameters_test.go rename to application/settings/parameters/parameters_test.go index ede86f5cec4b77c295434606daacef4067e08160..adcbb4b3288535751d843f1b2af262433e7cd23a 100644 --- a/settings/parameters_test.go +++ b/application/settings/parameters/parameters_test.go @@ -1,10 +1,10 @@ -package settings_test +package parameters_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - . "k8s.libre.sh/settings" + . "k8s.libre.sh/application/settings/parameters" corev1 "k8s.io/api/core/v1" ) @@ -24,8 +24,8 @@ var _ = Describe("Parameters", func() { valueFromSecret ValueFrom valueFromObject ValueFrom parameters *Parameters - settings *Settings - envFrom *EnvFrom + // settings *Settings + // envFrom *EnvFrom ) BeforeEach(func() { @@ -43,7 +43,7 @@ var _ = Describe("Parameters", func() { Value: "{{ .LITERAL_PARAMETER }}", Type: ConfigParameter, Generate: GenerateTemplate, - MountType: MountFrom, + MountType: MountEnvFile, } paramEnvVar = Parameter{ @@ -82,24 +82,6 @@ var _ = Describe("Parameters", func() { MountType: MountFrom, } - // TODO THIS SHOULD THROW AN ERROR - - // paramEnvFrom = Parameter{ - // ValueFrom: ValueFrom{ - // Ref: "confgRef", - // }, - // Type: ConfigParameter, - // MountType: MountFrom, - // } - - // paramEnvFromSecret = Parameter{ - // ValueFrom: ValueFrom{ - // Ref: "secretRef", - // }, - // Type: SecretParameter, - // MountType: MountFrom, - // } - paramEnvVarFromObject = Parameter{ Key: "PARAMETER_FROM_OBJECT", Type: ObjectFieldParameter, @@ -130,20 +112,20 @@ var _ = Describe("Parameters", func() { ¶mMountFile, } - envFrom = &EnvFrom{ - SecretRefs: []string{ - "mysecret", - "myothersecret", - }, - ConfigRefs: []string{ - "myconfigmap", - }, - } - - settings = &Settings{ - EnvFrom: envFrom, - Parameters: parameters, - } + /* envFrom = &EnvFrom{ + SecretRefs: []string{ + "mysecret", + "myothersecret", + }, + ConfigRefs: []string{ + "myconfigmap", + }, + } + + settings = &Settings{ + EnvFrom: envFrom, + Parameters: parameters, + } */ }) @@ -207,7 +189,7 @@ var _ = Describe("Parameters", func() { }) }) - Describe("Generating Env for containers with EnvFrom", func() { + /* Describe("Generating Env for containers with EnvFrom", func() { Context("Generating env", func() { It("should generate envFrom", func() { @@ -241,74 +223,78 @@ var _ = Describe("Parameters", func() { // Expect(err).NotTo(HaveOccurred()) }) }) - Describe("Generating Env for containers with Parameters", func() { - Context("Generating envFrom", func() { - It("should generate envVar", func() { - - expectedObj := []corev1.EnvVar{ - { - Name: "LITERAL_PARAMETER", - Value: "LiteralParameter", - }, - { - Name: "VALUE_FROM_CONFIG_PARAMETER", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "configRef", - }, - Key: "FROM_KEY_CONFIG_PARAMETER", + }) */ + + Describe("Generating Env for containers with Parameters", func() { + Context("Generating envFrom", func() { + It("should generate envVar", func() { + + expectedObj := []corev1.EnvVar{ + { + Name: "LITERAL_PARAMETER", + Value: "LiteralParameter", + }, + { + Name: "VALUE_FROM_CONFIG_PARAMETER", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "configRef", }, + Key: "FROM_KEY_CONFIG_PARAMETER", }, }, - { - Name: "VALUE_FROM_SECRET_PARAMETER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "secretRef", - }, - Key: "FROM_KEY_SECRET_PARAMETER", + }, + { + Name: "VALUE_FROM_SECRET_PARAMETER", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secretRef", }, + Key: "FROM_KEY_SECRET_PARAMETER", }, }, - { - Name: "PARAMETER_FROM_OBJECT", - ValueFrom: &corev1.EnvVarSource{ - FieldRef: &corev1.ObjectFieldSelector{ - APIVersion: "v1", - FieldPath: "status.podIP", - }, + }, + { + Name: "PARAMETER_FROM_OBJECT", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "status.podIP", }, }, - { - Name: "TEMPLATE_PARAMETER", - Value: "LiteralParameter", - }, - } + }, + { + Name: "TEMPLATE_PARAMETER", + Value: "LiteralParameter", + }, + } - parameters.InitValues() - res := parameters.GetEnv() + parameters.InitValues() + res := parameters.GetEnvVar() - Expect(res).To(Equal(expectedObj)) - // Expect(err).NotTo(HaveOccurred()) - }) + Expect(res).To(Equal(expectedObj)) + // Expect(err).NotTo(HaveOccurred()) }) }) - Describe("Generating data for configmap and secret with Parameters", func() { - Context("Generating data", func() { - It("should generate data", func() { - parameters.InitValues() + }) - expectedObj := map[string]string{ - "TEMPLATE_PARAMETER_FROM": "LiteralParameter", - } + Describe("Generating data for configmap and secret with Parameters", func() { + Context("Generating data", func() { + It("should generate data", func() { + parameters.InitValues() - Expect(parameters.GetConfigData()).To(Equal(expectedObj)) - // Expect(err).NotTo(HaveOccurred()) - }) + expectedObj := map[string]string{ + "TEMPLATE_PARAMETER_FROM": "LiteralParameter", + } + + Expect(parameters.GetData()).To(Equal(expectedObj)) + // Expect(err).NotTo(HaveOccurred()) }) }) + }) + /* Describe("Generating mount files", func() { Context("Generating volumes & volume mount", func() { It("should generate volume for pod", func() { @@ -339,5 +325,6 @@ var _ = Describe("Parameters", func() { }) }) }) - }) + */ + }) diff --git a/application/settings/parameters/utils.go b/application/settings/parameters/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..fde7867eefb073ff440a3b08cd898e407d7f0e97 --- /dev/null +++ b/application/settings/parameters/utils.go @@ -0,0 +1,149 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package parameters + +import ( + "context" + "errors" + "reflect" + + corev1 "k8s.io/api/core/v1" + + "k8s.libre.sh/interfaces" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func Marshal(i interface{}) (Parameters, error) { + parameters := Parameters{} + + t := reflect.TypeOf(i) + + ifv := reflect.ValueOf(i) + + for ii := 0; ii < t.NumField(); ii++ { + f := t.Field(ii) + + fv := ifv.Field(ii) + + parameter, ok := fv.Interface().(Parameter) + // TODO Return error + if !ok { + // return nil, ok + } + + env, ok := f.Tag.Lookup("env") + if !ok { + // return nil, ok + } + + if len(parameter.Key) == 0 { + parameter.Key = env + } + + // if len(parameter.MountType) == 0 { + // parameter.MountType = MountEnvFile + // } + + parameters = append(parameters, ¶meter) + } + + return parameters, nil +} + +// Sort parameters by keys +func ParametersByKey(p *Parameters) map[string]*Parameter { + paramsByKey := map[string]*Parameter{} + + for _, param := range *p { + /* if len(param.FromKey) > 0 { + paramsByKey[param.FromKey] = param + + } else { */ + paramsByKey[param.Key] = param + // } + } + return paramsByKey +} + +// Transform parameters to key:value +func KeyPairValues(p *Parameters) map[string]string { + data := make(map[string]string) + + for _, param := range *p { + data[param.Key] = param.Value + } + + return data +} + +func InitParametersFromResources() { + +} + +// TODO SPLIT IN GETPARAMETERSFROMSOURCES AND MERGEPARAMETERSBYKEYS +func GetAndMergeParameters( + params Parameters, + paramsByKey map[string]*Parameter, + c client.Client, + obj interfaces.Object) error { + + var pType ParameterType + data := map[string]string{} + + objectKey, _ := client.ObjectKeyFromObject(obj) + + err := c.Get(context.Background(), objectKey, obj) + + if err != nil { + return err + } + + switch obj.GetObjectKind().GroupVersionKind().Kind { + case "Secret": + pType = SecretParameter + for k, v := range obj.(*corev1.Secret).Data { + data[k] = string(v) + } + case "ConfigMap": + pType = ConfigParameter + for k, v := range obj.(*corev1.ConfigMap).Data { + data[k] = v + } + default: + return errors.New("object kind should be ConfigMap or Secret") + } + + if len(params) > 0 { + for _, pp := range params { + paramsByKey[pp.Key].Value = string(data[pp.FromKey]) + paramsByKey[pp.Key].Generate = "" + } + } else { + for kk, vv := range data { + if paramsByKey[kk] == nil { + paramsByKey[kk] = &Parameter{} + + } + paramsByKey[kk].Value = vv + paramsByKey[kk].Key = kk + // paramsByKey[kk].MountType = MountEnvFile + // TODO TO FIX This should be checked + paramsByKey[kk].Type = pType + } + } + + return nil +} diff --git a/settings/zz_generated.deepcopy.go b/application/settings/parameters/zz_generated.deepcopy.go similarity index 60% rename from settings/zz_generated.deepcopy.go rename to application/settings/parameters/zz_generated.deepcopy.go index be6342e4114b47cfd6fc3656778d18778e973134..7bf5882f7bbc9890bb4393e11ff2be6534efd1aa 100644 --- a/settings/zz_generated.deepcopy.go +++ b/application/settings/parameters/zz_generated.deepcopy.go @@ -17,35 +17,10 @@ limitations under the License. // Code generated by controller-gen. DO NOT EDIT. -package settings +package parameters import () -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvFrom) DeepCopyInto(out *EnvFrom) { - *out = *in - if in.SecretRefs != nil { - in, out := &in.SecretRefs, &out.SecretRefs - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ConfigRefs != nil { - in, out := &in.ConfigRefs, &out.ConfigRefs - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvFrom. -func (in *EnvFrom) DeepCopy() *EnvFrom { - if in == nil { - return nil - } - out := new(EnvFrom) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Parameter) DeepCopyInto(out *Parameter) { *out = *in @@ -87,19 +62,3 @@ func (in Parameters) DeepCopy() Parameters { in.DeepCopyInto(out) return *out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretParam) DeepCopyInto(out *SecretParam) { - *out = *in - out.ValueFrom = in.ValueFrom -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretParam. -func (in *SecretParam) DeepCopy() *SecretParam { - if in == nil { - return nil - } - out := new(SecretParam) - in.DeepCopyInto(out) - return out -} diff --git a/application/settings/settings.go b/application/settings/settings.go new file mode 100644 index 0000000000000000000000000000000000000000..e9c71e7e30d8e0ac4045e038c2abb84f867db75a --- /dev/null +++ b/application/settings/settings.go @@ -0,0 +1,92 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import ( + "k8s.libre.sh/meta" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type Settings interface { + GetMeta() meta.Instance + GetSecretMeta() meta.Instance + GetConfigMapMeta() meta.Instance + GetConfig() Config + SetDefaults() + Init(c client.Client) error +} + +func NewSettings(s Settings) *Component { + return &Component{ + CommonMeta: s.GetMeta().(*meta.ObjectMeta), + SecretMeta: s.GetSecretMeta().(*meta.ObjectMeta), + ConfigMeta: s.GetConfigMapMeta().(*meta.ObjectMeta), + ConfigSpec: &ConfigSpec{ + Sources: s.GetConfig().GetSources(), + Parameters: s.GetConfig().GetParameters(), + }, + } +} + +/* func GetObjects(s Settings) map[int]objects.Object { + + cm := &configmap.ConfigMap{ + ObjectMeta: &meta.ObjectMeta{}, + } + + secret := &secret.Secret{ + ObjectMeta: &meta.ObjectMeta{}, + } + + objs := make(map[int]objects.Object, 2) + + meta.SetObjectMeta(s.GetConfigMapMeta(), cm.ObjectMeta) + meta.SetObjectMeta(s.GetSecretMeta(), secret.ObjectMeta) + + params := s.GetConfig() + + for _, p := range *params.GetParameters() { + if p.MountType == parameters.MountEnvFile && + // TO FIX + p.Type == parameters.SecretParameter && + len(p.Value) > 0 { + secret.Parameters = append(secret.Parameters, p) + } + if p.MountType == parameters.MountEnvFile && + p.Type == parameters.ConfigParameter && + len(p.Value) > 0 { + cm.Parameters = append(cm.Parameters, p) + } + } + + // TODO IMPROVE + if len(cm.Parameters) > 0 { + objs[0] = cm + } + + if len(secret.Parameters) > 0 { + if objs[0] == nil { + objs[0] = secret + + } else { + objs[1] = secret + } + } + + return objs +} +*/ diff --git a/application/settings/utils.go b/application/settings/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..5f9e3598ce3a9b4e4b4679bae948336520fb769c --- /dev/null +++ b/application/settings/utils.go @@ -0,0 +1,73 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package settings + +import "k8s.libre.sh/application/settings/parameters" + +func OrderByResourceRef(s *ConfigSpec) (secrets, configMaps map[string]parameters.Parameters) { + secrets = make(map[string]parameters.Parameters) + configMaps = make(map[string]parameters.Parameters) + + for _, source := range s.Sources { + if source.Type == "secret" { + secrets[source.Ref] = parameters.Parameters{} + } else if source.Type == "configmap" { + configMaps[source.Ref] = parameters.Parameters{} + } + } + + // Then we get the sources that are provided for each parameters and will need a transformation + for _, p := range *s.Parameters { + if len(p.ValueFrom.Ref) > 0 && p.Type == parameters.SecretParameter { + secrets[p.ValueFrom.Ref] = append(secrets[p.ValueFrom.Ref], p) + } + if len(p.ValueFrom.Ref) > 0 && p.Type == parameters.ConfigParameter { + configMaps[p.ValueFrom.Ref] = append(configMaps[p.ValueFrom.Ref], p) + } + } + + return secrets, configMaps +} + +/* +func OrderBySourceTypeAndRef(s *ConfigSpec) (orderedParams map[string]map[string]parameters.Parameters) { + // We order the parameters by secret and configmap sources + // First we get the sources provided that should be mounted untouched + // paramsByResourceName = make(map[string]parameters.Parameters) + orderedParams = make(map[string]map[string]parameters.Parameters) + orderedParams["secret"] = make(map[string]parameters.Parameters) + orderedParams["configmap"] = make(map[string]parameters.Parameters) + orderedParams["field"] = make(map[string]parameters.Parameters) + orderedParams["templateValue"] = make(map[string]parameters.Parameters) + + for _, ref := range s.SecretRefs { + orderedParams["secret"][ref] = parameters.Parameters{} + } + for _, ref := range s.ConfigRefs { + orderedParams["configmap"][ref] = parameters.Parameters{} + + } + + // Then we get the sources that are provided for each parameters and will need a transformation + for _, p := range *s.Parameters { + if len(p.ValueFrom.Ref) > 0 { + orderedParams[string(p.Type)][p.ValueFrom.Ref] = append(orderedParams[string(p.Type)][p.ValueFrom.Ref], p) + + } + } + return orderedParams +} +*/ diff --git a/application/settings/zz_generated.deepcopy.go b/application/settings/zz_generated.deepcopy.go new file mode 100644 index 0000000000000000000000000000000000000000..00ff91684fff2eeb6147715f6bdf98e1ac75cccc --- /dev/null +++ b/application/settings/zz_generated.deepcopy.go @@ -0,0 +1,73 @@ +// +build !ignore_autogenerated + +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package settings + +import ( + "k8s.libre.sh/meta" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Component) DeepCopyInto(out *Component) { + *out = *in + if in.CommonMeta != nil { + in, out := &in.CommonMeta, &out.CommonMeta + *out = new(meta.ObjectMeta) + (*in).DeepCopyInto(*out) + } + if in.SecretMeta != nil { + in, out := &in.SecretMeta, &out.SecretMeta + *out = new(meta.ObjectMeta) + (*in).DeepCopyInto(*out) + } + if in.ConfigMeta != nil { + in, out := &in.ConfigMeta, &out.ConfigMeta + *out = new(meta.ObjectMeta) + (*in).DeepCopyInto(*out) + } + if in.ConfigSpec != nil { + in, out := &in.ConfigSpec, &out.ConfigSpec + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component. +func (in *Component) DeepCopy() *Component { + if in == nil { + return nil + } + out := new(Component) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Source) DeepCopyInto(out *Source) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source. +func (in *Source) DeepCopy() *Source { + if in == nil { + return nil + } + out := new(Source) + in.DeepCopyInto(out) + return out +} diff --git a/components/network.go b/components/network.go deleted file mode 100644 index 1a1a238d18d426664e444cb4f94314b4a7c05d7e..0000000000000000000000000000000000000000 --- a/components/network.go +++ /dev/null @@ -1,137 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package components - -import ( - "fmt" - "strings" - - corev1 "k8s.io/api/core/v1" - networkingv1beta1 "k8s.io/api/networking/v1beta1" - "k8s.io/apimachinery/pkg/util/intstr" - - meta "k8s.libre.sh/meta" - ingress "k8s.libre.sh/objects/ingress" - service "k8s.libre.sh/objects/service" -) - -// +kubebuilder:object:generate=true -type Network struct { - *meta.ObjectMeta `json:"commonMeta,omitempty"` - Service Service `json:"service,omitempty"` - Ingress Ingress `json:"ingress,omitempty"` -} - -// +kubebuilder:object:generate=true -type Service struct { - *meta.ObjectMeta `json:"meta,omitempty"` - Port service.Port `json:"port,omitempty"` - Type corev1.ServiceType `json:"type,omitempty"` -} - -// +kubebuilder:object:generate=true -type Ingress struct { - *meta.ObjectMeta `json:"meta,omitempty"` - Host string `json:"host,omitempty"` - Paths []string `json:"routes,omitempty"` - TLS bool `json:"tls,omitempty"` - TLSSecretRef string `json:"tlsSecretRef,omitempty"` -} - -func (r *Network) GetIngress() *ingress.Ingress { - ing := &ingress.Ingress{ - ObjectMeta: r.Ingress.ObjectMeta, - IngressSpec: &networkingv1beta1.IngressSpec{ - Rules: r.GetIngressRules(), - TLS: r.GetIngressTLS(), - }, - } - return ing -} - -func (c *Network) GetService() *service.Service { - svc := &service.Service{ - ObjectMeta: c.Service.ObjectMeta, - ServiceSpec: &service.ServiceSpec{ - Ports: []service.Port{ - c.Service.Port, - }, - Type: c.Service.Type, - }, - } - - return svc -} - -func (r *Network) GetIngressAnnotations() map[string]string { - return r.Ingress.ObjectMeta.Annotations -} - -func (r *Network) GetIngressBackendPaths() []networkingv1beta1.HTTPIngressPath { - - bkpaths := []networkingv1beta1.HTTPIngressPath{} - - for _, p := range r.Ingress.Paths { - path := networkingv1beta1.HTTPIngressPath{ - Path: p, - Backend: networkingv1beta1.IngressBackend{ - ServiceName: r.Service.ObjectMeta.Name, - ServicePort: intstr.FromString(r.Service.Port.Name), - }, - } - - bkpaths = append(bkpaths, path) - } - return bkpaths -} - -func (r *Network) GetIngressRules() []networkingv1beta1.IngressRule { - - rules := []networkingv1beta1.IngressRule{} - - rule := networkingv1beta1.IngressRule{ - Host: r.Ingress.Host, - IngressRuleValue: networkingv1beta1.IngressRuleValue{ - HTTP: &networkingv1beta1.HTTPIngressRuleValue{ - Paths: r.GetIngressBackendPaths(), - }, - }, - } - - rules = append(rules, rule) - - return rules -} - -func (r *Network) GetIngressTLS() []networkingv1beta1.IngressTLS { - - tls := networkingv1beta1.IngressTLS{} - tlsList := []networkingv1beta1.IngressTLS{} - - if &r.Ingress.TLS != nil { - if len(r.Ingress.TLSSecretRef) == 0 { - r.Ingress.TLSSecretRef = fmt.Sprintf("%v-%v", strings.Replace(r.Ingress.Host, ".", "-", -1), "tls") - } - tls = networkingv1beta1.IngressTLS{ - SecretName: r.Ingress.TLSSecretRef, - } - tls.Hosts = append(tls.Hosts, r.Ingress.Host) - tlsList = append(tlsList, tls) - } else { - tlsList = nil - } - return tlsList -} diff --git a/components/settings.go b/components/settings.go deleted file mode 100644 index ff41ea5978e075a28067cf88732d55060c4c29a9..0000000000000000000000000000000000000000 --- a/components/settings.go +++ /dev/null @@ -1,68 +0,0 @@ -package components - -/* -// +kubebuilder:object:generate=true -type Settings struct { - *meta.ObjectMeta `json:"meta,omitempty"` - parameters.Parameters `json:"parameters,omitempty"` -} - -func (s *Settings) GetParameters() *parameters.Parameters { - return &s.Parameters -} - -func (s *Settings) GetObjects() []instance.Object { - objects := []instance.Object{} - - // for _, param := range *s.Parameters { - // if len(param.Value) > 0 && len(param.Key) > 0 { - // if param.Type == "Secret" { - // objects = append(objects, secret) - // } - // objects = append(objects, secret) - // } - // } - return objects - -} - -func (s *Settings) GetConfigRefs() []string { return nil } - -func (s *Settings) GetSecretRefs() []string { return nil } - -func (s *Settings) SetDefaults(i instance.Instance) { - - if s.ObjectMeta == nil { - s.ObjectMeta = new(meta.ObjectMeta) - } - - if len(s.ObjectMeta.Labels) == 0 { - s.ObjectMeta.Labels = make(map[string]string) - } - - instanceLabels := instance.InstanceLabels(i) - - s.ObjectMeta.SetLabels(instanceLabels) - s.ObjectMeta.Labels["app.kubernetes.io/component"] = "settings" - - if len(s.ObjectMeta.Name) == 0 { - s.ObjectMeta.Name = fmt.Sprintf("%v-%v", i.GetName(), "settings") - } - - if len(s.ObjectMeta.Namespace) == 0 { - s.ObjectMeta.Namespace = i.GetNamespace() - } - -} - -func CreateAndInitSettings(i instance.Settings) *Settings { - return &Settings{ - ObjectMeta: &meta.ObjectMeta{ - Name: i.GetMeta().GetName(), - Namespace: i.GetMeta().GetNamespace(), - Labels: instance.InstanceLabels(i.GetMeta()), - }, - Parameters: *i.GetParameters().Parameters, - } -} -*/ diff --git a/components/workload.go b/components/workload.go deleted file mode 100644 index eda98b0e62ab6cb20cbc49ed41bbc5ee34e75038..0000000000000000000000000000000000000000 --- a/components/workload.go +++ /dev/null @@ -1,93 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package components - -import ( - instance "k8s.libre.sh/instance" - meta "k8s.libre.sh/meta" - deployment "k8s.libre.sh/objects/deployment" - parameters "k8s.libre.sh/settings" -) - -// +kubebuilder:object:generate=true -type Workload struct { - *meta.ObjectMeta `json:"commonMeta,omitempty"` - //*Settings `json:"settings,omitempty"` - *deployment.Deployment `json:"deployment,omitempty"` - *Network `json:"network,omitempty"` - Dependencies bool `json:"dependencies,omitempty"` -} - -func (w *Workload) HasDependencies() bool { - return w.Dependencies -} - -func (w *Workload) GetMeta() instance.Meta { - return w.ObjectMeta -} - -func (w *Workload) GetObjects() map[int]instance.Object { - - objects := make(map[int]instance.Object) - - objects[0] = w.Network.GetService() - objects[1] = w.Network.GetIngress() - objects[2] = w.Deployment - - return objects -} - -func (w *Workload) SetDependencies(s *parameters.Settings) { w.Settings = *s } -func (w *Workload) GetDependencies() parameters.Interface { return &w.Settings } - -// TODO make a generic function with component interface -// getObjects loop setObjectMetaFromComponent -// merge labels && annotations && finalizers not set -func (w *Workload) SetDefaults(i instance.Instance) { - - // TODO FIXME - w.Dependencies = true - - // TODO improve initialisation of objectMeta, labels... - if w.ObjectMeta == nil { - w.ObjectMeta = new(meta.ObjectMeta) - } - - if len(w.ObjectMeta.Labels) == 0 { - w.ObjectMeta.Labels = make(map[string]string) - } - - // TODO TOFIX - w.ObjectMeta.SetComponent("app") - - if w.Deployment.ObjectMeta == nil { - w.Deployment.ObjectMeta = new(meta.ObjectMeta) - } - - if w.Network.ObjectMeta == nil { - w.Network.ObjectMeta = new(meta.ObjectMeta) - } - - if w.Network.Ingress.ObjectMeta == nil { - w.Network.Ingress.ObjectMeta = new(meta.ObjectMeta) - } - - if w.Network.Service.ObjectMeta == nil { - w.Network.Service.ObjectMeta = new(meta.ObjectMeta) - } - - instance.InitComponent(i, w) -} diff --git a/cover.out b/cover.out new file mode 100644 index 0000000000000000000000000000000000000000..40f4c45a06e0b1c1d4f6aa6f0be5469d5a992702 --- /dev/null +++ b/cover.out @@ -0,0 +1,88 @@ +mode: set +k8s.libre.sh/application/settings/parameters/utils.go:22.49,29.39 4 0 +k8s.libre.sh/application/settings/parameters/utils.go:56.2,56.24 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:29.39,36.10 4 0 +k8s.libre.sh/application/settings/parameters/utils.go:40.3,41.10 2 0 +k8s.libre.sh/application/settings/parameters/utils.go:45.3,45.30 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:49.3,49.36 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:53.3,53.46 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:36.11,38.4 0 0 +k8s.libre.sh/application/settings/parameters/utils.go:41.11,43.4 0 0 +k8s.libre.sh/application/settings/parameters/utils.go:45.30,47.4 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:49.36,51.4 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:59.59,62.23 2 0 +k8s.libre.sh/application/settings/parameters/utils.go:66.2,66.20 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:62.23,64.3 1 0 +k8s.libre.sh/application/settings/parameters/utils.go:69.53,72.27 2 1 +k8s.libre.sh/application/settings/parameters/utils.go:76.2,76.13 1 1 +k8s.libre.sh/application/settings/parameters/utils.go:72.27,74.3 1 1 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:25.51,29.2 3 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:32.44,33.15 1 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:36.2,38.12 3 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:33.15,35.3 1 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:42.52,43.2 1 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:43.2,46.22 3 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:46.22,47.23 1 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:47.23,51.5 3 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:57.44,58.15 1 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:61.2,63.13 3 0 +k8s.libre.sh/application/settings/parameters/zz_generated.deepcopy.go:58.15,60.3 1 0 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:24.67,26.21 1 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:28.20,29.41 1 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:36.3,36.65 1 0 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:38.17,39.61 1 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:82.3,82.49 1 0 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:84.10,85.47 1 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:29.41,35.4 2 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:39.61,40.18 1 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:41.25,53.23 2 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:55.25,67.23 2 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:69.30,79.23 2 1 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:89.51,91.2 1 0 +k8s.libre.sh/application/settings/parameters/parameter_helper.go:93.58,95.2 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:29.35,32.2 2 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:34.39,35.27 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:35.27,37.126 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:37.126,39.26 2 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:40.24,43.19 3 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:45.5,45.25 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:47.24,50.19 3 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:52.5,52.25 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:43.20,44.6 0 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:50.20,51.6 0 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:58.73,60.27 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:78.2,78.12 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:60.27,61.41 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:61.41,64.18 2 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:68.4,71.18 3 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:75.4,75.30 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:64.18,66.5 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:71.18,73.5 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:81.50,84.27 2 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:92.2,92.13 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:84.27,87.25 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:87.25,89.4 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:95.50,101.27 4 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:112.2,112.22 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:115.2,115.12 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:101.27,104.17 2 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:107.3,107.27 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:104.18,105.4 0 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:107.27,109.4 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:112.22,114.3 1 1 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:118.128,124.16 3 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:128.2,130.61 2 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:135.2,135.64 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:141.2,141.21 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:157.2,157.12 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:124.16,126.3 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:130.61,131.47 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:131.47,133.4 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:135.64,136.50 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:136.50,138.4 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:141.21,142.29 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:142.29,144.4 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:145.8,146.28 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:146.28,147.30 1 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:150.4,153.44 3 0 +k8s.libre.sh/application/settings/parameters/parameters_helpers.go:147.30,149.5 1 0 diff --git a/go.mod b/go.mod index deb85833e8b1515c70950eb512fda0be14bfabde..28fa277b13e85b9486a404944fbf3deed0944eec 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,9 @@ module k8s.libre.sh go 1.13 require ( + github.com/golangci/golangci-lint v1.27.0 // indirect github.com/onsi/ginkgo v1.12.0 - github.com/onsi/gomega v1.8.1 + github.com/onsi/gomega v1.9.0 github.com/presslabs/controller-util v0.2.2 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 // indirect k8s.io/api v0.18.1 diff --git a/go.sum b/go.sum index 9d40e0c04ccccdddaa7856d175ca26a49d83d702..306ccabfe4adfdef0aba51f7a341c96c6d8894b4 100644 --- a/go.sum +++ b/go.sum @@ -10,14 +10,21 @@ github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxB github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157 h1:hY39LwQHh+1kaovmIjOrlqnXNX6tygSRfLkkK33IkZU= +github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -31,9 +38,13 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bombsimon/wsl/v3 v3.0.0 h1:w9f49xQatuaeTJFaNP4SpiWSR5vfT6IstPtM62JjcqA= +github.com/bombsimon/wsl/v3 v3.0.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -44,13 +55,16 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -65,6 +79,7 @@ github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -72,12 +87,18 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-critic/go-critic v0.4.1 h1:4DTQfT1wWwLg/hzxwD9bkdhDQrdJtxe6DUTadPlrIeE= +github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-lintpack/lintpack v0.5.2 h1:DI5mA3+eKdWeJ40nU4d6Wc26qmdG8RCi/btYq0TuRN0= +github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -121,9 +142,35 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v0.0.0-20180903215011-8f8ee99c3086/go.mod h1:mP93XdblcopXwlyN4X4uodxXQhldPGZbcEJIimQHrkg= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v0.0.0-20180903215135-0af7e3c24f30/go.mod h1:SV2ur98SGypH1UjcPpCatrV5hPazG6+IfNHbkDXBRrk= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0 h1:zKymWyA1TRYvqYrYDrfEMZULyrhcnGY3x7LDKU2XQaA= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b h1:ekuhfTjngPhisSjOJ0QWKpPQE8/rbknHaes6WVJj5Hw= +github.com/gofrs/flock v0.0.0-20190320160742-5135e617513b/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -132,6 +179,7 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -142,6 +190,36 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= +github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= +github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee h1:J2XAy40+7yz70uaOiMbNnluTg7gyQhtGqLQncQh+4J8= +github.com/golangci/gocyclo v0.0.0-20180528134321-2becd97e67ee/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.27.0 h1:VYLx63qb+XJsHdZ27PMS2w5JZacN0XG8ffUwe7yQomo= +github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770 h1:EL/O5HGrF7Jaq0yNhBLucz9hTuRzj2LdwGBOaENgxIk= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0 h1:HVfrLniijszjS1aiNg8JbBMO2+E1WIQ+j/gL4SQqGPg= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -154,6 +232,7 @@ github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -161,18 +240,25 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20190222133341-cfaf5686ec79/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.3.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -182,7 +268,13 @@ github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= +github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= +github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 h1:jNYPNLe3d8smommaoQlK7LOA5ESyUJJ+Wf79ZtA7Vp4= +github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -190,10 +282,17 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -202,19 +301,38 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= +github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= +github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -223,10 +341,18 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= +github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.4.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -246,9 +372,13 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -260,31 +390,56 @@ github.com/presslabs/controller-util v0.2.2 h1:1AOTpk4kQHzu3hp07JiFrXmpF6i0+oQBH github.com/presslabs/controller-util v0.2.2/go.mod h1:nPUlgmBbMD+9nWnyF/rgx0yfistieUfcbqRtcqJrK6A= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/ryancurrah/gomodguard v1.0.4 h1:oCreMAt9GuFXDe9jW4HBpc3GjdX3R/sUEcLAGh1zPx8= +github.com/ryancurrah/gomodguard v1.0.4/go.mod h1:9T/Cfuxs5StfsocWr4WzDL36HqnX0fVb9d5fSEaLhoE= +github.com/securego/gosec/v2 v2.3.0 h1:y/9mCF2WPDbSDpL3QDWZD3HHGrSYw0QSHnCqTfs4JPE= +github.com/securego/gosec/v2 v2.3.0/go.mod h1:UzeVyUXbxukhLeHKV3VVqo7HdoQR9MrRfFmZYotn8ME= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= +github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -292,22 +447,52 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= +github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ= +github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tetafro/godot v0.3.7 h1:+mecr7RKrUKB5UQ1gwqEMn13sDKTyDR8KNIquB9mm+8= +github.com/tetafro/godot v0.3.7/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= +github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa h1:RC4maTWLKKwb7p1cnoygsbKIgNlJqSYBeAFON3Ar8As= +github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= +github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= +github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= +github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -317,6 +502,8 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.uber.org/atomic v0.0.0-20181018215023-8dc6146f7569/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -329,9 +516,11 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1 h1:anGSYQpPhQwXlwsu5wmfq0nWkCNaMEMUwAv13Y92hd8= golang.org/x/crypto v0.0.0-20191128160524-b544559bb6d1/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= @@ -345,11 +534,15 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -359,6 +552,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -369,6 +563,8 @@ golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ym golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5PW3vNmnN64U2ZW759Lk= golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -390,6 +586,7 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -413,24 +610,45 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331202046-9d5940d49312/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770 h1:M9Fif0OxNji8w+HvmhVQ8KJtiZOsjU9RgslJGhn95XE= +golang.org/x/tools v0.0.0-20200502202811-ed308ab3e770/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= @@ -447,6 +665,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= @@ -455,12 +674,17 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= @@ -478,6 +702,8 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48= k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4= k8s.io/api v0.18.1 h1:pnHr0LH69kvL29eHldoepUDKTuiOejNZI2A1gaxve3Q= @@ -517,11 +743,19 @@ k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6 h1:p0Ai3qVtkbCG/Af26dBmU0E1W58NID3hSSh7cMyylpM= k8s.io/utils v0.0.0-20191114200735-6ca3b61696b6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.libre.sh v0.0.0-20200512221307-33a77e4357d3 h1:CaI2kDCfZEjLwKUYZFYuBVYNwKCOk8W2RbIzM81S5yM= +k8s.libre.sh v0.0.0-20200512221307-33a77e4357d3/go.mod h1:MZcprWTWk5YwauA7rnKx13F24/TSvKmfRv7p8yp9yYk= modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= +mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg= sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns= sigs.k8s.io/controller-runtime v0.5.0 h1:CbqIy5fbUX+4E9bpnBFd204YAzRYlM9SWW77BbrcDQo= @@ -539,3 +773,5 @@ sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UA sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/instance/component.go b/instance/component.go deleted file mode 100644 index 3e84a683a62dc6873c4df835de2435ace8a03ab8..0000000000000000000000000000000000000000 --- a/instance/component.go +++ /dev/null @@ -1,70 +0,0 @@ -package instance - -import ( - "github.com/presslabs/controller-util/syncer" - interfaces "k8s.libre.sh/interfaces" - parameters "k8s.libre.sh/settings" -) - -type Component interface { - Meta - GetMeta() Meta - SetDefaults(i Instance) - GetObjects() map[int]Object - HasDependencies() bool - GetDependencies() parameters.Interface - // SetDependencies(*parameters.Settings) -} - -func NewSyncer(i Component, r interfaces.Reconcile, owner interfaces.Object) (syncers []syncer.Interface) { - mutators := i.GetObjects() - - for _, m := range mutators { - syncers = append(syncers, NewObjectSyncer(m, owner, r)) - } - - return syncers -} - -func InitComponent(i Instance, c Component) { - - component := c.GetComponent() - - SetObjectMeta(i, c) - - if len(component) > 0 { - c.SetComponent(component) - } - - for _, o := range c.GetObjects() { - SetObjectMeta(c, o) - } - - if c.HasDependencies() { - dependencies := i.GetSettings().GetParameters() - - settings := c.GetDependencies() - - settings = parameters.MergeSettings(dependencies, settings) - - } -} - -func MergeSettings(dependencies, settings *parameters.Settings) *parameters.Settings { - params := parameters.Parameters{} - - if settings == nil { - settings = dependencies - } else { - - settings.SetConfigRefs(append(settings.GetConfigRefs(), dependencies.GetConfigRefs()...)) - settings.SetSecretRefs(append(settings.GetSecretRefs(), dependencies.GetSecretRefs()...)) - - for _, p := range *dependencies.GetParameters() { - params = append(params, p) - settings.Parameters = ¶ms - } - } - - return settings -} diff --git a/instance/instance.go b/instance/instance.go deleted file mode 100644 index 0dea0e79bfe83f7f133a66ba38437b04ab3a8b45..0000000000000000000000000000000000000000 --- a/instance/instance.go +++ /dev/null @@ -1,55 +0,0 @@ -package instance - -import ( - "github.com/presslabs/controller-util/syncer" - "k8s.io/apimachinery/pkg/labels" - interfaces "k8s.libre.sh/interfaces" - meta "k8s.libre.sh/meta" -) - -type Instance interface { - Meta - GetComponents() map[int]Component - GetOwner() interfaces.Object - GetSettings() Settings -} - -type Meta interface { - meta.Meta - GetApplication() string - SetApplication(string) - GetInstance() string - SetInstance(string) - GetVersion() string - SetVersion(string) - GetComponent() string - SetComponent(string) - GetPartOf() string - SetPartOf(string) - GetManagedBy() string - SetManagedBy(string) -} - -func InstanceLabels(m Meta) map[string]string { - labels := labels.Set{ - "app.kubernetes.io/name": m.GetApplication(), - "app.kubernetes.io/instance": m.GetInstance(), - "app.kubernetes.io/version": m.GetVersion(), - "app.kubernetes.io/component": m.GetComponent(), - "app.kubernetes.io/part-of": m.GetPartOf(), - "app.kubernetes.io/managed-by": m.GetManagedBy(), - } - return labels -} - -func NewSyncers(i Instance, r interfaces.Reconcile, owner interfaces.Object) (syncers []syncer.Interface) { - components := i.GetComponents() - - for _, c := range components { - mutators := c.GetObjects() - for _, m := range mutators { - syncers = append(syncers, NewObjectSyncer(m, owner, r)) - } - } - return syncers -} diff --git a/instance/object.go b/instance/object.go deleted file mode 100644 index 5f3ec2866768c67fd65c0323bc75d5ec6ccfe518..0000000000000000000000000000000000000000 --- a/instance/object.go +++ /dev/null @@ -1,54 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package instance - -import ( - "fmt" - - "k8s.io/apimachinery/pkg/labels" - interfaces "k8s.libre.sh/interfaces" - - "github.com/presslabs/controller-util/syncer" -) - -type Object interface { - Meta - Mutate(obj interfaces.Object) error - GetObject() interfaces.Object -} - -func SetObjectMeta(instance Meta, dest Meta) { - - dest.SetLabels(labels.Merge(dest.GetLabels(), InstanceLabels(instance))) - - if len(dest.GetName()) == 0 { - dest.SetName(fmt.Sprintf("%v-%v", instance.GetInstance(), dest.GetComponent())) - } - if len(dest.GetNamespace()) == 0 { - dest.SetNamespace(instance.GetNamespace()) - - } -} - -func NewObjectSyncer(i Object, owner interfaces.Object, r interfaces.Reconcile) syncer.Interface { - obj := i.GetObject() - obj.SetName(i.GetName()) - obj.SetNamespace(i.GetNamespace()) - - return syncer.NewObjectSyncer(obj.GetObjectKind().GroupVersionKind().Kind, owner, obj, r.GetClient(), r.GetScheme(), func() error { - return i.Mutate(obj) - }) -} diff --git a/instance/settings.go b/instance/settings.go deleted file mode 100644 index 94ed3a93372501450c93b6fd3797c96a2ac3126d..0000000000000000000000000000000000000000 --- a/instance/settings.go +++ /dev/null @@ -1,127 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package instance - -import ( - meta "k8s.libre.sh/meta" - "k8s.libre.sh/objects/configmap" - secret "k8s.libre.sh/objects/secret" - parameters "k8s.libre.sh/settings" -) - -type Dependency interface { - GetParameters() parameters.Interface - // GetSecretParameters() *parameters.Settings - // GetConfigParameters() *parameters.Settings - SetDefaults(i Instance) -} - -type Settings interface { - GetMeta() Meta - GetSecretMeta() Meta - GetConfigMapMeta() Meta - GetParameters() parameters.Interface - // GetSecretParameters() *parameters.Settings - // GetConfigParameters() *parameters.Settings - // GetSecret() secret.Mutate - // GetConfigMap() configmap.Mutate - SetDefaults(i Instance) -} - -func InitParametersFromSettings(s Settings, p parameters.Interface) { - - secretRefs := p.GetSecretRefs() - configRefs := p.GetConfigRefs() - - for _, param := range *p.GetParameters() { - if len(param.MountType) == 0 { - param.MountType = parameters.MountFrom - - if len(param.ValueFrom.Ref) == 0 { - if param.Type == parameters.SecretParameter { - secretRefs = append(secretRefs, s.GetMeta().GetName()) - } - configRefs = append(configRefs, s.GetMeta().GetName()) - } - } - - if len(param.Type) == 0 { - param.Type = parameters.ConfigParameter - } - } - - p.SetConfigRefs(Unique(configRefs)) - p.SetSecretRefs(Unique(secretRefs)) -} - -func Unique(stringSlice []string) []string { - keys := make(map[string]bool) - list := []string{} - for _, entry := range stringSlice { - if _, value := keys[entry]; !value { - keys[entry] = true - list = append(list, entry) - } - } - return list -} - -func GetObjects(s Settings) map[int]Object { - - cm := &configmap.ConfigMap{ - ObjectMeta: &meta.ObjectMeta{}, - } - - secret := &secret.Secret{ - ObjectMeta: &meta.ObjectMeta{}, - } - - objs := make(map[int]Object, 2) - - SetObjectMeta(s.GetMeta(), cm.ObjectMeta) - SetObjectMeta(s.GetMeta(), secret.ObjectMeta) - - // TODO REPLACE BY GET SECRET PARAMETERS & GET CONFIG PARAMETERS - params := s.GetParameters() - - for _, p := range *params.GetParameters() { - // TODO check not mountLiteral ?? - if p.Type == parameters.SecretParameter && len(p.Value) > 0 { - secret.Parameters = append(secret.Parameters, p) - } - if p.Type == parameters.ConfigParameter && len(p.Value) > 0 { - cm.Parameters = append(cm.Parameters, p) - } - } - - // TODO IMPROVE - if len(cm.Parameters) > 0 { - // cm.Parameters = cmParameters - objs[0] = cm - } - - if len(secret.Parameters) > 0 { - // secret.Parameters = secretParameters - if objs[0] == nil { - objs[0] = secret - - } else { - objs[1] = secret - } - } - - return objs -} diff --git a/interfaces/interfaces.go b/interfaces/interfaces.go index 70993dfea4b5e96a727aebbeaff5f3cbd155cb33..9d1dad70539e60892e5fec2afc2791c71484473b 100644 --- a/interfaces/interfaces.go +++ b/interfaces/interfaces.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -25,18 +25,16 @@ import ( // Reconcile is the interface for Reconcile object structs . This // interface can be used to pass around Reconcile structs commonly -// used in Operators. +// used in Kubebuilder. // // Note however that by default Reconcile structs generated using -// Operator SDK do not implement this interface. Add following +// Kubebuilder do not implement this interface. Add following // functions to implement this interface. // // func (r *ReconcileObject) GetClient() client.Client { return r.client } // func (r *ReconcileObject) GetScheme() *runtime.Scheme { return r.scheme } // func (r *ReconcileObject) GetScheme() *runtime.Recorder { return r.recorder } // -// The Reconcile object structs must implement this interface to use -// Operatorlib functions. type Reconcile interface { // Getter function for reconcile client GetClient() client.Client diff --git a/meta/instance.go b/meta/instance.go new file mode 100644 index 0000000000000000000000000000000000000000..8cc6fc205b5d2fe124168d5964ef6262d82f6cc8 --- /dev/null +++ b/meta/instance.go @@ -0,0 +1,73 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package meta + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/labels" +) + +// TODO remove meta in interface, not needed +// Instance interface can work with the commons app.kubernetes.io labels - https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels +type Instance interface { + Meta + // The name of the application - app.kubernetes.io/name + GetApplication() string + SetApplication(string) + // A unique name identifying the instance of an application - app.kubernetes.io/instance + GetInstance() string + SetInstance(string) + // The current version of the application (e.g., a semantic version, revision hash, etc.) - app.kubernetes.io/version + GetVersion() string + SetVersion(string) + // The component within the architecture - app.kubernetes.io/component + GetComponent() string + SetComponent(string) + // The name of a higher level application this one is part of - app.kubernetes.io/part-of + GetPartOf() string + SetPartOf(string) + // The tool being used to manage the operation of an application - app.kubernetes.io/managed-by + GetManagedBy() string + SetManagedBy(string) +} + +// Instance labels returns the app.kubernetes.io labels +func InstanceLabels(m Instance) map[string]string { + labels := labels.Set{ + "app.kubernetes.io/name": m.GetApplication(), + "app.kubernetes.io/instance": m.GetInstance(), + "app.kubernetes.io/version": m.GetVersion(), + "app.kubernetes.io/component": m.GetComponent(), + "app.kubernetes.io/part-of": m.GetPartOf(), + "app.kubernetes.io/managed-by": m.GetManagedBy(), + } + return labels +} + +// TODO use Object interface and rename Merge ? +func SetObjectMeta(src Instance, dest Instance) { + + dest.SetLabels(labels.Merge(dest.GetLabels(), InstanceLabels(src))) + + if len(dest.GetName()) == 0 { + dest.SetName(fmt.Sprintf("%v-%v", src.GetInstance(), dest.GetComponent())) + } + if len(dest.GetNamespace()) == 0 { + dest.SetNamespace(src.GetNamespace()) + + } +} diff --git a/meta/meta.go b/meta/meta.go new file mode 100644 index 0000000000000000000000000000000000000000..1aaad820e9a057b71375c42b28386fcc4dd74d30 --- /dev/null +++ b/meta/meta.go @@ -0,0 +1,47 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package meta + +import ( + "k8s.io/apimachinery/pkg/labels" + interfaces "k8s.libre.sh/interfaces" +) + +// Meta interface is a stripped down version of https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Object with +// only user definied specs. +// +// To mutates an object a type must implements this interface +type Meta interface { + GetLabels() map[string]string + SetLabels(labels map[string]string) + GetAnnotations() map[string]string + SetAnnotations(annotations map[string]string) + GetName() string + SetName(string) + GetNamespace() string + SetNamespace(string) +} + +// MutateMeta mutates an Object meta +func MutateMeta(o Meta, obj interfaces.Object) error { + obj.SetLabels(o.GetLabels()) + + if len(o.GetAnnotations()) > 0 { + obj.SetAnnotations(labels.Merge(obj.GetAnnotations(), o.GetAnnotations())) + } + + return nil +} diff --git a/meta/mutate.go b/meta/mutate.go deleted file mode 100644 index 5fb085689401318fa3c9105253b3ee27ec3b0645..0000000000000000000000000000000000000000 --- a/meta/mutate.go +++ /dev/null @@ -1,84 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package meta - -import ( - interfaces "k8s.libre.sh/interfaces" -) - -type Meta interface { - GetLabels() map[string]string - SetLabels(labels map[string]string) - GetName() string - SetName(string) - GetNamespace() string - SetNamespace(string) -} - -type Labels map[string]string - -/* func (l *Labels) GetApplication() string { return *l["app.kubernetes.io/name"] } - -func (l *Labels) SetApplication(s string) { *l["app.kubernetes.io/name"] = s } - -func (l *Labels) GetInstance() string { return *l["app.kubernetes.io/instance"] } - -func (l *Labels) SetInstance(s string) { *l["app.kubernetes.io/instance"] = s } - -func (l *Labels) GetVersion() string { return *l["app.kubernetes.io/version"] } - -func (l *Labels) SetVersion(s string) { *l["app.kubernetes.io/version"] = s } - -func (l *Labels) GetComponent() string { return *l["app.kubernetes.io/component"] } - -func (l *Labels) SetComponent(s string) { *l["app.kubernetes.io/component"] = s } - -func (l *Labels) GetPartOf() string { return *l["app.kubernetes.io/part-of"] } - -func (l *Labels) SetPartOf(s string) { *l["app.kubernetes.io/part-of"] = s } - -func (l *Labels) GetManagedBy() string { *l["app.kubernetes.io/managed-by"] } - -func (l *Labels) SetManagedBy(s string) { *l["app.kubernetes.io/managed-by"] = s } -*/ -type Application interface { - GetApplication() string - SetApplication(string) - GetInstance() string - SetInstance(string) - GetVersion() string - SetVersion(string) - GetComponent() string - SetComponent(string) - GetPartOf() string - SetPartOf(string) - GetManagedBy() string - SetManagedBy(string) -} - -func MutateMeta(o Meta, obj interfaces.Object) error { - obj.SetLabels(o.GetLabels()) - if len(obj.GetName()) == 0 { - obj.SetName(o.GetName()) - - } - - if len(obj.GetNamespace()) == 0 { - obj.SetNamespace(o.GetNamespace()) - } - - return nil -} diff --git a/meta/object.go b/meta/object.go index e6763bfef8f7732811184d1694f2b6f2bc4ba82b..749aa6595f12e718d18d0aea2e180702ef455f68 100644 --- a/meta/object.go +++ b/meta/object.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -15,17 +15,50 @@ limitations under the License. package meta -import "fmt" - +// ObjectMeta meta is a stripped down version of the ObjectMeta type https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta +// with only user defined specs +// +// This type can be used in an application CRD +// ObjectMeta implements the Meta interface and can be used to mutates an object +// // +kubebuilder:object:generate=true type ObjectMeta struct { - Name string `json:"name,omitempty"` - Namespace string `json:"namespace,omitempty"` - Labels map[string]string `json:"labels,omitempty"` + // Name must be unique within a namespace. Is required when creating resources, although + // some resources may allow a client to request the generation of an appropriate name + // automatically. Name is primarily intended for creation idempotence and configuration + // definition. + // Cannot be updated. + // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // +optional + Name string `json:"name,omitempty"` + + // Namespace defines the space within each name must be unique. An empty namespace is + // equivalent to the "default" namespace, but "default" is the canonical representation. + // Not all objects are required to be scoped to a namespace - the value of this field for + // those objects will be empty. + // + // Must be a DNS_LABEL. + // Cannot be updated. + // More info: http://kubernetes.io/docs/user-guide/namespaces + // +optional + Namespace string `json:"namespace,omitempty"` + + // Map of string keys and values that can be used to organize and categorize + // (scope and select) objects. May match selectors of replication controllers + // and services. + // More info: http://kubernetes.io/docs/user-guide/labels + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Annotations is an unstructured key value map stored with a resource that may be + // set by external tools to store and retrieve arbitrary metadata. They are not + // queryable and should be preserved when modifying objects. + // More info: http://kubernetes.io/docs/user-guide/annotations + // +optional Annotations map[string]string `json:"annotations,omitempty"` - Finalizers map[string]string `json:"finalizers,omitempty"` } +// SetLabels sets the ObjectMeta labels func (c *ObjectMeta) SetLabels(labels map[string]string) { if len(c.Labels) == 0 { c.Labels = make(map[string]string) @@ -39,56 +72,70 @@ func (c *ObjectMeta) SetLabels(labels map[string]string) { } } +// SetAnnotations sets the ObjectMeta annotations +func (c *ObjectMeta) SetAnnotations(annotations map[string]string) { + if len(c.Annotations) == 0 { + c.Annotations = make(map[string]string) + } + if len(annotations) > 0 { + for k, v := range annotations { + if len(c.Annotations[k]) == 0 { + c.Annotations[k] = v + } + } + } +} + +// GetLabels returns the ObjectMeta labels func (c *ObjectMeta) GetLabels() map[string]string { return c.Labels } +// GetAnnotations returns the Annotations labels func (c *ObjectMeta) GetAnnotations() map[string]string { return c.Annotations } -func (c *ObjectMeta) GetFinalizers() map[string]string { return c.Finalizers } - +// GetName returns the ObjectMeta name func (o *ObjectMeta) GetName() string { return o.Name } +// SetName sets the ObjectMeta name func (o *ObjectMeta) SetName(name string) { o.Name = name } +// GetNamespace returns the ObjectMeta namespace func (o *ObjectMeta) GetNamespace() string { return o.Namespace } +// SetNamespace sets the ObjectMeta namespace func (o *ObjectMeta) SetNamespace(namespace string) { o.Namespace = namespace } +// GetApplication returns the ObjectMeta application name from the app.kubernetes.io/name label func (c *ObjectMeta) GetApplication() string { return c.Labels["app.kubernetes.io/name"] } +// SetApplication sets the ObjectMeta application name from the app.kubernetes.io/name label func (c *ObjectMeta) SetApplication(s string) { c.Labels["app.kubernetes.io/name"] = s } +// GetInstance returns the ObjectMeta application name from the app.kubernetes.io/instance label func (c *ObjectMeta) GetInstance() string { return c.Labels["app.kubernetes.io/instance"] } +// SetInstance sets the ObjectMeta application name from the app.kubernetes.io/instance label func (c *ObjectMeta) SetInstance(s string) { c.Labels["app.kubernetes.io/instance"] = s } +// GetVersion returns the ObjectMeta application name from the app.kubernetes.io/version label func (c *ObjectMeta) GetVersion() string { return c.Labels["app.kubernetes.io/version"] } +// SetVersion sets the ObjectMeta application name from the app.kubernetes.io/version label func (c *ObjectMeta) SetVersion(s string) { c.Labels["app.kubernetes.io/version"] = s } +// GetComponent returns the ObjectMeta application name from the app.kubernetes.io/component label func (c *ObjectMeta) GetComponent() string { return c.Labels["app.kubernetes.io/component"] } +// SetComponent sets the ObjectMeta application name from the app.kubernetes.io/component label func (c *ObjectMeta) SetComponent(s string) { c.Labels["app.kubernetes.io/component"] = s } +// GetPartOf returns the ObjectMeta application name from the app.kubernetes.io/part-of label func (c *ObjectMeta) GetPartOf() string { return c.Labels["app.kubernetes.io/part-of"] } +// SetPartOf sets the ObjectMeta application name from the app.kubernetes.io/part-of label func (c *ObjectMeta) SetPartOf(s string) { c.Labels["app.kubernetes.io/part-of"] = s } +// GetManagedBy returns the ObjectMeta application name from the app.kubernetes.io/managed-by label func (c *ObjectMeta) GetManagedBy() string { return c.Labels["app.kubernetes.io/managed-by"] } +// SetManagedBy sets the ObjectMeta application name from the app.kubernetes.io/managed-by label func (c *ObjectMeta) SetManagedBy(s string) { c.Labels["app.kubernetes.io/managed-by"] = s } - -func Init(om *ObjectMeta) { - if om == nil { - om = new(ObjectMeta) - } - if len(om.Labels) == 0 { - om.Labels = make(map[string]string) - } - fmt.Println(om) -} - -func New() *ObjectMeta { - om := new(ObjectMeta) - om.Labels = make(map[string]string) - return om -} diff --git a/meta/zz_generated.deepcopy.go b/meta/zz_generated.deepcopy.go index a59226640186ea3c14e1db7030a326580418846b..7acc2a04b708c28f15e16eecc8bcab35f6c1ba43 100644 --- a/meta/zz_generated.deepcopy.go +++ b/meta/zz_generated.deepcopy.go @@ -38,13 +38,6 @@ func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) { (*out)[key] = val } } - if in.Finalizers != nil { - in, out := &in.Finalizers, &out.Finalizers - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMeta. diff --git a/objects/configmap/mutate.go b/objects/configmap/mutate.go index c6e35cb6aaa37e696d4e6b7786beac92ccde0c8c..bb182283b3e3d06ba0079b06a1f11526347a50f9 100644 --- a/objects/configmap/mutate.go +++ b/objects/configmap/mutate.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -29,14 +29,17 @@ func MutateConfigMap(r Mutate, obj *corev1.ConfigMap, m meta.Meta) error { data := r.GetData() if len(obj.Data) == 0 { - obj.Data = make(map[string]string) + obj.Data = make(map[string]string, len(data)) } - if len(data) > 0 { + // TODO TO FIX data won't be removed if parameter removed + /* if len(data) > 0 { for k, v := range data { obj.Data[k] = v } - } + } */ + + obj.Data = data meta.MutateMeta(m, obj) diff --git a/objects/configmap/object.go b/objects/configmap/object.go index 116e5bff8706263696aa9891ff0cf0b7bebfb267..ef420e93b89d5e0688be3d549efa1e37cfb27f60 100644 --- a/objects/configmap/object.go +++ b/objects/configmap/object.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,9 @@ limitations under the License. package configmap import ( + parameters "k8s.libre.sh/application/settings/parameters" interfaces "k8s.libre.sh/interfaces" meta "k8s.libre.sh/meta" - parameters "k8s.libre.sh/settings" corev1 "k8s.io/api/core/v1" ) diff --git a/objects/configmap/zz_generated.deepcopy.go b/objects/configmap/zz_generated.deepcopy.go index b63153f53344b8d407fac1bc2bb4565dc9d49c1e..aa97cb01884eecbcf8074e551f9352fa2eada87b 100644 --- a/objects/configmap/zz_generated.deepcopy.go +++ b/objects/configmap/zz_generated.deepcopy.go @@ -20,8 +20,8 @@ limitations under the License. package configmap import ( + "k8s.libre.sh/application/settings/parameters" "k8s.libre.sh/meta" - "k8s.libre.sh/settings" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -34,11 +34,11 @@ func (in *ConfigMap) DeepCopyInto(out *ConfigMap) { } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters - *out = make(settings.Parameters, len(*in)) + *out = make(parameters.Parameters, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(settings.Parameter) + *out = new(parameters.Parameter) **out = **in } } diff --git a/objects/container/mutate.go b/objects/container/mutate.go index 6dc1d3879adccc062f7d9ebca8568c0d7f30508c..da16e140143db65380669d95ff1aaaadf55c86bc 100644 --- a/objects/container/mutate.go +++ b/objects/container/mutate.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -23,8 +23,7 @@ type Mutate interface { // Parameters // GetVolumeMount() []corev1.VolumeMount GetEnvFrom() []corev1.EnvFromSource - GetEnv() []corev1.EnvVar - // GetParameters() parameters.Parameters + GetEnvVar() []corev1.EnvVar // Runtime GetContainerName() string GetContainerImage() string @@ -45,7 +44,7 @@ func MutateContainer(r Mutate, obj *corev1.Container) error { obj.Args = r.GetContainerArgs() obj.EnvFrom = r.GetEnvFrom() - obj.Env = r.GetEnv() + obj.Env = r.GetEnvVar() // obj.VolumeMounts = r.GetVolumeMount() diff --git a/objects/container/object.go b/objects/container/object.go index 12b392fa04a605874bea9a65f910b264f6235d84..d08c4b1a4e79d956922cca971938c9493fb20919 100644 --- a/objects/container/object.go +++ b/objects/container/object.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -17,45 +17,89 @@ package container import ( corev1 "k8s.io/api/core/v1" - parameters "k8s.libre.sh/settings" + parameters "k8s.libre.sh/application/settings" ) +// Container is the specification of the desired behavior of the Container. +// It is a stripped down version of https://godoc.org/k8s.io/api/core/v1#Container +// with only user definied specs +// +// Parameters are used to define how settings are passed on to the container. +// // +kubebuilder:object:generate=true type Container struct { - *TemplateSpec `json:",inline"` - parameters.Settings `json:"parameters,omitempty"` + *ContainerSpec `json:",inline"` + *parameters.ConfigSpec `json:"parameters,omitempty"` } // +kubebuilder:object:generate=true -type TemplateSpec struct { - Name string `json:"name,omitempty"` - Args []string `json:"args,omitempty"` - Image string `json:"image,omitempty"` - ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` - Ports []corev1.ContainerPort `json:"ports,omitempty"` - Probes `json:"inline,omitempty"` +type ContainerSpec struct { + // Name of the container specified as a DNS_LABEL. + // Each container in a pod must have a unique name (DNS_LABEL). + // Cannot be updated. + Name string `json:"name,omitempty"` + // Docker image name. + // More info: https://kubernetes.io/docs/concepts/containers/images + // This field is optional to allow higher level config management to default or override + // container images in workload controllers like Deployments and StatefulSets. + // +optional + Image string `json:"image,omitempty"` + // Arguments to the entrypoint. + // The docker image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax + // can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, + // regardless of whether the variable exists or not. + // Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + Args []string `json:"args,omitempty"` + // List of ports to expose from the container. Exposing a port here gives + // the system additional information about the network connections a + // container uses, but is primarily informational. Not specifying a port here + // DOES NOT prevent that port from being exposed. Any port which is + // listening on the default "0.0.0.0" address inside a container will be + // accessible from the network. + // Cannot be updated. + // +optional + // +patchMergeKey=containerPort + // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol + Ports []corev1.ContainerPort `json:"ports,omitempty"` + // Image pull policy. + // One of Always, Never, IfNotPresent. + // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + // +optional + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` + Probes `json:"inline,omitempty"` } +// Periodic probe for container health +// // +kubebuilder:object:generate=true type Probes struct { + // Periodic probe of container liveness. + // Container will be restarted if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"` - LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"` + // Periodic probe of container liveness. + // Container will be restarted if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"` } -func (r *TemplateSpec) GetContainerImage() string { return r.Image } -func (r *TemplateSpec) GetContainerName() string { return r.Name } -func (r *TemplateSpec) GetContainerImagePullPolicy() corev1.PullPolicy { return r.ImagePullPolicy } -func (r *TemplateSpec) GetContainerPorts() []corev1.ContainerPort { return r.Ports } -func (r *TemplateSpec) GetContainerLivenessProbe() *corev1.Probe { return r.LivenessProbe } -func (r *TemplateSpec) GetContainerReadinessProbe() *corev1.Probe { return r.ReadinessProbe } -func (r *TemplateSpec) GetContainerArgs() []string { return r.Args } - -// func (r *TemplateSpec) GetParameters() parameters.Parameters { return nil } - -//func NewContainer(spec *TemplateSpec, p parameters.Parameters) *Container { -// return &Container{ -// Parameters: p, -// TemplateSpec: spec, -// } -//} +func (c *ContainerSpec) GetContainerImage() string { return c.Image } +func (c *ContainerSpec) GetContainerName() string { return c.Name } +func (c *ContainerSpec) GetContainerImagePullPolicy() corev1.PullPolicy { return c.ImagePullPolicy } +func (c *ContainerSpec) GetContainerPorts() []corev1.ContainerPort { return c.Ports } +func (c *ContainerSpec) GetContainerLivenessProbe() *corev1.Probe { return c.LivenessProbe } +func (c *ContainerSpec) GetContainerReadinessProbe() *corev1.Probe { return c.ReadinessProbe } +func (c *ContainerSpec) GetContainerArgs() []string { return c.Args } diff --git a/objects/container/zz_generated.deepcopy.go b/objects/container/zz_generated.deepcopy.go index e0fb9d742d99892f65c7842451996c2dd8225931..bc8a234a376392f015e2264bffd2a13789054388 100644 --- a/objects/container/zz_generated.deepcopy.go +++ b/objects/container/zz_generated.deepcopy.go @@ -26,12 +26,15 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Container) DeepCopyInto(out *Container) { *out = *in - if in.TemplateSpec != nil { - in, out := &in.TemplateSpec, &out.TemplateSpec - *out = new(TemplateSpec) + if in.ContainerSpec != nil { + in, out := &in.ContainerSpec, &out.ContainerSpec + *out = new(ContainerSpec) (*in).DeepCopyInto(*out) } - in.Settings.DeepCopyInto(&out.Settings) + if in.ConfigSpec != nil { + in, out := &in.ConfigSpec, &out.ConfigSpec + *out = (*in).DeepCopy() + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container. @@ -45,57 +48,52 @@ func (in *Container) DeepCopy() *Container { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Probes) DeepCopyInto(out *Probes) { +func (in *ContainerSpec) DeepCopyInto(out *ContainerSpec) { *out = *in - if in.ReadinessProbe != nil { - in, out := &in.ReadinessProbe, &out.ReadinessProbe - *out = new(v1.Probe) - (*in).DeepCopyInto(*out) + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) } - if in.LivenessProbe != nil { - in, out := &in.LivenessProbe, &out.LivenessProbe - *out = new(v1.Probe) - (*in).DeepCopyInto(*out) + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1.ContainerPort, len(*in)) + copy(*out, *in) } + in.Probes.DeepCopyInto(&out.Probes) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes. -func (in *Probes) DeepCopy() *Probes { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerSpec. +func (in *ContainerSpec) DeepCopy() *ContainerSpec { if in == nil { return nil } - out := new(Probes) + out := new(ContainerSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TemplateSpec) DeepCopyInto(out *TemplateSpec) { +func (in *Probes) DeepCopyInto(out *Probes) { *out = *in - if in.Args != nil { - in, out := &in.Args, &out.Args - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]v1.LocalObjectReference, len(*in)) - copy(*out, *in) + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) } - if in.Ports != nil { - in, out := &in.Ports, &out.Ports - *out = make([]v1.ContainerPort, len(*in)) - copy(*out, *in) + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) } - in.Probes.DeepCopyInto(&out.Probes) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplateSpec. -func (in *TemplateSpec) DeepCopy() *TemplateSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes. +func (in *Probes) DeepCopy() *Probes { if in == nil { return nil } - out := new(TemplateSpec) + out := new(Probes) in.DeepCopyInto(out) return out } diff --git a/objects/deployment/deployment.go b/objects/deployment/deployment.go index bfc56cb3a294c07c539ca0cb40bfb9e8ca98b5c2..48b8757d994b1658b0b56a01fd978ed4815bfc3e 100644 --- a/objects/deployment/deployment.go +++ b/objects/deployment/deployment.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -24,53 +24,72 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// Deployment is the specification of the desired behavior of the Deployment. +// It is a stripped down version of https://godoc.org/k8s.io/api/apps/v1#Deployment +// with only user definied specs +// // +kubebuilder:object:generate=true type Deployment struct { + // Standard object metadata. + // +optional *meta.ObjectMeta `json:"meta,omitempty"` - *DeploymentSpec `json:",inline"` + // Specification of the desired behavior of the Deployment. + // +optional + *DeploymentSpec `json:",inline"` } +// DeploymentSpec is the specification of the desired behavior of the DeploymentSpec. +// It is a stripped down version of https://godoc.org/k8s.io/api/apps/v1#DeploymentSpec +// with only user definied specs +// // +kubebuilder:object:generate=true type DeploymentSpec struct { - Replicas *int32 `json:"replicas,omitempty"` - Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"` + // Number of desired pods. This is a pointer to distinguish between explicit + // zero and not specified. Defaults to 1. + // +optional + Replicas *int32 `json:"replicas,omitempty"` + // The deployment strategy to use to replace existing pods with new ones. + // +optional + // +patchStrategy=retainKeys + Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"` + // PodSpec describes the pods that will be created. *pod.PodSpec `json:",inline"` } -func (r *DeploymentSpec) GetReplicas() *int32 { - return r.Replicas +func (spec *DeploymentSpec) GetReplicas() *int32 { + return spec.Replicas } -func (r *DeploymentSpec) GetDeploymentStrategy() appsv1.DeploymentStrategy { - return r.Strategy +func (spec *DeploymentSpec) GetDeploymentStrategy() appsv1.DeploymentStrategy { + return spec.Strategy } func (o *Deployment) GetObject() interfaces.Object { return &appsv1.Deployment{} } -func (w *Deployment) Mutate(obj interfaces.Object) error { +func (o *Deployment) Mutate(obj interfaces.Object) error { deploy := obj.(*appsv1.Deployment) - w.PodSpec.ObjectMeta = w.ObjectMeta + // TODO TO FIX merge meta + o.PodSpec.ObjectMeta = o.ObjectMeta - MutateDeployment(w, deploy) + err := MutateDeployment(o, deploy) + if err != nil { + return err + } - meta.MutateMeta(w.ObjectMeta, obj) + err = meta.MutateMeta(o.ObjectMeta, obj) + if err != nil { + return err + } deploy.Spec.Template.ObjectMeta.Name = deploy.ObjectMeta.Name - deploy.Spec.Template.ObjectMeta.Labels = w.ObjectMeta.Labels + deploy.Spec.Template.ObjectMeta.Labels = o.ObjectMeta.Labels - deploy.Spec.Selector = metav1.SetAsLabelSelector(w.ObjectMeta.Labels) + deploy.Spec.Selector = metav1.SetAsLabelSelector(o.ObjectMeta.Labels) return nil } - -//func NewDeployment(spec *DeploymentSpec, p parameters.Parameters) *Deployment { -// return &Deployment{ -// Parameters: p, -// DeploymentSpec: spec, -// } -//} diff --git a/objects/deployment/mutate.go b/objects/deployment/mutate.go index f36491d3898944f604ef73e8779b6cc355d9b73a..848371b9404e3d36aa4b14acc50605b99041cf0d 100644 --- a/objects/deployment/mutate.go +++ b/objects/deployment/mutate.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/objects/ingress/mutate.go b/objects/ingress/mutate.go index 1f6f8a19aadf0a480fd61b9eac000e376042be9e..cce3d3e8042cd9b6a5e813d7334389a722efcddf 100644 --- a/objects/ingress/mutate.go +++ b/objects/ingress/mutate.go @@ -1,3 +1,18 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package ingress import ( diff --git a/objects/ingress/object.go b/objects/ingress/object.go index d7f7899f7e5fd4c6a8215a078483545c0f43c2e4..e299707f4c35f7e43c5e9d8fd8d6d384793f786f 100644 --- a/objects/ingress/object.go +++ b/objects/ingress/object.go @@ -1,9 +1,23 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package ingress import ( interfaces "k8s.libre.sh/interfaces" meta "k8s.libre.sh/meta" - parameters "k8s.libre.sh/settings" networkingv1beta1 "k8s.io/api/networking/v1beta1" ) @@ -31,5 +45,3 @@ func (o *Ingress) Mutate(obj interfaces.Object) error { func (o *Ingress) GetObject() interfaces.Object { return &networkingv1beta1.Ingress{} } - -func (o *Ingress) SetSettings(parameters parameters.Parameters) {} diff --git a/objects/object.go b/objects/object.go new file mode 100644 index 0000000000000000000000000000000000000000..cc6f70506019e57100f8038297e3693beeae7145 --- /dev/null +++ b/objects/object.go @@ -0,0 +1,48 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Objects package contains core kubernetes resources definitions that can be included in an application CRD. +// The definitions are stripped down version with only specs that should be user-defined. +// +// Every objects definied in this package implements a mutate interface which can create or update its associated kubernetes resource. +// +// All those objects also implements the Object inteface from which we can create an object syncer - see https://github.com/presslabs/controller-util/syncer +package objects + +import ( + interfaces "k8s.libre.sh/interfaces" + meta "k8s.libre.sh/meta" + + "github.com/presslabs/controller-util/syncer" +) + +// Object interface must be supported by all types that want to sync an object. +// The object interface provides a mutate function and a runtime.Object that can be used in controller-runtime CreateOrUpdate +type Object interface { + meta.Instance + Mutate(obj interfaces.Object) error + GetObject() interfaces.Object +} + +// NewObjectSyncer returns a syncer interface from https://github.com/presslabs/controller-util/syncer which can reconcile an object, create events and logs. +func NewObjectSyncer(i Object, owner interfaces.Object, r interfaces.Reconcile) syncer.Interface { + obj := i.GetObject() + obj.SetName(i.GetName()) + obj.SetNamespace(i.GetNamespace()) + + return syncer.NewObjectSyncer(obj.GetObjectKind().GroupVersionKind().Kind, owner, obj, r.GetClient(), r.GetScheme(), func() error { + return i.Mutate(obj) + }) +} diff --git a/objects/pod/mutate.go b/objects/pod/mutate.go index 4bd43f8e101ae14cd1c8fdda53c136d244ab4e05..d24a204adca599eca134dceb6a7842850090804b 100644 --- a/objects/pod/mutate.go +++ b/objects/pod/mutate.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -38,7 +38,7 @@ func MutatePod(r Mutate, obj *corev1.PodTemplateSpec) error { containerList := []corev1.Container{} obj.Spec.SecurityContext = r.GetPodSecurityContext() - //& obj.Spec.Volumes = r.GetPodVolumes() + // obj.Spec.Volumes = r.GetPodVolumes() obj.Spec.RestartPolicy = r.GetPodRestartPolicy() obj.Spec.NodeSelector = r.GetPodNodeSelector() obj.Spec.Affinity = r.GetPodAffinity() @@ -46,24 +46,19 @@ func MutatePod(r Mutate, obj *corev1.PodTemplateSpec) error { containers := r.GetContainers() if len(containers) > 0 { - /* MutateContainer(r, container) - containerList = append(containerList, *container) - obj.Spec.Containers = containerList - */ for k, c := range containers { if len(obj.Spec.Containers) == 0 { container.MutateContainer(c, containerSpec) containerList = append(containerList, *containerSpec) obj.Spec.Containers = containerList } else { + // TODO FIX mutate container by name ? container.MutateContainer(c, &obj.Spec.Containers[k]) } } - } /* else { - // for k, c := range containers { - // MutateContainer(c, &obj.Spec.Containers[k]) - // } - // } */ + } + + // TODO add init containers if r.GetPodSecurityContext() != nil { diff --git a/objects/pod/object.go b/objects/pod/object.go index 60b2dfbbd82298f4223599d80083f8d7b0a0b056..880842ff9388b951fe6c1ad79f3b5f3ee566e540 100644 --- a/objects/pod/object.go +++ b/objects/pod/object.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -28,18 +28,73 @@ type Pod struct { // Parameters parameters.Parameters `json:"parameters,omitempty"` } +// PodSpec is the specification of the desired behavior of the Pod. +// It is a stripped down version of https://godoc.org/k8s.io/api/core/v1#PodSpec +// with only user definied specs +// +// Here we consider that a pod has a main container that is embedded in the PodSpec definition +// +// Extra and init containers can also be definied +// +// This is similar to the container / sidecar container pattern +// // +kubebuilder:object:generate=true type PodSpec struct { - *meta.ObjectMeta `json:"meta,omitempty"` - Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` - SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty" protobuf:"bytes,14,opt,name=securityContext"` - Affinity *corev1.Affinity `json:"affinity,omitempty"` - RestartPolicy corev1.RestartPolicy `json:"restartPolicy,omitempty"` - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - NodeSelector map[string]string `json:"nodeSelector,omitempty"` + *meta.ObjectMeta `json:"meta,omitempty"` + Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // SecurityContext holds pod-level security attributes and common container settings. + // Optional: Defaults to empty. See type description for default values of each field. + // +optional + SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty" protobuf:"bytes,14,opt,name=securityContext"` + // If specified, the pod's scheduling constraints + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // Restart policy for all containers within the pod. + // One of Always, OnFailure, Never. + // Default to Always. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy + // +optional + RestartPolicy corev1.RestartPolicy `json:"restartPolicy,omitempty"` + // If specified, the pod's tolerations. + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` + // NodeSelector is a selector which must be true for the pod to fit on a node. + // Selector which must match a node's labels for the pod to be scheduled on that node. + // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + // +optional + NodeSelector map[string]string `json:"nodeSelector,omitempty"` container.Container `json:",inline"` - ExtraContainers []container.Container `json:"extraContainers,omitempty"` - InitContainers []container.Container `json:"initContainers,omitempty"` + // List of containers belonging to the pod. + // Containers cannot currently be added or removed. + // There must be at least one container in a Pod. + // Cannot be updated. + // +patchMergeKey=name + // +patchStrategy=merge + ExtraContainers []container.Container `json:"extraContainers,omitempty"` + // List of initialization containers belonging to the pod. + // Init containers are executed in order prior to containers being started. If any + // init container fails, the pod is considered to have failed and is handled according + // to its restartPolicy. The name for an init container or normal container must be + // unique among all containers. + // Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. + // The resourceRequirements of an init container are taken into account during scheduling + // by finding the highest request/limit for each resource type, and then using the max of + // of that value or the sum of the normal containers. Limits are applied to init containers + // in a similar fashion. + // Init containers cannot currently be added or removed. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + // +patchMergeKey=name + // +patchStrategy=merge + InitContainers []container.Container `json:"initContainers,omitempty"` + // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. + // If specified, these secrets will be passed to individual puller implementations for them to use. For example, + // in the case of docker, only DockerConfig type secrets are honored. + // More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` } func (r *PodSpec) GetPodAffinity() *corev1.Affinity { return r.Affinity } @@ -56,8 +111,8 @@ func (o *PodSpec) Mutate(obj interfaces.Object) error { } func (spec *PodSpec) GetContainers() []container.Mutate { - if len(spec.Container.TemplateSpec.Name) == 0 { - spec.Container.TemplateSpec.Name = spec.ObjectMeta.GetComponent() + if len(spec.Container.ContainerSpec.Name) == 0 { + spec.Container.ContainerSpec.Name = spec.ObjectMeta.GetComponent() } containers := []container.Mutate{} diff --git a/objects/pod/pod_suite_test.go b/objects/pod/pod_suite_test.go deleted file mode 100644 index 56d109160e8388de7bd91d3236febbcd53171523..0000000000000000000000000000000000000000 --- a/objects/pod/pod_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package pod_test - -import ( - "testing" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" -) - -func TestPod(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Pod Suite") -} diff --git a/objects/pod/pod_test.go b/objects/pod/pod_test.go deleted file mode 100644 index fe65bf0568cb0236bb6128a4f425f9242a5d81b4..0000000000000000000000000000000000000000 --- a/objects/pod/pod_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package pod_test - -import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "k8s.libre.sh/meta" - container "k8s.libre.sh/objects/container" - . "k8s.libre.sh/objects/pod" - parameters "k8s.libre.sh/settings" - - corev1 "k8s.io/api/core/v1" -) - -var _ = Describe("Pod", func() { - Describe("Mutate Pod", func() { - Context("With a single container", func() { - It("should generate pod with single container", func() { - - pod := Pod{ - PodSpec: &PodSpec{ - ObjectMeta: &meta.ObjectMeta{ - Name: "test", - Namespace: "test", - // Labels: - }, - // Resources: corev1.ResourceRequirements{}, - // SecurityContext: &corev1.PodSecurityContext{}, - // Affinity: &corev1.Affinity{}, - // RestartPolicy: "restart", - // Tolerations: []corev1.Toleration{}, - // NodeSelector: map[string]string{}, - Container: container.Container{ - TemplateSpec: &container.TemplateSpec{ - Name: "mycontainer", - }, - Settings: parameters.Settings{ - // TODO FIX PARAMETERS HAS TO BE INITIALIZE OR NIL POINTER RECEIVER ERROR - // ENVFROM & ENV returns empty array it should return nil - Parameters: new(parameters.Parameters), - }, - }, - // ExtraContainers: []container.Container{}, - // InitContainers: []container.Container{}, - }, - } - - // initialObject := &corev1.Pod{ - // Spec: corev1.PodSpec{ - // Containers: []corev1.Container{ - // corev1.Container{ - // Name: "mycontainer", - // }, - // }, - // }, - // } - - initialObject := &corev1.PodTemplateSpec{} - - expectedObj := corev1.PodSpec{ - Containers: []corev1.Container{ - corev1.Container{ - Name: "mycontainer", - }, - }, - } - - err := MutatePod(pod, initialObject) - - Expect(initialObject.Spec).To(Equal(expectedObj)) - Expect(err).NotTo(HaveOccurred()) - }) - }) - }) -}) diff --git a/objects/pod/zz_generated.deepcopy.go b/objects/pod/zz_generated.deepcopy.go index 1b303950c0de878d15170fb41423a264ea10cb1c..a33772b397062f9197da3bf0689cb841501e390c 100644 --- a/objects/pod/zz_generated.deepcopy.go +++ b/objects/pod/zz_generated.deepcopy.go @@ -93,6 +93,11 @@ func (in *PodSpec) DeepCopyInto(out *PodSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]v1.LocalObjectReference, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSpec. diff --git a/objects/secret/mutate.go b/objects/secret/mutate.go index 92803b729e9430d825f3a1652c925446d5354f16..f9fb46d99afb2ffad84a420fda69a48c1599d20f 100644 --- a/objects/secret/mutate.go +++ b/objects/secret/mutate.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -16,6 +16,8 @@ limitations under the License. package secret import ( + "strings" + corev1 "k8s.io/api/core/v1" meta "k8s.libre.sh/meta" ) @@ -28,20 +30,28 @@ func MutateSecret(r Mutate, obj *corev1.Secret, m meta.Meta) error { data := r.GetData() + genParams := strings.Split(obj.ObjectMeta.Annotations["settings.k8s.libre.sh/generate"], ",") + + for _, p := range genParams { + delete(data, p) + } + if len(obj.Data) == 0 { obj.Data = make(map[string][]byte, len(data)) } if len(data) > 0 { for k, v := range data { - // TODO IMPROVE SECRET GENERATION CYCLE - if len(obj.Data[k]) == 0 { - obj.Data[k] = []byte(v) + /* // TODO TOFIX IMPROVE SECRET GENERATION CYCLE, only generated secrets should not be updated unless asked for + if len(obj.Data[k]) == 0 { + obj.Data[k] = []byte(v) - } + } */ + obj.Data[k] = []byte(v) } } + // TOD TO FIX meta.MutateMeta(m, obj) return nil diff --git a/objects/secret/object.go b/objects/secret/object.go index 71e85e33afdca93c14c38bf422a8e4352eb17951..e1bb609926f95d1e0c7265e9459cb17457a96626 100644 --- a/objects/secret/object.go +++ b/objects/secret/object.go @@ -1,10 +1,10 @@ /* -Licensed under the Apache License, Version 2.0 (the "License"); +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.gnu.org/licenses/agpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, @@ -16,9 +16,9 @@ limitations under the License. package secret import ( + settings "k8s.libre.sh/application/settings/parameters" interfaces "k8s.libre.sh/interfaces" meta "k8s.libre.sh/meta" - settings "k8s.libre.sh/settings" corev1 "k8s.io/api/core/v1" ) diff --git a/objects/secret/zz_generated.deepcopy.go b/objects/secret/zz_generated.deepcopy.go index 6a435624ad5921b89f0c9af952b8414eaea6eaba..7b34f57c48c650ef311a432e3c55a7c3bc2b9917 100644 --- a/objects/secret/zz_generated.deepcopy.go +++ b/objects/secret/zz_generated.deepcopy.go @@ -20,8 +20,8 @@ limitations under the License. package secret import ( + "k8s.libre.sh/application/settings/parameters" "k8s.libre.sh/meta" - "k8s.libre.sh/settings" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -34,11 +34,11 @@ func (in *Secret) DeepCopyInto(out *Secret) { } if in.Parameters != nil { in, out := &in.Parameters, &out.Parameters - *out = make(settings.Parameters, len(*in)) + *out = make(parameters.Parameters, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(settings.Parameter) + *out = new(parameters.Parameter) **out = **in } } diff --git a/objects/service/mutate.go b/objects/service/mutate.go index 9b1778bbd69443fe0f74a2d0de7ee8755310a6b5..29f6ee6cde9a110847418cf643fabbbca570f5b7 100644 --- a/objects/service/mutate.go +++ b/objects/service/mutate.go @@ -1,8 +1,23 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package service import ( - meta "k8s.libre.sh/meta" corev1 "k8s.io/api/core/v1" + meta "k8s.libre.sh/meta" ) type Mutate interface { diff --git a/objects/service/object.go b/objects/service/object.go index 7718a5b455f81a97b9690f4dba3e6fd54faecaeb..dbb22eb5acb4b51981f6c19bc608b83a1ba4dd2c 100644 --- a/objects/service/object.go +++ b/objects/service/object.go @@ -1,9 +1,23 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package service import ( interfaces "k8s.libre.sh/interfaces" meta "k8s.libre.sh/meta" - settings "k8s.libre.sh/settings" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" @@ -23,8 +37,30 @@ type Service struct { // +kubebuilder:object:generate=true type ServiceSpec struct { - Ports []Port `json:"ports,omitempty"` - Type corev1.ServiceType `json:"type,omitempty"` + // The list of ports that are exposed by this service. + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + // +patchMergeKey=port + // +patchStrategy=merge + // +listType=map + // +listMapKey=port + // +listMapKey=protocol + Ports []Port `json:"ports,omitempty"` + // type determines how the Service is exposed. Defaults to ClusterIP. Valid + // options are ExternalName, ClusterIP, NodePort, and LoadBalancer. + // "ExternalName" maps to the specified externalName. + // "ClusterIP" allocates a cluster-internal IP address for load-balancing to + // endpoints. Endpoints are determined by the selector or if that is not + // specified, by manual construction of an Endpoints object. If clusterIP is + // "None", no virtual IP is allocated and the endpoints are published as a + // set of endpoints rather than a stable IP. + // "NodePort" builds on ClusterIP and allocates a port on every node which + // routes to the clusterIP. + // "LoadBalancer" builds on NodePort and creates an + // external load-balancer (if supported in the current cloud) which routes + // to the clusterIP. + // More info: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + // +optional + Type corev1.ServiceType `json:"type,omitempty"` } type Port struct { @@ -34,14 +70,6 @@ type Port struct { // Ingress Ingress `json:"ingress,omitempty"` } -// type Ingress struct { -// Path string `json:"ingress,omitempty"` -// Host Host `json:"host,omitempty"` -// TLS bool `json:"tls,omitempty"` -//} - -func (o *Service) SetSettings(parameters settings.Parameters) {} - func (r *ServiceSpec) GetServiceType() corev1.ServiceType { return r.Type } func (r *ServiceSpec) GetServicePorts() []corev1.ServicePort { @@ -73,7 +101,6 @@ func (p *Port) GetServicePort() corev1.ServicePort { func (o *Service) Mutate(obj interfaces.Object) error { MutateService(o, obj.(*corev1.Service), o.ObjectMeta) meta.MutateMeta(o, obj) - // mutate.MutateMetaService(o, obj) return nil } diff --git a/settings/interface.go b/settings/interface.go deleted file mode 100644 index 3d872efef57ca17de1fbdab00313b967ac29636c..0000000000000000000000000000000000000000 --- a/settings/interface.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -type Interface interface { - // GetConfigParameters() *Parameters - // SetConfigParameters(*Parameters) - GetConfigRefs() []string - SetConfigRefs([]string) - - GetParameters() *Parameters - SetParameters(*Parameters) - - // GetSecretParameters() *Parameters - // SetSecretParameters(*Parameters) - GetSecretRefs() []string - SetSecretRefs([]string) -} - -func MergeSettings(dependencies, settings Interface) Interface { - - if settings == nil { - settings = dependencies - } else { - settings.SetConfigRefs(append(settings.GetConfigRefs(), dependencies.GetConfigRefs()...)) - settings.SetSecretRefs(append(settings.GetSecretRefs(), dependencies.GetSecretRefs()...)) - - params := *settings.GetParameters() - - if params == nil { - params = *dependencies.GetParameters() - } else { - for _, p := range *dependencies.GetParameters() { - params = append(params, p) - } - } - settings.SetParameters(¶ms) - } - - return settings -} - -/* type Env interface { - GetName() string // GetKey() - SetName(string) // GetKey() - GetValue() string - SetValue(string) - GetLocalObjectRef() string - SetLocalObjectRef(string) - GetFromKey() string // GetKey() if GetName() ?? - SetFromKey(string) // GetKey() if GetName() ?? - GetType() ParameterType - // GetMountType() MountType -} */ diff --git a/settings/parameter.go b/settings/parameter.go deleted file mode 100644 index f1969015f69bcfc3d25472fefa31c5bc7c8f74ec..0000000000000000000000000000000000000000 --- a/settings/parameter.go +++ /dev/null @@ -1,86 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -const ( - GenerateRand Generate = "rand" - GenerateRand12 Generate = "rand12" - GenerateRand24 Generate = "rand24" - GenerateTemplate Generate = "template" -) - -const ( - MountLiteral MountType = "literal" - MountFrom MountType = "from" - MountFile MountType = "file" - -// MountEnvVar MountType = "envVar" -// MountEnvVarFrom MountType = "envVarFrom" -) - -const ( - ConfigParameter ParameterType = "configmap" - SecretParameter ParameterType = "secret" - ObjectFieldParameter ParameterType = "field" -) - -type MountType string -type Generate string -type ParameterType string - -// +kubebuilder:object:generate=true -type Parameters []*Parameter - -// +kubebuilder:object:generate=true -type Parameter struct { - // Key that will be mounted as environment variable - Key string `json:"key,omitempty"` - // Value of the paramater, should not contain secret values - Value string `json:"value,omitempty"` - // ValueFrom specifies where to get the value from for the parameter - ValueFrom `json:",inline"` - // MountFrom specifies where the parameter will be mounted as file - MountPath MountPath `json:"mountFrom,omitempty"` - // Generate is specified if a secret or configmap data needs to be randomly generated - Generate Generate `json:"generate,omitempty"` - // Type specifies if its a ConfigMap or Secret - Type ParameterType `json:"type,omitempty"` - MountType MountType `json:"mountType,omitempty"` -} - -type ValueFrom struct { - // Key to select from in ConfigMap or Secret - FromKey string `json:"fromKey,omitempty"` - // Ref is a reference to a local object, set ParameterType to define the object - Ref string `json:"ref,omitempty"` -} - -type MountPath struct { - Path string `json:"path,omitempty"` - SubPath string `json:"subPath,omitempty"` -} - -// +kubebuilder:object:generate=true -type SecretParam struct { - // Key that will be mounted as environment variable - Key string `json:"key,omitempty"` - // ValueFrom specifies where to get the value from for the parameter - ValueFrom `json:",inline"` - // Source of the Secret or ConfigMap - Destination string `json:"destination,omitempty"` - // Source of the Secret or ConfigMap - Generate bool `json:"generate,omitempty"` -} diff --git a/settings/parameters_helpers.go b/settings/parameters_helpers.go deleted file mode 100644 index c5c6dfe768876e66c16f1e065466ad938623380c..0000000000000000000000000000000000000000 --- a/settings/parameters_helpers.go +++ /dev/null @@ -1,203 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -import ( - "bytes" - "reflect" - "text/template" - - "github.com/presslabs/controller-util/rand" - corev1 "k8s.io/api/core/v1" -) - -func (p *Parameters) InitValues() { - p.InitRandValues() - p.InitTemplateValues(p.KeyPairValues()) -} - -func (p *Parameters) InitRandValues() { - for _, param := range *p { - - if len(param.Key) > 0 && len(param.Value) == 0 && param.Generate != GenerateTemplate && param.Type != ObjectFieldParameter { - var size int - switch param.Generate { - case GenerateRand24: - size = 24 - random, err := rand.AlphaNumericString(size) - if err != nil { - } - param.Value = random - - case GenerateRand12: - size = 12 - random, err := rand.AlphaNumericString(size) - if err != nil { - } - param.Value = random - } - } - } -} - -func (p *Parameters) InitTemplateValues(values map[string]string) { - - for _, param := range *p { - if param.Generate == GenerateTemplate { - tmpl, err := template.New(param.Key).Parse(param.Value) - - if err != nil { - // return nil, err - } - - var tpl bytes.Buffer - err = tmpl.Execute(&tpl, values) - - if err != nil { - // return nil, err - } - - param.Value = tpl.String() - } - } -} - -func (p *Parameters) SortByMountType() map[MountType]Parameters { - data := make(map[MountType]Parameters) - - for _, param := range *p { - data[param.MountType] = append(data[param.MountType], param) - } - - return data -} - -func (p *Parameters) KeyPairValues() map[string]string { - data := make(map[string]string) - - sorted := p.SortByMountType() - - for _, param := range sorted[MountLiteral] { - - if len(param.Value) > 0 && len(param.Key) > 0 { - data[param.Key] = param.Value - } - - } - - for _, param := range sorted[MountFrom] { - - if len(param.Value) > 0 && len(param.Key) > 0 { - data[param.Key] = param.Value - } - } - - return data -} - -func (p *Parameters) GetData() map[string]string { - data := make(map[string]string) - - for _, param := range *p { - if param.MountType == MountFrom && param.Type != ObjectFieldParameter && len(param.Value) > 0 { - data[param.Key] = param.Value - } - } - - return data -} - -func (p *Parameters) GetSecretData() map[string]string { - data := make(map[string]string) - - for _, param := range *p { - if param.MountType == MountFrom && param.Type == SecretParameter { - data[param.Key] = param.Value - } - } - - return data -} - -func (p *Parameters) GetConfigData() map[string]string { - data := make(map[string]string) - - for _, param := range *p { - if param.MountType == MountFrom && - param.Type == ConfigParameter && - len(param.Value) > 0 { - data[param.Key] = param.Value - } - } - - return data -} - -func (p *Parameters) GetEnv() []corev1.EnvVar { - envVars := []corev1.EnvVar{} - envVar := corev1.EnvVar{} - - var err error - - for _, param := range *p { - envVar, err = param.GetEnvVar() - - if err != nil { - } - - if len(envVar.Name) > 0 { - envVars = append(envVars, envVar) - } - } - - // TODO IMPROVE - if len(envVars) > 0 { - return envVars - } - return nil -} - -func Marshal(i interface{}) (Parameters, error) { - parameters := Parameters{} - - t := reflect.TypeOf(i) - - ifv := reflect.ValueOf(i) - - for ii := 0; ii < t.NumField(); ii++ { - f := t.Field(ii) - - fv := ifv.Field(ii) - - parameter, ok := fv.Interface().(Parameter) - if !ok { - // return nil, ok - } - - env, ok := f.Tag.Lookup("env") - if !ok { - // return nil, ok - } - - if len(parameter.Key) == 0 { - parameter.Key = env - } - - parameters = append(parameters, ¶meter) - } - - return parameters, nil -} diff --git a/settings/settings.go b/settings/settings.go deleted file mode 100644 index e4eda5350ba714015673fadb0f17220bc2974f4e..0000000000000000000000000000000000000000 --- a/settings/settings.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package settings - -import ( - corev1 "k8s.io/api/core/v1" -) - -type Settings struct { - *EnvFrom `json:",inline"` - *Parameters `json:"parameters,omitempty"` -} - -// +kubebuilder:object:generate=true -type EnvFrom struct { - SecretRefs []string `json:"secretRefs,omitempty"` - ConfigRefs []string `json:"configRefs,omitempty"` -} - -func (s *Settings) SetParameters(parameters *Parameters) { - s.Parameters = parameters -} - -func (s *Settings) GetParameters() *Parameters { - if s.Parameters == nil { - s.Parameters = new(Parameters) - } - return s.Parameters -} - -func (s *Settings) GetSecretRefs() []string { - if s.EnvFrom != nil { - return s.EnvFrom.SecretRefs - } - - return nil -} - -func (s *Settings) SetSecretRefs(refs []string) { - if s.EnvFrom == nil { - s.EnvFrom = new(EnvFrom) - } - s.SecretRefs = refs -} - -func (s *Settings) GetConfigRefs() []string { - if s.EnvFrom != nil { - return s.EnvFrom.ConfigRefs - } - - return nil -} - -func (s *Settings) SetConfigRefs(refs []string) { - if s.EnvFrom == nil { - s.EnvFrom = new(EnvFrom) - } - s.ConfigRefs = refs -} - -/* -type SecretParameters struct { - Refs []string `json:"configRefs,omitempty"` - *Parameters `json:"parameters,omitempty"` -} - -func (s *Settings) GetEnvFrom() []corev1.EnvFromSource { - envFrom := []corev1.EnvFromSource{} - if len(s.Secrets.GetEnvFrom()) > 0 { - envFrom = append(envFrom, s.Secrets.GetEnvFrom()...) - } - if len(s.Parameters.GetEnvFrom()) > 0 { - envFrom = append(envFrom, s.Parameters.GetEnvFrom()...) - } - return envFrom -} - -func (e *SecretParameters) GetEnvFrom() []corev1.EnvFromSource { - envFroms := []corev1.EnvFromSource{} - envFrom := corev1.EnvFromSource{} - - if e != nil { - // if len(e.Refs) > 0 { - for _, ref := range e.Refs { - envFrom = corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: ref, - }, - }, - } - envFroms = append(envFroms, envFrom) - } - // } - } - - if len(envFroms) > 0 { - return envFroms - } - - return nil -} - -type ConfigParameters struct { - Refs []string `json:"configRefs,omitempty"` - *Parameters `json:"parameters,omitempty"` -} - -func (e *ConfigParameters) GetEnvFrom() []corev1.EnvFromSource { - envFroms := []corev1.EnvFromSource{} - envFrom := corev1.EnvFromSource{} - - if e != nil { - // if len(e.Refs) > 0 { - for _, ref := range e.Refs { - envFrom = corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: ref, - }, - }, - } - envFroms = append(envFroms, envFrom) - } - // } - } - - if len(envFroms) > 0 { - return envFroms - } - - return nil -} -*/ -func (e *EnvFrom) GetEnvFrom() []corev1.EnvFromSource { - envFroms := []corev1.EnvFromSource{} - envFrom := corev1.EnvFromSource{} - - if e != nil { - if len(e.ConfigRefs) > 0 { - for _, configRef := range e.ConfigRefs { - envFrom = corev1.EnvFromSource{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: configRef, - }, - }, - } - envFroms = append(envFroms, envFrom) - } - } - - if len(e.SecretRefs) > 0 { - for _, secretRef := range e.SecretRefs { - envFrom = corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: secretRef, - }, - }, - } - envFroms = append(envFroms, envFrom) - } - } - } - - if len(envFroms) > 0 { - return envFroms - } - - return nil -} - -// We need to manually change this autogenerated function as it is broken with Paramete drs type, its trying to do new([]*Parameter) instead of new(Parameters) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Settings) DeepCopyInto(out *Settings) { - *out = *in - if in.EnvFrom != nil { - in, out := &in.EnvFrom, &out.EnvFrom - *out = new(EnvFrom) - (*in).DeepCopyInto(*out) - } - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - *out = new(Parameters) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Settings. -func (in *Settings) DeepCopy() *Settings { - if in == nil { - return nil - } - out := new(Settings) - in.DeepCopyInto(out) - return out -} diff --git a/utils/utils.go b/utils/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..c7c0468a8942f68029c45e4acc37f720fedfc454 --- /dev/null +++ b/utils/utils.go @@ -0,0 +1,29 @@ +/* + +Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.gnu.org/licenses/agpl-3.0.html + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +// Uniquer returns a unique list of strings +func Unique(stringSlice []string) []string { + keys := make(map[string]bool) + list := []string{} + for _, entry := range stringSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +}