From 01f7f3801f948e1011ba145bb475991a56bfc976 Mon Sep 17 00:00:00 2001
From: Gavin
Date: Wed, 17 Jan 2018 16:22:37 +0800
Subject: [PATCH 1/2] Add generic Bootstrap Token constants and helpers to
client-go
Kubernetes-commit: bb5e156aba3ff73ceb85576670c35d7565b84a4c
---
tools/bootstrap/token/api/doc.go | 20 +++++
tools/bootstrap/token/api/types.go | 100 +++++++++++++++++++++
tools/bootstrap/token/util/helpers.go | 52 +++++++++++
tools/bootstrap/token/util/helpers_test.go | 76 ++++++++++++++++
4 files changed, 248 insertions(+)
create mode 100644 tools/bootstrap/token/api/doc.go
create mode 100644 tools/bootstrap/token/api/types.go
create mode 100644 tools/bootstrap/token/util/helpers.go
create mode 100644 tools/bootstrap/token/util/helpers_test.go
diff --git a/tools/bootstrap/token/api/doc.go b/tools/bootstrap/token/api/doc.go
new file mode 100644
index 00000000..72738711
--- /dev/null
+++ b/tools/bootstrap/token/api/doc.go
@@ -0,0 +1,20 @@
+/*
+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 api (pkg/bootstrap/api) contains constants and types needed for
+// bootstrap tokens as maintained by the BootstrapSigner and TokenCleaner
+// controllers (in pkg/controller/bootstrap)
+package api // import "k8s.io/client-go/tools/bootstrap/api"
diff --git a/tools/bootstrap/token/api/types.go b/tools/bootstrap/token/api/types.go
new file mode 100644
index 00000000..c30814c0
--- /dev/null
+++ b/tools/bootstrap/token/api/types.go
@@ -0,0 +1,100 @@
+/*
+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 api
+
+import (
+ "k8s.io/api/core/v1"
+)
+
+const (
+ // BootstrapTokenSecretPrefix is the prefix for bootstrap token names.
+ // Bootstrap tokens secrets must be named in the form
+ // `bootstrap-token-`. This is the prefix to be used before the
+ // token ID.
+ BootstrapTokenSecretPrefix = "bootstrap-token-"
+
+ // SecretTypeBootstrapToken is used during the automated bootstrap process (first
+ // implemented by kubeadm). It stores tokens that are used to sign well known
+ // ConfigMaps. They may also eventually be used for authentication.
+ SecretTypeBootstrapToken v1.SecretType = "bootstrap.kubernetes.io/token"
+
+ // BootstrapTokenIDKey is the id of this token. This can be transmitted in the
+ // clear and encoded in the name of the secret. It must be a random 6 character
+ // string that matches the regexp `^([a-z0-9]{6})$`. Required.
+ BootstrapTokenIDKey = "token-id"
+
+ // BootstrapTokenSecretKey is the actual secret. It must be a random 16 character
+ // string that matches the regexp `^([a-z0-9]{16})$`. Required.
+ BootstrapTokenSecretKey = "token-secret"
+
+ // BootstrapTokenExpirationKey is when this token should be expired and no
+ // longer used. A controller will delete this resource after this time. This
+ // is an absolute UTC time using RFC3339. If this cannot be parsed, the token
+ // should be considered invalid. Optional.
+ BootstrapTokenExpirationKey = "expiration"
+
+ // BootstrapTokenDescriptionKey is a description in human-readable format that
+ // describes what the bootstrap token is used for. Optional.
+ BootstrapTokenDescriptionKey = "description"
+
+ // BootstrapTokenExtraGroupsKey is a comma-separated list of group names.
+ // The bootstrap token will authenticate as these groups in addition to the
+ // "system:bootstrappers" group.
+ BootstrapTokenExtraGroupsKey = "auth-extra-groups"
+
+ // BootstrapTokenUsagePrefix is the prefix for the other usage constants that specifies different
+ // functions of a bootstrap token
+ BootstrapTokenUsagePrefix = "usage-bootstrap-"
+
+ // BootstrapTokenUsageSigningKey signals that this token should be used to
+ // sign configs as part of the bootstrap process. Value must be "true". Any
+ // other value is assumed to be false. Optional.
+ BootstrapTokenUsageSigningKey = "usage-bootstrap-signing"
+
+ // BootstrapTokenUsageAuthentication signals that this token should be used
+ // as a bearer token to authenticate against the Kubernetes API. The bearer
+ // token takes the form "." and authenticates as the
+ // user "system:bootstrap:" in the "system:bootstrappers" group
+ // as well as any groups specified using BootstrapTokenExtraGroupsKey.
+ // Value must be "true". Any other value is assumed to be false. Optional.
+ BootstrapTokenUsageAuthentication = "usage-bootstrap-authentication"
+
+ // ConfigMapClusterInfo defines the name for the ConfigMap where the information how to connect and trust the cluster exist
+ ConfigMapClusterInfo = "cluster-info"
+
+ // KubeConfigKey defines at which key in the Data object of the ConfigMap the KubeConfig object is stored
+ KubeConfigKey = "kubeconfig"
+
+ // JWSSignatureKeyPrefix defines what key prefix the JWS-signed tokens have
+ JWSSignatureKeyPrefix = "jws-kubeconfig-"
+
+ // BootstrapUserPrefix is the username prefix bootstrapping bearer tokens
+ // authenticate as. The full username given is "system:bootstrap:".
+ BootstrapUserPrefix = "system:bootstrap:"
+
+ // BootstrapGroupPattern is the valid regex pattern that all groups
+ // assigned to a bootstrap token by BootstrapTokenExtraGroupsKey must match.
+ // See also ValidateBootstrapGroupName().
+ BootstrapGroupPattern = "system:bootstrappers:[a-z0-9:-]{0,255}[a-z0-9]"
+
+ // BootstrapDefaultGroup is the default group for bootstrapping bearer
+ // tokens (in addition to any groups from BootstrapTokenExtraGroupsKey).
+ BootstrapDefaultGroup = "system:bootstrappers"
+)
+
+// KnownTokenUsages specifies the known functions a token will get.
+var KnownTokenUsages = []string{"signing", "authentication"}
diff --git a/tools/bootstrap/token/util/helpers.go b/tools/bootstrap/token/util/helpers.go
new file mode 100644
index 00000000..d28fd28f
--- /dev/null
+++ b/tools/bootstrap/token/util/helpers.go
@@ -0,0 +1,52 @@
+/*
+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 util
+
+import (
+ "fmt"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "k8s.io/client-go/tools/bootstrap/token/api"
+ "regexp"
+ "strings"
+)
+
+var bootstrapGroupRegexp = regexp.MustCompile(`\A` + api.BootstrapGroupPattern + `\z`)
+
+// ValidateBootstrapGroupName checks if the provided group name is a valid
+// bootstrap group name. Returns nil if valid or a validation error if invalid.
+// TODO(mattmoyer): this validation should migrate out to client-go (see https://github.com/kubernetes/client-go/issues/114)
+func ValidateBootstrapGroupName(name string) error {
+ if bootstrapGroupRegexp.Match([]byte(name)) {
+ return nil
+ }
+ return fmt.Errorf("bootstrap group %q is invalid (must match %s)", name, api.BootstrapGroupPattern)
+}
+
+// ValidateUsages validates that the passed in string are valid usage strings for bootstrap tokens.
+func ValidateUsages(usages []string) error {
+ validUsages := sets.NewString(api.KnownTokenUsages...)
+ invalidUsages := sets.NewString()
+ for _, usage := range usages {
+ if !validUsages.Has(usage) {
+ invalidUsages.Insert(usage)
+ }
+ }
+ if len(invalidUsages) > 0 {
+ return fmt.Errorf("invalide bootstrap token usage string: %s, valid usage options: %s", strings.Join(invalidUsages.List(), ","), strings.Join(api.KnownTokenUsages, ","))
+ }
+ return nil
+}
diff --git a/tools/bootstrap/token/util/helpers_test.go b/tools/bootstrap/token/util/helpers_test.go
new file mode 100644
index 00000000..915bf754
--- /dev/null
+++ b/tools/bootstrap/token/util/helpers_test.go
@@ -0,0 +1,76 @@
+/*
+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 util
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestValidateBootstrapGroupName(t *testing.T) {
+ tests := []struct {
+ name string
+ input string
+ valid bool
+ }{
+ {"valid", "system:bootstrappers:foo", true},
+ {"valid nested", "system:bootstrappers:foo:bar:baz", true},
+ {"valid with dashes and number", "system:bootstrappers:foo-bar-42", true},
+ {"invalid uppercase", "system:bootstrappers:Foo", false},
+ {"missing prefix", "foo", false},
+ {"prefix with no body", "system:bootstrappers:", false},
+ {"invalid spaces", "system:bootstrappers: ", false},
+ {"invalid asterisk", "system:bootstrappers:*", false},
+ {"trailing colon", "system:bootstrappers:foo:", false},
+ {"trailing dash", "system:bootstrappers:foo-", false},
+ {"script tags", "system:bootstrappers:", false},
+ {"too long", "system:bootstrappers:" + strings.Repeat("x", 300), false},
+ }
+ for _, test := range tests {
+ err := ValidateBootstrapGroupName(test.input)
+ if err != nil && test.valid {
+ t.Errorf("test %q: ValidateBootstrapGroupName(%q) returned unexpected error: %v", test.name, test.input, err)
+ }
+ if err == nil && !test.valid {
+ t.Errorf("test %q: ValidateBootstrapGroupName(%q) was supposed to return an error but didn't", test.name, test.input)
+ }
+ }
+}
+
+func TestValidateUsages(t *testing.T) {
+ tests := []struct {
+ name string
+ input []string
+ valid bool
+ }{
+ {"valid of signing", []string{"signing"}, true},
+ {"valid of authentication", []string{"authentication"}, true},
+ {"all valid", []string{"authentication", "signing"}, true},
+ {"single invalid", []string{"authentication", "foo"}, false},
+ {"all invalid", []string{"foo", "bar"}, false},
+ }
+
+ for _, test := range tests {
+ err := ValidateUsages(test.input)
+ if err != nil && test.valid {
+ t.Errorf("test %q: ValidateUsages(%v) returned unexpected error: %v", test.name, test.input, err)
+ }
+ if err == nil && !test.valid {
+ t.Errorf("test %q: ValidateUsages(%v) was supposed to return an error but didn't", test.name, test.input)
+ }
+ }
+}
From ced341259581d32deb8921559aa3f64e14dee1d5 Mon Sep 17 00:00:00 2001
From: Gavin
Date: Wed, 17 Jan 2018 16:23:03 +0800
Subject: [PATCH 2/2] create auto-gen files
Kubernetes-commit: f653d02b059b78b6a540fb7eadc4b8862226fc7a
---
tools/bootstrap/token/api/BUILD | 26 +++++++++++++++++++++++++
tools/bootstrap/token/api/OWNERS | 5 +++++
tools/bootstrap/token/util/BUILD | 33 ++++++++++++++++++++++++++++++++
3 files changed, 64 insertions(+)
create mode 100644 tools/bootstrap/token/api/BUILD
create mode 100644 tools/bootstrap/token/api/OWNERS
create mode 100644 tools/bootstrap/token/util/BUILD
diff --git a/tools/bootstrap/token/api/BUILD b/tools/bootstrap/token/api/BUILD
new file mode 100644
index 00000000..7416adc0
--- /dev/null
+++ b/tools/bootstrap/token/api/BUILD
@@ -0,0 +1,26 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+
+go_library(
+ name = "go_default_library",
+ srcs = [
+ "doc.go",
+ "types.go",
+ ],
+ importpath = "k8s.io/client-go/tools/bootstrap/token/api",
+ visibility = ["//visibility:public"],
+ deps = ["//vendor/k8s.io/api/core/v1:go_default_library"],
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/bootstrap/token/api/OWNERS b/tools/bootstrap/token/api/OWNERS
new file mode 100644
index 00000000..8a2f5b59
--- /dev/null
+++ b/tools/bootstrap/token/api/OWNERS
@@ -0,0 +1,5 @@
+approvers:
+- jbeda
+- luxas
+reviewers:
+- mattmoyer
diff --git a/tools/bootstrap/token/util/BUILD b/tools/bootstrap/token/util/BUILD
new file mode 100644
index 00000000..9c015fb5
--- /dev/null
+++ b/tools/bootstrap/token/util/BUILD
@@ -0,0 +1,33 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
+
+go_library(
+ name = "go_default_library",
+ srcs = ["helpers.go"],
+ importpath = "k8s.io/client-go/tools/bootstrap/token/util",
+ visibility = ["//visibility:public"],
+ deps = [
+ "//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
+ "//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
+ ],
+)
+
+go_test(
+ name = "go_default_test",
+ srcs = ["helpers_test.go"],
+ embed = [":go_default_library"],
+ importpath = "k8s.io/client-go/tools/bootstrap/token/util",
+)
+
+filegroup(
+ name = "package-srcs",
+ srcs = glob(["**"]),
+ tags = ["automanaged"],
+ visibility = ["//visibility:private"],
+)
+
+filegroup(
+ name = "all-srcs",
+ srcs = [":package-srcs"],
+ tags = ["automanaged"],
+ visibility = ["//visibility:public"],
+)