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
20 type Config struct {
21
22
23
24 clusterUUID string
25
26 Provider cluster.Provider
27
28
29
30 providerConfigMapRef string
31 providerConfigMapKey string
32
33
34 SvcAct string
35
36 Namespace string
37
38 memoryCacheLimit int
39
40 UpCfg UnpackedPalletCfg
41 ShipCfg ShipmentCfg
42
43 Cache cache.Cache
44 }
45
46
47 type ShipmentCfg struct {
48
49 Concurrent int
50 }
51
52
53 type UnpackedPalletCfg struct {
54
55 Concurrent int
56
57 DepRequeueInterval time.Duration
58 }
59
60
61
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
79 func (c *Config) afterParse(ctx context.Context, k client.Client) error {
80
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
131 func (c *Config) bindFlags(fs *flag.FlagSet) {
132
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
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
151 fs.IntVar(&c.memoryCacheLimit, "memory-cache-limit", 200,
152 "entries limit for the in-memory artifact cache")
153
154
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
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