Skip to content

Commit 1e2b38a

Browse files
Merge pull request #2148 from njhale/fix/auth
fix(packageserver): add tolerant delegating auth config
2 parents 8118f7d + 59f2187 commit 1e2b38a

File tree

1 file changed

+70
-18
lines changed

1 file changed

+70
-18
lines changed

pkg/package-server/server/server.go

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
log "github.com/sirupsen/logrus"
1111
"github.com/spf13/cobra"
12+
"k8s.io/apimachinery/pkg/util/wait"
1213
genericserver "k8s.io/apiserver/pkg/server"
1314
genericoptions "k8s.io/apiserver/pkg/server/options"
1415
"k8s.io/client-go/informers"
@@ -52,7 +53,6 @@ func NewCommandStartPackageServer(ctx context.Context, defaults *PackageServerOp
5253
}
5354

5455
type PackageServerOptions struct {
55-
// RecommendedOptions *genericoptions.RecommendedOptions
5656
SecureServing *genericoptions.SecureServingOptionsWithLoopback
5757
Authentication *genericoptions.DelegatingAuthenticationOptions
5858
Authorization *genericoptions.DelegatingAuthorizationOptions
@@ -77,7 +77,6 @@ type PackageServerOptions struct {
7777

7878
func NewPackageServerOptions(out, errOut io.Writer) *PackageServerOptions {
7979
o := &PackageServerOptions{
80-
8180
SecureServing: genericoptions.NewSecureServingOptions().WithLoopback(),
8281
Authentication: genericoptions.NewDelegatingAuthenticationOptions(),
8382
Authorization: genericoptions.NewDelegatingAuthorizationOptions(),
@@ -96,29 +95,82 @@ func NewPackageServerOptions(out, errOut io.Writer) *PackageServerOptions {
9695
}
9796

9897
// Config returns config for the PackageServerOptions.
99-
func (o *PackageServerOptions) Config() (*apiserver.Config, error) {
98+
func (o *PackageServerOptions) Config(ctx context.Context) (*apiserver.Config, error) {
10099
if err := o.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
101100
return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
102101
}
103102

104-
serverConfig := genericserver.NewConfig(genericpackageserver.Codecs)
105-
if err := o.SecureServing.ApplyTo(&serverConfig.SecureServing, &serverConfig.LoopbackClientConfig); err != nil {
103+
config := genericserver.NewConfig(genericpackageserver.Codecs)
104+
if err := o.SecureServing.ApplyTo(&config.SecureServing, &config.LoopbackClientConfig); err != nil {
106105
return nil, err
107106
}
108107

109-
if !o.DisableAuthForTesting {
110-
if err := o.Authentication.ApplyTo(&serverConfig.Authentication, serverConfig.SecureServing, nil); err != nil {
111-
return nil, err
108+
serverConfig := &apiserver.Config{
109+
GenericConfig: config,
110+
ProviderConfig: genericpackageserver.ProviderConfig{},
111+
}
112+
113+
if o.DisableAuthForTesting {
114+
return serverConfig, nil
115+
}
116+
117+
// See https://github.com/openshift/library-go/blob/7a65fdb398e28782ee1650959a5e0419121e97ae/pkg/config/serving/server.go#L61-L63 for details on
118+
// the following auth/z config
119+
pollCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
120+
defer cancel()
121+
122+
authenticationOptions := genericoptions.NewDelegatingAuthenticationOptions()
123+
authenticationOptions.RemoteKubeConfigFile = o.Kubeconfig
124+
125+
// The platform generally uses 30s for /metrics scraping, avoid API request for every other /metrics request to the component
126+
authenticationOptions.CacheTTL = 35 * time.Second
127+
128+
// In some cases the API server can return connection refused when getting the "extension-apiserver-authentication" config map
129+
var lastApplyErr error
130+
err := wait.PollImmediateUntil(1*time.Second, func() (done bool, err error) {
131+
lastApplyErr := authenticationOptions.ApplyTo(&config.Authentication, config.SecureServing, config.OpenAPIConfig)
132+
if lastApplyErr != nil {
133+
log.WithError(lastApplyErr).Warn("Error initializing delegating authentication (will retry)")
134+
return false, nil
112135
}
113-
if err := o.Authorization.ApplyTo(&serverConfig.Authorization); err != nil {
114-
return nil, err
136+
return true, nil
137+
}, pollCtx.Done())
138+
139+
if err != nil {
140+
return nil, lastApplyErr
141+
}
142+
143+
if err := o.Authentication.ApplyTo(&config.Authentication, config.SecureServing, nil); err != nil {
144+
return nil, err
145+
}
146+
147+
authorizationOptions := genericoptions.NewDelegatingAuthorizationOptions().
148+
WithAlwaysAllowPaths("/healthz", "/readyz", "/livez"). // This allows the kubelet to always get health and readiness without causing an access check
149+
WithAlwaysAllowGroups("system:masters") // in a kube cluster, system:masters can take any action, so there is no need to ask for an authz check
150+
authenticationOptions.RemoteKubeConfigFile = o.Kubeconfig
151+
152+
// The platform generally uses 30s for /metrics scraping, avoid API request for every other /metrics request to the component
153+
authorizationOptions.AllowCacheTTL = 35 * time.Second
154+
155+
// In some cases the API server can return connection refused when getting the "extension-apiserver-authentication" config map
156+
err = wait.PollImmediateUntil(1*time.Second, func() (done bool, err error) {
157+
lastApplyErr = authorizationOptions.ApplyTo(&config.Authorization)
158+
if lastApplyErr != nil {
159+
log.WithError(lastApplyErr).Warn("Error initializing delegating authorization (will retry)")
160+
return false, nil
115161
}
162+
return true, nil
163+
}, pollCtx.Done())
164+
165+
if err != nil {
166+
return nil, lastApplyErr
116167
}
117168

118-
return &apiserver.Config{
119-
GenericConfig: serverConfig,
120-
ProviderConfig: genericpackageserver.ProviderConfig{},
121-
}, nil
169+
if err := o.Authorization.ApplyTo(&config.Authorization); err != nil {
170+
return nil, err
171+
}
172+
173+
return serverConfig, nil
122174
}
123175

124176
// Run starts a new packageserver for the PackageServerOptions.
@@ -127,14 +179,14 @@ func (o *PackageServerOptions) Run(ctx context.Context) error {
127179
log.SetLevel(log.DebugLevel)
128180
}
129181

130-
// grab the config for the API server
131-
config, err := o.Config()
182+
// Grab the config for the API server
183+
config, err := o.Config(ctx)
132184
if err != nil {
133185
return err
134186
}
135187
config.GenericConfig.EnableMetrics = true
136188

137-
// set up the client config
189+
// Set up the client config
138190
var clientConfig *rest.Config
139191
if len(o.Kubeconfig) > 0 {
140192
loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: o.Kubeconfig}
@@ -169,7 +221,7 @@ func (o *PackageServerOptions) Run(ctx context.Context) error {
169221
}
170222
config.ProviderConfig.Provider = sourceProvider
171223

172-
// we should never need to resync, since we're not worried about missing events,
224+
// We should never need to resync, since we're not worried about missing events,
173225
// and resync is actually for regular interval-based reconciliation these days,
174226
// so set the default resync interval to 0
175227
informerFactory := informers.NewSharedInformerFactory(kubeClient, 0)

0 commit comments

Comments
 (0)