mirror of https://github.com/k3s-io/k3s
Merge pull request #59492 from dims/remove-old-keystone-authenticator
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.
Remove experimental keystone authenticator
**What this PR does / why we need it**:
experimental-keystone-url and experimental-keystone-ca-file were always
experimental. So we don't need a deprecation period.
KeystoneAuthenticator was on the server side and needed userid/password
to be passed in and used that to authenticate with Keystone. We now
have authentication and authorization web hooks that can be used. There
is a external repo with a webook for keystone which works fine along
with the kubectl auth provider that was added in:
a0cebcb559
So we don't need this older style / hard coded / experimental code
anymore.
**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #
**Special notes for your reviewer**:
**Release note**:
```release-note
kube-apiserver: the experimental in-tree Keystone password authenticator has been removed in favor of extensions that enable use of Keystone tokens.
```
pull/6/head
commit
2a8049890a
|
@ -208,7 +208,6 @@ func TestAddFlags(t *testing.T) {
|
|||
ConfigFile: "/token-webhook-config",
|
||||
},
|
||||
BootstrapToken: &kubeoptions.BootstrapTokenAuthenticationOptions{},
|
||||
Keystone: &kubeoptions.KeystoneAuthenticationOptions{},
|
||||
OIDC: &kubeoptions.OIDCAuthenticationOptions{
|
||||
UsernameClaim: "sub",
|
||||
},
|
||||
|
|
|
@ -602,7 +602,6 @@ staging/src/k8s.io/apiserver/pkg/util/trace
|
|||
staging/src/k8s.io/apiserver/pkg/util/webhook
|
||||
staging/src/k8s.io/apiserver/pkg/util/wsstream
|
||||
staging/src/k8s.io/apiserver/plugin/pkg/audit/log
|
||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone
|
||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile
|
||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
|
||||
staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/testing
|
||||
|
|
|
@ -24,7 +24,6 @@ go_library(
|
|||
"//vendor/k8s.io/apiserver/pkg/authentication/token/cache:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
||||
|
|
|
@ -33,7 +33,6 @@ import (
|
|||
tokencache "k8s.io/apiserver/pkg/authentication/token/cache"
|
||||
"k8s.io/apiserver/pkg/authentication/token/tokenfile"
|
||||
tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/keystone"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
|
||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
||||
|
@ -61,8 +60,6 @@ type AuthenticatorConfig struct {
|
|||
OIDCGroupsPrefix string
|
||||
ServiceAccountKeyFiles []string
|
||||
ServiceAccountLookup bool
|
||||
KeystoneURL string
|
||||
KeystoneCAFile string
|
||||
WebhookTokenAuthnConfigFile string
|
||||
WebhookTokenAuthnCacheTTL time.Duration
|
||||
|
||||
|
@ -108,14 +105,6 @@ func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDe
|
|||
authenticators = append(authenticators, basicAuth)
|
||||
hasBasicAuth = true
|
||||
}
|
||||
if len(config.KeystoneURL) > 0 {
|
||||
keystoneAuth, err := newAuthenticatorFromKeystoneURL(config.KeystoneURL, config.KeystoneCAFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authenticators = append(authenticators, keystoneAuth)
|
||||
hasBasicAuth = true
|
||||
}
|
||||
|
||||
// X509 methods
|
||||
if len(config.ClientCAFile) > 0 {
|
||||
|
@ -306,16 +295,6 @@ func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Reques
|
|||
return x509.New(opts, x509.CommonNameUserConversion), nil
|
||||
}
|
||||
|
||||
// newAuthenticatorFromKeystoneURL returns an authenticator.Request or an error
|
||||
func newAuthenticatorFromKeystoneURL(keystoneURL string, keystoneCAFile string) (authenticator.Request, error) {
|
||||
keystoneAuthenticator, err := keystone.NewKeystoneAuthenticator(keystoneURL, keystoneCAFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return basicauth.New(keystoneAuthenticator), nil
|
||||
}
|
||||
|
||||
func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Token, error) {
|
||||
webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, ttl)
|
||||
if err != nil {
|
||||
|
|
|
@ -34,7 +34,6 @@ type BuiltInAuthenticationOptions struct {
|
|||
Anonymous *AnonymousAuthenticationOptions
|
||||
BootstrapToken *BootstrapTokenAuthenticationOptions
|
||||
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
||||
Keystone *KeystoneAuthenticationOptions
|
||||
OIDC *OIDCAuthenticationOptions
|
||||
PasswordFile *PasswordFileAuthenticationOptions
|
||||
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
|
||||
|
@ -54,11 +53,6 @@ type BootstrapTokenAuthenticationOptions struct {
|
|||
Enable bool
|
||||
}
|
||||
|
||||
type KeystoneAuthenticationOptions struct {
|
||||
URL string
|
||||
CAFile string
|
||||
}
|
||||
|
||||
type OIDCAuthenticationOptions struct {
|
||||
CAFile string
|
||||
ClientID string
|
||||
|
@ -99,7 +93,6 @@ func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
|
|||
WithAnonymous().
|
||||
WithBootstrapToken().
|
||||
WithClientCert().
|
||||
WithKeystone().
|
||||
WithOIDC().
|
||||
WithPasswordFile().
|
||||
WithRequestHeader().
|
||||
|
@ -123,11 +116,6 @@ func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOp
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithKeystone() *BuiltInAuthenticationOptions {
|
||||
s.Keystone = &KeystoneAuthenticationOptions{}
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions {
|
||||
s.OIDC = &OIDCAuthenticationOptions{}
|
||||
return s
|
||||
|
@ -189,15 +177,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
|||
s.ClientCert.AddFlags(fs)
|
||||
}
|
||||
|
||||
if s.Keystone != nil {
|
||||
fs.StringVar(&s.Keystone.URL, "experimental-keystone-url", s.Keystone.URL,
|
||||
"If passed, activates the keystone authentication plugin.")
|
||||
|
||||
fs.StringVar(&s.Keystone.CAFile, "experimental-keystone-ca-file", s.Keystone.CAFile, ""+
|
||||
"If set, the Keystone server's certificate will be verified by one of the authorities "+
|
||||
"in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.")
|
||||
}
|
||||
|
||||
if s.OIDC != nil {
|
||||
fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+
|
||||
"The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+
|
||||
|
@ -285,11 +264,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.Au
|
|||
ret.ClientCAFile = s.ClientCert.ClientCA
|
||||
}
|
||||
|
||||
if s.Keystone != nil {
|
||||
ret.KeystoneURL = s.Keystone.URL
|
||||
ret.KeystoneCAFile = s.Keystone.CAFile
|
||||
}
|
||||
|
||||
if s.OIDC != nil {
|
||||
ret.OIDCCAFile = s.OIDC.CAFile
|
||||
ret.OIDCClientID = s.OIDC.ClientID
|
||||
|
|
|
@ -490,34 +490,6 @@
|
|||
"ImportPath": "github.com/googleapis/gnostic/extensions",
|
||||
"Rev": "0c5108395e2debce0d731cf0287ddf7242066aba"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tenants",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/openstack/utils",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gophercloud/gophercloud/pagination",
|
||||
"Rev": "8e59687aa4b27ab22a0bf3295f1e165ff7bd5f97"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/grpc-ecosystem/go-grpc-prometheus",
|
||||
"Rev": "2500245aa6110c562d17020fb31a2c133d737799"
|
||||
|
|
|
@ -23,7 +23,6 @@ filegroup(
|
|||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/allow:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/keystone:all-srcs",
|
||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"keystone.go",
|
||||
],
|
||||
importpath = "k8s.io/apiserver/plugin/pkg/authenticator/password/keystone",
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud:go_default_library",
|
||||
"//vendor/github.com/gophercloud/gophercloud/openstack:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package keystone provides authentication via keystone.
|
||||
// For details about keystone and how to use the plugin, refer to
|
||||
// https://github.com/kubernetes/kubernetes.github.io/blob/master/docs/admin/authentication.md
|
||||
package keystone // import "k8s.io/apiserver/plugin/pkg/authenticator/password/keystone"
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package keystone
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack"
|
||||
|
||||
netutil "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
certutil "k8s.io/client-go/util/cert"
|
||||
)
|
||||
|
||||
// KeystoneAuthenticator contacts openstack keystone to validate user's credentials passed in the request.
|
||||
// The keystone endpoint is passed during apiserver startup
|
||||
type KeystoneAuthenticator struct {
|
||||
authURL string
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
// AuthenticatePassword checks the username, password via keystone call
|
||||
func (keystoneAuthenticator *KeystoneAuthenticator) AuthenticatePassword(username string, password string) (user.Info, bool, error) {
|
||||
opts := gophercloud.AuthOptions{
|
||||
IdentityEndpoint: keystoneAuthenticator.authURL,
|
||||
Username: username,
|
||||
Password: password,
|
||||
}
|
||||
|
||||
_, err := keystoneAuthenticator.AuthenticatedClient(opts)
|
||||
if err != nil {
|
||||
glog.Info("Failed: Starting openstack authenticate client:" + err.Error())
|
||||
return nil, false, errors.New("Failed to authenticate")
|
||||
}
|
||||
|
||||
return &user.DefaultInfo{Name: username}, true, nil
|
||||
}
|
||||
|
||||
// AuthenticatedClient logs in to an OpenStack cloud found at the identity endpoint specified by options, acquires a
|
||||
// token, and returns a Client instance that's ready to operate.
|
||||
func (keystoneAuthenticator *KeystoneAuthenticator) AuthenticatedClient(options gophercloud.AuthOptions) (*gophercloud.ProviderClient, error) {
|
||||
client, err := openstack.NewClient(options.IdentityEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if keystoneAuthenticator.transport != nil {
|
||||
client.HTTPClient.Transport = keystoneAuthenticator.transport
|
||||
}
|
||||
|
||||
err = openstack.Authenticate(client, options)
|
||||
return client, err
|
||||
}
|
||||
|
||||
// NewKeystoneAuthenticator returns a password authenticator that validates credentials using openstack keystone
|
||||
func NewKeystoneAuthenticator(authURL string, caFile string) (*KeystoneAuthenticator, error) {
|
||||
if !strings.HasPrefix(authURL, "https") {
|
||||
return nil, errors.New("Auth URL should be secure and start with https")
|
||||
}
|
||||
if authURL == "" {
|
||||
return nil, errors.New("Auth URL is empty")
|
||||
}
|
||||
if caFile != "" {
|
||||
roots, err := certutil.NewPool(caFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config := &tls.Config{}
|
||||
config.RootCAs = roots
|
||||
transport := netutil.SetOldTransportDefaults(&http.Transport{TLSClientConfig: config})
|
||||
return &KeystoneAuthenticator{authURL, transport}, nil
|
||||
}
|
||||
|
||||
return &KeystoneAuthenticator{authURL: authURL}, nil
|
||||
}
|
Loading…
Reference in New Issue