1
2
3
4 package main
5
6 import (
7 "context"
8 "flag"
9 "fmt"
10 "os"
11 "strings"
12 "time"
13
14 "github.com/spf13/cobra"
15 "k8s.io/cli-runtime/pkg/genericclioptions"
16 "k8s.io/client-go/rest"
17 "k8s.io/component-base/cli"
18 "k8s.io/klog/v2"
19 "k8s.io/kubectl/pkg/cmd/util"
20 "sigs.k8s.io/cli-utils/cmd/apply"
21 "sigs.k8s.io/cli-utils/cmd/destroy"
22 "sigs.k8s.io/cli-utils/cmd/diff"
23 "sigs.k8s.io/cli-utils/cmd/initcmd"
24 "sigs.k8s.io/cli-utils/cmd/preview"
25 "sigs.k8s.io/cli-utils/cmd/status"
26 "sigs.k8s.io/cli-utils/pkg/flowcontrol"
27 "sigs.k8s.io/cli-utils/pkg/inventory"
28 "sigs.k8s.io/cli-utils/pkg/manifestreader"
29
30
31
32 _ "k8s.io/client-go/plugin/pkg/client/auth"
33 )
34
35 func main() {
36 cmd := &cobra.Command{
37 Use: "kapply",
38 Short: "Perform cluster operations using declarative configuration",
39 Long: "Perform cluster operations using declarative configuration",
40
41
42 SilenceErrors: true,
43 SilenceUsage: true,
44 }
45
46
47 flags := cmd.PersistentFlags()
48 kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
49 kubeConfigFlags.AddFlags(flags)
50 matchVersionKubeConfigFlags := util.NewMatchVersionFlags(kubeConfigFlags)
51 matchVersionKubeConfigFlags.AddFlags(flags)
52 flags.AddGoFlagSet(flag.CommandLine)
53 f := util.NewFactory(matchVersionKubeConfigFlags)
54
55
56 preRunE := newConfigFilerPreRunE(f, kubeConfigFlags)
57
58 ioStreams := genericclioptions.IOStreams{
59 In: os.Stdin,
60 Out: os.Stdout,
61 ErrOut: os.Stderr,
62 }
63
64 loader := manifestreader.NewManifestLoader(f)
65 invFactory := inventory.ClusterClientFactory{StatusPolicy: inventory.StatusPolicyNone}
66
67 names := []string{"init", "apply", "destroy", "diff", "preview", "status"}
68 subCmds := []*cobra.Command{
69 initcmd.NewCmdInit(f, ioStreams),
70 apply.Command(f, invFactory, loader, ioStreams),
71 destroy.Command(f, invFactory, loader, ioStreams),
72 diff.NewCommand(f, ioStreams),
73 preview.Command(f, invFactory, loader, ioStreams),
74 status.Command(context.TODO(), f, invFactory, status.NewInventoryLoader(loader)),
75 }
76 for _, subCmd := range subCmds {
77 subCmd.PreRunE = preRunE
78 updateHelp(names, subCmd)
79 cmd.AddCommand(subCmd)
80 }
81
82 code := cli.Run(cmd)
83 os.Exit(code)
84 }
85
86
87 func updateHelp(names []string, c *cobra.Command) {
88 for i := range names {
89 name := names[i]
90 c.Short = strings.ReplaceAll(c.Short, "kubectl "+name, "kapply "+name)
91 c.Long = strings.ReplaceAll(c.Long, "kubectl "+name, "kapply "+name)
92 c.Example = strings.ReplaceAll(c.Example, "kubectl "+name, "kapply "+name)
93 }
94 }
95
96
97
98
99 func newConfigFilerPreRunE(f util.Factory, configFlags *genericclioptions.ConfigFlags) func(*cobra.Command, []string) error {
100 return func(_ *cobra.Command, args []string) error {
101 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
102 defer cancel()
103
104 restConfig, err := f.ToRESTConfig()
105 if err != nil {
106 return err
107 }
108 enabled, err := flowcontrol.IsEnabled(ctx, restConfig)
109 if err != nil {
110 return fmt.Errorf("checking server-side throttling enablement: %w", err)
111 }
112 if enabled {
113
114 klog.V(3).Infof("Client-side throttling disabled")
115
116 configFlags.WrapConfigFn = func(cfg *rest.Config) *rest.Config {
117 cfg.QPS = -1
118 cfg.Burst = -1
119 return cfg
120 }
121 }
122 return nil
123 }
124 }
125
View as plain text