refactor bootstrap token utils
This commit is contained in:
@@ -31,6 +31,7 @@ import (
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
bootstrapsecretutil "k8s.io/cluster-bootstrap/util/secrets"
|
||||
"k8s.io/klog"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
@@ -187,7 +188,7 @@ func (tc *TokenCleaner) syncFunc(key string) error {
|
||||
|
||||
func (tc *TokenCleaner) evalSecret(o interface{}) {
|
||||
secret := o.(*v1.Secret)
|
||||
if isSecretExpired(secret) {
|
||||
if bootstrapsecretutil.HasExpired(secret, time.Now()) {
|
||||
klog.V(3).Infof("Deleting expired secret %s/%s", secret.Namespace, secret.Name)
|
||||
var options *metav1.DeleteOptions
|
||||
if len(secret.UID) > 0 {
|
||||
|
@@ -17,46 +17,23 @@ limitations under the License.
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
bootstrapsecretutil "k8s.io/cluster-bootstrap/util/secrets"
|
||||
)
|
||||
|
||||
var namePattern = `^` + regexp.QuoteMeta(bootstrapapi.BootstrapTokenSecretPrefix) + `([a-z0-9]{6})$`
|
||||
var nameRegExp = regexp.MustCompile(namePattern)
|
||||
|
||||
// getSecretString gets a string value from a secret. If there is an error or
|
||||
// if the key doesn't exist, an empty string is returned.
|
||||
func getSecretString(secret *v1.Secret, key string) string {
|
||||
data, ok := secret.Data[key]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(data)
|
||||
}
|
||||
|
||||
// parseSecretName parses the name of the secret to extract the secret ID.
|
||||
func parseSecretName(name string) (secretID string, ok bool) {
|
||||
r := nameRegExp.FindStringSubmatch(name)
|
||||
if r == nil {
|
||||
return "", false
|
||||
}
|
||||
return r[1], true
|
||||
}
|
||||
|
||||
func validateSecretForSigning(secret *v1.Secret) (tokenID, tokenSecret string, ok bool) {
|
||||
nameTokenID, ok := parseSecretName(secret.Name)
|
||||
nameTokenID, ok := bootstrapsecretutil.ParseName(secret.Name)
|
||||
if !ok {
|
||||
klog.V(3).Infof("Invalid secret name: %s. Must be of form %s<secret-id>.", secret.Name, bootstrapapi.BootstrapTokenSecretPrefix)
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
tokenID = getSecretString(secret, bootstrapapi.BootstrapTokenIDKey)
|
||||
tokenID = bootstrapsecretutil.GetData(secret, bootstrapapi.BootstrapTokenIDKey)
|
||||
if len(tokenID) == 0 {
|
||||
klog.V(3).Infof("No %s key in %s/%s Secret", bootstrapapi.BootstrapTokenIDKey, secret.Namespace, secret.Name)
|
||||
return "", "", false
|
||||
@@ -67,7 +44,7 @@ func validateSecretForSigning(secret *v1.Secret) (tokenID, tokenSecret string, o
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
tokenSecret = getSecretString(secret, bootstrapapi.BootstrapTokenSecretKey)
|
||||
tokenSecret = bootstrapsecretutil.GetData(secret, bootstrapapi.BootstrapTokenSecretKey)
|
||||
if len(tokenSecret) == 0 {
|
||||
klog.V(3).Infof("No %s key in %s/%s Secret", bootstrapapi.BootstrapTokenSecretKey, secret.Namespace, secret.Name)
|
||||
return "", "", false
|
||||
@@ -76,34 +53,15 @@ func validateSecretForSigning(secret *v1.Secret) (tokenID, tokenSecret string, o
|
||||
// Ensure this secret hasn't expired. The TokenCleaner should remove this
|
||||
// but if that isn't working or it hasn't gotten there yet we should check
|
||||
// here.
|
||||
if isSecretExpired(secret) {
|
||||
if bootstrapsecretutil.HasExpired(secret, time.Now()) {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
// Make sure this secret can be used for signing
|
||||
okToSign := getSecretString(secret, bootstrapapi.BootstrapTokenUsageSigningKey)
|
||||
okToSign := bootstrapsecretutil.GetData(secret, bootstrapapi.BootstrapTokenUsageSigningKey)
|
||||
if okToSign != "true" {
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
return tokenID, tokenSecret, true
|
||||
}
|
||||
|
||||
// isSecretExpired returns true if the Secret is expired.
|
||||
func isSecretExpired(secret *v1.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
|
||||
}
|
||||
|
@@ -20,8 +20,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
@@ -180,27 +178,3 @@ func TestMismatchSecretName(t *testing.T) {
|
||||
t.Errorf("Token validation should fail with mismatched name")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseSecretName(t *testing.T) {
|
||||
tokenID, ok := parseSecretName("bootstrap-token-abc123")
|
||||
assert.True(t, ok, "parseSecretName should accept valid name")
|
||||
assert.Equal(t, "abc123", tokenID, "parseSecretName should return token ID")
|
||||
|
||||
_, ok = parseSecretName("")
|
||||
assert.False(t, ok, "parseSecretName should reject blank name")
|
||||
|
||||
_, ok = parseSecretName("abc123")
|
||||
assert.False(t, ok, "parseSecretName should reject with no prefix")
|
||||
|
||||
_, ok = parseSecretName("bootstrap-token-")
|
||||
assert.False(t, ok, "parseSecretName should reject no token ID")
|
||||
|
||||
_, ok = parseSecretName("bootstrap-token-abc")
|
||||
assert.False(t, ok, "parseSecretName should reject short token ID")
|
||||
|
||||
_, ok = parseSecretName("bootstrap-token-abc123ghi")
|
||||
assert.False(t, ok, "parseSecretName should reject long token ID")
|
||||
|
||||
_, ok = parseSecretName("bootstrap-token-ABC123")
|
||||
assert.False(t, ok, "parseSecretName should reject invalid token ID")
|
||||
}
|
||||
|
Reference in New Issue
Block a user