github.com/codefresh-io/kcfi@v0.0.0-20230301195427-c1578715cc46/cmd/kcfi/root.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main // import "helm.sh/helm/v3/cmd/helm" 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "os" 24 "path" 25 "strings" 26 27 "github.com/spf13/cobra" 28 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 "k8s.io/client-go/tools/clientcmd" 31 32 c "github.com/codefresh-io/kcfi/pkg/config" 33 "github.com/codefresh-io/kcfi/pkg/helm-internal/completion" 34 "helm.sh/helm/v3/pkg/action" 35 ) 36 37 var kcfiUsage = `Codefresh installer 38 actions: 39 - kcfi init [ /path/to/codefresh-config-dir ] - < pprepare configuration directory 40 - kcfi deploy [ -c <config-file> ] - install/upgrade/reconfigure codefresh 41 - kcfi images push [ -c <config-file> ] [options] [images...] - pushes images to private registry 42 - kcfi operator deploy - manage codefresh operator 43 44 - kcfi helm <helm args and parameters> executes helm v3 45 46 ` 47 var globalUsage = `The Kubernetes package manager 48 49 Common actions for Helm: 50 51 - helm search: search for charts 52 - helm pull: download a chart to your local directory to view 53 - helm install: upload the chart to Kubernetes 54 - helm list: list releases of charts 55 56 Environment variables: 57 58 +------------------+--------------------------------------------------------------------------------------------------------+ 59 | Name | Description | 60 +------------------+--------------------------------------------------------------------------------------------------------+ 61 | $XDG_CACHE_HOME | set an alternative location for storing cached files. | 62 | $XDG_CONFIG_HOME | set an alternative location for storing Helm configuration. | 63 | $XDG_DATA_HOME | set an alternative location for storing Helm data. | 64 | $HELM_DRIVER | set the backend storage driver. Values are: configmap, secret, memory, postgres | 65 | $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use. | 66 | $HELM_NO_PLUGINS | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. | 67 | $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") | 68 +------------------+--------------------------------------------------------------------------------------------------------+ 69 70 Helm stores configuration based on the XDG base directory specification, so 71 72 - cached files are stored in $XDG_CACHE_HOME/helm 73 - configuration is stored in $XDG_CONFIG_HOME/helm 74 - data is stored in $XDG_DATA_HOME/helm 75 76 By default, the default directories depend on the Operating System. The defaults are listed below: 77 78 +------------------+---------------------------+--------------------------------+-------------------------+ 79 | Operating System | Cache Path | Configuration Path | Data Path | 80 +------------------+---------------------------+--------------------------------+-------------------------+ 81 | Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm | 82 | macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm | 83 | Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm | 84 +------------------+---------------------------+--------------------------------+-------------------------+ 85 ` 86 87 func newRootCmd(actionConfig *action.Configuration, out io.Writer, args []string) *cobra.Command { 88 cmd := &cobra.Command{ 89 Use: "kcfi", 90 Short: "The Codefresh installer", 91 Long: kcfiUsage, 92 SilenceUsage: true, 93 BashCompletionFunction: completion.GetBashCustomFunction(), 94 } 95 flags := cmd.PersistentFlags() 96 97 settings.AddFlags(flags) 98 99 // Setup shell completion for the namespace flag 100 flag := flags.Lookup("namespace") 101 completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { 102 if client, err := actionConfig.KubernetesClientSet(); err == nil { 103 // Choose a long enough timeout that the user notices somethings is not working 104 // but short enough that the user is not made to wait very long 105 to := int64(3) 106 completion.CompDebugln(fmt.Sprintf("About to call kube client for namespaces with timeout of: %d", to)) 107 108 nsNames := []string{} 109 if namespaces, err := client.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{TimeoutSeconds: &to}); err == nil { 110 for _, ns := range namespaces.Items { 111 if strings.HasPrefix(ns.Name, toComplete) { 112 nsNames = append(nsNames, ns.Name) 113 } 114 } 115 return nsNames, completion.BashCompDirectiveNoFileComp 116 } 117 } 118 return nil, completion.BashCompDirectiveDefault 119 }) 120 121 // Setup shell completion for the kube-context flag 122 flag = flags.Lookup("kube-context") 123 completion.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, completion.BashCompDirective) { 124 completion.CompDebugln("About to get the different kube-contexts") 125 126 loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() 127 if len(settings.KubeConfig) > 0 { 128 loadingRules = &clientcmd.ClientConfigLoadingRules{ExplicitPath: settings.KubeConfig} 129 } 130 if config, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( 131 loadingRules, 132 &clientcmd.ConfigOverrides{}).RawConfig(); err == nil { 133 ctxs := []string{} 134 for name := range config.Contexts { 135 if strings.HasPrefix(name, toComplete) { 136 ctxs = append(ctxs, name) 137 } 138 } 139 return ctxs, completion.BashCompDirectiveNoFileComp 140 } 141 return nil, completion.BashCompDirectiveNoFileComp 142 }) 143 144 // We can safely ignore any errors that flags.Parse encounters since 145 // those errors will be caught later during the call to cmd.Execution. 146 // This call is required to gather configuration information prior to 147 // execution. 148 flags.ParseErrorsWhitelist.UnknownFlags = true 149 flags.Parse(args) 150 151 //Add Codefresh subcommands 152 c.Debug = settings.Debug 153 cmd.AddCommand( 154 newOperatorCmd(actionConfig, out), 155 cfInitCmd(out), 156 cfApplyCmd(actionConfig, out), 157 cfImagesCmd(out), 158 cfVersionCmd(out), 159 ) 160 161 helmCmd := &cobra.Command{ 162 Use: "helm", 163 Short: "The Helm", 164 Long: globalUsage, 165 SilenceUsage: true, 166 BashCompletionFunction: completion.GetBashCustomFunction(), 167 } 168 169 // Add subcommands 170 helmCmd.AddCommand( 171 // chart commands 172 newCreateCmd(out), 173 newDependencyCmd(out), 174 newPullCmd(out), 175 newShowCmd(out), 176 newLintCmd(out), 177 newPackageCmd(out), 178 newRepoCmd(out), 179 newSearchCmd(out), 180 newVerifyCmd(out), 181 182 // release commands 183 newGetCmd(actionConfig, out), 184 newHistoryCmd(actionConfig, out), 185 newInstallCmd(actionConfig, out), 186 newListCmd(actionConfig, out), 187 newReleaseTestCmd(actionConfig, out), 188 newRollbackCmd(actionConfig, out), 189 newStatusCmd(actionConfig, out), 190 newTemplateCmd(actionConfig, out), 191 newUninstallCmd(actionConfig, out), 192 newUpgradeCmd(actionConfig, out), 193 194 newCompletionCmd(out), 195 newEnvCmd(out), 196 newPluginCmd(out), 197 newVersionCmd(out), 198 199 // Hidden documentation generator command: 'helm docs' 200 newDocsCmd(out), 201 202 // Setup the special hidden __complete command to allow for dynamic auto-completion 203 completion.NewCompleteCmd(settings, out), 204 ) 205 206 cmd.AddCommand(helmCmd) 207 208 // Find and add plugins 209 loadPlugins(helmCmd, out) 210 211 return cmd 212 } 213 214 func defaultConfigFileName() string { 215 defaultConfigFileName := "config.yaml" 216 stageDir, err := os.Getwd() 217 if err != nil { 218 panic(err) 219 } 220 return path.Join(stageDir, defaultConfigFileName) 221 } 222 223 func hideKubeFlags(cmd *cobra.Command) { 224 cmd.Flags().MarkHidden("kube-apiserver") 225 cmd.Flags().MarkHidden("kube-context") 226 cmd.Flags().MarkHidden("kube-token") 227 cmd.Flags().MarkHidden("kubeconfig") 228 cmd.Flags().MarkHidden("namespace") 229 } 230 231 func hideHelmCommonFlags(cmd *cobra.Command) { 232 cmd.Flags().MarkHidden("add-dir-header") 233 cmd.Flags().MarkHidden("skip-headers") 234 cmd.Flags().MarkHidden("skip-log-headers") 235 cmd.Flags().MarkHidden("stderrthreshold") 236 cmd.Flags().MarkHidden("vmodule") 237 238 cmd.Flags().MarkHidden("alsologtostderr") 239 cmd.Flags().MarkHidden("log-backtrace-at") 240 cmd.Flags().MarkHidden("log-dir") 241 cmd.Flags().MarkHidden("log-file") 242 cmd.Flags().MarkHidden("log-file-max-size") 243 cmd.Flags().MarkHidden("logtostderr") 244 cmd.Flags().MarkHidden("v") 245 246 cmd.Flags().MarkHidden("registry-config") 247 cmd.Flags().MarkHidden("repository-cache") 248 cmd.Flags().MarkHidden("repository-config") 249 }