-
Notifications
You must be signed in to change notification settings - Fork 14
/
patch.go
126 lines (101 loc) · 3.85 KB
/
patch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright 2020-Present VMware, Inc.
// SPDX-License-Identifier: Apache-2.0
package clusterbuilder
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"github.com/pivotal/kpack/pkg/apis/build/v1alpha2"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/dynamic"
"github.com/vmware-tanzu/kpack-cli/pkg/builder"
"github.com/vmware-tanzu/kpack-cli/pkg/commands"
"github.com/vmware-tanzu/kpack-cli/pkg/k8s"
)
func NewPatchCommand(clientSetProvider k8s.ClientSetProvider, newWaiter func(dynamic.Interface) commands.ResourceWaiter) *cobra.Command {
var (
flags CommandFlags
)
cmd := &cobra.Command{
Use: "patch <name>",
Short: "Patch an existing cluster builder configuration",
Long: `Patch an existing clusterbuilder configuration by providing command line arguments.
A buildpack order must be provided with either the path to an order yaml or via the --buildpack flag.
Multiple buildpacks provided via the --buildpack flag will be added to the same order group.`,
Example: `kp clusterbuilder patch my-builder --order /path/to/order.yaml --stack tiny --store my-store
kp clusterbuilder patch my-builder --order /path/to/order.yaml
kp clusterbuilder patch my-builder --buildpack my-buildpack-id --buildpack my-other-buildpack@1.0.1`,
Args: commands.ExactArgsWithUsage(1),
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
cs, err := clientSetProvider.GetClientSet("")
if err != nil {
return err
}
ch, err := commands.NewCommandHelper(cmd)
if err != nil {
return err
}
name := args[0]
ctx := cmd.Context()
cb, err := cs.KpackClient.KpackV1alpha2().ClusterBuilders().Get(ctx, name, metav1.GetOptions{})
if err != nil {
return err
}
return patch(ctx, cb, flags, ch, cs, newWaiter(cs.DynamicClient))
},
}
cmd.Flags().StringVarP(&flags.tag, "tag", "t", "", "registry location where the builder will be created")
cmd.Flags().StringVarP(&flags.stack, "stack", "s", "", "stack resource to use")
cmd.Flags().StringVar(&flags.store, "store", "", "buildpack store to use")
cmd.Flags().StringVarP(&flags.order, "order", "o", "", "path to buildpack order yaml")
cmd.Flags().StringSliceVarP(&flags.buildpacks, "buildpack", "b", []string{}, "buildpack id and optional version in the form of either '<buildpack>@<version>' or '<buildpack>'\n repeat for each buildpack in order, or supply once with comma-separated list")
commands.SetDryRunOutputFlags(cmd)
return cmd
}
func patch(ctx context.Context, cb *v1alpha2.ClusterBuilder, flags CommandFlags, ch *commands.CommandHelper, cs k8s.ClientSet, waiter commands.ResourceWaiter) error {
updatedCb := cb.DeepCopy()
if flags.tag != "" {
updatedCb.Spec.Tag = flags.tag
}
if flags.stack != "" {
updatedCb.Spec.Stack.Name = flags.stack
}
if flags.store != "" {
updatedCb.Spec.Store.Name = flags.store
}
if len(flags.buildpacks) > 0 && flags.order != "" {
return fmt.Errorf("cannot use --order and --buildpack together")
}
if flags.order != "" {
orderEntries, err := builder.ReadOrder(flags.order)
if err != nil {
return err
}
updatedCb.Spec.Order = orderEntries
}
if len(flags.buildpacks) > 0 {
updatedCb.Spec.Order = builder.CreateOrder(flags.buildpacks)
}
patch, err := k8s.CreatePatch(cb, updatedCb)
if err != nil {
return err
}
hasPatch := len(patch) > 0
if hasPatch && !ch.IsDryRun() {
updatedCb, err = cs.KpackClient.KpackV1alpha2().ClusterBuilders().Patch(ctx, updatedCb.Name, types.MergePatchType, patch, metav1.PatchOptions{})
if err != nil {
return err
}
if err := waiter.Wait(ctx, updatedCb); err != nil {
return err
}
}
updatedCbArray := []runtime.Object{updatedCb}
if err = ch.PrintObjs(updatedCbArray); err != nil {
return err
}
return ch.PrintChangeResult(hasPatch, "ClusterBuilder %q patched", updatedCb.Name)
}