github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/commands/alpha/repo/get/command.go (about) 1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package get 16 17 import ( 18 "context" 19 "strings" 20 21 "github.com/GoogleContainerTools/kpt/internal/docs/generated/repodocs" 22 "github.com/GoogleContainerTools/kpt/internal/errors" 23 "github.com/GoogleContainerTools/kpt/internal/options" 24 "github.com/GoogleContainerTools/kpt/internal/util/porch" 25 "github.com/spf13/cobra" 26 "k8s.io/cli-runtime/pkg/genericclioptions" 27 "k8s.io/cli-runtime/pkg/printers" 28 "k8s.io/client-go/rest" 29 "k8s.io/kubectl/pkg/cmd/get" 30 ) 31 32 const ( 33 command = "cmdrepoget" 34 ) 35 36 func NewCommand(ctx context.Context, rcg *genericclioptions.ConfigFlags) *cobra.Command { 37 return newRunner(ctx, rcg).Command 38 } 39 40 func newRunner(ctx context.Context, rcg *genericclioptions.ConfigFlags) *runner { 41 r := &runner{ 42 ctx: ctx, 43 getFlags: options.Get{ConfigFlags: rcg}, 44 printFlags: get.NewGetPrintFlags(), 45 } 46 c := &cobra.Command{ 47 Use: "get [REPOSITORY_NAME]", 48 Aliases: []string{"ls", "list"}, 49 Short: repodocs.GetShort, 50 Long: repodocs.GetShort + "\n" + repodocs.GetLong, 51 Example: repodocs.GetExamples, 52 PreRunE: r.preRunE, 53 RunE: r.runE, 54 Hidden: porch.HidePorchCommands, 55 } 56 r.Command = c 57 58 // Create flags 59 r.getFlags.AddFlags(c) 60 r.printFlags.AddFlags(c) 61 return r 62 } 63 64 type runner struct { 65 ctx context.Context 66 Command *cobra.Command 67 68 // Flags 69 getFlags options.Get 70 printFlags *get.PrintFlags 71 72 requestTable bool 73 } 74 75 func (r *runner) preRunE(cmd *cobra.Command, args []string) error { 76 outputOption := cmd.Flags().Lookup("output").Value.String() 77 if strings.Contains(outputOption, "custom-columns") || outputOption == "yaml" || strings.Contains(outputOption, "json") { 78 r.requestTable = false 79 } else { 80 r.requestTable = true 81 } 82 return nil 83 } 84 85 func (r *runner) runE(cmd *cobra.Command, args []string) error { 86 const op errors.Op = command + ".runE" 87 88 // For some reason our use of k8s libraries result in error when decoding 89 // RepositoryList when we use strongly typed data. Therefore for now we 90 // use unstructured communication. 91 // The error is: `no kind "RepositoryList" is registered for the internal 92 // version of group "config.porch.kpt.dev" in scheme`. Of course there _is_ 93 // no such kind since CRDs seem to have only versioned resources. 94 b, err := r.getFlags.ResourceBuilder() 95 if err != nil { 96 return err 97 } 98 99 // TODO: Support table mode over proto 100 // TODO: Print namespace in multi-namespace mode 101 b = b.Unstructured() 102 103 if len(args) > 0 { 104 b.ResourceNames("repository", args...) 105 } else { 106 b = b.SelectAllParam(true). 107 ResourceTypes("repository") 108 } 109 110 b = b.ContinueOnError().Latest().Flatten() 111 112 if r.requestTable { 113 b = b.TransformRequests(func(req *rest.Request) { 114 req.SetHeader("Accept", strings.Join([]string{ 115 "application/json;as=Table;g=meta.k8s.io;v=v1", 116 "application/json", 117 }, ",")) 118 }) 119 } 120 res := b.Do() 121 if err := res.Err(); err != nil { 122 return errors.E(op, err) 123 } 124 125 infos, err := res.Infos() 126 if err != nil { 127 return errors.E(op, err) 128 } 129 130 printer, err := r.printFlags.ToPrinter() 131 if err != nil { 132 return errors.E(op, err) 133 } 134 135 if r.requestTable { 136 printer = &get.TablePrinter{ 137 Delegate: printer, 138 } 139 } 140 141 w := printers.GetNewTabWriter(cmd.OutOrStdout()) 142 143 for _, i := range infos { 144 if err := printer.PrintObj(i.Object, w); err != nil { 145 return errors.E(op, err) 146 } 147 } 148 149 if err := w.Flush(); err != nil { 150 return errors.E(op, err) 151 } 152 153 return nil 154 }