Skip to content
Commits on Source (15)
/*
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 (
......
/*
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,
......@@ -33,7 +33,7 @@ import (
type Network struct {
IngressMeta *meta.ObjectMeta `json:"ingressMeta,omitempty"`
ServiceMeta *meta.ObjectMeta `json:"serviceMeta,omitempty"`
*Backend `json:"backend,inline"`
*Backend `json:",inline"`
}
type Service struct {
......
/*
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,
......@@ -20,8 +20,12 @@ import (
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"`
......@@ -66,8 +70,8 @@ func (w *Workload) GetObjects() map[int]objects.Object {
return objects
}
func (w *Workload) SetDependencies(s *Settings) { w.ConfigSpec = s.ConfigSpec }
func (w *Workload) GetDependencies() settings.Config { return w.ConfigSpec }
func (w *Workload) SetDependencies(s *settings.Component) { w.ConfigSpec = s.ConfigSpec }
func (w *Workload) GetDependencies() settings.Config { return w.ConfigSpec }
func (w *Workload) SetDefaults() {
......@@ -75,13 +79,22 @@ func (w *Workload) SetDefaults() {
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 = new(meta.ObjectMeta)
w.ObjectMeta = &meta.ObjectMeta{}
}
if len(w.ObjectMeta.Labels) == 0 {
......@@ -89,14 +102,16 @@ func (w *Workload) Init() {
}
// TODO FIXME
w.ObjectMeta.SetComponent("app")
if len(w.ObjectMeta.GetComponent()) == 0 {
w.ObjectMeta.SetComponent(DefaultComponent)
}
if w.Deployment.ObjectMeta == nil {
w.Deployment.ObjectMeta = new(meta.ObjectMeta)
w.Deployment.ObjectMeta = &meta.ObjectMeta{}
}
if w.ConfigSpec == nil {
w.ConfigSpec = new(settings.ConfigSpec)
w.ConfigSpec = &settings.ConfigSpec{}
}
if w.Backend == nil {
......@@ -104,10 +119,10 @@ func (w *Workload) Init() {
}
if w.ServiceMeta == nil {
w.ServiceMeta = new(meta.ObjectMeta)
w.ServiceMeta = &meta.ObjectMeta{}
}
if w.IngressMeta == nil {
w.IngressMeta = new(meta.ObjectMeta)
w.IngressMeta = &meta.ObjectMeta{}
}
}
......@@ -75,40 +75,6 @@ func (in *Network) DeepCopy() *Network {
return out
}
// 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.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 Settings.
func (in *Settings) DeepCopy() *Settings {
if in == nil {
return nil
}
out := new(Settings)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Workload) DeepCopyInto(out *Workload) {
*out = *in
......
/*
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 (
......@@ -5,7 +20,6 @@ import (
"github.com/presslabs/controller-util/syncer"
"k8s.libre.sh/application/components"
settings "k8s.libre.sh/application/settings"
"k8s.libre.sh/interfaces"
"k8s.libre.sh/meta"
......@@ -16,7 +30,8 @@ type Instance interface {
meta.Instance
GetComponents() map[int]Component
GetOwner() interfaces.Object
GetSettings() Settings
GetSettings() settings.Settings
// GetSettings() map[int]settings.Settings
SetDefaults()
}
......@@ -54,7 +69,7 @@ func NewSyncers(app Instance, r interfaces.Reconcile, owner interfaces.Object) (
// 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().(*components.Settings)
sett := app.GetSettings().(*settings.Component)
err = sett.Init(r.GetClient())
......@@ -69,7 +84,7 @@ func NewSyncers(app Instance, r interfaces.Reconcile, owner interfaces.Object) (
s := objects.NewObjectSyncer(obj, owner, r)
if err := syncer.Sync(context.TODO(), s, r.GetRecorder()); err != nil {
// return nil, err
return syncers, err
}
}
......
/*
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,13 +13,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package components
package settings
import (
"strings"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"k8s.libre.sh/application/settings"
"k8s.libre.sh/application/settings/parameters"
"k8s.libre.sh/meta"
"k8s.libre.sh/objects"
......@@ -27,70 +28,123 @@ import (
"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 Settings 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"`
*settings.ConfigSpec `json:",inline"`
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 *Settings) GetConfig() settings.Config { return s.ConfigSpec }
func (s *Component) GetConfig() Config { return s.ConfigSpec }
func (s *Settings) GetMeta() meta.Instance { return s.CommonMeta }
func (s *Component) GetMeta() meta.Instance { return s.CommonMeta }
func (s *Settings) GetSecretMeta() meta.Instance { return s.SecretMeta }
func (s *Component) GetSecretMeta() meta.Instance { return s.SecretMeta }
func (s *Settings) GetConfigMapMeta() meta.Instance { return s.ConfigMeta }
func (s *Component) GetConfigMapMeta() meta.Instance { return s.ConfigMeta }
func (s *Settings) SetDefaults() {
func (s *Component) SetDefaults() {
// TODO TO FIX DUPLICATE WITH INIT
meta.SetObjectMeta(s.CommonMeta, s.SecretMeta)
meta.SetObjectMeta(s.CommonMeta, s.ConfigMeta)
}
func (s *Settings) GetObjects() map[int]objects.Object {
func (s *Component) GetObjects() map[int]objects.Object {
cm := &configmap.ConfigMap{
ObjectMeta: s.GetConfigMapMeta().(*meta.ObjectMeta),
ObjectMeta: s.ConfigMeta,
}
secret := &secret.Secret{
ObjectMeta: s.GetSecretMeta().(*meta.ObjectMeta),
ObjectMeta: s.SecretMeta,
}
objs := make(map[int]objects.Object, 2)
// meta.SetObjectMeta(s.CommonMeta, cm.ObjectMeta)
// meta.SetObjectMeta(s.CommonMeta, secret.ObjectMeta)
genConfigParams := []string{}
genSecretParams := []string{}
// TODO REPLACE BY GET SECRET PARAMETERS & GET CONFIG PARAMETERS
// params := s.GetConfig()
for _, p := range *s.ConfigSpec.GetParameters() {
// TODO check not mountLiteral ??
for _, p := range *s.ConfigSpec.Parameters {
// TODO TO FIX
if p.MountType == parameters.MountEnvFile &&
p.Type == parameters.SecretParameter &&
// 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 {
// secret.Parameters = secretParameters
if objs[0] == nil {
objs[0] = secret
......@@ -102,11 +156,11 @@ func (s *Settings) GetObjects() map[int]objects.Object {
return objs
}
func (s *Settings) Init(c client.Client) error {
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)
// TODO ADD SECRET REFS HERE ??
err := InitParametersValueFrom(s, c)
if err != nil {
......@@ -117,17 +171,22 @@ func (s *Settings) Init(c client.Client) error {
err = s.InitTemplateValues(parameters.KeyPairValues(s.Parameters))
if err != nil {
return err
}
return nil
}
// InitParametersValueFrom intialise the paremeters with values provided in external resources (secrets and configmaps) in the same namespace
// InitParametersValueFrom intialise the parameters with values provided in external resources in the same namespace
// All parameters values are filled from those resources
func InitParametersValueFrom(s *Settings, c client.Client) error {
// Only Secrets and Configmaps are supported
func InitParametersValueFrom(s *Component, c client.Client) error {
params := parameters.Parameters{}
paramsByKey := parameters.ParametersByKey(s.Parameters)
paramsBySecretSource, paramsByConfigMapSource := settings.OrderByResourceRef(s.ConfigSpec)
paramsBySecretSource, paramsByConfigMapSource := OrderByResourceRef(s.ConfigSpec)
cm := &corev1.ConfigMap{}
sec := &corev1.Secret{}
......@@ -137,6 +196,7 @@ func InitParametersValueFrom(s *Settings, c client.Client) error {
for k, v := range paramsBySecretSource {
sec.SetName(k)
err := parameters.GetAndMergeParameters(v, paramsByKey, c, sec)
if err != nil {
return err
......@@ -151,26 +211,93 @@ func InitParametersValueFrom(s *Settings, c client.Client) error {
}
}
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 = &params
return nil
}
addSecretSrc := false
addConfigSrc := false
for _, v := range paramsByKey {
if v.MountType == parameters.MountEnvFile {
if v.Type == parameters.ConfigParameter {
v.Ref = s.GetConfigMapMeta().GetName()
}
if v.Type == parameters.SecretParameter {
v.Ref = s.GetSecretMeta().GetName()
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)
}
// if defaultMountType == EnvFile {
// }
// TODO FIX THIS we need to check if we want to mount as EnvFile and reset old resources references
s.SecretRefs = []string{}
s.ConfigRefs = []string{}
s.Parameters = &params
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
}
/*
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,22 +13,47 @@ 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"
"k8s.libre.sh/utils"
)
// ConfigSpec defines a list of parameters and some sources from which those parameters can be fetched
// It can be used in the conta
// +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 {
// SecretRefs is a list of secrets in the name namespace
SecretRefs []string `json:"secretRefs,omitempty"`
// ConfigRefs is a list of configmaps in the name namespace
ConfigRefs []string `json:"configRefs,omitempty"`
// 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"`
}
......@@ -39,94 +64,120 @@ func (c *ConfigSpec) SetParameters(parameters *parameters.Parameters) { c.Parame
// GetParameters return the parameters
func (c *ConfigSpec) GetParameters() *parameters.Parameters {
if c.Parameters == nil {
c.Parameters = new(parameters.Parameters)
c.Parameters = &parameters.Parameters{}
}
return c.Parameters
}
func (c *ConfigSpec) GetConfigRefs() []string { return c.ConfigRefs }
func (c *ConfigSpec) SetConfigRefs(refs []string) { c.ConfigRefs = refs }
func (c *ConfigSpec) GetSecretRefs() []string { return c.SecretRefs }
func (c *ConfigSpec) GetSources() []Source { return c.Sources }
func (c *ConfigSpec) SetSecretRefs(refs []string) { c.SecretRefs = refs }
func (c *ConfigSpec) SetSources(sources []Source) { c.Sources = sources }
// GetEnvFrom returns a list of sources to populate environment variables in the container.
// GetEnvFrom returns a list of EnvFromSource to populate environment variables in the container.
func (c *ConfigSpec) GetEnvFrom() []corev1.EnvFromSource {
envFroms := []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 len(p.Ref) > 0 {
if p.MountType == parameters.MountEnvFile {
if p.Type == parameters.ConfigParameter {
c.ConfigRefs = append(c.ConfigRefs, p.Ref)
} else if p.Type != parameters.ObjectFieldParameter {
c.SecretRefs = append(c.SecretRefs, p.Ref)
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)
}
}
}
c.SecretRefs = utils.Unique(c.SecretRefs)
c.ConfigRefs = utils.Unique(c.ConfigRefs)
if len(c.ConfigRefs) > 0 {
for _, configRef := range c.ConfigRefs {
envFrom = corev1.EnvFromSource{
ConfigMapRef: &corev1.ConfigMapEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: configRef,
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,
},
},
},
}
envFroms = append(envFroms, envFrom)
}
}
if len(c.SecretRefs) > 0 {
for _, secretRef := range c.SecretRefs {
envFrom = corev1.EnvFromSource{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: secretRef,
}
// 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)
}
envFroms = append(envFroms, envFrom)
}
}
if len(envFroms) > 0 {
return envFroms
}
return nil
// 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
}
// 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 *ConfigSpec) DeepCopyInto(out *ConfigSpec) {
*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))
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)
(*in).DeepCopyInto(*out)
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 Settings.
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigSpec.
func (in *ConfigSpec) DeepCopy() *ConfigSpec {
if in == nil {
return nil
......
/*
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,18 @@ limitations under the License.
package settings
import "k8s.libre.sh/application/settings/parameters"
import (
"k8s.libre.sh/application/settings/parameters"
)
type Config interface {
GetConfigRefs() []string
SetConfigRefs([]string)
GetParameters() *parameters.Parameters
SetParameters(*parameters.Parameters)
GetSecretRefs() []string
SetSecretRefs([]string)
InitRandValues()
InitTemplateValues(map[string]string) error
// InitExternaValues(c client.Client) error
SetSources(sources []Source)
GetSources() (sources []Source)
}
func MergeSettings(src, dest Config) Config {
......@@ -33,8 +34,7 @@ func MergeSettings(src, dest Config) Config {
if dest == nil {
dest = src
} else {
dest.SetConfigRefs(append(dest.GetConfigRefs(), src.GetConfigRefs()...))
dest.SetSecretRefs(append(dest.GetSecretRefs(), src.GetSecretRefs()...))
dest.SetSources(append(dest.GetSources(), src.GetSources()...))
params := *dest.GetParameters()
......
/*
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,
......@@ -31,11 +31,12 @@ 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
// 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 the crds or external resources specified in the envFrom
// 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"
)
......@@ -58,9 +59,11 @@ type Parameters []*Parameter
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
// It can be a template, ParameterType should be template
// 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.
......@@ -81,9 +84,9 @@ type ValueFrom struct {
FromKey string `json:"fromKey,omitempty"`
// Name of the referent.
Ref string `json:"ref,omitempty"`
// Type of the source othe parameter
// Type of the parameter's source
// Defaults to the parameter type if not specified
Type ParameterType `json:"type,omitempty"`
RefType ParameterType `json:"refType,omitempty"`
}
type MountPath struct {
......
/*
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,7 +23,6 @@ import (
// 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 {
......
/*
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,13 +17,11 @@ package parameters
import (
"bytes"
"context"
"sort"
"text/template"
"github.com/presslabs/controller-util/rand"
corev1 "k8s.io/api/core/v1"
"k8s.libre.sh/interfaces"
"sigs.k8s.io/controller-runtime/pkg/client"
)
func (p *Parameters) InitValues() {
......@@ -89,7 +87,8 @@ func (p *Parameters) GetData() map[string]string {
data := make(map[string]string)
for _, param := range *p {
if param.MountType == MountEnvFile &&
// TODO TO FIX
if (param.MountType == MountEnvFile || param.MountType == "") &&
param.Type != ObjectFieldParameter &&
len(param.Value) > 0 {
data[param.Key] = param.Value
......@@ -108,7 +107,7 @@ func (p *Parameters) GetEnvVar() []corev1.EnvVar {
for _, param := range *p {
envVar, err = param.GetEnvVar()
// TODO TOFIX
if err != nil {
}
......@@ -118,61 +117,12 @@ func (p *Parameters) GetEnvVar() []corev1.EnvVar {
}
if len(envVars) > 0 {
return envVars
}
return nil
}
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
// 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
})
if obj.GetObjectKind().GroupVersionKind().Kind == "Secret" {
pType = SecretParameter
for k, v := range obj.(*corev1.Secret).Data {
data[k] = string(v)
}
}
if obj.GetObjectKind().GroupVersionKind().Kind == "ConfigMap" {
pType = ConfigParameter
for k, v := range obj.(*corev1.ConfigMap).Data {
data[k] = v
}
}
if len(params) > 0 {
for _, pp := range params {
paramsByKey[pp.Key].Value = string(data[pp.FromKey])
}
} else {
for kk, vv := range data {
// TODO TO FIX
if paramsByKey[kk] == nil {
paramsByKey[kk] = new(Parameter)
}
paramsByKey[kk].Value = vv
paramsByKey[kk].Key = kk
// TODO This would be checked if we want to recreate the data or just mount the whole secret
paramsByKey[kk].MountType = MountEnvFile
paramsByKey[kk].Type = pType
}
return envVars
}
return nil
}
/*
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,7 +16,14 @@ 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) {
......@@ -46,9 +53,9 @@ func Marshal(i interface{}) (Parameters, error) {
parameter.Key = env
}
if len(parameter.MountType) == 0 {
parameter.MountType = MountEnvFile
}
// if len(parameter.MountType) == 0 {
// parameter.MountType = MountEnvFile
// }
parameters = append(parameters, &parameter)
}
......@@ -56,12 +63,17 @@ func Marshal(i interface{}) (Parameters, error) {
return parameters, nil
}
// Sort parameters by keys, it takes the fromKey if it exists
// 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
}
......@@ -76,3 +88,62 @@ func KeyPairValues(p *Parameters) map[string]string {
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
}
/*
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,16 +13,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package application
package settings
import (
"k8s.libre.sh/application/components"
"k8s.libre.sh/application/settings"
"k8s.libre.sh/application/settings/parameters"
"k8s.libre.sh/meta"
"k8s.libre.sh/objects"
"k8s.libre.sh/objects/configmap"
"k8s.libre.sh/objects/secret"
"sigs.k8s.io/controller-runtime/pkg/client"
)
......@@ -31,25 +25,24 @@ type Settings interface {
GetMeta() meta.Instance
GetSecretMeta() meta.Instance
GetConfigMapMeta() meta.Instance
GetConfig() settings.Config
GetConfig() Config
SetDefaults()
Init(c client.Client) error
}
func NewSettings(s Settings) *components.Settings {
return &components.Settings{
func NewSettings(s Settings) *Component {
return &Component{
CommonMeta: s.GetMeta().(*meta.ObjectMeta),
SecretMeta: s.GetSecretMeta().(*meta.ObjectMeta),
ConfigMeta: s.GetConfigMapMeta().(*meta.ObjectMeta),
ConfigSpec: &settings.ConfigSpec{
ConfigRefs: s.GetConfig().GetConfigRefs(),
SecretRefs: s.GetConfig().GetSecretRefs(),
ConfigSpec: &ConfigSpec{
Sources: s.GetConfig().GetSources(),
Parameters: s.GetConfig().GetParameters(),
},
}
}
func GetObjects(s Settings) map[int]objects.Object {
/* func GetObjects(s Settings) map[int]objects.Object {
cm := &configmap.ConfigMap{
ObjectMeta: &meta.ObjectMeta{},
......@@ -64,12 +57,11 @@ func GetObjects(s Settings) map[int]objects.Object {
meta.SetObjectMeta(s.GetConfigMapMeta(), cm.ObjectMeta)
meta.SetObjectMeta(s.GetSecretMeta(), secret.ObjectMeta)
// TODO REPLACE BY GET SECRET PARAMETERS & GET CONFIG PARAMETERS
params := s.GetConfig()
for _, p := range *params.GetParameters() {
// TODO check not mountLiteral ??
if p.MountType == parameters.MountEnvFile &&
// TO FIX
p.Type == parameters.SecretParameter &&
len(p.Value) > 0 {
secret.Parameters = append(secret.Parameters, p)
......@@ -97,3 +89,4 @@ func GetObjects(s Settings) map[int]objects.Object {
return objs
}
*/
/*
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,17 +17,16 @@ package settings
import "k8s.libre.sh/application/settings/parameters"
func OrderByResourceRef(s *ConfigSpec) (secrets, configs map[string]parameters.Parameters) {
func OrderByResourceRef(s *ConfigSpec) (secrets, configMaps map[string]parameters.Parameters) {
secrets = make(map[string]parameters.Parameters)
configs = make(map[string]parameters.Parameters)
configMaps = make(map[string]parameters.Parameters)
// We order the parameters by secret and configmap sources
// First we get the sources provided as resources that should be mounted untouched
for _, ref := range s.SecretRefs {
secrets[ref] = parameters.Parameters{}
}
for _, ref := range s.ConfigRefs {
configs[ref] = 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
......@@ -36,8 +35,39 @@ func OrderByResourceRef(s *ConfigSpec) (secrets, configs map[string]parameters.P
secrets[p.ValueFrom.Ref] = append(secrets[p.ValueFrom.Ref], p)
}
if len(p.ValueFrom.Ref) > 0 && p.Type == parameters.ConfigParameter {
configs[p.ValueFrom.Ref] = append(configs[p.ValueFrom.Ref], p)
configMaps[p.ValueFrom.Ref] = append(configMaps[p.ValueFrom.Ref], p)
}
}
return secrets, configs
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
}
*/
// +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
}
......@@ -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
......
This diff is collapsed.
/*
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
......
/*
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,
......@@ -21,37 +21,31 @@ import (
"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)
}
/* 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)
} */
// Instance labels returns the app.kubernetes.io labels
func InstanceLabels(m Instance) map[string]string {
labels := labels.Set{
"app.kubernetes.io/name": m.GetApplication(),
......@@ -64,6 +58,7 @@ func InstanceLabels(m Instance) map[string]string {
return labels
}
// TODO use Object interface and rename Merge ?
func SetObjectMeta(src Instance, dest Instance) {
dest.SetLabels(labels.Merge(dest.GetLabels(), InstanceLabels(src)))
......
/*
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,
......@@ -20,6 +20,10 @@ import (
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)
......@@ -31,6 +35,7 @@ type Meta interface {
SetNamespace(string)
}
// MutateMeta mutates an Object meta
func MutateMeta(o Meta, obj interfaces.Object) error {
obj.SetLabels(o.GetLabels())
......@@ -38,14 +43,5 @@ func MutateMeta(o Meta, obj interfaces.Object) error {
obj.SetAnnotations(labels.Merge(obj.GetAnnotations(), o.GetAnnotations()))
}
// if len(obj.GetName()) == 0 {
// obj.SetName(o.GetName())
// }
// if len(obj.GetNamespace()) == 0 {
// obj.SetNamespace(o.GetNamespace())
// }
return nil
}