package render import ( "context" "fmt" "github.com/google/go-containerregistry/pkg/name" "sigs.k8s.io/controller-runtime/pkg/client" whv1 "edge-infra.dev/pkg/f8n/warehouse/k8s/apis/v1alpha2" "edge-infra.dev/pkg/f8n/warehouse/lift" "edge-infra.dev/pkg/f8n/warehouse/lift/cmd/internal" "edge-infra.dev/pkg/f8n/warehouse/lift/unpack" "edge-infra.dev/pkg/f8n/warehouse/oci/remote" "edge-infra.dev/pkg/lib/cli/sink" ) func newRenderShipmentCmd(cfg lift.Config) *sink.Command { var ( applier = internal.NewApplier() unpacker = internal.NewUnpacker(cfg.Parameters) ) cmd := &sink.Command{ Use: "shipment [flags] ", Short: "render package contents from Shipment object on a K8s cluster", Extensions: []sink.Extension{applier, unpacker}, Exec: func(ctx context.Context, r sink.Run) error { switch len(r.Args()) { case 0: return fmt.Errorf("a shipment is required") case 1: default: return fmt.Errorf("only one shipment can be rendered at a time") } var s whv1.Shipment if err := applier.Klient.Get(ctx, client.ObjectKey{Name: r.Args()[0]}, &s); err != nil { return err } renderingParams, err := resolveParameters(ctx, applier.Klient, s) if err != nil { return err } unpackOpts := []unpack.Option{ unpack.RenderWith(renderingParams), unpack.ForLayerKeys(s.Layers()...), // TODO: get this info from controller deployment / config unpack.ForProvider(unpacker.Provider), } repo := s.Spec.Repository for _, s := range s.Status.LastApplied { packageName := s.Name digest := s.Digest ref, err := name.ParseReference(fmt.Sprintf("%s/%s@%s", repo, packageName, digest)) if err != nil { return err } artifact, err := remote.Get(ref) if err != nil { return err } if err := unpack.Walk(artifact, pkgRender, unpackOpts...); err != nil { return err } } return nil }, } return cmd } // TODO: make part of Shipment types code? func resolveParameters(ctx context.Context, client client.Client, s whv1.Shipment) (map[string]string, error) { result := make(map[string]string, 0) for _, p := range s.Spec.Rendering { vars, err := p.Resolve(ctx, client) if err != nil { return nil, err } for k, v := range vars { result[k] = v } } return result, nil }