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  }