diff --git a/cmd/kubeadm/app/node/BUILD b/cmd/kubeadm/app/node/BUILD index 75ae162bdf3..b0acdc30986 100644 --- a/cmd/kubeadm/app/node/BUILD +++ b/cmd/kubeadm/app/node/BUILD @@ -33,3 +33,23 @@ go_library( "//vendor:github.com/square/go-jose", ], ) + +go_test( + name = "go_default_test", + srcs = [ + "bootstrap_test.go", + "csr_test.go", + "discovery_test.go", + ], + library = "go_default_library", + tags = ["automanaged"], + deps = [ + "//cmd/kubeadm/app/apis/kubeadm:go_default_library", + "//pkg/api/unversioned:go_default_library", + "//pkg/client/clientset_generated/internalclientset:go_default_library", + "//pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion:go_default_library", + "//pkg/client/restclient:go_default_library", + "//pkg/client/typed/discovery:go_default_library", + "//pkg/version:go_default_library", + ], +) diff --git a/cmd/kubeadm/app/node/bootstrap_test.go b/cmd/kubeadm/app/node/bootstrap_test.go new file mode 100644 index 00000000000..2f3922e9813 --- /dev/null +++ b/cmd/kubeadm/app/node/bootstrap_test.go @@ -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" + + kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" + "k8s.io/kubernetes/pkg/api/unversioned" + clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + "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 = &unversioned.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 = &unversioned.APIGroupList{ + Groups: []unversioned.APIGroup{ + { + Name: "certificates.k8s.io", + Versions: []unversioned.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.NodeConfiguration{} + 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 = &unversioned.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 = &unversioned.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 = &unversioned.APIGroupList{ + Groups: []unversioned.APIGroup{ + { + Name: "certificates.k8s.io", + Versions: []unversioned.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), + ) + } + } +} diff --git a/cmd/kubeadm/app/node/csr_test.go b/cmd/kubeadm/app/node/csr_test.go new file mode 100644 index 00000000000..34c014a48b7 --- /dev/null +++ b/cmd/kubeadm/app/node/csr_test.go @@ -0,0 +1,79 @@ +/* +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" + + certclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/certificates/internalversion" + restclient "k8s.io/kubernetes/pkg/client/restclient" +) + +func TestPerformTLSBootstrap(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + switch req.URL.Path { + default: + output, err := json.Marshal(nil) + 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 { + h string + expect bool + }{ + { + h: "", + expect: false, + }, + { + h: "localhost", + expect: false, + }, + { + h: srv.URL, + expect: false, + }, + } + for _, rt := range tests { + cd := &ConnectionDetails{} + r := &restclient.Config{Host: rt.h} + tmpConfig, err := certclient.NewForConfig(r) + if err != nil { + t.Fatalf("encountered an error while trying to get New Cert Client: %v", err) + } + cd.CertClient = tmpConfig + _, actual := PerformTLSBootstrap(cd) + if (actual == nil) != rt.expect { + t.Errorf( + "failed createClients:\n\texpected: %t\n\t actual: %t", + rt.expect, + (actual == nil), + ) + } + } +} diff --git a/cmd/kubeadm/app/node/discovery_test.go b/cmd/kubeadm/app/node/discovery_test.go new file mode 100644 index 00000000000..4626b6c7124 --- /dev/null +++ b/cmd/kubeadm/app/node/discovery_test.go @@ -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 int32 + payload string + expect bool + }{ + { + h: host, + p: int32(iPort), + payload: "", + expect: false, + }, + { + h: host, + p: int32(iPort), + payload: "foo", + expect: false, + }, + } + for _, rt := range tests { + j.Payload = rt.payload + nc := &kubeadmapi.NodeConfiguration{MasterAddresses: []string{host}, DiscoveryPort: int32(iPort)} + _, actual := RetrieveTrustedClusterInfo(nc) + if (actual == nil) != rt.expect { + t.Errorf( + "failed createClients:\n\texpected: %t\n\t actual: %t", + rt.expect, + (actual == nil), + ) + } + } +} diff --git a/test/test_owners.csv b/test/test_owners.csv index 838c3c1f706..1e62931699c 100644 --- a/test/test_owners.csv +++ b/test/test_owners.csv @@ -504,6 +504,7 @@ k8s.io/kubernetes/cmd/kube-discovery/app,pmorie,1 k8s.io/kubernetes/cmd/kube-proxy/app,luxas,1 k8s.io/kubernetes/cmd/kubeadm/app/cmd,caesarxuchao,1 k8s.io/kubernetes/cmd/kubeadm/app/images,davidopp,1 +k8s.io/kubernetes/cmd/kubeadm/app/node,apprenda,0 k8s.io/kubernetes/cmd/kubeadm/app/preflight,apprenda,0 k8s.io/kubernetes/cmd/kubeadm/app/util,krousey,1 k8s.io/kubernetes/cmd/kubeadm/test,pipejakob,0