github.com/fafucoder/cilium@v1.6.11/cilium/cmd/root.go (about)

     1  // Copyright 2017 Authors of Cilium
     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 cmd
    16  
    17  import (
    18  	"fmt"
    19  	"io"
    20  	"os"
    21  
    22  	clientPkg "github.com/cilium/cilium/pkg/client"
    23  	"github.com/cilium/cilium/pkg/components"
    24  
    25  	"github.com/sirupsen/logrus"
    26  	"github.com/spf13/cobra"
    27  	"github.com/spf13/viper"
    28  )
    29  
    30  var (
    31  	cfgFile string
    32  	client  *clientPkg.Client
    33  	log     = logrus.New()
    34  	verbose = false
    35  )
    36  
    37  // rootCmd represents the base command when called without any subcommands
    38  var rootCmd = &cobra.Command{
    39  	Use:   "cilium",
    40  	Short: "CLI",
    41  	Long:  `CLI for interacting with the local Cilium Agent`,
    42  }
    43  
    44  // Execute adds all child commands to the root command sets flags appropriately.
    45  // This is called by main.main(). It only needs to happen once to the rootCmd.
    46  func Execute() {
    47  	if err := rootCmd.Execute(); err != nil {
    48  		fmt.Println(err)
    49  		os.Exit(-1)
    50  	}
    51  }
    52  
    53  func init() {
    54  	if components.IsCiliumAgent() {
    55  		return
    56  	}
    57  
    58  	cobra.OnInitialize(initConfig)
    59  	flags := rootCmd.PersistentFlags()
    60  	flags.StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cilium.yaml)")
    61  	flags.BoolP("debug", "D", false, "Enable debug messages")
    62  	flags.StringP("host", "H", "", "URI to server-side API")
    63  	viper.BindPFlags(flags)
    64  	rootCmd.AddCommand(newCmdCompletion(os.Stdout))
    65  	rootCmd.SetOutput(os.Stderr)
    66  }
    67  
    68  // initConfig reads in config file and ENV variables if set.
    69  func initConfig() {
    70  	if cfgFile != "" { // enable ability to specify config file via flag
    71  		viper.SetConfigFile(cfgFile)
    72  	}
    73  
    74  	viper.SetEnvPrefix("cilium")
    75  	viper.SetConfigName(".cilium") // name of config file (without extension)
    76  	viper.AddConfigPath("$HOME")   // adding home directory as first search path
    77  	viper.AutomaticEnv()           // read in environment variables that match
    78  
    79  	// If a config file is found, read it in.
    80  	if err := viper.ReadInConfig(); err == nil {
    81  		fmt.Println("Using config file:", viper.ConfigFileUsed())
    82  	}
    83  
    84  	if viper.GetBool("debug") {
    85  		log.Level = logrus.DebugLevel
    86  	} else {
    87  		log.Level = logrus.InfoLevel
    88  	}
    89  
    90  	if cl, err := clientPkg.NewClient(viper.GetString("host")); err != nil {
    91  		Fatalf("Error while creating client: %s\n", err)
    92  	} else {
    93  		client = cl
    94  	}
    95  }
    96  
    97  const copyRightHeader = `
    98  # Copyright 2017 Authors of Cilium
    99  #
   100  # Licensed under the Apache License, Version 2.0 (the "License");
   101  # you may not use this file except in compliance with the License.
   102  # You may obtain a copy of the License at
   103  #
   104  #     http://www.apache.org/licenses/LICENSE-2.0
   105  #
   106  # Unless required by applicable law or agreed to in writing, software
   107  # distributed under the License is distributed on an "AS IS" BASIS,
   108  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   109  # See the License for the specific language governing permissions and
   110  # limitations under the License.
   111  `
   112  
   113  var (
   114  	completionExample = `
   115  # Installing bash completion on macOS using homebrew
   116  ## If running Bash 3.2 included with macOS
   117  	brew install bash-completion
   118  ## or, if running Bash 4.1+
   119  	brew install bash-completion@2
   120  ## afterwards you only need to run
   121  	cilium completion bash > $(brew --prefix)/etc/bash_completion.d/cilium
   122  
   123  
   124  # Installing bash completion on Linux
   125  ## Load the cilium completion code for bash into the current shell
   126  	source <(cilium completion bash)
   127  ## Write bash completion code to a file and source if from .bash_profile
   128  	cilium completion bash > ~/.cilium/completion.bash.inc
   129  	printf "
   130  	  # Cilium shell completion
   131  	  source '$HOME/.cilium/completion.bash.inc'
   132  	  " >> $HOME/.bash_profile
   133  	source $HOME/.bash_profile`
   134  )
   135  
   136  func newCmdCompletion(out io.Writer) *cobra.Command {
   137  	cmd := &cobra.Command{
   138  		Use:     "completion [bash]",
   139  		Short:   "Output shell completion code for bash",
   140  		Long:    ``,
   141  		Example: completionExample,
   142  		Run: func(cmd *cobra.Command, args []string) {
   143  			runCompletion(out, cmd, args)
   144  		},
   145  		ValidArgs: []string{"bash"},
   146  	}
   147  
   148  	return cmd
   149  }
   150  
   151  func runCompletion(out io.Writer, cmd *cobra.Command, args []string) error {
   152  	if len(args) > 1 {
   153  		return fmt.Errorf("Too many arguments. Expected only the shell type.")
   154  	}
   155  	if _, err := out.Write([]byte(copyRightHeader)); err != nil {
   156  		return err
   157  	}
   158  
   159  	return cmd.Parent().GenBashCompletion(out)
   160  }