1
16
17 package options
18
19 import (
20 "net"
21 "reflect"
22 "testing"
23 "time"
24
25 "github.com/google/go-cmp/cmp"
26 "github.com/google/go-cmp/cmp/cmpopts"
27 "github.com/spf13/pflag"
28 oteltrace "go.opentelemetry.io/otel/trace"
29
30 "k8s.io/apiserver/pkg/admission"
31 apiserveroptions "k8s.io/apiserver/pkg/server/options"
32 "k8s.io/apiserver/pkg/storage/etcd3"
33 "k8s.io/apiserver/pkg/storage/storagebackend"
34 auditbuffered "k8s.io/apiserver/plugin/pkg/audit/buffered"
35 audittruncate "k8s.io/apiserver/plugin/pkg/audit/truncate"
36 cliflag "k8s.io/component-base/cli/flag"
37 "k8s.io/component-base/logs"
38 "k8s.io/component-base/metrics"
39 kapi "k8s.io/kubernetes/pkg/apis/core"
40 controlplaneapiserver "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
41 "k8s.io/kubernetes/pkg/controlplane/reconcilers"
42 kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
43 kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
44 netutils "k8s.io/utils/net"
45 )
46
47 func TestAddFlags(t *testing.T) {
48 fs := pflag.NewFlagSet("addflagstest", pflag.PanicOnError)
49 s := NewServerRunOptions()
50 for _, f := range s.Flags().FlagSets {
51 fs.AddFlagSet(f)
52 }
53
54 args := []string{
55 "--enable-admission-plugins=AlwaysDeny",
56 "--admission-control-config-file=/admission-control-config",
57 "--advertise-address=192.168.10.10",
58 "--allow-privileged=false",
59 "--anonymous-auth=false",
60 "--apiserver-count=5",
61 "--audit-log-maxage=11",
62 "--audit-log-maxbackup=12",
63 "--audit-log-maxsize=13",
64 "--audit-log-path=/var/log",
65 "--audit-log-mode=blocking",
66 "--audit-log-batch-buffer-size=46",
67 "--audit-log-batch-max-size=47",
68 "--audit-log-batch-max-wait=48s",
69 "--audit-log-batch-throttle-enable=true",
70 "--audit-log-batch-throttle-qps=49.5",
71 "--audit-log-batch-throttle-burst=50",
72 "--audit-log-truncate-enabled=true",
73 "--audit-log-truncate-max-batch-size=45",
74 "--audit-log-truncate-max-event-size=44",
75 "--audit-log-version=audit.k8s.io/v1",
76 "--audit-policy-file=/policy",
77 "--audit-webhook-config-file=/webhook-config",
78 "--audit-webhook-mode=blocking",
79 "--audit-webhook-batch-buffer-size=42",
80 "--audit-webhook-batch-max-size=43",
81 "--audit-webhook-batch-max-wait=1s",
82 "--audit-webhook-batch-throttle-enable=false",
83 "--audit-webhook-batch-throttle-qps=43.5",
84 "--audit-webhook-batch-throttle-burst=44",
85 "--audit-webhook-truncate-enabled=true",
86 "--audit-webhook-truncate-max-batch-size=43",
87 "--audit-webhook-truncate-max-event-size=42",
88 "--audit-webhook-initial-backoff=2s",
89 "--audit-webhook-version=audit.k8s.io/v1",
90 "--authentication-token-webhook-cache-ttl=3m",
91 "--authentication-token-webhook-config-file=/token-webhook-config",
92 "--authorization-mode=AlwaysDeny,RBAC",
93 "--authorization-policy-file=/policy",
94 "--authorization-webhook-cache-authorized-ttl=3m",
95 "--authorization-webhook-cache-unauthorized-ttl=1m",
96 "--authorization-webhook-config-file=/webhook-config",
97 "--bind-address=192.168.10.20",
98 "--client-ca-file=/client-ca",
99 "--cloud-config=/cloud-config",
100 "--cloud-provider=azure",
101 "--cors-allowed-origins=10.10.10.100,10.10.10.200",
102 "--contention-profiling=true",
103 "--egress-selector-config-file=/var/run/kubernetes/egress-selector/connectivity.yaml",
104 "--enable-aggregator-routing=true",
105 "--enable-priority-and-fairness=false",
106 "--enable-logs-handler=false",
107 "--endpoint-reconciler-type=" + string(reconcilers.LeaseEndpointReconcilerType),
108 "--etcd-keyfile=/var/run/kubernetes/etcd.key",
109 "--etcd-certfile=/var/run/kubernetes/etcdce.crt",
110 "--etcd-cafile=/var/run/kubernetes/etcdca.crt",
111 "--http2-max-streams-per-connection=42",
112 "--kubelet-read-only-port=10255",
113 "--kubelet-timeout=5s",
114 "--kubelet-client-certificate=/var/run/kubernetes/ceserver.crt",
115 "--kubelet-client-key=/var/run/kubernetes/server.key",
116 "--kubelet-certificate-authority=/var/run/kubernetes/caserver.crt",
117 "--tracing-config-file=/var/run/kubernetes/tracing_config.yaml",
118 "--proxy-client-cert-file=/var/run/kubernetes/proxy.crt",
119 "--proxy-client-key-file=/var/run/kubernetes/proxy.key",
120 "--request-timeout=2m",
121 "--storage-backend=etcd3",
122 "--service-cluster-ip-range=192.168.128.0/17",
123 "--lease-reuse-duration-seconds=100",
124 }
125 fs.Parse(args)
126
127
128 expected := &ServerRunOptions{
129 Options: &controlplaneapiserver.Options{
130 GenericServerRunOptions: &apiserveroptions.ServerRunOptions{
131 AdvertiseAddress: netutils.ParseIPSloppy("192.168.10.10"),
132 CorsAllowedOriginList: []string{"10.10.10.100", "10.10.10.200"},
133 MaxRequestsInFlight: 400,
134 MaxMutatingRequestsInFlight: 200,
135 RequestTimeout: time.Duration(2) * time.Minute,
136 MinRequestTimeout: 1800,
137 JSONPatchMaxCopyBytes: int64(3 * 1024 * 1024),
138 MaxRequestBodyBytes: int64(3 * 1024 * 1024),
139 },
140 Admission: &kubeoptions.AdmissionOptions{
141 GenericAdmission: &apiserveroptions.AdmissionOptions{
142 RecommendedPluginOrder: s.Options.Admission.GenericAdmission.RecommendedPluginOrder,
143 DefaultOffPlugins: s.Options.Admission.GenericAdmission.DefaultOffPlugins,
144 EnablePlugins: []string{"AlwaysDeny"},
145 ConfigFile: "/admission-control-config",
146 Plugins: s.Options.Admission.GenericAdmission.Plugins,
147 Decorators: s.Options.Admission.GenericAdmission.Decorators,
148 },
149 },
150 Etcd: &apiserveroptions.EtcdOptions{
151 StorageConfig: storagebackend.Config{
152 Type: "etcd3",
153 Transport: storagebackend.TransportConfig{
154 ServerList: nil,
155 KeyFile: "/var/run/kubernetes/etcd.key",
156 TrustedCAFile: "/var/run/kubernetes/etcdca.crt",
157 CertFile: "/var/run/kubernetes/etcdce.crt",
158 TracerProvider: oteltrace.NewNoopTracerProvider(),
159 },
160 Prefix: "/registry",
161 CompactionInterval: storagebackend.DefaultCompactInterval,
162 CountMetricPollPeriod: time.Minute,
163 DBMetricPollInterval: storagebackend.DefaultDBMetricPollInterval,
164 HealthcheckTimeout: storagebackend.DefaultHealthcheckTimeout,
165 ReadycheckTimeout: storagebackend.DefaultReadinessTimeout,
166 LeaseManagerConfig: etcd3.LeaseManagerConfig{
167 ReuseDurationSeconds: 100,
168 MaxObjectCount: 1000,
169 },
170 },
171 DefaultStorageMediaType: "application/vnd.kubernetes.protobuf",
172 DeleteCollectionWorkers: 1,
173 EnableGarbageCollection: true,
174 EnableWatchCache: true,
175 DefaultWatchCacheSize: 100,
176 },
177 SecureServing: (&apiserveroptions.SecureServingOptions{
178 BindAddress: netutils.ParseIPSloppy("192.168.10.20"),
179 BindPort: 6443,
180 ServerCert: apiserveroptions.GeneratableKeyCert{
181 CertDirectory: "/var/run/kubernetes",
182 PairName: "apiserver",
183 },
184 HTTP2MaxStreamsPerConnection: 42,
185 Required: true,
186 }).WithLoopback(),
187 EventTTL: 1 * time.Hour,
188 Audit: &apiserveroptions.AuditOptions{
189 LogOptions: apiserveroptions.AuditLogOptions{
190 Path: "/var/log",
191 MaxAge: 11,
192 MaxBackups: 12,
193 MaxSize: 13,
194 Format: "json",
195 BatchOptions: apiserveroptions.AuditBatchOptions{
196 Mode: "blocking",
197 BatchConfig: auditbuffered.BatchConfig{
198 BufferSize: 46,
199 MaxBatchSize: 47,
200 MaxBatchWait: 48 * time.Second,
201 ThrottleEnable: true,
202 ThrottleQPS: 49.5,
203 ThrottleBurst: 50,
204 },
205 },
206 TruncateOptions: apiserveroptions.AuditTruncateOptions{
207 Enabled: true,
208 TruncateConfig: audittruncate.Config{
209 MaxBatchSize: 45,
210 MaxEventSize: 44,
211 },
212 },
213 GroupVersionString: "audit.k8s.io/v1",
214 },
215 WebhookOptions: apiserveroptions.AuditWebhookOptions{
216 ConfigFile: "/webhook-config",
217 BatchOptions: apiserveroptions.AuditBatchOptions{
218 Mode: "blocking",
219 BatchConfig: auditbuffered.BatchConfig{
220 BufferSize: 42,
221 MaxBatchSize: 43,
222 MaxBatchWait: 1 * time.Second,
223 ThrottleEnable: false,
224 ThrottleQPS: 43.5,
225 ThrottleBurst: 44,
226 AsyncDelegate: true,
227 },
228 },
229 TruncateOptions: apiserveroptions.AuditTruncateOptions{
230 Enabled: true,
231 TruncateConfig: audittruncate.Config{
232 MaxBatchSize: 43,
233 MaxEventSize: 42,
234 },
235 },
236 InitialBackoff: 2 * time.Second,
237 GroupVersionString: "audit.k8s.io/v1",
238 },
239 PolicyFile: "/policy",
240 },
241 Features: &apiserveroptions.FeatureOptions{
242 EnableProfiling: true,
243 EnableContentionProfiling: true,
244 },
245 Authentication: &kubeoptions.BuiltInAuthenticationOptions{
246 Anonymous: &kubeoptions.AnonymousAuthenticationOptions{
247 Allow: false,
248 },
249 ClientCert: &apiserveroptions.ClientCertAuthenticationOptions{
250 ClientCA: "/client-ca",
251 },
252 WebHook: &kubeoptions.WebHookAuthenticationOptions{
253 CacheTTL: 180000000000,
254 ConfigFile: "/token-webhook-config",
255 Version: "v1beta1",
256 RetryBackoff: apiserveroptions.DefaultAuthWebhookRetryBackoff(),
257 },
258 BootstrapToken: &kubeoptions.BootstrapTokenAuthenticationOptions{},
259 OIDC: s.Authentication.OIDC,
260 RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
261 ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
262 Lookup: true,
263 ExtendExpiration: true,
264 },
265 TokenFile: &kubeoptions.TokenFileAuthenticationOptions{},
266 TokenSuccessCacheTTL: 10 * time.Second,
267 TokenFailureCacheTTL: 0,
268 },
269 Authorization: &kubeoptions.BuiltInAuthorizationOptions{
270 Modes: []string{"AlwaysDeny", "RBAC"},
271 PolicyFile: "/policy",
272 WebhookConfigFile: "/webhook-config",
273 WebhookCacheAuthorizedTTL: 180000000000,
274 WebhookCacheUnauthorizedTTL: 60000000000,
275 WebhookVersion: "v1beta1",
276 WebhookRetryBackoff: apiserveroptions.DefaultAuthWebhookRetryBackoff(),
277 },
278 APIEnablement: &apiserveroptions.APIEnablementOptions{
279 RuntimeConfig: cliflag.ConfigurationMap{},
280 },
281 EgressSelector: &apiserveroptions.EgressSelectorOptions{
282 ConfigFile: "/var/run/kubernetes/egress-selector/connectivity.yaml",
283 },
284 EnableLogsHandler: false,
285 EnableAggregatorRouting: true,
286 ProxyClientKeyFile: "/var/run/kubernetes/proxy.key",
287 ProxyClientCertFile: "/var/run/kubernetes/proxy.crt",
288 Metrics: &metrics.Options{},
289 Logs: logs.NewOptions(),
290 Traces: &apiserveroptions.TracingOptions{
291 ConfigFile: "/var/run/kubernetes/tracing_config.yaml",
292 },
293 AggregatorRejectForwardingRedirects: true,
294 },
295
296 Extra: Extra{
297 ServiceNodePortRange: kubeoptions.DefaultServiceNodePortRange,
298 ServiceClusterIPRanges: (&net.IPNet{IP: netutils.ParseIPSloppy("192.168.128.0"), Mask: net.CIDRMask(17, 32)}).String(),
299 EndpointReconcilerType: string(reconcilers.LeaseEndpointReconcilerType),
300 AllowPrivileged: false,
301 KubeletConfig: kubeletclient.KubeletClientConfig{
302 Port: 10250,
303 ReadOnlyPort: 10255,
304 PreferredAddressTypes: []string{
305 string(kapi.NodeHostName),
306 string(kapi.NodeInternalDNS),
307 string(kapi.NodeInternalIP),
308 string(kapi.NodeExternalDNS),
309 string(kapi.NodeExternalIP),
310 },
311 HTTPTimeout: time.Duration(5) * time.Second,
312 TLSClientConfig: kubeletclient.KubeletTLSConfig{
313 CertFile: "/var/run/kubernetes/ceserver.crt",
314 KeyFile: "/var/run/kubernetes/server.key",
315 CAFile: "/var/run/kubernetes/caserver.crt",
316 },
317 },
318 MasterCount: 5,
319 },
320 CloudProvider: &kubeoptions.CloudProviderOptions{
321 CloudConfigFile: "/cloud-config",
322 CloudProvider: "azure",
323 },
324 }
325
326 expected.Authentication.OIDC.UsernameClaim = "sub"
327 expected.Authentication.OIDC.SigningAlgs = []string{"RS256"}
328
329 if !s.Authorization.AreLegacyFlagsSet() {
330 t.Errorf("expected legacy authorization flags to be set")
331 }
332
333
334 s.Authorization.AreLegacyFlagsSet = nil
335
336 if !reflect.DeepEqual(expected, s) {
337 t.Errorf("Got different run options than expected.\nDifference detected on:\n%s", cmp.Diff(expected, s, cmpopts.IgnoreUnexported(admission.Plugins{}, kubeoptions.OIDCAuthenticationOptions{})))
338 }
339 }
340
View as plain text