istio

Форк
0
203 строки · 7.3 Кб
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 bugreport
16

17
import (
18
	"encoding/json"
19
	"fmt"
20
	"os"
21
	"time"
22

23
	jsonpatch "github.com/evanphx/json-patch/v5"
24
	"github.com/spf13/cobra"
25
	"sigs.k8s.io/yaml"
26

27
	"istio.io/istio/pkg/kube/inject"
28
	"istio.io/istio/pkg/slices"
29
	config2 "istio.io/istio/tools/bug-report/pkg/config"
30
)
31

32
var (
33
	startTime, endTime, configFile, tempDir, outputDir string
34
	included, excluded                                 []string
35
	commandTimeout, since                              time.Duration
36
	gConfig                                            = &config2.BugReportConfig{}
37
)
38

39
func addFlags(cmd *cobra.Command, args *config2.BugReportConfig) {
40
	// k8s client config
41
	cmd.PersistentFlags().StringVarP(&args.KubeConfigPath, "kubeconfig", "c", "",
42
		"Path to kube config.")
43
	cmd.PersistentFlags().StringVar(&args.Context, "context", "",
44
		"Name of the kubeconfig Context to use.")
45

46
	// input config
47
	cmd.PersistentFlags().StringVarP(&configFile, "filename", "f", "",
48
		"Path to a file containing configuration in YAML format. The file contents are applied over the default "+
49
			"values and flag settings, with lists being replaced per JSON merge semantics.")
50

51
	// dry run
52
	cmd.PersistentFlags().BoolVarP(&args.DryRun, "dry-run", "", false,
53
		"Only log commands that would be run, don't fetch or write.")
54

55
	// full secrets
56
	cmd.PersistentFlags().BoolVarP(&args.FullSecrets, "full-secrets", "", false,
57
		"If set, secret contents are included in output.")
58

59
	// istio namespaces
60
	cmd.PersistentFlags().StringVar(&args.IstioNamespace, "istio-namespace", bugReportDefaultIstioNamespace,
61
		"Namespace where Istio control plane is installed.")
62

63
	// timeouts and max sizes
64
	cmd.PersistentFlags().DurationVar(&commandTimeout, "timeout", bugReportDefaultTimeout,
65
		"Maximum amount of time to spend fetching logs. When timeout is reached "+
66
			"only the logs captured so far are saved to the archive.")
67
	// include / exclude specs
68
	cmd.PersistentFlags().StringSliceVar(&included, "include", bugReportDefaultInclude,
69
		"Spec for which pod's proxy logs to include in the archive. See above for format and examples.")
70
	cmd.PersistentFlags().StringSliceVar(&excluded, "exclude", bugReportDefaultExclude,
71
		"Spec for which pod's proxy logs to exclude from the archive, after the include spec "+
72
			"is processed. See above for format and examples.")
73

74
	// log time ranges
75
	cmd.PersistentFlags().StringVar(&startTime, "start-time", "",
76
		"Start time for the range of log entries to include in the archive. "+
77
			"Default is the infinite past. If set, --duration must be unset.")
78
	cmd.PersistentFlags().StringVar(&endTime, "end-time", "",
79
		"End time for the range of log entries to include in the archive. Default is now.")
80
	cmd.PersistentFlags().DurationVar(&since, "duration", 0,
81
		"How far to go back in time from end-time for log entries to include in the archive. "+
82
			"Default is infinity. If set, --start-time must be unset.")
83

84
	// log error control
85
	cmd.PersistentFlags().StringSliceVar(&args.CriticalErrors, "critical-errs", nil,
86
		"List of comma separated glob patterns to match against log error strings. "+
87
			"If any pattern matches an error in the log, the logs is given the highest priority for archive inclusion.")
88
	cmd.PersistentFlags().StringSliceVar(&args.IgnoredErrors, "ignore-errs", nil,
89
		"List of comma separated glob patterns to match against log error strings. "+
90
			"Any error matching these patterns is ignored when calculating the log importance heuristic.")
91

92
	// working dir to store temporary artifacts
93
	cmd.PersistentFlags().StringVar(&tempDir, "dir", "",
94
		"Set a specific directory for temporary artifact storage.")
95

96
	cmd.PersistentFlags().StringVar(&outputDir, "output-dir", "",
97
		"Set a specific directory for output archive file.")
98

99
	// in-flight request limit
100
	cmd.PersistentFlags().IntVar(&args.RequestConcurrency, "rq-concurrency", 0,
101
		"Set the concurrency limit of requests to the Kubernetes API server, defaults to 32.")
102
}
103

104
func parseConfig() (*config2.BugReportConfig, error) {
105
	fileConfig := &config2.BugReportConfig{}
106
	if configFile != "" {
107
		b, err := os.ReadFile(configFile)
108
		if err != nil {
109
			return nil, err
110
		}
111
		if err := yaml.Unmarshal(b, fileConfig); err != nil {
112
			return nil, err
113
		}
114
	}
115

116
	if err := parseTimes(gConfig, startTime, endTime, since); err != nil {
117
		return nil, err
118
	}
119
	gConfig.CommandTimeout = config2.Duration(commandTimeout)
120
	for _, s := range included {
121
		ss := &config2.SelectionSpec{}
122
		if err := ss.UnmarshalJSON([]byte(s)); err != nil {
123
			return nil, err
124
		}
125
		gConfig.Include = append(gConfig.Include, ss)
126
	}
127
	// Exclude default system namespaces eg: bugReportDefaultExclude
128
	dss := &config2.SelectionSpec{}
129
	if err := dss.UnmarshalJSON([]byte(bugReportDefaultExclude[0])); err != nil {
130
		return nil, err
131
	}
132
	gConfig.Exclude = append(gConfig.Exclude, dss)
133
	// Exclude namespace provided by --exclude flag
134
	for _, s := range excluded {
135
		ess := &config2.SelectionSpec{}
136
		if err := ess.UnmarshalJSON([]byte(s)); err != nil {
137
			return nil, err
138
		}
139
		ess.Namespaces = slices.FilterInPlace(ess.Namespaces, func(ns string) bool { return !inject.IgnoredNamespaces.Contains(ns) })
140
		if len(ess.Namespaces) > 0 {
141
			gConfig.Exclude = append(gConfig.Exclude, ess)
142
		}
143
	}
144
	return overlayConfig(fileConfig, gConfig)
145
}
146

147
func parseTimes(config *config2.BugReportConfig, startTime, endTime string, duration time.Duration) error {
148
	if startTime == "" && endTime == "" {
149
		config.TimeFilterApplied = false
150
	} else {
151
		config.TimeFilterApplied = true
152
	}
153

154
	config.EndTime = time.Now()
155
	config.Since = config2.Duration(duration)
156
	if endTime != "" {
157
		var err error
158
		config.EndTime, err = time.Parse(time.RFC3339, endTime)
159
		if err != nil {
160
			return fmt.Errorf("bad format for end-time: %s, expect RFC3339 e.g. %s", endTime, time.RFC3339)
161
		}
162
	}
163
	if config.Since != 0 {
164
		if startTime != "" {
165
			return fmt.Errorf("only one --start-time or --duration may be set")
166
		}
167
		config.StartTime = config.EndTime.Add(-1 * time.Duration(config.Since))
168
	} else {
169
		var err error
170
		if startTime == "" {
171
			config.StartTime = time.Time{}
172
		} else {
173
			config.StartTime, err = time.Parse(time.RFC3339, startTime)
174
			if err != nil {
175
				return fmt.Errorf("bad format for start-time: %s, expect RFC3339 e.g. %s", startTime, time.RFC3339)
176
			}
177
			if config.StartTime.After(config.EndTime) {
178
				return fmt.Errorf("bad format for start-time and end-time: start-time is after end-time")
179
			}
180
		}
181
	}
182
	return nil
183
}
184

185
func overlayConfig(base, overlay *config2.BugReportConfig) (*config2.BugReportConfig, error) {
186
	bj, err := json.Marshal(base)
187
	if err != nil {
188
		return nil, err
189
	}
190
	oj, err := json.Marshal(overlay)
191
	if err != nil {
192
		return nil, err
193
	}
194

195
	mj, err := jsonpatch.MergePatch(bj, oj)
196
	if err != nil {
197
		return nil, fmt.Errorf("json merge error (%s) for base object: \n%s\n override object: \n%s", err, bj, oj)
198
	}
199

200
	out := &config2.BugReportConfig{}
201
	err = json.Unmarshal(mj, out)
202
	return out, err
203
}
204

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

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

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

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