Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
aa1ed3d1
Commit
aa1ed3d1
authored
Oct 08, 2018
by
Darren Shepherd
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Delete bootstrap token
parent
bc0214a0
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1 addition
and
673 deletions
+1
-673
server.go
cmd/kube-apiserver/app/server.go
+1
-5
config.go
pkg/kubeapiserver/authenticator/config.go
+0
-8
authentication.go
pkg/kubeapiserver/options/authentication.go
+0
-21
BUILD
plugin/pkg/auth/authenticator/token/bootstrap/BUILD
+0
-52
bootstrap.go
plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go
+0
-228
bootstrap_test.go
.../pkg/auth/authenticator/token/bootstrap/bootstrap_test.go
+0
-359
No files found.
cmd/kube-apiserver/app/server.go
View file @
aa1ed3d1
...
@@ -32,7 +32,6 @@ import (
...
@@ -32,7 +32,6 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra"
v1
"k8s.io/apimachinery/pkg/apis/meta/v1"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
utilnet
"k8s.io/apimachinery/pkg/util/net"
utilnet
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
...
@@ -69,12 +68,12 @@ import (
...
@@ -69,12 +68,12 @@ import (
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/cachesize"
rbacrest
"k8s.io/kubernetes/pkg/registry/rbac/rest"
rbacrest
"k8s.io/kubernetes/pkg/registry/rbac/rest"
"k8s.io/kubernetes/pkg/serviceaccount"
"k8s.io/kubernetes/pkg/serviceaccount"
utilflag
"k8s.io/kubernetes/pkg/util/flag"
utilflag
"k8s.io/kubernetes/pkg/util/flag"
_
"k8s.io/kubernetes/pkg/util/reflector/prometheus"
// for reflector metric registration
_
"k8s.io/kubernetes/pkg/util/reflector/prometheus"
// for reflector metric registration
_
"k8s.io/kubernetes/pkg/util/workqueue/prometheus"
// for workqueue metric registration
_
"k8s.io/kubernetes/pkg/util/workqueue/prometheus"
// for workqueue metric registration
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version/verflag"
"k8s.io/kubernetes/pkg/version/verflag"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap"
)
)
const
etcdRetryLimit
=
60
const
etcdRetryLimit
=
60
...
@@ -455,9 +454,6 @@ func BuildAuthenticator(s *options.ServerRunOptions, extclient clientgoclientset
...
@@ -455,9 +454,6 @@ func BuildAuthenticator(s *options.ServerRunOptions, extclient clientgoclientset
versionedInformer
.
Core
()
.
V1
()
.
Pods
()
.
Lister
(),
versionedInformer
.
Core
()
.
V1
()
.
Pods
()
.
Lister
(),
)
)
}
}
authenticatorConfig
.
BootstrapTokenAuthenticator
=
bootstrap
.
NewTokenAuthenticator
(
versionedInformer
.
Core
()
.
V1
()
.
Secrets
()
.
Lister
()
.
Secrets
(
v1
.
NamespaceSystem
),
)
return
authenticatorConfig
.
New
()
return
authenticatorConfig
.
New
()
}
}
...
...
pkg/kubeapiserver/authenticator/config.go
View file @
aa1ed3d1
...
@@ -49,7 +49,6 @@ import (
...
@@ -49,7 +49,6 @@ import (
type
Config
struct
{
type
Config
struct
{
Anonymous
bool
Anonymous
bool
BasicAuthFile
string
BasicAuthFile
string
BootstrapToken
bool
ClientCAFile
string
ClientCAFile
string
TokenAuthFile
string
TokenAuthFile
string
OIDCIssuerURL
string
OIDCIssuerURL
string
...
@@ -75,7 +74,6 @@ type Config struct {
...
@@ -75,7 +74,6 @@ type Config struct {
// TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig
// TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig
ServiceAccountTokenGetter
serviceaccount
.
ServiceAccountTokenGetter
ServiceAccountTokenGetter
serviceaccount
.
ServiceAccountTokenGetter
BootstrapTokenAuthenticator
authenticator
.
Token
}
}
// New returns an authenticator.Request or an error that supports the standard
// New returns an authenticator.Request or an error that supports the standard
...
@@ -140,12 +138,6 @@ func (config Config) New() (authenticator.Request, error) {
...
@@ -140,12 +138,6 @@ func (config Config) New() (authenticator.Request, error) {
}
}
tokenAuthenticators
=
append
(
tokenAuthenticators
,
serviceAccountAuth
)
tokenAuthenticators
=
append
(
tokenAuthenticators
,
serviceAccountAuth
)
}
}
if
config
.
BootstrapToken
{
if
config
.
BootstrapTokenAuthenticator
!=
nil
{
// TODO: This can sometimes be nil because of
tokenAuthenticators
=
append
(
tokenAuthenticators
,
authenticator
.
WrapAudienceAgnosticToken
(
config
.
APIAudiences
,
config
.
BootstrapTokenAuthenticator
))
}
}
// NOTE(ericchiang): Keep the OpenID Connect after Service Accounts.
// NOTE(ericchiang): Keep the OpenID Connect after Service Accounts.
//
//
// Because both plugins verify JWTs whichever comes first in the union experiences
// Because both plugins verify JWTs whichever comes first in the union experiences
...
...
pkg/kubeapiserver/options/authentication.go
View file @
aa1ed3d1
...
@@ -37,7 +37,6 @@ import (
...
@@ -37,7 +37,6 @@ import (
type
BuiltInAuthenticationOptions
struct
{
type
BuiltInAuthenticationOptions
struct
{
APIAudiences
[]
string
APIAudiences
[]
string
Anonymous
*
AnonymousAuthenticationOptions
Anonymous
*
AnonymousAuthenticationOptions
BootstrapToken
*
BootstrapTokenAuthenticationOptions
ClientCert
*
genericoptions
.
ClientCertAuthenticationOptions
ClientCert
*
genericoptions
.
ClientCertAuthenticationOptions
OIDC
*
OIDCAuthenticationOptions
OIDC
*
OIDCAuthenticationOptions
PasswordFile
*
PasswordFileAuthenticationOptions
PasswordFile
*
PasswordFileAuthenticationOptions
...
@@ -54,10 +53,6 @@ type AnonymousAuthenticationOptions struct {
...
@@ -54,10 +53,6 @@ type AnonymousAuthenticationOptions struct {
Allow
bool
Allow
bool
}
}
type
BootstrapTokenAuthenticationOptions
struct
{
Enable
bool
}
type
OIDCAuthenticationOptions
struct
{
type
OIDCAuthenticationOptions
struct
{
CAFile
string
CAFile
string
ClientID
string
ClientID
string
...
@@ -100,7 +95,6 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
...
@@ -100,7 +95,6 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
func
(
s
*
BuiltInAuthenticationOptions
)
WithAll
()
*
BuiltInAuthenticationOptions
{
func
(
s
*
BuiltInAuthenticationOptions
)
WithAll
()
*
BuiltInAuthenticationOptions
{
return
s
.
return
s
.
WithAnonymous
()
.
WithAnonymous
()
.
WithBootstrapToken
()
.
WithClientCert
()
.
WithClientCert
()
.
WithOIDC
()
.
WithOIDC
()
.
WithPasswordFile
()
.
WithPasswordFile
()
.
...
@@ -115,11 +109,6 @@ func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOpt
...
@@ -115,11 +109,6 @@ func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOpt
return
s
return
s
}
}
func
(
s
*
BuiltInAuthenticationOptions
)
WithBootstrapToken
()
*
BuiltInAuthenticationOptions
{
s
.
BootstrapToken
=
&
BootstrapTokenAuthenticationOptions
{}
return
s
}
func
(
s
*
BuiltInAuthenticationOptions
)
WithClientCert
()
*
BuiltInAuthenticationOptions
{
func
(
s
*
BuiltInAuthenticationOptions
)
WithClientCert
()
*
BuiltInAuthenticationOptions
{
s
.
ClientCert
=
&
genericoptions
.
ClientCertAuthenticationOptions
{}
s
.
ClientCert
=
&
genericoptions
.
ClientCertAuthenticationOptions
{}
return
s
return
s
...
@@ -188,12 +177,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
...
@@ -188,12 +177,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated."
)
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated."
)
}
}
if
s
.
BootstrapToken
!=
nil
{
fs
.
BoolVar
(
&
s
.
BootstrapToken
.
Enable
,
"enable-bootstrap-token-auth"
,
s
.
BootstrapToken
.
Enable
,
""
+
"Enable to allow secrets of type 'bootstrap.kubernetes.io/token' in the 'kube-system' "
+
"namespace to be used for TLS bootstrapping authentication."
)
}
if
s
.
ClientCert
!=
nil
{
if
s
.
ClientCert
!=
nil
{
s
.
ClientCert
.
AddFlags
(
fs
)
s
.
ClientCert
.
AddFlags
(
fs
)
}
}
...
@@ -302,10 +285,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticato
...
@@ -302,10 +285,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticato
ret
.
Anonymous
=
s
.
Anonymous
.
Allow
ret
.
Anonymous
=
s
.
Anonymous
.
Allow
}
}
if
s
.
BootstrapToken
!=
nil
{
ret
.
BootstrapToken
=
s
.
BootstrapToken
.
Enable
}
if
s
.
ClientCert
!=
nil
{
if
s
.
ClientCert
!=
nil
{
ret
.
ClientCAFile
=
s
.
ClientCert
.
ClientCA
ret
.
ClientCAFile
=
s
.
ClientCert
.
ClientCA
}
}
...
...
plugin/pkg/auth/authenticator/token/bootstrap/BUILD
deleted
100644 → 0
View file @
bc0214a0
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = ["bootstrap_test.go"],
embed = [":go_default_library"],
deps = [
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["bootstrap.go"],
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/bootstrap",
deps = [
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/cluster-bootstrap/token/api:go_default_library",
"//staging/src/k8s.io/cluster-bootstrap/token/util:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
plugin/pkg/auth/authenticator/token/bootstrap/bootstrap.go
deleted
100644 → 0
View file @
bc0214a0
/*
Copyright 2017 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 bootstrap provides a token authenticator for TLS bootstrap secrets.
*/
package
bootstrap
import
(
"context"
"crypto/subtle"
"fmt"
"regexp"
"strings"
"time"
"k8s.io/klog"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/user"
corev1listers
"k8s.io/client-go/listers/core/v1"
bootstrapapi
"k8s.io/cluster-bootstrap/token/api"
bootstraputil
"k8s.io/cluster-bootstrap/token/util"
)
// TODO: A few methods in this package is copied from other sources. Either
// because the existing functionality isn't exported or because it is in a
// package that shouldn't be directly imported by this packages.
// NewTokenAuthenticator initializes a bootstrap token authenticator.
//
// Lister is expected to be for the "kube-system" namespace.
func
NewTokenAuthenticator
(
lister
corev1listers
.
SecretNamespaceLister
)
*
TokenAuthenticator
{
return
&
TokenAuthenticator
{
lister
}
}
// TokenAuthenticator authenticates bootstrap tokens from secrets in the API server.
type
TokenAuthenticator
struct
{
lister
corev1listers
.
SecretNamespaceLister
}
// tokenErrorf prints a error message for a secret that has matched a bearer
// token but fails to meet some other criteria.
//
// tokenErrorf(secret, "has invalid value for key %s", key)
//
func
tokenErrorf
(
s
*
corev1
.
Secret
,
format
string
,
i
...
interface
{})
{
format
=
fmt
.
Sprintf
(
"Bootstrap secret %s/%s matching bearer token "
,
s
.
Namespace
,
s
.
Name
)
+
format
klog
.
V
(
3
)
.
Infof
(
format
,
i
...
)
}
// AuthenticateToken tries to match the provided token to a bootstrap token secret
// in a given namespace. If found, it authenticates the token in the
// "system:bootstrappers" group and with the "system:bootstrap:(token-id)" username.
//
// All secrets must be of type "bootstrap.kubernetes.io/token". An example secret:
//
// apiVersion: v1
// kind: Secret
// metadata:
// # Name MUST be of form "bootstrap-token-( token id )".
// name: bootstrap-token-( token id )
// namespace: kube-system
// # Only secrets of this type will be evaluated.
// type: bootstrap.kubernetes.io/token
// data:
// token-secret: ( private part of token )
// token-id: ( token id )
// # Required key usage.
// usage-bootstrap-authentication: true
// auth-extra-groups: "system:bootstrappers:custom-group1,system:bootstrappers:custom-group2"
// # May also contain an expiry.
//
// Tokens are expected to be of the form:
//
// ( token-id ).( token-secret )
//
func
(
t
*
TokenAuthenticator
)
AuthenticateToken
(
ctx
context
.
Context
,
token
string
)
(
*
authenticator
.
Response
,
bool
,
error
)
{
tokenID
,
tokenSecret
,
err
:=
parseToken
(
token
)
if
err
!=
nil
{
// Token isn't of the correct form, ignore it.
return
nil
,
false
,
nil
}
secretName
:=
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
secret
,
err
:=
t
.
lister
.
Get
(
secretName
)
if
err
!=
nil
{
if
errors
.
IsNotFound
(
err
)
{
klog
.
V
(
3
)
.
Infof
(
"No secret of name %s to match bootstrap bearer token"
,
secretName
)
return
nil
,
false
,
nil
}
return
nil
,
false
,
err
}
if
secret
.
DeletionTimestamp
!=
nil
{
tokenErrorf
(
secret
,
"is deleted and awaiting removal"
)
return
nil
,
false
,
nil
}
if
string
(
secret
.
Type
)
!=
string
(
bootstrapapi
.
SecretTypeBootstrapToken
)
||
secret
.
Data
==
nil
{
tokenErrorf
(
secret
,
"has invalid type, expected %s."
,
bootstrapapi
.
SecretTypeBootstrapToken
)
return
nil
,
false
,
nil
}
ts
:=
getSecretString
(
secret
,
bootstrapapi
.
BootstrapTokenSecretKey
)
if
subtle
.
ConstantTimeCompare
([]
byte
(
ts
),
[]
byte
(
tokenSecret
))
!=
1
{
tokenErrorf
(
secret
,
"has invalid value for key %s, expected %s."
,
bootstrapapi
.
BootstrapTokenSecretKey
,
tokenSecret
)
return
nil
,
false
,
nil
}
id
:=
getSecretString
(
secret
,
bootstrapapi
.
BootstrapTokenIDKey
)
if
id
!=
tokenID
{
tokenErrorf
(
secret
,
"has invalid value for key %s, expected %s."
,
bootstrapapi
.
BootstrapTokenIDKey
,
tokenID
)
return
nil
,
false
,
nil
}
if
isSecretExpired
(
secret
)
{
// logging done in isSecretExpired method.
return
nil
,
false
,
nil
}
if
getSecretString
(
secret
,
bootstrapapi
.
BootstrapTokenUsageAuthentication
)
!=
"true"
{
tokenErrorf
(
secret
,
"not marked %s=true."
,
bootstrapapi
.
BootstrapTokenUsageAuthentication
)
return
nil
,
false
,
nil
}
groups
,
err
:=
getGroups
(
secret
)
if
err
!=
nil
{
tokenErrorf
(
secret
,
"has invalid value for key %s: %v."
,
bootstrapapi
.
BootstrapTokenExtraGroupsKey
,
err
)
return
nil
,
false
,
nil
}
return
&
authenticator
.
Response
{
User
:
&
user
.
DefaultInfo
{
Name
:
bootstrapapi
.
BootstrapUserPrefix
+
string
(
id
),
Groups
:
groups
,
},
},
true
,
nil
}
// Copied from k8s.io/cluster-bootstrap/token/api
func
getSecretString
(
secret
*
corev1
.
Secret
,
key
string
)
string
{
data
,
ok
:=
secret
.
Data
[
key
]
if
!
ok
{
return
""
}
return
string
(
data
)
}
// Copied from k8s.io/cluster-bootstrap/token/api
func
isSecretExpired
(
secret
*
corev1
.
Secret
)
bool
{
expiration
:=
getSecretString
(
secret
,
bootstrapapi
.
BootstrapTokenExpirationKey
)
if
len
(
expiration
)
>
0
{
expTime
,
err2
:=
time
.
Parse
(
time
.
RFC3339
,
expiration
)
if
err2
!=
nil
{
klog
.
V
(
3
)
.
Infof
(
"Unparseable expiration time (%s) in %s/%s Secret: %v. Treating as expired."
,
expiration
,
secret
.
Namespace
,
secret
.
Name
,
err2
)
return
true
}
if
time
.
Now
()
.
After
(
expTime
)
{
klog
.
V
(
3
)
.
Infof
(
"Expired bootstrap token in %s/%s Secret: %v"
,
secret
.
Namespace
,
secret
.
Name
,
expiration
)
return
true
}
}
return
false
}
// Copied from kubernetes/cmd/kubeadm/app/util/token
var
(
// tokenRegexpString defines id.secret regular expression pattern
tokenRegexpString
=
"^([a-z0-9]{6})
\\
.([a-z0-9]{16})$"
// tokenRegexp is a compiled regular expression of TokenRegexpString
tokenRegexp
=
regexp
.
MustCompile
(
tokenRegexpString
)
)
// parseToken tries and parse a valid token from a string.
// A token ID and token secret are returned in case of success, an error otherwise.
func
parseToken
(
s
string
)
(
string
,
string
,
error
)
{
split
:=
tokenRegexp
.
FindStringSubmatch
(
s
)
if
len
(
split
)
!=
3
{
return
""
,
""
,
fmt
.
Errorf
(
"token [%q] was not of form [%q]"
,
s
,
tokenRegexpString
)
}
return
split
[
1
],
split
[
2
],
nil
}
// getGroups loads and validates the bootstrapapi.BootstrapTokenExtraGroupsKey
// key from the bootstrap token secret, returning a list of group names or an
// error if any of the group names are invalid.
func
getGroups
(
secret
*
corev1
.
Secret
)
([]
string
,
error
)
{
// always include the default group
groups
:=
sets
.
NewString
(
bootstrapapi
.
BootstrapDefaultGroup
)
// grab any extra groups and if there are none, return just the default
extraGroupsString
:=
getSecretString
(
secret
,
bootstrapapi
.
BootstrapTokenExtraGroupsKey
)
if
extraGroupsString
==
""
{
return
groups
.
List
(),
nil
}
// validate the names of the extra groups
for
_
,
group
:=
range
strings
.
Split
(
extraGroupsString
,
","
)
{
if
err
:=
bootstraputil
.
ValidateBootstrapGroupName
(
group
);
err
!=
nil
{
return
nil
,
err
}
groups
.
Insert
(
group
)
}
// return the result as a deduplicated, sorted list
return
groups
.
List
(),
nil
}
plugin/pkg/auth/authenticator/token/bootstrap/bootstrap_test.go
deleted
100644 → 0
View file @
bc0214a0
/*
Copyright 2017 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
bootstrap
import
(
"context"
"reflect"
"testing"
corev1
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authentication/user"
bootstrapapi
"k8s.io/cluster-bootstrap/token/api"
)
type
lister
struct
{
secrets
[]
*
corev1
.
Secret
}
func
(
l
*
lister
)
List
(
selector
labels
.
Selector
)
(
ret
[]
*
corev1
.
Secret
,
err
error
)
{
return
l
.
secrets
,
nil
}
func
(
l
*
lister
)
Get
(
name
string
)
(
*
corev1
.
Secret
,
error
)
{
for
_
,
s
:=
range
l
.
secrets
{
if
s
.
Name
==
name
{
return
s
,
nil
}
}
return
nil
,
errors
.
NewNotFound
(
schema
.
GroupResource
{},
name
)
}
const
(
tokenID
=
"foobar"
// 6 letters
tokenSecret
=
"circumnavigation"
// 16 letters
)
func
TestTokenAuthenticator
(
t
*
testing
.
T
)
{
now
:=
metav1
.
Now
()
tests
:=
[]
struct
{
name
string
secrets
[]
*
corev1
.
Secret
token
string
wantNotFound
bool
wantUser
*
user
.
DefaultInfo
}{
{
name
:
"valid token"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantUser
:
&
user
.
DefaultInfo
{
Name
:
"system:bootstrap:"
+
tokenID
,
Groups
:
[]
string
{
"system:bootstrappers"
},
},
},
{
name
:
"valid token with extra group"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
bootstrapapi
.
BootstrapTokenExtraGroupsKey
:
[]
byte
(
"system:bootstrappers:foo"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantUser
:
&
user
.
DefaultInfo
{
Name
:
"system:bootstrap:"
+
tokenID
,
Groups
:
[]
string
{
"system:bootstrappers"
,
"system:bootstrappers:foo"
},
},
},
{
name
:
"invalid group"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
bootstrapapi
.
BootstrapTokenExtraGroupsKey
:
[]
byte
(
"foo"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"invalid secret name"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"bad-name"
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"no usage"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"wrong token"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
"barfoo"
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"deleted token"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
DeletionTimestamp
:
&
now
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"expired token"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
bootstrapapi
.
BootstrapTokenExpirationKey
:
[]
byte
(
"2009-11-10T23:00:00Z"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
{
name
:
"not expired token"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
tokenID
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
tokenID
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
bootstrapapi
.
BootstrapTokenExpirationKey
:
[]
byte
(
"2109-11-10T23:00:00Z"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
token
:
tokenID
+
"."
+
tokenSecret
,
wantUser
:
&
user
.
DefaultInfo
{
Name
:
"system:bootstrap:"
+
tokenID
,
Groups
:
[]
string
{
"system:bootstrappers"
},
},
},
{
name
:
"token id wrong length"
,
secrets
:
[]
*
corev1
.
Secret
{
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
bootstrapapi
.
BootstrapTokenSecretPrefix
+
"foo"
,
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenIDKey
:
[]
byte
(
"foo"
),
bootstrapapi
.
BootstrapTokenSecretKey
:
[]
byte
(
tokenSecret
),
bootstrapapi
.
BootstrapTokenUsageAuthentication
:
[]
byte
(
"true"
),
},
Type
:
"bootstrap.kubernetes.io/token"
,
},
},
// Token ID must be 6 characters.
token
:
"foo"
+
"."
+
tokenSecret
,
wantNotFound
:
true
,
},
}
for
_
,
test
:=
range
tests
{
func
()
{
a
:=
NewTokenAuthenticator
(
&
lister
{
test
.
secrets
})
resp
,
found
,
err
:=
a
.
AuthenticateToken
(
context
.
Background
(),
test
.
token
)
if
err
!=
nil
{
t
.
Errorf
(
"test %q returned an error: %v"
,
test
.
name
,
err
)
return
}
if
!
found
{
if
!
test
.
wantNotFound
{
t
.
Errorf
(
"test %q expected to get user"
,
test
.
name
)
}
return
}
if
test
.
wantNotFound
{
t
.
Errorf
(
"test %q expected to not get a user"
,
test
.
name
)
return
}
gotUser
:=
resp
.
User
.
(
*
user
.
DefaultInfo
)
if
!
reflect
.
DeepEqual
(
gotUser
,
test
.
wantUser
)
{
t
.
Errorf
(
"test %q want user=%#v, got=%#v"
,
test
.
name
,
test
.
wantUser
,
gotUser
)
}
}()
}
}
func
TestGetGroups
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
secret
*
corev1
.
Secret
expectResult
[]
string
expectError
bool
}{
{
name
:
"not set"
,
secret
:
&
corev1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
},
Data
:
map
[
string
][]
byte
{},
},
expectResult
:
[]
string
{
"system:bootstrappers"
},
},
{
name
:
"set to empty value"
,
secret
:
&
corev1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenExtraGroupsKey
:
[]
byte
(
""
),
},
},
expectResult
:
[]
string
{
"system:bootstrappers"
},
},
{
name
:
"invalid prefix"
,
secret
:
&
corev1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenExtraGroupsKey
:
[]
byte
(
"foo"
),
},
},
expectError
:
true
,
},
{
name
:
"valid"
,
secret
:
&
corev1
.
Secret
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"test"
},
Data
:
map
[
string
][]
byte
{
bootstrapapi
.
BootstrapTokenExtraGroupsKey
:
[]
byte
(
"system:bootstrappers:foo,system:bootstrappers:bar,system:bootstrappers:bar"
),
},
},
// expect the results in deduplicated, sorted order
expectResult
:
[]
string
{
"system:bootstrappers"
,
"system:bootstrappers:bar"
,
"system:bootstrappers:foo"
,
},
},
}
for
_
,
test
:=
range
tests
{
result
,
err
:=
getGroups
(
test
.
secret
)
if
test
.
expectError
{
if
err
==
nil
{
t
.
Errorf
(
"test %q expected an error, but didn't get one (result: %#v)"
,
test
.
name
,
result
)
}
continue
}
if
err
!=
nil
{
t
.
Errorf
(
"test %q return an unexpected error: %v"
,
test
.
name
,
err
)
continue
}
if
!
reflect
.
DeepEqual
(
result
,
test
.
expectResult
)
{
t
.
Errorf
(
"test %q expected %#v, got %#v"
,
test
.
name
,
test
.
expectResult
,
result
)
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment