...

Source file src/edge-infra.dev/pkg/f8n/warehouse/k8s/controllers/lumperctl/config.go

Documentation: edge-infra.dev/pkg/f8n/warehouse/k8s/controllers/lumperctl

     1  package lumperctl
     2  
     3  import (
     4  	"context"
     5  	"flag"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/peterbourgon/ff/v3"
    10  	corev1 "k8s.io/api/core/v1"
    11  	"sigs.k8s.io/controller-runtime/pkg/client"
    12  
    13  	"edge-infra.dev/pkg/f8n/warehouse/cluster"
    14  	"edge-infra.dev/pkg/f8n/warehouse/k8s/controllers/lumperctl/internal"
    15  	"edge-infra.dev/pkg/f8n/warehouse/oci/cache"
    16  	eclient "edge-infra.dev/pkg/k8s/runtime/client"
    17  )
    18  
    19  // config is the controllers application config
    20  type Config struct {
    21  	// cluster and provider options
    22  	//
    23  	// clusterUUID is the uuid of the cluster the controller is running on
    24  	clusterUUID string
    25  	// provider is the cluster provider the controller is deployed on
    26  	Provider cluster.Provider
    27  	// the provider information can also be provided via a reference to a ConfigMap
    28  	// and an optional key to pull the value from. if the key isn't provided, the
    29  	// default "cluster_provider" is used
    30  	providerConfigMapRef string
    31  	providerConfigMapKey string
    32  
    33  	// svcAct is the name of the service account used to deploy the controller
    34  	SvcAct string
    35  	// namespace is the namespace this controller is deployed to
    36  	Namespace string
    37  
    38  	memoryCacheLimit int
    39  
    40  	UpCfg   UnpackedPalletCfg
    41  	ShipCfg ShipmentCfg
    42  
    43  	Cache cache.Cache // computed by afterParse if not set directly
    44  }
    45  
    46  // shipmentCfg is config that only applie to the Shipment reconciler
    47  type ShipmentCfg struct {
    48  	// concurrent reconciles
    49  	Concurrent int
    50  }
    51  
    52  // unpackedPalletCfg is config that only applies to the UnpackedPallet reconciler
    53  type UnpackedPalletCfg struct {
    54  	// concurrent reconciles
    55  	Concurrent int
    56  	// how frequently we re-reconcile when unpackedpallet dep isn't ready
    57  	DepRequeueInterval time.Duration
    58  }
    59  
    60  // newConfig creates the controller config, reading initial values via flags and
    61  // environment variables via ff
    62  func newConfig(args []string) (*Config, error) {
    63  	fs := flag.NewFlagSet("lumperctl", flag.ExitOnError)
    64  
    65  	cfg := &Config{}
    66  	cfg.bindFlags(fs)
    67  
    68  	if err := ff.Parse(fs, args, ff.WithEnvVarNoPrefix()); err != nil {
    69  		return nil, fmt.Errorf("failed to parse configuration: %w", err)
    70  	}
    71  	if err := cfg.validate(); err != nil {
    72  		return nil, fmt.Errorf("invalid configuration: %w", err)
    73  	}
    74  
    75  	return cfg, nil
    76  }
    77  
    78  // afterParse computes additional values after flags have been parsed
    79  func (c *Config) afterParse(ctx context.Context, k client.Client) error {
    80  	// read provider from configmap if not provided
    81  	if c.Provider == "" {
    82  		key, err := eclient.ObjectKeyFromRefStr(c.providerConfigMapRef)
    83  		if err != nil {
    84  			return err
    85  		}
    86  
    87  		cmap := &corev1.ConfigMap{}
    88  		if err := k.Get(ctx, key, cmap); err != nil {
    89  			return err
    90  		}
    91  
    92  		switch {
    93  		case len(cmap.Data) == 0:
    94  			return fmt.Errorf("%s is invalid: no data keys", c.providerConfigMapRef)
    95  		case len(cmap.Data) == 1:
    96  			for _, v := range cmap.Data {
    97  				c.Provider = cluster.Provider(v)
    98  			}
    99  		case cmap.Data[c.providerConfigMapKey] != "":
   100  			c.Provider = cluster.Provider(cmap.Data[c.providerConfigMapKey])
   101  		default:
   102  			return fmt.Errorf("%s is invalid: key %s not found",
   103  				c.providerConfigMapRef, c.providerConfigMapKey)
   104  		}
   105  	}
   106  
   107  	if c.Cache == nil {
   108  		var err error
   109  
   110  		c.Cache, err = cache.New(
   111  			cache.WithRecorder(internal.CacheRecorder{}),
   112  			cache.WithMemoryCacheSize(c.memoryCacheLimit),
   113  		)
   114  		if err != nil {
   115  			return err
   116  		}
   117  	}
   118  
   119  	return nil
   120  }
   121  
   122  func (c *Config) validate() error {
   123  	if c.Provider == "" && c.providerConfigMapRef == "" {
   124  		return fmt.Errorf("--cluster-provider or --cluster-provider-configmap-ref are required")
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  // bindFlags binds the controller's configuration to command line flags.
   131  func (c *Config) bindFlags(fs *flag.FlagSet) {
   132  	// cluster flags
   133  	fs.Var(&c.Provider, "cluster-provider",
   134  		"K8s cluster provider. Takes precedence over other provider flags.")
   135  	fs.StringVar(&c.providerConfigMapRef, "cluster-provider-configmap-ref", "",
   136  		"Reference to ConfigMap containing cluster provider information, in the "+
   137  			"namespace/name format")
   138  	fs.StringVar(&c.providerConfigMapKey, "cluster-provider-configmap-key", "cluster_provider",
   139  		"Key to read cluster provider information from. If only a single key exists, "+
   140  			"it will be used. If more than one key exists, the value of this flag will "+
   141  			"be used.")
   142  	fs.StringVar(&c.clusterUUID, "cluster-uuid", "", "uuid of the cluster that the controller is running on")
   143  
   144  	// k8s deployment flags
   145  	fs.StringVar(&c.Namespace, "namespace", "",
   146  		"K8s Namespace the controller is deployed to")
   147  	fs.StringVar(&c.SvcAct, "service-account", "",
   148  		"K8s ServiceAccount scheduling the controller")
   149  
   150  	// caching flags
   151  	fs.IntVar(&c.memoryCacheLimit, "memory-cache-limit", 200,
   152  		"entries limit for the in-memory artifact cache")
   153  
   154  	// UnpackedPalletReconciler flags
   155  	fs.IntVar(&c.UpCfg.Concurrent, "unpacked-pallet-concurrency", 24,
   156  		"how many UnpackedPallets can reconcile at the same time")
   157  	fs.DurationVar(&c.UpCfg.DepRequeueInterval, "dependency-requeue-interval", 30*time.Second,
   158  		"how frequently not-Ready dependencies are checked")
   159  
   160  	// ShipmentReconciler flags
   161  	fs.IntVar(&c.ShipCfg.Concurrent, "shipment-concurrency", 6,
   162  		"how many Shipments can reconcile at the same time")
   163  }
   164  

View as plain text