github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/config/reader.go (about)

     1  package config
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/sirupsen/logrus"
     9  	coreV1 "k8s.io/api/core/v1"
    10  	"sigs.k8s.io/controller-runtime/pkg/client"
    11  )
    12  
    13  const (
    14  	namespace                 = "kcp-system"
    15  	runtimeVersionLabelPrefix = "runtime-version-"
    16  	kebConfigLabel            = "keb-config"
    17  	defaultConfigKey          = "default"
    18  )
    19  
    20  type ConfigMapReader struct {
    21  	ctx                context.Context
    22  	k8sClient          client.Client
    23  	logger             logrus.FieldLogger
    24  	defaultKymaVersion string
    25  }
    26  
    27  func NewConfigMapReader(ctx context.Context, k8sClient client.Client, logger logrus.FieldLogger, defaultKymaVersion string) *ConfigMapReader {
    28  	return &ConfigMapReader{
    29  		ctx:                ctx,
    30  		k8sClient:          k8sClient,
    31  		logger:             logger,
    32  		defaultKymaVersion: defaultKymaVersion,
    33  	}
    34  }
    35  
    36  func (r *ConfigMapReader) Read(kymaVersion, planName string) (string, error) {
    37  	r.logger.Infof("getting configuration for Kyma version %v and %v plan", kymaVersion, planName)
    38  	var cfgMapList *coreV1.ConfigMapList
    39  	cfgMapList, err := r.getConfigMapList(kymaVersion)
    40  	if err != nil {
    41  		return "", err
    42  	}
    43  	if len(cfgMapList.Items) == 0 && isCustomVersion(kymaVersion) {
    44  		r.logger.Infof("configuration for Kyma version %v does not exist. Getting configuration for the latest official release version: %v", kymaVersion, r.defaultKymaVersion)
    45  		cfgMapList, err = r.getConfigMapList(r.defaultKymaVersion)
    46  		if err != nil {
    47  			return "", err
    48  		}
    49  	}
    50  
    51  	if err = r.verifyConfigMapExistence(cfgMapList); err != nil {
    52  		return "", fmt.Errorf("while verifying configuration configmap existence: %w", err)
    53  	}
    54  
    55  	cfgMap := cfgMapList.Items[0]
    56  	cfgString, err := r.getConfigStringForPlanOrDefaults(&cfgMap, planName)
    57  	if err != nil {
    58  		return "", fmt.Errorf("while getting configuration string: %w", err)
    59  	}
    60  
    61  	return cfgString, nil
    62  }
    63  
    64  func (r *ConfigMapReader) getConfigMapList(kymaVersion string) (*coreV1.ConfigMapList, error) {
    65  	cfgMapList := &coreV1.ConfigMapList{}
    66  	listOptions := configMapListOptions(kymaVersion)
    67  	if err := r.k8sClient.List(r.ctx, cfgMapList, listOptions...); err != nil {
    68  		return nil, fmt.Errorf("while fetching configmap with configuration for Kyma version %v: %w",
    69  			kymaVersion, err)
    70  	}
    71  	return cfgMapList, nil
    72  }
    73  
    74  func configMapListOptions(version string) []client.ListOption {
    75  	versionLabel := runtimeVersionLabelPrefix + strings.ToLower(version)
    76  
    77  	labels := map[string]string{
    78  		versionLabel:   "true",
    79  		kebConfigLabel: "true",
    80  	}
    81  
    82  	return []client.ListOption{
    83  		client.InNamespace(namespace),
    84  		client.MatchingLabels(labels),
    85  	}
    86  }
    87  
    88  func (r *ConfigMapReader) verifyConfigMapExistence(cfgMapList *coreV1.ConfigMapList) error {
    89  	switch n := len(cfgMapList.Items); n {
    90  	case 1:
    91  		return nil
    92  	case 0:
    93  		return fmt.Errorf("configmap with configuration does not exist")
    94  	default:
    95  		return fmt.Errorf("allowed number of configuration configmaps: 1, found: %d", n)
    96  	}
    97  }
    98  
    99  func (r *ConfigMapReader) getConfigStringForPlanOrDefaults(cfgMap *coreV1.ConfigMap, planName string) (string, error) {
   100  	cfgString, exists := cfgMap.Data[planName]
   101  	if !exists {
   102  		r.logger.Infof("configuration for plan %v does not exist. Using default values", planName)
   103  		cfgString, exists = cfgMap.Data[defaultConfigKey]
   104  		if !exists {
   105  			return "", fmt.Errorf("default configuration does not exist")
   106  		}
   107  	}
   108  	return cfgString, nil
   109  }
   110  
   111  func isCustomVersion(version string) bool {
   112  	return strings.HasPrefix(version, "PR-") || strings.HasPrefix(version, "main-")
   113  }