github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/commands/alpha/rpkg/propose/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 propose 16 17 import ( 18 "context" 19 "fmt" 20 "strings" 21 22 "github.com/GoogleContainerTools/kpt/internal/docs/generated/rpkgdocs" 23 "github.com/GoogleContainerTools/kpt/internal/errors" 24 "github.com/GoogleContainerTools/kpt/internal/util/porch" 25 "github.com/GoogleContainerTools/kpt/porch/api/porch/v1alpha1" 26 "github.com/spf13/cobra" 27 "k8s.io/cli-runtime/pkg/genericclioptions" 28 "sigs.k8s.io/controller-runtime/pkg/client" 29 ) 30 31 const ( 32 command = "cmdrpkgpropose" 33 ) 34 35 func NewCommand(ctx context.Context, rcg *genericclioptions.ConfigFlags) *cobra.Command { 36 return newRunner(ctx, rcg).Command 37 } 38 39 func newRunner(ctx context.Context, rcg *genericclioptions.ConfigFlags) *runner { 40 r := &runner{ 41 ctx: ctx, 42 cfg: rcg, 43 client: nil, 44 } 45 46 c := &cobra.Command{ 47 Use: "propose [PACKAGE ...] [flags]", 48 Short: rpkgdocs.ProposeShort, 49 Long: rpkgdocs.ProposeShort + "\n" + rpkgdocs.ProposeLong, 50 Example: rpkgdocs.ProposeExamples, 51 PreRunE: r.preRunE, 52 RunE: r.runE, 53 Hidden: porch.HidePorchCommands, 54 } 55 r.Command = c 56 57 return r 58 } 59 60 type runner struct { 61 ctx context.Context 62 cfg *genericclioptions.ConfigFlags 63 client client.Client 64 Command *cobra.Command 65 66 // Flags 67 } 68 69 func (r *runner) preRunE(cmd *cobra.Command, args []string) error { 70 const op errors.Op = command + ".preRunE" 71 72 client, err := porch.CreateClient(r.cfg) 73 if err != nil { 74 return errors.E(op, err) 75 } 76 r.client = client 77 return nil 78 } 79 80 func (r *runner) runE(cmd *cobra.Command, args []string) error { 81 const op errors.Op = command + ".runE" 82 var messages []string 83 namespace := *r.cfg.Namespace 84 85 for _, name := range args { 86 pr := &v1alpha1.PackageRevision{} 87 if err := r.client.Get(r.ctx, client.ObjectKey{ 88 Namespace: namespace, 89 Name: name, 90 }, pr); err != nil { 91 return errors.E(op, err) 92 } 93 94 switch pr.Spec.Lifecycle { 95 case v1alpha1.PackageRevisionLifecycleDraft: 96 // ok 97 case v1alpha1.PackageRevisionLifecycleProposed: 98 fmt.Fprintf(r.Command.OutOrStderr(), "%s is already proposed\n", name) 99 continue 100 default: 101 msg := fmt.Sprintf("cannot propose %s package", pr.Spec.Lifecycle) 102 messages = append(messages, msg) 103 fmt.Fprintln(r.Command.ErrOrStderr(), msg) 104 continue 105 } 106 107 pr.Spec.Lifecycle = v1alpha1.PackageRevisionLifecycleProposed 108 if err := r.client.Update(r.ctx, pr); err != nil { 109 messages = append(messages, err.Error()) 110 fmt.Fprintf(r.Command.ErrOrStderr(), "%s failed (%s)\n", name, err) 111 } else { 112 fmt.Fprintf(r.Command.OutOrStderr(), "%s proposed\n", name) 113 } 114 } 115 116 if len(messages) > 0 { 117 return errors.E(op, fmt.Errorf("errors:\n %s", strings.Join(messages, "\n "))) 118 } 119 120 return nil 121 }