From baebd7cfd962ae7dcf9ddf08f3964c4ce707ab81 Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Thu, 25 Aug 2016 10:54:42 -0300 Subject: [PATCH] Expand on kube-discovery API and integrate container build. --- cluster/images/kube-discovery/Dockerfile | 18 ++ cluster/images/kube-discovery/Makefile | 53 +++++ cluster/images/kube-discovery/README.md | 45 ++++ .../kube-discovery/app}/handlers.go | 27 ++- cmd/kube-discovery/app/handlers_test.go | 208 ++++++++++++++++++ .../kube-discovery/app}/model.go | 8 +- .../kube-discovery/app}/routes.go | 8 +- cmd/kube-discovery/dummy.go | 24 -- .../kubediscovery.go | 8 +- discovery/Dockerfile | 6 - discovery/README.md | 39 ---- discovery/ca-secret.yaml | 7 - discovery/kubediscovery.yaml | 37 ---- pkg/kubediscovery/handlers_test.go | 100 --------- 14 files changed, 359 insertions(+), 229 deletions(-) create mode 100644 cluster/images/kube-discovery/Dockerfile create mode 100644 cluster/images/kube-discovery/Makefile create mode 100644 cluster/images/kube-discovery/README.md rename {pkg/kubediscovery => cmd/kube-discovery/app}/handlers.go (92%) create mode 100644 cmd/kube-discovery/app/handlers_test.go rename {pkg/kubediscovery => cmd/kube-discovery/app}/model.go (92%) rename {pkg/kubediscovery => cmd/kube-discovery/app}/routes.go (94%) delete mode 100644 cmd/kube-discovery/dummy.go rename cmd/{kubediscovery => kube-discovery}/kubediscovery.go (93%) delete mode 100644 discovery/Dockerfile delete mode 100644 discovery/README.md delete mode 100644 discovery/ca-secret.yaml delete mode 100644 discovery/kubediscovery.yaml delete mode 100644 pkg/kubediscovery/handlers_test.go diff --git a/cluster/images/kube-discovery/Dockerfile b/cluster/images/kube-discovery/Dockerfile new file mode 100644 index 00000000000..edd456334c6 --- /dev/null +++ b/cluster/images/kube-discovery/Dockerfile @@ -0,0 +1,18 @@ +# 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. + +FROM BASEIMAGE + +COPY kube-discovery /usr/local/bin +ENTRYPOINT "/usr/local/bin/kube-discovery" diff --git a/cluster/images/kube-discovery/Makefile b/cluster/images/kube-discovery/Makefile new file mode 100644 index 00000000000..d291f858886 --- /dev/null +++ b/cluster/images/kube-discovery/Makefile @@ -0,0 +1,53 @@ +# 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. + +# Build the kube-discovery image. +# +# Requires a pre-built kube-discovery binary: +# build/run.sh /bin/bash -c "KUBE_BUILD_PLATFORMS=linux/ARCH make WHAT=cmd/kube-discovery" +# +# Usage: +# [ARCH=amd64] [REGISTRY="gcr.io/google_containers"] make (build|push) VERSION={some_released_version_of_kubernetes} + +REGISTRY?=gcr.io/google_containers +ARCH?=amd64 +TEMP_DIR:=$(shell mktemp -d) +VERSION?=1.0 + +ifeq ($(ARCH),amd64) + BASEIMAGE?=debian:jessie +endif +ifeq ($(ARCH),arm) + BASEIMAGE?=armel/debian:jessie +endif +ifeq ($(ARCH),arm64) + BASEIMAGE?=aarch64/debian:jessie +endif +ifeq ($(ARCH),ppc64le) + BASEIMAGE?=ppc64le/debian:jessie +endif + +all: build + +build: + cp -r ./* ${TEMP_DIR} + cp ../../../_output/dockerized/bin/linux/${ARCH}/kube-discovery ${TEMP_DIR} + cd ${TEMP_DIR} && sed -i.back "s|BASEIMAGE|${BASEIMAGE}|g" Dockerfile + docker build -t ${REGISTRY}/kube-discovery-${ARCH}:${VERSION} ${TEMP_DIR} + rm -rf "${TEMP_DIR}" + +push: build + gcloud docker push ${REGISTRY}/kube-discovery-${ARCH}:${VERSION} + +.PHONY: all diff --git a/cluster/images/kube-discovery/README.md b/cluster/images/kube-discovery/README.md new file mode 100644 index 00000000000..bc61db6fb7d --- /dev/null +++ b/cluster/images/kube-discovery/README.md @@ -0,0 +1,45 @@ +### kube-discovery + +An initial implementation of a Kubernetes discovery service using JSON Web Signatures. + +This prototype is configured by kubeadm and run within Kubernetes itself. + +## Requirements + +This pod expects the cluster CA, endpoints list, and token map to exist in /tmp/secret. This allows us to pass them in as kubernetes secrets when deployed as a pod. + +``` +$ cd /tmp/secret +$ ls +ca.pem endpoint-list.json token-map.json +$ cat endpoint-list.json +["http://192.168.1.5:8080", "http://192.168.1.6:8080"] +$ cat token-map.json +{ + "TOKENID": "ABCDEF1234123456" +} +``` + +## Build And Run From Source + +``` +$ build/run.sh /bin/bash -c "KUBE_BUILD_PLATFORMS=linux/amd64 make WHAT=cmd/kube-discovery" +$ _output/dockerized/bin/linux/amd64/kube-discovery +2016/08/23 19:17:28 Listening for requests on port 9898. + +``` + +## Running in Docker + +This image is published at: gcr.io/google_containers/kube-discovery + +`docker run -d -p 9898:9898 -v /tmp/secret/ca.pem:/tmp/secret/ca.pem -v /tmp/secret/endpoint-list.json:/tmp/secret/endpoint-list.json -v /tmp/secret/token-map.json:/tmp/secret/token-map.json --name kubediscovery gcr.io/google_containers/kube-discovery` + +## Testing the API + +`curl "http://localhost:9898/cluster-info/v1/?token-id=TOKENID"` + +You should see JSON containing a signed payload. For code to verify and decode that payload see handler_test.go. + + +[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/cluster/images/kube-discovery/README.md?pixel)]() diff --git a/pkg/kubediscovery/handlers.go b/cmd/kube-discovery/app/handlers.go similarity index 92% rename from pkg/kubediscovery/handlers.go rename to cmd/kube-discovery/app/handlers.go index d4d7305db50..2d974a44448 100644 --- a/pkg/kubediscovery/handlers.go +++ b/cmd/kube-discovery/app/handlers.go @@ -1,19 +1,22 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2014 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 kubediscovery + +package discovery import ( - "encoding/base64" "encoding/json" "errors" "fmt" @@ -45,13 +48,13 @@ type fsCALoader struct { } func (cl *fsCALoader) LoadPEM() (string, error) { - if cl.certData != "" { + if cl.certData == "" { data, err := ioutil.ReadFile(CAPath) if err != nil { return "", err } - cl.certData = base64.StdEncoding.EncodeToString(data) + cl.certData = string(data) } return cl.certData, nil @@ -92,11 +95,11 @@ type endpointsLoader interface { LoadList() ([]string, error) } -type jsonFileEnpointsLoader struct { +type jsonFileEndpointsLoader struct { endpoints []string } -func (el *jsonFileEnpointsLoader) LoadList() ([]string, error) { +func (el *jsonFileEndpointsLoader) LoadList() ([]string, error) { if len(el.endpoints) == 0 { data, err := ioutil.ReadFile(EndpointListPath) if err != nil { @@ -121,7 +124,7 @@ func NewClusterInfoHandler() *ClusterInfoHandler { return &ClusterInfoHandler{ tokenLoader: &jsonFileTokenLoader{}, caLoader: &fsCALoader{}, - endpointsLoader: &jsonFileEnpointsLoader{}, + endpointsLoader: &jsonFileEndpointsLoader{}, } } @@ -130,7 +133,7 @@ func (cih *ClusterInfoHandler) ServeHTTP(resp http.ResponseWriter, req *http.Req log.Printf("Got token ID: %s", tokenID) token, err := cih.tokenLoader.LoadAndLookup(tokenID) if err != nil { - log.Printf("Invalid token: %s", err) + log.Print(err) http.Error(resp, "Forbidden", http.StatusForbidden) return } @@ -138,6 +141,7 @@ func (cih *ClusterInfoHandler) ServeHTTP(resp http.ResponseWriter, req *http.Req // TODO probably should not leak server-side errors to the client caPEM, err := cih.caLoader.LoadPEM() + log.Printf("Loaded CA: %s", caPEM) if err != nil { err = fmt.Errorf("Error loading root CA certificate data: %s", err) log.Println(err) @@ -159,7 +163,10 @@ func (cih *ClusterInfoHandler) ServeHTTP(resp http.ResponseWriter, req *http.Req } // Instantiate an signer using HMAC-SHA256. - signer, err := jose.NewSigner(jose.HS256, []byte(token)) + hmacKey := []byte(token) + + log.Printf("Key is %d bytes long", len(hmacKey)) + signer, err := jose.NewSigner(jose.HS256, hmacKey) if err != nil { err = fmt.Errorf("Error creating JWS signer: %s", err) log.Println(err) diff --git a/cmd/kube-discovery/app/handlers_test.go b/cmd/kube-discovery/app/handlers_test.go new file mode 100644 index 00000000000..2aaaa597d90 --- /dev/null +++ b/cmd/kube-discovery/app/handlers_test.go @@ -0,0 +1,208 @@ +/* +Copyright 2014 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 discovery + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/square/go-jose" +) + +type mockTokenLoader struct { + tokenID string + token string +} + +func (tl *mockTokenLoader) LoadAndLookup(tokenID string) (string, error) { + if tokenID == tl.tokenID { + return tl.token, nil + } + return "", errors.New(fmt.Sprintf("invalid token: %s", tokenID)) +} + +const mockEndpoint1 = "https://192.168.1.5:8080" +const mockEndpoint2 = "https://192.168.1.6:8080" + +type mockEndpointsLoader struct { +} + +func (el *mockEndpointsLoader) LoadList() ([]string, error) { + return []string{mockEndpoint1, mockEndpoint2}, nil +} + +const mockCA = "---BEGIN------END---DUMMYDATA" + +type mockCALoader struct { +} + +func (cl *mockCALoader) LoadPEM() (string, error) { + return mockCA, nil +} + +const mockTokenID = "AAAAAA" +const mockToken = "9537434E638E4378" + +const mockTokenIDCustom = "SHAREDSECRET" +const mockTokenCustom = "VERYSECRETTOKEN" + +func TestClusterInfoIndex(t *testing.T) { + longToken := strings.Repeat("a", 1000) + tests := map[string]struct { + tokenID string // token ID the mock loader will use + token string // token the mock loader will use + reqTokenID string // token ID the will request with + reqToken string // token the caller will validate response with + expStatus int + expVerifyFailure bool + }{ + "no token": { + tokenID: mockTokenID, + token: mockToken, + reqTokenID: "", + reqToken: "", + expStatus: http.StatusForbidden, + }, + "valid token ID": { + tokenID: mockTokenID, + token: mockToken, + reqTokenID: mockTokenID, + reqToken: mockToken, + expStatus: http.StatusOK, + }, + "valid arbitrary string token": { + tokenID: mockTokenIDCustom, + token: mockTokenCustom, + reqTokenID: mockTokenIDCustom, + reqToken: mockTokenCustom, + expStatus: http.StatusOK, + }, + "valid arbitrary long string token": { + tokenID: "LONGTOKENTEST", + token: longToken, + reqTokenID: "LONGTOKENTEST", + reqToken: longToken, + expStatus: http.StatusOK, + }, + "invalid token ID": { + tokenID: mockTokenID, + token: mockToken, + reqTokenID: "BADTOKENID", + reqToken: mockToken, + expStatus: http.StatusForbidden, + }, + "invalid token": { + tokenID: mockTokenID, + token: mockToken, + reqTokenID: mockTokenID, + reqToken: "badtoken", + expStatus: http.StatusOK, + expVerifyFailure: true, + }, + } + + for name, test := range tests { + t.Logf("Running test: %s", name) + tokenLoader := &mockTokenLoader{test.tokenID, test.token} + // Create a request to pass to our handler. We don't have any query parameters for now, so we'll + // pass 'nil' as the third parameter. + url := "/cluster-info/v1/" + if test.tokenID != "" { + url = fmt.Sprintf("%s?token-id=%s", url, test.reqTokenID) + } + req, err := http.NewRequest("GET", url, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + handler := &ClusterInfoHandler{ + tokenLoader: tokenLoader, + caLoader: &mockCALoader{}, + endpointsLoader: &mockEndpointsLoader{}, + } + + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != test.expStatus { + t.Errorf("handler returned wrong status code: got %v want %v", + status, test.expStatus) + continue + } + + // If we were expecting valid status validate the body: + if test.expStatus == http.StatusOK { + var ci ClusterInfo + + body := string(rr.Body.Bytes()) + + // Parse the JSON web signature: + jws, err := jose.ParseSigned(body) + if err != nil { + t.Errorf("Error parsing JWS from request body: %s", err) + continue + } + + // Now we can verify the signature on the payload. An error here would + // indicate the the message failed to verify, e.g. because the signature was + // broken or the message was tampered with. + var clusterInfoBytes []byte + hmacTestKey := []byte(test.reqToken) + clusterInfoBytes, err = jws.Verify(hmacTestKey) + + if test.expVerifyFailure { + if err == nil { + t.Errorf("Signature verification did not fail as expected.") + } + // We are done the test here either way. + continue + } + + if err != nil { + t.Errorf("Error verifing signature: %s", err) + continue + } + + err = json.Unmarshal(clusterInfoBytes, &ci) + if err != nil { + t.Errorf("Unable to unmarshall payload to JSON: error=%s body=%s", err, rr.Body.String()) + continue + } + if len(ci.Endpoints) != 2 { + t.Errorf("Expected 2 endpoints, got: %d", len(ci.Endpoints)) + } + if mockEndpoint1 != ci.Endpoints[0] { + t.Errorf("Unexpected endpoint: %s", ci.Endpoints[0]) + } + if mockEndpoint2 != ci.Endpoints[1] { + t.Errorf("Unexpected endpoint: %s", ci.Endpoints[1]) + } + + if len(ci.CertificateAuthorities) != 1 { + t.Errorf("Expected 1 root certificate, got: %d", len(ci.CertificateAuthorities)) + } + if ci.CertificateAuthorities[0] != mockCA { + t.Errorf("Expected CA: %s, got: %s", mockCA, ci.CertificateAuthorities[0]) + } + } + } +} diff --git a/pkg/kubediscovery/model.go b/cmd/kube-discovery/app/model.go similarity index 92% rename from pkg/kubediscovery/model.go rename to cmd/kube-discovery/app/model.go index d0aaedffba3..652c00f0ab5 100644 --- a/pkg/kubediscovery/model.go +++ b/cmd/kube-discovery/app/model.go @@ -1,16 +1,20 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2014 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 kubediscovery + +package discovery type ClusterInfo struct { // TODO Kind, apiVersion diff --git a/pkg/kubediscovery/routes.go b/cmd/kube-discovery/app/routes.go similarity index 94% rename from pkg/kubediscovery/routes.go rename to cmd/kube-discovery/app/routes.go index c0df303b3db..55dfa461962 100644 --- a/pkg/kubediscovery/routes.go +++ b/cmd/kube-discovery/app/routes.go @@ -1,16 +1,20 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2014 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 kubediscovery + +package discovery import ( "net/http" diff --git a/cmd/kube-discovery/dummy.go b/cmd/kube-discovery/dummy.go deleted file mode 100644 index 17711df5045..00000000000 --- a/cmd/kube-discovery/dummy.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2014 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 main - -import ( - _ "github.com/square/go-jose" -) - -func main() { -} diff --git a/cmd/kubediscovery/kubediscovery.go b/cmd/kube-discovery/kubediscovery.go similarity index 93% rename from cmd/kubediscovery/kubediscovery.go rename to cmd/kube-discovery/kubediscovery.go index 3194edb05bf..b37e602a1f9 100644 --- a/cmd/kubediscovery/kubediscovery.go +++ b/cmd/kube-discovery/kubediscovery.go @@ -1,15 +1,19 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2014 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 main import ( @@ -17,7 +21,7 @@ import ( "net/http" "os" - kd "k8s.io/kubernetes/pkg/kubediscovery" + kd "k8s.io/kubernetes/cmd/kube-discovery/app" ) func main() { diff --git a/discovery/Dockerfile b/discovery/Dockerfile deleted file mode 100644 index 2e500ec31b2..00000000000 --- a/discovery/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM golang - -ADD kubediscovery /usr/bin/ -ENTRYPOINT /usr/bin/kubernetes-discovery - -EXPOSE 8080 diff --git a/discovery/README.md b/discovery/README.md deleted file mode 100644 index 3ade93b4a18..00000000000 --- a/discovery/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# kubernetes-discovery -An initial implementation of a Kubernetes discovery service using JSON Web Signatures. - -This prototype is expected to be run by Kubernetes itself for the time being, -and will hopefully be merged into the core API at a later time. - -## Requirements - -Generate a CA cert save it to: /tmp/secret/ca.pem to run the service or unit tests. (will not be required for unit tests for long) Similarly when run within kubernetes we expect a secret to be provided at this location as well. (see below) - -## Build And Run From Source - -``` -$ make WHAT=cmd/kubediscovery -$ _output/local/bin/linux/amd64/kubediscovery -2016/08/23 19:17:28 Listening for requests on port 9898. - -``` - -## Running in Docker - -This image is published temporarily on Docker Hub as dgoodwin/kubediscovery - -`docker run --rm -p 9898:9898 -v /tmp/secret/ca.pem:/tmp/secret/ca.pem --name kubediscovery dgoodwin/kubediscovery` - -## Running in Kubernetes - -A dummy certificate is included in ca-secret.yaml. - -``` -kubectl create -f ca-secret.yaml -kubectl create -f kubediscovery.yaml -``` - -## Testing the API - -`curl "http://localhost:9898/cluster-info/v1/?token-id=TOKENID"` - -You should see JSON containing a signed payload. For code to verify and decode that payload see handler_test.go. diff --git a/discovery/ca-secret.yaml b/discovery/ca-secret.yaml deleted file mode 100644 index f0811c342fa..00000000000 --- a/discovery/ca-secret.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ca-secret -type: Opaque -data: - ca.pem: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR4RENDQXF5Z0F3SUJBZ0lVV3pqUDl5RUk0eHlRSnBzVHVERU4yV2ROaUFzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2FERUxNQWtHQTFVRUJoTUNWVk14RHpBTkJnTlZCQWdUQms5eVpXZHZiakVSTUE4R0ExVUVCeE1JVUc5eQpkR3hoYm1ReEV6QVJCZ05WQkFvVENrdDFZbVZ5Ym1WMFpYTXhDekFKQmdOVkJBc1RBa05CTVJNd0VRWURWUVFECkV3cExkV0psY201bGRHVnpNQjRYRFRFMk1EZ3hNVEUyTkRnd01Gb1hEVEl4TURneE1ERTJORGd3TUZvd2FERUwKTUFrR0ExVUVCaE1DVlZNeER6QU5CZ05WQkFnVEJrOXlaV2R2YmpFUk1BOEdBMVVFQnhNSVVHOXlkR3hoYm1ReApFekFSQmdOVkJBb1RDa3QxWW1WeWJtVjBaWE14Q3pBSkJnTlZCQXNUQWtOQk1STXdFUVlEVlFRREV3cExkV0psCmNtNWxkR1Z6TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF3QkhNOGN6anc0Q1cKK05wbklhV012RzZlcVhtelNZT20vbHdaNUhOMnVLck9xaTNHYUUyTjFKd2tzcGRmMXNOUGFZMHdPR2xkbURIZgoxSnlyTW8rUFdLVUVjWko1WGE4Vm02d2I0MlpjczN3MEp5dlEzWFJjaDQyMFJRWGRKayszcmMybWRvSVRkL0lmCnZjWms0N0RzQTMrQU5QSUlSTzdWRmZpS1JNRFpTUDR1OThnVjI2eW1zbjc0TzFVKzNVUHR1TEFTVTFLck9FTk4KR01FWG0ydTJpdmVvbTJrbjFlZTZuM1hCR1o2bU52cUNPdWUxRXdza0gvWkhoUVh1UDgyV1U5dVk0aGVORnoyQwpBNmR0Q0Q0c3Z6eHc3ZFQ2cVhsV0ZIWUYrc3VLVDhXNkczd3NkOWxzV0ZVY0ZWL0lwaTVobEVaTWprNFNoY3RqCjdpYnlrRURKM1FJREFRQUJvMll3WkRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RWdZRFZSMFRBUUgvQkFnd0JnRUIKL3dJQkFqQWRCZ05WSFE0RUZnUVVOdnhRZ3o5ZTNXS2VscU1KTmZXNE1KUHYzc0V3SHdZRFZSMGpCQmd3Rm9BVQpOdnhRZ3o5ZTNXS2VscU1KTmZXNE1KUHYzc0V3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUp1TUhYUms1TEVyCmxET1p4Mm9aRUNQZ29reXMzSGJsM05oempXd2pncXdxNVN6a011V3QrUnVkdnRTK0FUQjFtTjRjYTN0eSt2bWcKT09heTkvaDZoditmSE5jZHpYdWR5dFZYZW1KN3F4ZFoxd25DUUcwdnpqOWRZY0xFSGpJWi94dU1jNlY3dnJ4YwpSc0preGp5aE01UXBmRHd0eVZKeGpkUmVBZ0huSyswTkNieHdtQ3cyRGIvOXpudm9LWGk4TEQwbkQzOFQxY3R3CmhmdGxwTmRoZXFNRlpEZXBuTUYwY2g2cHo5TFV5Mkh1cnhrV2dkWVNjY2VNU0hPTzBMcG4xeVVBMWczOTJhUjUKWk81Zm5KMW95Vm1LVWFCeDJCMndsSVlUSXlES1ZiMnY1UXNHbnYvRHVTMDZhcmVLTmsvTGpHRTRlMXlHOHJkcwpacnZHMzNvUmtEbz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= diff --git a/discovery/kubediscovery.yaml b/discovery/kubediscovery.yaml deleted file mode 100644 index feaa39de540..00000000000 --- a/discovery/kubediscovery.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: ReplicaSet -metadata: - name: kubediscovery - # these labels can be applied automatically - # from the labels in the pod template if not set - # labels: - # app: guestbook - # tier: frontend -spec: - # this replicas value is default - # modify it according to your case - replicas: 1 - # selector can be applied automatically - # from the labels in the pod template if not set, - # but we are specifying the selector here to - # demonstrate its usage. - template: - metadata: - labels: - app: kubediscovery - spec: - hostNetwork: true - containers: - - name: kubediscovery - image: dgoodwin/kubediscovery - imagePullPolicy: IfNotPresent - ports: - - containerPort: 9898 - volumeMounts: - - name: ca-secret-vol - mountPath: /tmp/secret - readOnly: true - volumes: - - name: ca-secret-vol - secret: - secretName: ca-secret diff --git a/pkg/kubediscovery/handlers_test.go b/pkg/kubediscovery/handlers_test.go deleted file mode 100644 index 2374fef911b..00000000000 --- a/pkg/kubediscovery/handlers_test.go +++ /dev/null @@ -1,100 +0,0 @@ -/* -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 kubediscovery - -import ( - "encoding/json" - "fmt" - "net/http" - "net/http/httptest" - "testing" - - "github.com/square/go-jose" -) - -func TestClusterInfoIndex(t *testing.T) { - tests := map[string]struct { - url string - expStatus int - }{ - "no token": { - "/cluster-info/v1/", - http.StatusForbidden, - }, - "valid token": { - fmt.Sprintf("/cluster-info/v1/?token-id=%s", tempTokenId), - http.StatusOK, - }, - "invalid token": { - "/cluster-info/v1/?token-id=JUNK", - http.StatusForbidden, - }, - } - - for name, test := range tests { - t.Logf("Running test: %s", name) - // Create a request to pass to our handler. We don't have any query parameters for now, so we'll - // pass 'nil' as the third parameter. - req, err := http.NewRequest("GET", test.url, nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - // TODO: mock/stub here - handler := NewClusterInfoHandler() - - handler.ServeHTTP(rr, req) - - if status := rr.Code; status != test.expStatus { - t.Errorf("handler returned wrong status code: got %v want %v", - status, test.expStatus) - continue - } - - // If we were expecting valid status validate the body: - if test.expStatus == http.StatusOK { - var ci ClusterInfo - - body := string(rr.Body.Bytes()) - - // Parse the JSON web signature: - jws, err := jose.ParseSigned(body) - if err != nil { - t.Errorf("Error parsing JWS from request body: %s", err) - continue - } - - // Now we can verify the signature on the payload. An error here would - // indicate the the message failed to verify, e.g. because the signature was - // broken or the message was tampered with. - var clusterInfoBytes []byte - hmacTestKey := fromHexBytes(tempToken) - clusterInfoBytes, err = jws.Verify(hmacTestKey) - if err != nil { - t.Errorf("Error verifing signature: %s", err) - continue - } - - err = json.Unmarshal(clusterInfoBytes, &ci) - if err != nil { - t.Errorf("Unable to unmarshall payload to JSON: error=%s body=%s", err, rr.Body.String()) - continue - } - if ci.RootCertificates == "" { - t.Error("No root certificates in response") - continue - } - } - } -}