Switch to github.com/golang/dep for vendoring
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
This commit is contained in:
parent
d6ab91be27
commit
8e5b17cf13
15431 changed files with 3971413 additions and 8881 deletions
65
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/BUILD
generated
vendored
Normal file
65
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/BUILD
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"bootstrap.go",
|
||||
"csr.go",
|
||||
"discovery.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||
"//cmd/kubeadm/app/util:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/certificates:go_default_library",
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd/api:go_default_library",
|
||||
"//pkg/kubelet/util/csr:go_default_library",
|
||||
"//pkg/util/cert:go_default_library",
|
||||
"//vendor:github.com/square/go-jose",
|
||||
"//vendor:k8s.io/apimachinery/pkg/types",
|
||||
"//vendor:k8s.io/apimachinery/pkg/util/wait",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"bootstrap_test.go",
|
||||
"discovery_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
|
||||
"//pkg/client/clientset_generated/clientset:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/typed/discovery:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
164
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/bootstrap.go
generated
vendored
Normal file
164
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/bootstrap.go
generated
vendored
Normal file
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
Copyright 2016 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 node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/certificates"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||
)
|
||||
|
||||
// retryTimeout between the subsequent attempts to connect
|
||||
// to an API endpoint
|
||||
const retryTimeout = 5
|
||||
|
||||
type apiClient struct {
|
||||
clientSet *clientset.Clientset
|
||||
clientConfig *clientcmdapi.Config
|
||||
}
|
||||
|
||||
// EstablishMasterConnection establishes a connection with exactly one of the provided API endpoints.
|
||||
// The function builds a client for every endpoint and concurrently keeps trying to connect to any one
|
||||
// of the provided endpoints. Blocks until at least one connection is established, then it stops the
|
||||
// connection attempts for other endpoints and returns the valid client configuration, if any.
|
||||
func EstablishMasterConnection(c *kubeadmapi.TokenDiscovery, clusterInfo *kubeadmapi.ClusterInfo) (*clientcmdapi.Config, error) {
|
||||
hostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get node hostname [%v]", err)
|
||||
}
|
||||
// TODO(phase1+) https://github.com/kubernetes/kubernetes/issues/33641
|
||||
nodeName := types.NodeName(hostName)
|
||||
|
||||
endpoints := clusterInfo.Endpoints
|
||||
caCert := []byte(clusterInfo.CertificateAuthorities[0])
|
||||
|
||||
stopChan := make(chan struct{})
|
||||
var clientConfig *clientcmdapi.Config
|
||||
var once sync.Once
|
||||
var wg sync.WaitGroup
|
||||
for _, endpoint := range endpoints {
|
||||
ac, err := createClients(caCert, endpoint, kubeadmutil.BearerToken(c), nodeName)
|
||||
if err != nil {
|
||||
fmt.Printf("[bootstrap] Warning: %s. Skipping endpoint %s\n", err, endpoint)
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go func(apiEndpoint string) {
|
||||
defer wg.Done()
|
||||
wait.Until(func() {
|
||||
fmt.Printf("[bootstrap] Trying to connect to endpoint %s\n", apiEndpoint)
|
||||
err := checkAPIEndpoint(ac.clientSet, apiEndpoint)
|
||||
if err != nil {
|
||||
fmt.Printf("[bootstrap] Endpoint check failed [%v]\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("[bootstrap] Successfully established connection with endpoint %q\n", apiEndpoint)
|
||||
// connection established, stop all wait threads
|
||||
close(stopChan)
|
||||
once.Do(func() {
|
||||
clientConfig = ac.clientConfig
|
||||
})
|
||||
}, retryTimeout*time.Second, stopChan)
|
||||
}(endpoint)
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
if clientConfig == nil {
|
||||
return nil, fmt.Errorf("failed to create bootstrap clients for any of the provided API endpoints")
|
||||
}
|
||||
|
||||
return clientConfig, nil
|
||||
}
|
||||
|
||||
// creates a set of clients for this endpoint
|
||||
func createClients(caCert []byte, endpoint, token string, nodeName types.NodeName) (*apiClient, error) {
|
||||
clientConfig := kubeconfigphase.MakeClientConfigWithToken(
|
||||
endpoint,
|
||||
"kubernetes",
|
||||
fmt.Sprintf("kubelet-%s", nodeName),
|
||||
caCert,
|
||||
token,
|
||||
)
|
||||
|
||||
bootstrapClientConfig, err := clientcmd.NewDefaultClientConfig(*clientConfig, &clientcmd.ConfigOverrides{}).ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create API client configuration [%v]", err)
|
||||
}
|
||||
clientSet, err := clientset.NewForConfig(bootstrapClientConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create clients for the API endpoint %q: [%v]", endpoint, err)
|
||||
}
|
||||
|
||||
ac := &apiClient{
|
||||
clientSet: clientSet,
|
||||
clientConfig: clientConfig,
|
||||
}
|
||||
return ac, nil
|
||||
}
|
||||
|
||||
// checkForNodeNameDuplicates checks whether there are other nodes in the cluster with identical node names.
|
||||
func checkForNodeNameDuplicates(clientSet *clientset.Clientset) error {
|
||||
hostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get node hostname [%v]", err)
|
||||
}
|
||||
nodeList, err := clientSet.Nodes().List(v1.ListOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to list the nodes in the cluster: [%v]\n", err)
|
||||
}
|
||||
for _, node := range nodeList.Items {
|
||||
if hostName == node.Name {
|
||||
return fmt.Errorf("Node with name [%q] already exists.", node.Name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checks the connection requirements for a specific API endpoint
|
||||
func checkAPIEndpoint(clientSet *clientset.Clientset, endpoint string) error {
|
||||
// check general connectivity
|
||||
version, err := clientSet.DiscoveryClient.ServerVersion()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to %q [%v]", endpoint, err)
|
||||
}
|
||||
fmt.Printf("[bootstrap] Detected server version: %s\n", version.String())
|
||||
|
||||
// check certificates API
|
||||
serverGroups, err := clientSet.DiscoveryClient.ServerGroups()
|
||||
if err != nil {
|
||||
return fmt.Errorf("certificate API check failed: failed to retrieve a list of supported API objects [%v]", err)
|
||||
}
|
||||
for _, group := range serverGroups.Groups {
|
||||
if group.Name == certificates.GroupName {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("certificate API check failed: API version %s does not support certificates API, use v1.4.0 or newer",
|
||||
version.String())
|
||||
}
|
262
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/bootstrap_test.go
generated
vendored
Normal file
262
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/bootstrap_test.go
generated
vendored
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
Copyright 2016 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 node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
func TestEstablishMasterConnection(t *testing.T) {
|
||||
expect := version.Info{
|
||||
Major: "foo",
|
||||
Minor: "bar",
|
||||
GitCommit: "baz",
|
||||
}
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
"v1.4",
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
case "/apis":
|
||||
obj = &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "certificates.k8s.io",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
default:
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
tests := []struct {
|
||||
c string
|
||||
e string
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
c: "",
|
||||
e: "",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
c: "",
|
||||
e: srv.URL,
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
c: "foo",
|
||||
e: srv.URL,
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
s := &kubeadmapi.TokenDiscovery{}
|
||||
c := &kubeadmapi.ClusterInfo{Endpoints: []string{rt.e}, CertificateAuthorities: []string{rt.c}}
|
||||
_, actual := EstablishMasterConnection(s, c)
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed EstablishMasterConnection:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateClients(t *testing.T) {
|
||||
tests := []struct {
|
||||
e string
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
e: "",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
e: "foo",
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
_, actual := createClients(nil, rt.e, "", "")
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed createClients:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckAPIEndpoint(t *testing.T) {
|
||||
expect := version.Info{
|
||||
Major: "foo",
|
||||
Minor: "bar",
|
||||
GitCommit: "baz",
|
||||
}
|
||||
tests := []struct {
|
||||
s *httptest.Server
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {})),
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
"v1.4",
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
default:
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
})),
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
s: httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &metav1.APIVersions{
|
||||
Versions: []string{
|
||||
"v1.4",
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
case "/apis":
|
||||
obj = &metav1.APIGroupList{
|
||||
Groups: []metav1.APIGroup{
|
||||
{
|
||||
Name: "certificates.k8s.io",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
default:
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
})),
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
defer rt.s.Close()
|
||||
rc := &restclient.Config{Host: rt.s.URL}
|
||||
c, err := discovery.NewDiscoveryClientForConfig(rc)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to get New Discovery Client: %v", err)
|
||||
}
|
||||
cs := &clientset.Clientset{DiscoveryClient: c}
|
||||
actual := checkAPIEndpoint(cs, "")
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed runChecks:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
76
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/csr.go
generated
vendored
Normal file
76
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/csr.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2016 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 node
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/csr"
|
||||
certutil "k8s.io/kubernetes/pkg/util/cert"
|
||||
)
|
||||
|
||||
// PerformTLSBootstrap executes a node certificate signing request.
|
||||
func PerformTLSBootstrap(cfg *clientcmdapi.Config) error {
|
||||
hostName, err := os.Hostname()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := types.NodeName(hostName)
|
||||
|
||||
rc, err := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{}).ClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := clientset.NewForConfig(rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request")
|
||||
|
||||
key, err := certutil.MakeEllipticPrivateKeyPEM()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate private key [%v]", err)
|
||||
}
|
||||
|
||||
// Make sure there are no other nodes in the cluster with identical node name.
|
||||
if err := checkForNodeNameDuplicates(c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cert, err := csr.RequestNodeCertificate(c.Certificates().CertificateSigningRequests(), key, name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to request signed certificate from the API server [%v]", err)
|
||||
}
|
||||
fmt.Printf("[csr] Received signed certificate from the API server")
|
||||
fmt.Println("[csr] Generating kubelet configuration")
|
||||
|
||||
cfg.AuthInfos["kubelet"] = &clientcmdapi.AuthInfo{
|
||||
ClientKeyData: key,
|
||||
ClientCertificateData: cert,
|
||||
}
|
||||
cfg.Contexts["kubelet"] = &clientcmdapi.Context{
|
||||
AuthInfo: "kubelet",
|
||||
Cluster: cfg.Contexts[cfg.CurrentContext].Cluster,
|
||||
}
|
||||
cfg.CurrentContext = "kubelet"
|
||||
return nil
|
||||
}
|
84
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/discovery.go
generated
vendored
Normal file
84
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/discovery.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Copyright 2016 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 node
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
jose "github.com/square/go-jose"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
// the amount of time to wait between each request to the discovery API
|
||||
const discoveryRetryTimeout = 5 * time.Second
|
||||
|
||||
func RetrieveTrustedClusterInfo(d *kubeadmapi.TokenDiscovery) (*kubeadmapi.ClusterInfo, error) {
|
||||
requestURL := fmt.Sprintf("http://%s/cluster-info/v1/?token-id=%s", d.Addresses[0], d.ID)
|
||||
req, err := http.NewRequest("GET", requestURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to consturct an HTTP request [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Printf("[discovery] Created cluster info discovery client, requesting info from %q\n", requestURL)
|
||||
|
||||
var res *http.Response
|
||||
wait.PollInfinite(discoveryRetryTimeout, func() (bool, error) {
|
||||
res, err = http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
fmt.Printf("[discovery] Failed to request cluster info, will try again: [%s]\n", err)
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
io.Copy(buf, res.Body)
|
||||
res.Body.Close()
|
||||
|
||||
object, err := jose.ParseSigned(buf.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse response as JWS object [%v]", err)
|
||||
}
|
||||
|
||||
fmt.Println("[discovery] Cluster info object received, verifying signature using given token")
|
||||
|
||||
output, err := object.Verify([]byte(d.Secret))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to verify JWS signature of received cluster info object [%v]", err)
|
||||
}
|
||||
|
||||
clusterInfo := kubeadmapi.ClusterInfo{}
|
||||
|
||||
if err := json.Unmarshal(output, &clusterInfo); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode received cluster info object [%v]", err)
|
||||
}
|
||||
|
||||
if len(clusterInfo.CertificateAuthorities) == 0 || len(clusterInfo.Endpoints) == 0 {
|
||||
return nil, fmt.Errorf("cluster info object is invalid - no endpoint(s) and/or root CA certificate(s) found")
|
||||
}
|
||||
|
||||
// TODO(phase1+) print summary info about the CA certificate, along with the the checksum signature
|
||||
// we also need an ability for the user to configure the client to validate received CA cert against a checksum
|
||||
fmt.Printf("[discovery] Cluster info signature and contents are valid, will use API endpoints %v\n", clusterInfo.Endpoints)
|
||||
return &clusterInfo, nil
|
||||
}
|
99
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/discovery_test.go
generated
vendored
Normal file
99
vendor/k8s.io/kubernetes/cmd/kubeadm/app/node/discovery_test.go
generated
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright 2016 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 node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||
)
|
||||
|
||||
type rawJsonWebSignatureFake struct {
|
||||
Payload string `json:"payload,omitempty"`
|
||||
Signatures string `json:"signatures,omitempty"`
|
||||
Protected string `json:"protected,omitempty"`
|
||||
Header string `json:"header,omitempty"`
|
||||
Signature string `json:"signature,omitempty"`
|
||||
}
|
||||
|
||||
func TestRetrieveTrustedClusterInfo(t *testing.T) {
|
||||
j := rawJsonWebSignatureFake{}
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.URL.Path {
|
||||
default:
|
||||
output, err := json.Marshal(j)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
pURL, err := url.Parse(srv.URL)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to parse httptest server url: %v", err)
|
||||
}
|
||||
host, port, err := net.SplitHostPort(pURL.Host)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to split host and port info from httptest server: %v", err)
|
||||
}
|
||||
iPort, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
t.Fatalf("encountered an error while trying to convert string to int (httptest server port): %v", err)
|
||||
}
|
||||
tests := []struct {
|
||||
h string
|
||||
p int
|
||||
payload string
|
||||
expect bool
|
||||
}{
|
||||
{
|
||||
h: host,
|
||||
p: iPort,
|
||||
payload: "",
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
h: host,
|
||||
p: iPort,
|
||||
payload: "foo",
|
||||
expect: false,
|
||||
},
|
||||
}
|
||||
for _, rt := range tests {
|
||||
j.Payload = rt.payload
|
||||
nc := &kubeadmapi.TokenDiscovery{Addresses: []string{rt.h + ":" + strconv.Itoa(rt.p)}}
|
||||
_, actual := RetrieveTrustedClusterInfo(nc)
|
||||
if (actual == nil) != rt.expect {
|
||||
t.Errorf(
|
||||
"failed createClients:\n\texpected: %t\n\t actual: %t",
|
||||
rt.expect,
|
||||
(actual == nil),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue