1// Copyright 2017 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
15package server
16
17import (
18	"bytes"
19	"fmt"
20	"time"
21
22	"istio.io/istio/mixer/pkg/adapter"
23	"istio.io/istio/mixer/pkg/config/store"
24	"istio.io/istio/mixer/pkg/loadshedding"
25	"istio.io/istio/mixer/pkg/runtime/config/constant"
26	"istio.io/istio/mixer/pkg/template"
27	"istio.io/istio/pkg/mcp/creds"
28	"istio.io/istio/pkg/tracing"
29	"istio.io/pkg/ctrlz"
30	"istio.io/pkg/log"
31	"istio.io/pkg/probe"
32)
33
34// Args contains the startup arguments to instantiate Mixer.
35type Args struct {
36	// The templates to register.
37	Templates map[string]template.Info
38
39	// The adapters to use
40	Adapters []adapter.InfoFn
41
42	// Maximum size of individual gRPC messages
43	MaxMessageSize uint
44
45	// Maximum number of outstanding RPCs per connection
46	MaxConcurrentStreams uint
47
48	// Maximum number of goroutines in the API worker pool
49	APIWorkerPoolSize int
50
51	// Maximum number of goroutines in the adapter worker pool
52	AdapterWorkerPoolSize int
53
54	// URL of the config store. Use k8s://path_to_kubeconfig, fs:// for file system, or mcps://<host> to
55	// connect to Galley. If path_to_kubeconfig is empty, in-cluster kubeconfig is used.")
56	// If this is empty (and ConfigStore isn't specified), "k8s://" will be used.
57	ConfigStoreURL string
58
59	// The certificate file locations for the MCP config backend.
60	CredentialOptions *creds.Options
61
62	// For testing; this one is used for the backend store if ConfigStoreURL is empty. Specifying both is invalid.
63	ConfigStore store.Store
64
65	// Kubernetes namespace used to store mesh-wide configuration.")
66	ConfigDefaultNamespace string
67
68	// Timeout until the initial set of configurations are received, before declaring as ready.
69	ConfigWaitTimeout time.Duration
70
71	// The logging options to use
72	LoggingOptions *log.Options
73
74	// The tracing options to use
75	TracingOptions *tracing.Options
76
77	// The path to the file which indicates the liveness of the server by its existence.
78	// This will be used for k8s liveness probe. If empty, it does nothing.
79	LivenessProbeOptions *probe.Options
80
81	// The path to the file for readiness probe, similar to LivenessProbePath.
82	ReadinessProbeOptions *probe.Options
83
84	// The introspection options to use
85	IntrospectionOptions *ctrlz.Options
86
87	// Address to use for Mixer's gRPC API. This setting supersedes the API port setting.
88	APIAddress string
89
90	// Port to use for Mixer's gRPC API
91	APIPort uint16
92
93	// Port to use for exposing mixer self-monitoring information
94	MonitoringPort uint16
95
96	// Maximum number of entries in the check cache
97	NumCheckCacheEntries int32
98
99	// Enable profiling via web interface host:port/debug/pprof
100	EnableProfiling bool
101
102	// Enables gRPC-level tracing
103	EnableGRPCTracing bool
104
105	// If true, each request to Mixer will be executed in a single go routine (useful for debugging)
106	SingleThreaded bool
107
108	// Whether or not to establish watches for adapter-specific CRDs
109	UseAdapterCRDs bool
110
111	// Whether or not to establish watches for template-specific CRDs
112	UseTemplateCRDs bool
113
114	LoadSheddingOptions loadshedding.Options
115}
116
117// DefaultArgs allocates an Args struct initialized with Mixer's default configuration.
118func DefaultArgs() *Args {
119	return &Args{
120		APIPort:                9091,
121		MonitoringPort:         15014,
122		MaxMessageSize:         1024 * 1024,
123		MaxConcurrentStreams:   1024,
124		APIWorkerPoolSize:      1024,
125		AdapterWorkerPoolSize:  1024,
126		CredentialOptions:      creds.DefaultOptions(),
127		ConfigDefaultNamespace: constant.DefaultConfigNamespace,
128		ConfigWaitTimeout:      2 * time.Minute,
129		LoggingOptions:         log.DefaultOptions(),
130		TracingOptions:         tracing.DefaultOptions(),
131		LivenessProbeOptions:   &probe.Options{},
132		ReadinessProbeOptions:  &probe.Options{},
133		IntrospectionOptions:   ctrlz.DefaultOptions(),
134		EnableProfiling:        true,
135		NumCheckCacheEntries:   5000 * 5 * 60, // 5000 QPS with average TTL of 5 minutes
136		UseAdapterCRDs:         true,
137		UseTemplateCRDs:        true,
138		LoadSheddingOptions:    loadshedding.DefaultOptions(),
139	}
140}
141
142func (a *Args) validate() error {
143	if a.MaxMessageSize == 0 {
144		return fmt.Errorf("max message size must be > 0, got %d", a.MaxMessageSize)
145	}
146
147	if a.MaxConcurrentStreams == 0 {
148		return fmt.Errorf("max concurrent streams must be > 0, got %d", a.MaxConcurrentStreams)
149	}
150
151	if a.APIWorkerPoolSize <= 0 {
152		return fmt.Errorf("api worker pool size must be > 0, got pool size %d", a.APIWorkerPoolSize)
153	}
154
155	if a.AdapterWorkerPoolSize <= 0 {
156		return fmt.Errorf("adapter worker pool size must be > 0 , got pool size %d", a.AdapterWorkerPoolSize)
157	}
158
159	if a.NumCheckCacheEntries < 0 {
160		return fmt.Errorf("# check cache entries must be >= 0 and <= 2^31-1, got %d", a.NumCheckCacheEntries)
161	}
162
163	if a.ConfigStore != nil && a.ConfigStoreURL != "" {
164		return fmt.Errorf("invalid arguments: both ConfigStore and ConfigStoreURL are specified")
165	}
166
167	return nil
168}
169
170// String produces a stringified version of the arguments for debugging.
171func (a *Args) String() string {
172	buf := &bytes.Buffer{}
173
174	fmt.Fprintln(buf, "MaxMessageSize: ", a.MaxMessageSize)
175	fmt.Fprintln(buf, "MaxConcurrentStreams: ", a.MaxConcurrentStreams)
176	fmt.Fprintln(buf, "APIWorkerPoolSize: ", a.APIWorkerPoolSize)
177	fmt.Fprintln(buf, "AdapterWorkerPoolSize: ", a.AdapterWorkerPoolSize)
178	fmt.Fprintln(buf, "APIPort: ", a.APIPort)
179	fmt.Fprintln(buf, "APIAddress: ", a.APIAddress)
180	fmt.Fprintln(buf, "MonitoringPort: ", a.MonitoringPort)
181	fmt.Fprintln(buf, "EnableProfiling: ", a.EnableProfiling)
182	fmt.Fprintln(buf, "SingleThreaded: ", a.SingleThreaded)
183	fmt.Fprintln(buf, "NumCheckCacheEntries: ", a.NumCheckCacheEntries)
184	fmt.Fprintln(buf, "ConfigStoreURL: ", a.ConfigStoreURL)
185	fmt.Fprintln(buf, "CertificateFile: ", a.CredentialOptions.CertificateFile)
186	fmt.Fprintln(buf, "KeyFile: ", a.CredentialOptions.KeyFile)
187	fmt.Fprintln(buf, "CACertificateFile: ", a.CredentialOptions.CACertificateFile)
188	fmt.Fprintln(buf, "ConfigDefaultNamespace: ", a.ConfigDefaultNamespace)
189	fmt.Fprintln(buf, "ConfigWaitTimeout: ", a.ConfigWaitTimeout)
190	fmt.Fprintf(buf, "LoggingOptions: %#v\n", *a.LoggingOptions)
191	fmt.Fprintf(buf, "TracingOptions: %#v\n", *a.TracingOptions)
192	fmt.Fprintf(buf, "IntrospectionOptions: %#v\n", *a.IntrospectionOptions)
193	fmt.Fprintf(buf, "UseTemplateCRDs: %#v\n", a.UseTemplateCRDs)
194	fmt.Fprintf(buf, "LoadSheddingOptions: %#v\n", a.LoadSheddingOptions)
195	fmt.Fprintf(buf, "UseAdapterCRDs: %#v\n", a.UseAdapterCRDs)
196
197	return buf.String()
198}
199