-
Notifications
You must be signed in to change notification settings - Fork 459
/
apiserver.go
162 lines (133 loc) · 7.06 KB
/
apiserver.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
package apiserver
import (
"errors"
"fmt"
"time"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/util/sets"
genericapiserver "k8s.io/apiserver/pkg/server"
kubeinformers "k8s.io/client-go/informers"
corerest "github.com/gardener/gardener/pkg/apiserver/registry/core/rest"
operationsrest "github.com/gardener/gardener/pkg/apiserver/registry/operations/rest"
securityrest "github.com/gardener/gardener/pkg/apiserver/registry/security/rest"
seedmanagementrest "github.com/gardener/gardener/pkg/apiserver/registry/seedmanagement/rest"
settingsrest "github.com/gardener/gardener/pkg/apiserver/registry/settings/rest"
gardencoreinformers "github.com/gardener/gardener/pkg/client/core/informers/externalversions"
"github.com/gardener/gardener/pkg/logger"
)
// ExtraConfig contains non-generic Gardener API server configuration.
type ExtraConfig struct {
AdminKubeconfigMaxExpiration time.Duration
ViewerKubeconfigMaxExpiration time.Duration
CredentialsRotationInterval time.Duration
}
// Config contains Gardener API server configuration.
type Config struct {
GenericConfig *genericapiserver.RecommendedConfig
ExtraConfig ExtraConfig
KubeInformerFactory kubeinformers.SharedInformerFactory
CoreInformerFactory gardencoreinformers.SharedInformerFactory
}
// GardenerServer contains state for a Gardener API server.
type GardenerServer struct {
GenericAPIServer *genericapiserver.GenericAPIServer
}
type completedConfig struct {
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
kubeInformerFactory kubeinformers.SharedInformerFactory
coreInformerFactory gardencoreinformers.SharedInformerFactory
}
// CompletedConfig contains completed Gardener API server configuration.
type CompletedConfig struct {
*completedConfig
}
// Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
func (cfg *Config) Complete() CompletedConfig {
c := completedConfig{
cfg.GenericConfig.Complete(),
&cfg.ExtraConfig,
cfg.KubeInformerFactory,
cfg.CoreInformerFactory,
}
return CompletedConfig{&c}
}
// New returns a new instance of GardenerServer from the given config.
func (c completedConfig) New() (*GardenerServer, error) {
genericServer, err := c.GenericConfig.New("gardener-apiserver", genericapiserver.NewEmptyDelegate())
if err != nil {
return nil, err
}
var (
s = &GardenerServer{GenericAPIServer: genericServer}
coreAPIGroupInfo = (corerest.StorageProvider{
AdminKubeconfigMaxExpiration: c.ExtraConfig.AdminKubeconfigMaxExpiration,
ViewerKubeconfigMaxExpiration: c.ExtraConfig.ViewerKubeconfigMaxExpiration,
CredentialsRotationInterval: c.ExtraConfig.CredentialsRotationInterval,
KubeInformerFactory: c.kubeInformerFactory,
CoreInformerFactory: c.coreInformerFactory,
}).NewRESTStorage(c.GenericConfig.RESTOptionsGetter)
seedManagementAPIGroupInfo = (seedmanagementrest.StorageProvider{}).NewRESTStorage(c.GenericConfig.RESTOptionsGetter)
settingsAPIGroupInfo = (settingsrest.StorageProvider{}).NewRESTStorage(c.GenericConfig.RESTOptionsGetter)
operationsAPIGroupInfo = (operationsrest.StorageProvider{}).NewRESTStorage(c.GenericConfig.RESTOptionsGetter)
securityAPIGroupInfo = (securityrest.StorageProvider{}).NewRESTStorage(c.GenericConfig.RESTOptionsGetter)
)
if err := s.GenericAPIServer.InstallAPIGroups(&coreAPIGroupInfo, &settingsAPIGroupInfo, &seedManagementAPIGroupInfo, &operationsAPIGroupInfo, &securityAPIGroupInfo); err != nil {
return nil, err
}
return s, nil
}
// ExtraOptions is used for providing additional options to the Gardener API Server
type ExtraOptions struct {
ClusterIdentity string
AdminKubeconfigMaxExpiration time.Duration
ViewerKubeconfigMaxExpiration time.Duration
CredentialsRotationInterval time.Duration
LogLevel string
LogFormat string
}
// Validate checks if the required flags are set
func (o *ExtraOptions) Validate() []error {
allErrors := []error{}
if len(o.ClusterIdentity) == 0 {
allErrors = append(allErrors, errors.New("--cluster-identity must be specified"))
}
if o.AdminKubeconfigMaxExpiration < time.Hour ||
o.AdminKubeconfigMaxExpiration > time.Duration(1<<32)*time.Second {
allErrors = append(allErrors, errors.New("--shoot-admin-kubeconfig-max-expiration must be between 1 hour and 2^32 seconds"))
}
if o.ViewerKubeconfigMaxExpiration < time.Hour ||
o.ViewerKubeconfigMaxExpiration > time.Duration(1<<32)*time.Second {
allErrors = append(allErrors, errors.New("--shoot-viewer-kubeconfig-max-expiration must be between 1 hour and 2^32 seconds"))
}
if o.CredentialsRotationInterval < 24*time.Hour ||
o.CredentialsRotationInterval > time.Duration(1<<32)*time.Second {
allErrors = append(allErrors, errors.New("--shoot-credentials-rotation-interval must be between 24 hours and 2^32 seconds"))
}
if !sets.New(logger.AllLogLevels...).Has(o.LogLevel) {
allErrors = append(allErrors, fmt.Errorf("invalid --log-level: %s", o.LogLevel))
}
if !sets.New(logger.AllLogFormats...).Has(o.LogFormat) {
allErrors = append(allErrors, fmt.Errorf("invalid --log-format: %s", o.LogFormat))
}
return allErrors
}
// AddFlags adds flags related to cluster identity to the options
func (o *ExtraOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&o.ClusterIdentity, "cluster-identity", o.ClusterIdentity, "This flag is used for specifying the identity of the Garden cluster")
fs.DurationVar(&o.AdminKubeconfigMaxExpiration, "shoot-admin-kubeconfig-max-expiration", time.Hour*24, "The maximum validity duration of a credential requested to a Shoot by an AdminKubeconfigRequest. If an otherwise valid AdminKubeconfigRequest with a validity duration larger than this value is requested, a credential will be issued with a validity duration of this value.")
fs.DurationVar(&o.ViewerKubeconfigMaxExpiration, "shoot-viewer-kubeconfig-max-expiration", time.Hour*24, "The maximum validity duration of a credential requested to a Shoot by an ViewerKubeconfigRequest. If an otherwise valid ViewerKubeconfigRequest with a validity duration larger than this value is requested, a credential will be issued with a validity duration of this value.")
fs.DurationVar(&o.CredentialsRotationInterval, "shoot-credentials-rotation-interval", time.Hour*24*90, "The duration after the initial shoot creation or the last credentials rotation when a client warning for the next credentials rotation is issued.")
fs.StringVar(&o.LogLevel, "log-level", "info", "The level/severity for the logs. Must be one of [info,debug,error]")
fs.StringVar(&o.LogFormat, "log-format", "json", "The format for the logs. Must be one of [json,text]")
}
// ApplyTo applies the extra options to the API Server config.
func (o *ExtraOptions) ApplyTo(c *Config) error {
c.ExtraConfig.AdminKubeconfigMaxExpiration = o.AdminKubeconfigMaxExpiration
c.ExtraConfig.ViewerKubeconfigMaxExpiration = o.ViewerKubeconfigMaxExpiration
c.ExtraConfig.CredentialsRotationInterval = o.CredentialsRotationInterval
return nil
}