istio

Форк
0
260 строк · 8.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
// An example implementation of a client.
16

17
package main
18

19
import (
20
	"context"
21
	"fmt"
22
	"net/url"
23
	"os"
24
	"strings"
25
	"time"
26

27
	"github.com/spf13/cobra"
28
	// To install the xds resolvers and balancers.
29
	_ "google.golang.org/grpc/xds"
30
	wrappers "google.golang.org/protobuf/types/known/wrapperspb"
31

32
	"istio.io/istio/pkg/cmd"
33
	"istio.io/istio/pkg/log"
34
	"istio.io/istio/pkg/test/echo/common"
35
	"istio.io/istio/pkg/test/echo/proto"
36
	"istio.io/istio/pkg/test/echo/server/forwarder"
37
)
38

39
var (
40
	count                   int
41
	timeout                 time.Duration
42
	qps                     int
43
	uds                     string
44
	headers                 []string
45
	msg                     string
46
	expect                  string
47
	expectSet               bool
48
	method                  string
49
	http2                   bool
50
	http3                   bool
51
	insecureSkipVerify      bool
52
	alpn                    []string
53
	serverName              string
54
	serverFirst             bool
55
	followRedirects         bool
56
	newConnectionPerRequest bool
57
	forceDNSLookup          bool
58

59
	clientCert string
60
	clientKey  string
61

62
	caFile string
63

64
	hboneAddress            string
65
	hboneHeaders            []string
66
	hboneClientCert         string
67
	hboneClientKey          string
68
	hboneCaFile             string
69
	hboneInsecureSkipVerify bool
70

71
	loggingOptions = log.DefaultOptions()
72

73
	rootCmd = &cobra.Command{
74
		Use:          "client",
75
		Short:        "Istio test Echo client.",
76
		SilenceUsage: true,
77
		Long: `Istio test Echo client used for generating traffic between instances of the Echo service.
78
For Kubernetes, this can be run from a source pod via "kubectl exec" with the desired flags.
79
In general, Echo's gRPC interface (ForwardEcho) should be preferred. This client is only needed in cases
80
where the network configuration doesn't support gRPC to the source pod.'
81
`,
82
		Args:              cobra.ExactArgs(1),
83
		PersistentPreRunE: configureLogging,
84
		Run: func(cmd *cobra.Command, args []string) {
85
			expectSet = cmd.Flags().Changed("expect")
86
			// Create a request from the flags.
87
			request, err := getRequest(args[0])
88
			if err != nil {
89
				log.Fatal(err)
90
			}
91

92
			// Create a forwarder.
93
			f := forwarder.New()
94
			defer func() {
95
				_ = f.Close()
96
			}()
97

98
			// Forward the requests.
99
			response, err := f.ForwardEcho(context.Background(), &forwarder.Config{
100
				Request: request,
101
				UDS:     uds,
102
			})
103
			if err != nil {
104
				log.Fatalf("Error %s\n", err) // nolint: revive
105
				os.Exit(-1)
106
			}
107

108
			// Log the output to stdout.
109
			for _, line := range response.Output {
110
				fmt.Println(line)
111
			}
112

113
			log.Infof("All requests succeeded")
114
		},
115
	}
116
)
117

118
func configureLogging(_ *cobra.Command, _ []string) error {
119
	if err := log.Configure(loggingOptions); err != nil {
120
		return err
121
	}
122
	return nil
123
}
124

125
func init() {
126
	rootCmd.PersistentFlags().IntVar(&count, "count", common.DefaultCount, "Number of times to make the request")
127
	rootCmd.PersistentFlags().IntVar(&qps, "qps", 0, "Queries per second")
128
	rootCmd.PersistentFlags().DurationVar(&timeout, "timeout", common.DefaultRequestTimeout, "Request timeout")
129
	rootCmd.PersistentFlags().StringVar(&uds, "uds", "",
130
		"Specify the Unix Domain Socket to connect to")
131
	rootCmd.PersistentFlags().StringSliceVarP(&headers, "header", "H", headers,
132
		"A list of http headers (use Host for authority) - 'name: value', following curl syntax")
133
	rootCmd.PersistentFlags().StringVar(&caFile, "ca", "", "CA root cert file")
134
	rootCmd.PersistentFlags().StringVar(&msg, "msg", "HelloWorld",
135
		"message to send (for websockets)")
136
	rootCmd.PersistentFlags().StringVar(&expect, "expect", "",
137
		"message to expect (for tcp)")
138
	rootCmd.PersistentFlags().StringVar(&method, "method", "", "method to use (for HTTP)")
139
	rootCmd.PersistentFlags().BoolVar(&http2, "http2", false,
140
		"send http requests as HTTP2 with prior knowledge")
141
	rootCmd.PersistentFlags().BoolVar(&http3, "http3", false,
142
		"send http requests as HTTP 3")
143
	rootCmd.PersistentFlags().BoolVarP(&insecureSkipVerify, "insecure-skip-verify", "k", insecureSkipVerify,
144
		"do not verify TLS")
145
	rootCmd.PersistentFlags().BoolVar(&serverFirst, "server-first", false,
146
		"Treat as a server first protocol; do not send request until magic string is received")
147
	rootCmd.PersistentFlags().BoolVarP(&followRedirects, "follow-redirects", "L", false,
148
		"If enabled, will follow 3xx redirects with the Location header")
149
	rootCmd.PersistentFlags().BoolVar(&newConnectionPerRequest, "new-connection-per-request", false,
150
		"If enabled, a new connection will be made to the server for each individual request. "+
151
			"If false, an attempt will be made to re-use the connection for the life of the forward request. "+
152
			"This is automatically set for DNS, TCP, TLS, and WebSocket protocols.")
153
	rootCmd.PersistentFlags().BoolVar(&forceDNSLookup, "force-dns-lookup", false,
154
		"If enabled, each request will force a DNS lookup. Only applies if new-connection-per-request is also enabled.")
155
	rootCmd.PersistentFlags().StringVar(&clientCert, "client-cert", "", "client certificate file to use for request")
156
	rootCmd.PersistentFlags().StringVar(&clientKey, "client-key", "", "client certificate key file to use for request")
157
	rootCmd.PersistentFlags().StringSliceVarP(&alpn, "alpn", "", nil, "alpn to set")
158
	rootCmd.PersistentFlags().StringVarP(&serverName, "server-name", "", serverName, "server name to set")
159

160
	rootCmd.PersistentFlags().StringVar(&hboneAddress, "hbone", "", "address to send HBONE request to")
161
	rootCmd.PersistentFlags().StringSliceVarP(&hboneHeaders, "hbone-header", "M", hboneHeaders,
162
		"A list of http headers for HBONE connection (use Host for authority) - 'name: value', following curl syntax")
163
	rootCmd.PersistentFlags().StringVar(&hboneCaFile, "hbone-ca", "", "CA root cert file used for the HBONE request")
164
	rootCmd.PersistentFlags().StringVar(&hboneClientCert, "hbone-client-cert", "", "client certificate file used for the HBONE request")
165
	rootCmd.PersistentFlags().StringVar(&hboneClientKey, "hbone-client-key", "", "client certificate key file used for the HBONE request")
166
	rootCmd.PersistentFlags().BoolVar(&hboneInsecureSkipVerify, "hbone-insecure-skip-verify", hboneInsecureSkipVerify, "skip TLS verification of HBONE request")
167

168
	loggingOptions.AttachCobraFlags(rootCmd)
169

170
	cmd.AddFlags(rootCmd)
171
}
172

173
// Adds http scheme to and url if not set. This matches curl logic
174
func defaultScheme(u string) string {
175
	p, err := url.Parse(u)
176
	if err != nil {
177
		return u
178
	}
179
	if p.Scheme == "" {
180
		return "http://" + u
181
	}
182
	return u
183
}
184

185
func getRequest(url string) (*proto.ForwardEchoRequest, error) {
186
	request := &proto.ForwardEchoRequest{
187
		Url:                     defaultScheme(url),
188
		TimeoutMicros:           common.DurationToMicros(timeout),
189
		Count:                   int32(count),
190
		Qps:                     int32(qps),
191
		Message:                 msg,
192
		Http2:                   http2,
193
		Http3:                   http3,
194
		ServerFirst:             serverFirst,
195
		FollowRedirects:         followRedirects,
196
		Method:                  method,
197
		ServerName:              serverName,
198
		InsecureSkipVerify:      insecureSkipVerify,
199
		NewConnectionPerRequest: newConnectionPerRequest,
200
		ForceDNSLookup:          forceDNSLookup,
201
	}
202
	if len(hboneAddress) > 0 {
203
		request.Hbone = &proto.HBONE{
204
			Address:            hboneAddress,
205
			CertFile:           hboneClientCert,
206
			KeyFile:            hboneClientKey,
207
			CaCertFile:         hboneCaFile,
208
			InsecureSkipVerify: hboneInsecureSkipVerify,
209
		}
210
		for _, header := range hboneHeaders {
211
			parts := strings.SplitN(header, ":", 2)
212
			// require name:value format
213
			if len(parts) != 2 {
214
				return nil, fmt.Errorf("invalid header format: %q (want name:value)", header)
215
			}
216

217
			request.Hbone.Headers = append(request.Hbone.Headers, &proto.Header{
218
				Key:   parts[0],
219
				Value: strings.Trim(parts[1], " "),
220
			})
221
		}
222
	}
223

224
	if expectSet {
225
		request.ExpectedResponse = &wrappers.StringValue{Value: expect}
226
	}
227

228
	if alpn != nil {
229
		request.Alpn = &proto.Alpn{Value: alpn}
230
	}
231

232
	for _, header := range headers {
233
		parts := strings.Split(header, ":")
234

235
		// require name:value format
236
		if len(parts) != 2 {
237
			return nil, fmt.Errorf("invalid header format: %q (want name:value)", header)
238
		}
239

240
		request.Headers = append(request.Headers, &proto.Header{
241
			Key:   parts[0],
242
			Value: strings.Trim(parts[1], " "),
243
		})
244
	}
245

246
	if clientCert != "" && clientKey != "" {
247
		request.CertFile = clientCert
248
		request.KeyFile = clientKey
249
	}
250
	if caFile != "" {
251
		request.CaCertFile = caFile
252
	}
253
	return request, nil
254
}
255

256
func main() {
257
	if err := rootCmd.Execute(); err != nil {
258
		os.Exit(-1)
259
	}
260
}
261

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

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

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

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