Skip to content
utils.go 4.73 KiB
Newer Older
Timothee Gosselin's avatar
Timothee Gosselin committed
/*

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"
	"strings"
Timothee Gosselin's avatar
Timothee Gosselin committed

	corev1 "k8s.io/api/core/v1"
Timothee Gosselin's avatar
Timothee Gosselin committed
	"k8s.io/apimachinery/pkg/runtime"
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
	"k8s.libre.sh/controller-utils/interfaces"
Timothee Gosselin's avatar
Timothee Gosselin committed
	"sigs.k8s.io/controller-runtime/pkg/client"
Timothee Gosselin's avatar
Timothee Gosselin committed
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Timothee Gosselin's avatar
Timothee Gosselin committed
)

Timothee Gosselin's avatar
Timothee Gosselin committed
func Marshal(i interface{}) (*Parameters, error) {
	parameters := &Parameters{}
Timothee Gosselin's avatar
Timothee Gosselin committed

	t := reflect.TypeOf(i)

	ifv := reflect.ValueOf(i)

	for ii := 0; ii < t.NumField(); ii++ {
		f := t.Field(ii)

		fv := ifv.Field(ii)

Timothee Gosselin's avatar
Timothee Gosselin committed
		parameter, ok := fv.Interface().(*Parameter)
Timothee Gosselin's avatar
Timothee Gosselin committed
		if !ok {
Timothee Gosselin's avatar
Timothee Gosselin committed
			return parameters, errors.New("not parameters type")
Timothee Gosselin's avatar
Timothee Gosselin committed
		}

		env, ok := f.Tag.Lookup("env")
		if !ok {
Timothee Gosselin's avatar
Timothee Gosselin committed
			return parameters, errors.New("missing env tag")
Timothee Gosselin's avatar
Timothee Gosselin committed
		}

Timothee Gosselin's avatar
Timothee Gosselin committed
		if parameter == nil {
			parameter = &Parameter{}
		}
Timothee Gosselin's avatar
Timothee Gosselin committed
		if len(parameter.Key) == 0 {
			parameter.Key = env
		}

Timothee Gosselin's avatar
Timothee Gosselin committed
		*parameters = append(*parameters, parameter)
Timothee Gosselin's avatar
Timothee Gosselin committed
	}

	return parameters, nil
}

Timothee Gosselin's avatar
Timothee Gosselin committed
// ByKey returns the parameters sorted by keys
func ByKey(p *Parameters) map[string]*Parameter {
Timothee Gosselin's avatar
Timothee Gosselin committed
	paramsByKey := map[string]*Parameter{}

	for _, param := range *p {
		paramsByKey[param.Key] = param
	}
	return paramsByKey
}

Timothee Gosselin's avatar
Timothee Gosselin committed
// KeyPairValues returns the parameters as key:value pairs
Timothee Gosselin's avatar
Timothee Gosselin committed
func KeyPairValues(p *Parameters) map[string]string {
	data := make(map[string]string)

	for _, param := range *p {
		data[param.Key] = param.Value
	}

	return data
}

Timothee Gosselin's avatar
Timothee Gosselin committed
// OrderByResourceRef returns a list of parameters ordered reference type and reference name
func OrderByResourceRef(ps *Parameters) map[ParameterType]map[string]*Parameters {
Timothee Gosselin's avatar
Timothee Gosselin committed

	sorted := make(map[ParameterType]map[string]*Parameters)
Timothee Gosselin's avatar
Timothee Gosselin committed

	for _, p := range *ps {
		if p != nil {
			// TOFIX only refType ? by default secret ?
			if len(p.ValueFrom.Ref) > 0 {
				// TO DO TO FIX
				if len(p.RefType) == 0 {
					p.RefType = SecretParameter
Timothee Gosselin's avatar
Timothee Gosselin committed
				}
				if len(sorted[p.RefType]) == 0 {
					sorted[p.RefType] = make(map[string]*Parameters)
Timothee Gosselin's avatar
Timothee Gosselin committed
				}
				if sorted[p.RefType][p.ValueFrom.Ref] == nil {
					sorted[p.RefType][p.ValueFrom.Ref] = &Parameters{}
				}
				*sorted[p.RefType][p.ValueFrom.Ref] = append(*sorted[p.RefType][p.ValueFrom.Ref], p)
Timothee Gosselin's avatar
Timothee Gosselin committed
			}
		}
Timothee Gosselin's avatar
Timothee Gosselin committed
	}

Timothee Gosselin's avatar
Timothee Gosselin committed
// GetDataFromResource return the data as key:value pairs from external resources.
// If resources are owned by the owner object, only generated resources are returned.
// Only secrets and configmaps are supported.
Timothee Gosselin's avatar
Timothee Gosselin committed
func GetDataFromResource(c client.Client, obj, owner interfaces.Object, scheme *runtime.Scheme) (data map[string]string, err error) {
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
	// TODO TO FIX
	if obj != nil {
		objData := make(map[string]string)
		data = make(map[string]string)
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
		objectKey, err := client.ObjectKeyFromObject(obj)
		if err != nil {
			return data, err
		}
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
		err = c.Get(context.Background(), objectKey, obj)
		if err != nil {
			return data, err
Timothee Gosselin's avatar
Timothee Gosselin committed
		}
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
		switch ro := obj.(type) {
		case *corev1.Secret:
			for k, v := range ro.Data {
				objData[k] = string(v)
			}
		case *corev1.ConfigMap:
			objData = ro.Data

		default:
			return data, errors.New("object kind should be ConfigMap or Secret")
		}
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
		// If object is owner we only want to get the generated data in order to not regenerate it,
		// other parameters are set in crds or valueFrom
		if ownerRefs := obj.GetOwnerReferences(); ownerRefs != nil {
			for _, ref := range ownerRefs {
				if ref.UID == owner.GetUID() {
					if ref.Controller != nil && *ref.Controller {
						if len(obj.GetAnnotations()["settings.k8s.libre.sh/generate"]) > 0 {
							for _, param := range strings.Split(obj.GetAnnotations()["settings.k8s.libre.sh/generate"], ",") {
								data[param] = objData[param]
							}
						}
					} else {
						data = objData
					}
					return data, nil
				}
Timothee Gosselin's avatar
Timothee Gosselin committed
		}
Timothee Gosselin's avatar
Timothee Gosselin committed

Timothee Gosselin's avatar
Timothee Gosselin committed
		data = objData
Timothee Gosselin's avatar
Timothee Gosselin committed
		controllerutil.SetOwnerReference(owner, obj, scheme)
		if err := c.Update(context.Background(), obj); err != nil {
			return data, err
		}

		/* 	if metav1.IsControlledBy(obj, owner) {
		   		if len(obj.GetAnnotations()["settings.k8s.libre.sh/generate"]) > 0 {
		   			for _, param := range strings.Split(obj.GetAnnotations()["settings.k8s.libre.sh/generate"], ",") {
		   				data[param] = objData[param]
		   			}
		   			return data, nil
		   		}
		   	} else {
		   		data = objData

		   		controllerutil.SetOwnerReference(owner, obj, scheme)

		   	} */

Timothee Gosselin's avatar
Timothee Gosselin committed
	}

	return data, nil
}