istio

Форк
0
/
root.go 
310 строк · 9.9 Кб
1
// Copyright Istio Authors
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
	"errors"
19
	"fmt"
20
	"path/filepath"
21
	"strings"
22

23
	"github.com/spf13/cobra"
24
	"github.com/spf13/viper"
25

26
	"istio.io/istio/istioctl/pkg/admin"
27
	"istio.io/istio/istioctl/pkg/analyze"
28
	"istio.io/istio/istioctl/pkg/authz"
29
	"istio.io/istio/istioctl/pkg/checkinject"
30
	"istio.io/istio/istioctl/pkg/cli"
31
	"istio.io/istio/istioctl/pkg/completion"
32
	"istio.io/istio/istioctl/pkg/config"
33
	"istio.io/istio/istioctl/pkg/dashboard"
34
	"istio.io/istio/istioctl/pkg/describe"
35
	"istio.io/istio/istioctl/pkg/injector"
36
	"istio.io/istio/istioctl/pkg/internaldebug"
37
	"istio.io/istio/istioctl/pkg/kubeinject"
38
	"istio.io/istio/istioctl/pkg/metrics"
39
	"istio.io/istio/istioctl/pkg/multicluster"
40
	"istio.io/istio/istioctl/pkg/precheck"
41
	"istio.io/istio/istioctl/pkg/proxyconfig"
42
	"istio.io/istio/istioctl/pkg/proxystatus"
43
	"istio.io/istio/istioctl/pkg/root"
44
	"istio.io/istio/istioctl/pkg/tag"
45
	"istio.io/istio/istioctl/pkg/util"
46
	"istio.io/istio/istioctl/pkg/validate"
47
	"istio.io/istio/istioctl/pkg/version"
48
	"istio.io/istio/istioctl/pkg/wait"
49
	"istio.io/istio/istioctl/pkg/waypoint"
50
	"istio.io/istio/istioctl/pkg/workload"
51
	"istio.io/istio/operator/cmd/mesh"
52
	"istio.io/istio/pkg/cmd"
53
	"istio.io/istio/pkg/collateral"
54
	"istio.io/istio/pkg/config/constants"
55
	"istio.io/istio/pkg/log"
56
	"istio.io/istio/tools/bug-report/pkg/bugreport"
57
)
58

59
const (
60
	// Location to read istioctl defaults from
61
	defaultIstioctlConfig = "$HOME/.istioctl/config.yaml"
62
)
63

64
const (
65
	FlagCharts = "charts"
66
)
67

68
// ConfigAndEnvProcessing uses spf13/viper for overriding CLI parameters
69
func ConfigAndEnvProcessing() error {
70
	configPath := filepath.Dir(root.IstioConfig)
71
	baseName := filepath.Base(root.IstioConfig)
72
	configType := filepath.Ext(root.IstioConfig)
73
	configName := baseName[0 : len(baseName)-len(configType)]
74
	if configType != "" {
75
		configType = configType[1:]
76
	}
77

78
	// Allow users to override some variables through $HOME/.istioctl/config.yaml
79
	// and environment variables.
80
	viper.SetEnvPrefix("ISTIOCTL")
81
	viper.AutomaticEnv()
82
	viper.AllowEmptyEnv(true) // So we can say ISTIOCTL_CERT_DIR="" to suppress certs
83
	viper.SetConfigName(configName)
84
	viper.SetConfigType(configType)
85
	viper.AddConfigPath(configPath)
86
	viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
87
	err := viper.ReadInConfig()
88
	// Ignore errors reading the configuration unless the file is explicitly customized
89
	if root.IstioConfig != defaultIstioctlConfig {
90
		return err
91
	}
92

93
	return nil
94
}
95

96
func init() {
97
	viper.SetDefault("istioNamespace", constants.IstioSystemNamespace)
98
	viper.SetDefault("xds-port", 15012)
99
}
100

101
// GetRootCmd returns the root of the cobra command-tree.
102
func GetRootCmd(args []string) *cobra.Command {
103
	rootCmd := &cobra.Command{
104
		Use:               "istioctl",
105
		Short:             "Istio control interface.",
106
		SilenceUsage:      true,
107
		DisableAutoGenTag: true,
108
		PersistentPreRunE: ConfigureLogging,
109
		Long: `Istio configuration command line utility for service operators to
110
debug and diagnose their Istio mesh.
111
`,
112
	}
113

114
	rootCmd.SetArgs(args)
115

116
	flags := rootCmd.PersistentFlags()
117
	rootOptions := cli.AddRootFlags(flags)
118

119
	ctx := cli.NewCLIContext(rootOptions)
120

121
	_ = rootCmd.RegisterFlagCompletionFunc(cli.FlagIstioNamespace, func(
122
		cmd *cobra.Command, args []string, toComplete string,
123
	) ([]string, cobra.ShellCompDirective) {
124
		return completion.ValidNamespaceArgs(cmd, ctx, args, toComplete)
125
	})
126
	_ = rootCmd.RegisterFlagCompletionFunc(cli.FlagNamespace, func(
127
		cmd *cobra.Command, args []string, toComplete string,
128
	) ([]string, cobra.ShellCompDirective) {
129
		return completion.ValidNamespaceArgs(cmd, ctx, args, toComplete)
130
	})
131

132
	// Attach the Istio logging options to the command.
133
	root.LoggingOptions.AttachCobraFlags(rootCmd)
134
	hiddenFlags := []string{
135
		"log_as_json", "log_rotate", "log_rotate_max_age", "log_rotate_max_backups",
136
		"log_rotate_max_size", "log_stacktrace_level", "log_target", "log_caller", "log_output_level",
137
	}
138
	for _, opt := range hiddenFlags {
139
		_ = rootCmd.PersistentFlags().MarkHidden(opt)
140
	}
141

142
	cmd.AddFlags(rootCmd)
143

144
	kubeInjectCmd := kubeinject.InjectCommand(ctx)
145
	hideInheritedFlags(kubeInjectCmd, cli.FlagNamespace)
146
	rootCmd.AddCommand(kubeInjectCmd)
147

148
	experimentalCmd := &cobra.Command{
149
		Use:     "experimental",
150
		Aliases: []string{"x", "exp"},
151
		Short:   "Experimental commands that may be modified or deprecated",
152
	}
153

154
	xdsBasedTroubleshooting := []*cobra.Command{
155
		// TODO(hanxiaop): I think experimental version still has issues, so we keep the old version for now.
156
		version.XdsVersionCommand(ctx),
157
		// TODO(hanxiaop): this is kept for some releases in case someone is using it.
158
		proxystatus.XdsStatusCommand(ctx),
159
	}
160
	troubleshootingCommands := []*cobra.Command{
161
		version.NewVersionCommand(ctx),
162
		proxystatus.StableXdsStatusCommand(ctx),
163
	}
164
	var debugCmdAttachmentPoint *cobra.Command
165
	if viper.GetBool("PREFER-EXPERIMENTAL") {
166
		legacyCmd := &cobra.Command{
167
			Use:   "legacy",
168
			Short: "Legacy command variants",
169
		}
170
		rootCmd.AddCommand(legacyCmd)
171
		for _, c := range xdsBasedTroubleshooting {
172
			rootCmd.AddCommand(c)
173
		}
174
		debugCmdAttachmentPoint = legacyCmd
175
	} else {
176
		debugCmdAttachmentPoint = rootCmd
177
	}
178
	for _, c := range xdsBasedTroubleshooting {
179
		experimentalCmd.AddCommand(c)
180
	}
181
	for _, c := range troubleshootingCommands {
182
		debugCmdAttachmentPoint.AddCommand(c)
183
	}
184

185
	rootCmd.AddCommand(experimentalCmd)
186
	rootCmd.AddCommand(proxyconfig.ProxyConfig(ctx))
187
	rootCmd.AddCommand(admin.Cmd(ctx))
188
	experimentalCmd.AddCommand(injector.Cmd(ctx))
189

190
	rootCmd.AddCommand(mesh.NewVerifyCommand(ctx))
191
	rootCmd.AddCommand(mesh.UninstallCmd(ctx))
192

193
	experimentalCmd.AddCommand(authz.AuthZ(ctx))
194
	rootCmd.AddCommand(seeExperimentalCmd("authz"))
195
	experimentalCmd.AddCommand(metrics.Cmd(ctx))
196
	experimentalCmd.AddCommand(describe.Cmd(ctx))
197
	experimentalCmd.AddCommand(wait.Cmd(ctx))
198
	experimentalCmd.AddCommand(config.Cmd())
199
	experimentalCmd.AddCommand(workload.Cmd(ctx))
200
	experimentalCmd.AddCommand(internaldebug.DebugCommand(ctx))
201
	experimentalCmd.AddCommand(precheck.Cmd(ctx))
202
	experimentalCmd.AddCommand(proxyconfig.StatsConfigCmd(ctx))
203
	experimentalCmd.AddCommand(checkinject.Cmd(ctx))
204
	experimentalCmd.AddCommand(waypoint.Cmd(ctx))
205

206
	analyzeCmd := analyze.Analyze(ctx)
207
	hideInheritedFlags(analyzeCmd, cli.FlagIstioNamespace)
208
	rootCmd.AddCommand(analyzeCmd)
209

210
	dashboardCmd := dashboard.Dashboard(ctx)
211
	hideInheritedFlags(dashboardCmd, cli.FlagNamespace, cli.FlagIstioNamespace)
212
	rootCmd.AddCommand(dashboardCmd)
213

214
	manifestCmd := mesh.ManifestCmd(ctx)
215
	hideInheritedFlags(manifestCmd, cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
216
	rootCmd.AddCommand(manifestCmd)
217

218
	operatorCmd := mesh.OperatorCmd(ctx)
219
	hideInheritedFlags(operatorCmd, cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
220
	rootCmd.AddCommand(operatorCmd)
221

222
	installCmd := mesh.InstallCmd(ctx)
223
	hideInheritedFlags(installCmd, cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
224
	rootCmd.AddCommand(installCmd)
225

226
	profileCmd := mesh.ProfileCmd(ctx)
227
	hideInheritedFlags(profileCmd, cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
228
	rootCmd.AddCommand(profileCmd)
229

230
	upgradeCmd := mesh.UpgradeCmd(ctx)
231
	hideInheritedFlags(upgradeCmd, cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
232
	rootCmd.AddCommand(upgradeCmd)
233

234
	bugReportCmd := bugreport.Cmd(ctx, root.LoggingOptions)
235
	hideInheritedFlags(bugReportCmd, cli.FlagNamespace, cli.FlagIstioNamespace)
236
	rootCmd.AddCommand(bugReportCmd)
237

238
	tagCmd := tag.TagCommand(ctx)
239
	hideInheritedFlags(tag.TagCommand(ctx), cli.FlagNamespace, cli.FlagIstioNamespace, FlagCharts)
240
	rootCmd.AddCommand(tagCmd)
241

242
	// leave the multicluster commands in x for backwards compat
243
	rootCmd.AddCommand(multicluster.NewCreateRemoteSecretCommand(ctx))
244
	rootCmd.AddCommand(proxyconfig.ClustersCommand(ctx))
245

246
	rootCmd.AddCommand(collateral.CobraCommand(rootCmd, collateral.Metadata{
247
		Title:   "Istio Control",
248
		Section: "istioctl CLI",
249
		Manual:  "Istio Control",
250
	}))
251

252
	validateCmd := validate.NewValidateCommand(ctx)
253
	hideInheritedFlags(validateCmd, "kubeconfig")
254
	rootCmd.AddCommand(validateCmd)
255

256
	rootCmd.AddCommand(optionsCommand(rootCmd))
257

258
	// BFS applies the flag error function to all subcommands
259
	seenCommands := make(map[*cobra.Command]bool)
260
	var commandStack []*cobra.Command
261

262
	commandStack = append(commandStack, rootCmd)
263

264
	for len(commandStack) > 0 {
265
		n := len(commandStack) - 1
266
		curCmd := commandStack[n]
267
		commandStack = commandStack[:n]
268
		seenCommands[curCmd] = true
269
		for _, command := range curCmd.Commands() {
270
			if !seenCommands[command] {
271
				commandStack = append(commandStack, command)
272
			}
273
		}
274
		curCmd.SetFlagErrorFunc(func(_ *cobra.Command, e error) error {
275
			return util.CommandParseError{Err: e}
276
		})
277
	}
278

279
	return rootCmd
280
}
281

282
func hideInheritedFlags(orig *cobra.Command, hidden ...string) {
283
	orig.SetHelpFunc(func(cmd *cobra.Command, args []string) {
284
		for _, hidden := range hidden {
285
			_ = cmd.Flags().MarkHidden(hidden) // nolint: errcheck
286
		}
287

288
		orig.SetHelpFunc(nil)
289
		orig.HelpFunc()(cmd, args)
290
	})
291
}
292

293
func ConfigureLogging(_ *cobra.Command, _ []string) error {
294
	return log.Configure(root.LoggingOptions)
295
}
296

297
// seeExperimentalCmd is used for commands that have been around for a release but not graduated from
298
// Other alternative
299
// for graduatedCmd see https://github.com/istio/istio/pull/26408
300
// for softGraduatedCmd see https://github.com/istio/istio/pull/26563
301
func seeExperimentalCmd(name string) *cobra.Command {
302
	msg := fmt.Sprintf("(%s is experimental. Use `istioctl experimental %s`)", name, name)
303
	return &cobra.Command{
304
		Use:   name,
305
		Short: msg,
306
		RunE: func(_ *cobra.Command, _ []string) error {
307
			return errors.New(msg)
308
		},
309
	}
310
}
311

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.