package internal import ( "context" "fmt" "strings" "edge-infra.dev/pkg/f8n/warehouse/capability" "edge-infra.dev/pkg/f8n/warehouse/cluster" "edge-infra.dev/pkg/f8n/warehouse/lift" "edge-infra.dev/pkg/f8n/warehouse/lift/unpack" "edge-infra.dev/pkg/f8n/warehouse/oci/layer" "edge-infra.dev/pkg/lib/cli/rags" "edge-infra.dev/pkg/lib/cli/sink" ) type Unpacker struct { Provider cluster.Provider infraNamespace string infra bool runtime bool capabilities capability.Capabilities RenderingParams map[string]string renderingFlags map[string]*string registeredParams []lift.Parameter } func NewUnpacker(p []lift.Parameter) *Unpacker { return &Unpacker{registeredParams: p} } func (u *Unpacker) Options() []unpack.Option { o := []unpack.Option{ unpack.WithInfraNamespace(u.infraNamespace), unpack.ForLayerKeys(u.LayerKeys()...), u.RenderOption(), } if u.Provider != "" { o = append(o, unpack.ForProvider(u.Provider)) } return o } // LayerKeys returns the keys for the layers that will be unpacked func (u *Unpacker) LayerKeys() []string { keys := []string{} if u.runtime { keys = append(keys, layer.Runtime.String()) } if u.infra { keys = append(keys, layer.Infra.String()) } for _, c := range u.capabilities { keys = append(keys, string(c)) } return keys } func (u *Unpacker) RenderOption() unpack.Option { return unpack.RenderWith( u.RenderingParams, ) } func (u *Unpacker) Info(r sink.Run) { values := []any{ "k8s-provider", u.Provider, "layers", u.LayerKeys(), } if u.infraNamespace != "" { values = append(values, "infra namespace", u.infraNamespace) } if len(u.RenderingParams) > 0 { values = append(values, "parameters", u.RenderingParams) } r.Log.Info("unpacking", values...) } func (u *Unpacker) RegisterFlags(fs *rags.RagSet) { u.renderingFlags = make(map[string]*string) for _, r := range u.registeredParams { // Don't bind flags for computed rendering parameters because the user // cannot set them. if r.Key == lift.ClusterProviderRenderingParameter || r.Key == lift.ClusterHashRenderingParameter || r.Key == lift.PalletNameRenderingParameter { continue } u.renderingFlags[r.Key] = fs.String( strings.ReplaceAll(r.Key, "_", "-"), "", r.Description, rags.WithCategory("rendering"), ) } fs.Var(&u.Provider, "cluster-provider", "K8s cluster provider variant to unpack. This is required if the pallet "+ "contains multiple variants.") fs.Var(&u.capabilities, "runtime-capabilities", "comma separated list of runtime capabilities to unpack.") fs.BoolVar(&u.infra, "infra", false, "unpack infrastructure resources.") fs.StringVar(&u.infraNamespace, "infra-namespace", "", "target namespace for all applied infrastructure resources, including "+ "dependencies. the namespace is created if it does not already exist.") fs.BoolVar(&u.runtime, "runtime", true, "unpack the base runtime layer. --run-capabilities is needed to "+ "unpack additional runtime layers.") } func (u *Unpacker) BeforeRun(ctx context.Context, r sink.Run) (context.Context, sink.Run, error) { u.RenderingParams = make(map[string]string) for key, val := range u.renderingFlags { u.RenderingParams[key] = *val } if !u.runtime && u.infraNamespace == "" { return ctx, r, fmt.Errorf("if runtime resources aren't being applied, " + "--infra-namespace must be provided") } return ctx, r, nil }