diff --git a/cmd/BUILD b/cmd/BUILD index 3e0beea93d..64074c630d 100644 --- a/cmd/BUILD +++ b/cmd/BUILD @@ -20,7 +20,6 @@ filegroup( "//cmd/genswaggertypedocs:all-srcs", "//cmd/genutils:all-srcs", "//cmd/genyaml:all-srcs", - "//cmd/gke-certificates-controller:all-srcs", "//cmd/hyperkube:all-srcs", "//cmd/importverifier:all-srcs", "//cmd/kube-apiserver:all-srcs", diff --git a/cmd/gke-certificates-controller/BUILD b/cmd/gke-certificates-controller/BUILD deleted file mode 100644 index 2799b64369..0000000000 --- a/cmd/gke-certificates-controller/BUILD +++ /dev/null @@ -1,42 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_binary", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = ["main.go"], - importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller", - deps = [ - "//cmd/gke-certificates-controller/app:go_default_library", - "//pkg/kubectl/util/logs:go_default_library", - "//pkg/version/verflag:go_default_library", - "//vendor/github.com/spf13/pflag:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//cmd/gke-certificates-controller/app:all-srcs", - ], - tags = ["automanaged"], -) - -go_binary( - name = "gke-certificates-controller", - embed = [":go_default_library"], - importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller", -) diff --git a/cmd/gke-certificates-controller/OWNERS b/cmd/gke-certificates-controller/OWNERS deleted file mode 100644 index 8ab9ac5f08..0000000000 --- a/cmd/gke-certificates-controller/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -approvers: -- pipejakob -- mikedanese -- roberthbailey -reviewers: -- pipejakob -- mikedanese -- roberthbailey diff --git a/cmd/gke-certificates-controller/app/BUILD b/cmd/gke-certificates-controller/app/BUILD deleted file mode 100644 index f7f1d24af6..0000000000 --- a/cmd/gke-certificates-controller/app/BUILD +++ /dev/null @@ -1,62 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", - "go_test", -) - -go_library( - name = "go_default_library", - srcs = [ - "gke_certificates_controller.go", - "gke_signer.go", - "options.go", - ], - importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller/app", - deps = [ - "//pkg/api/legacyscheme:go_default_library", - "//pkg/apis/certificates/install:go_default_library", - "//pkg/controller:go_default_library", - "//pkg/controller/certificates:go_default_library", - "//vendor/github.com/golang/glog:go_default_library", - "//vendor/github.com/spf13/cobra:go_default_library", - "//vendor/github.com/spf13/pflag:go_default_library", - "//vendor/k8s.io/api/certificates/v1beta1:go_default_library", - "//vendor/k8s.io/api/core/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", - "//vendor/k8s.io/apiserver/pkg/util/webhook:go_default_library", - "//vendor/k8s.io/client-go/informers:go_default_library", - "//vendor/k8s.io/client-go/kubernetes:go_default_library", - "//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", - "//vendor/k8s.io/client-go/plugin/pkg/client/auth:go_default_library", - "//vendor/k8s.io/client-go/rest:go_default_library", - "//vendor/k8s.io/client-go/tools/clientcmd:go_default_library", - "//vendor/k8s.io/client-go/tools/record:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], -) - -go_test( - name = "go_default_test", - srcs = ["gke_signer_test.go"], - embed = [":go_default_library"], - importpath = "k8s.io/kubernetes/cmd/gke-certificates-controller/app", - deps = [ - "//vendor/k8s.io/api/certificates/v1beta1:go_default_library", - "//vendor/k8s.io/client-go/tools/record:go_default_library", - ], -) diff --git a/cmd/gke-certificates-controller/app/gke_certificates_controller.go b/cmd/gke-certificates-controller/app/gke_certificates_controller.go deleted file mode 100644 index 9e9db774c9..0000000000 --- a/cmd/gke-certificates-controller/app/gke_certificates_controller.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -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 app implements a server that runs a stand-alone version of the -// certificates controller for GKE clusters. -package app - -import ( - "time" - - "k8s.io/api/core/v1" - "k8s.io/client-go/informers" - clientset "k8s.io/client-go/kubernetes" - v1core "k8s.io/client-go/kubernetes/typed/core/v1" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/tools/record" - "k8s.io/kubernetes/pkg/api/legacyscheme" - "k8s.io/kubernetes/pkg/controller" - "k8s.io/kubernetes/pkg/controller/certificates" - - // Install all auth plugins - _ "k8s.io/client-go/plugin/pkg/client/auth" - - "github.com/golang/glog" - "github.com/spf13/cobra" -) - -// NewGKECertificatesControllerCommand creates a new *cobra.Command with default parameters. -func NewGKECertificatesControllerCommand() *cobra.Command { - cmd := &cobra.Command{ - Use: "gke-certificates-controller", - Long: `The Kubernetes GKE certificates controller is a daemon that -handles auto-approving and signing certificates for GKE clusters.`, - } - - return cmd -} - -// Run runs the GKECertificatesController. This should never exit. -func Run(s *GKECertificatesController) error { - kubeconfig, err := clientcmd.BuildConfigFromFlags("", s.Kubeconfig) - if err != nil { - return err - } - - kubeClient, err := clientset.NewForConfig(restclient.AddUserAgent(kubeconfig, "gke-certificates-controller")) - if err != nil { - return err - } - - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartLogging(glog.Infof) - eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: v1core.New(kubeClient.CoreV1().RESTClient()).Events("")}) - recorder := eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "gke-certificates-controller"}) - - clientBuilder := controller.SimpleControllerClientBuilder{ClientConfig: kubeconfig} - client := clientBuilder.ClientOrDie("certificate-controller") - - sharedInformers := informers.NewSharedInformerFactory(client, time.Duration(12)*time.Hour) - - signer, err := NewGKESigner(s.ClusterSigningGKEKubeconfig, s.ClusterSigningGKERetryBackoff.Duration, recorder, client) - if err != nil { - return err - } - - controller := certificates.NewCertificateController( - client, - sharedInformers.Certificates().V1beta1().CertificateSigningRequests(), - signer.handle, - ) - - sharedInformers.Start(nil) - controller.Run(5, nil) // runs forever - panic("unreachable") -} diff --git a/cmd/gke-certificates-controller/app/gke_signer.go b/cmd/gke-certificates-controller/app/gke_signer.go deleted file mode 100644 index 69552a417d..0000000000 --- a/cmd/gke-certificates-controller/app/gke_signer.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -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 app - -import ( - "encoding/json" - "fmt" - "time" - - "github.com/golang/glog" - - capi "k8s.io/api/certificates/v1beta1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/util/webhook" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/record" - "k8s.io/kubernetes/pkg/api/legacyscheme" - _ "k8s.io/kubernetes/pkg/apis/certificates/install" - "k8s.io/kubernetes/pkg/controller/certificates" -) - -var ( - groupVersions = []schema.GroupVersion{capi.SchemeGroupVersion} -) - -// GKESigner uses external calls to GKE in order to sign certificate signing -// requests. -type GKESigner struct { - webhook *webhook.GenericWebhook - kubeConfigFile string - retryBackoff time.Duration - recorder record.EventRecorder - client clientset.Interface -} - -// NewGKESigner will create a new instance of a GKESigner. -func NewGKESigner(kubeConfigFile string, retryBackoff time.Duration, recorder record.EventRecorder, client clientset.Interface) (*GKESigner, error) { - webhook, err := webhook.NewGenericWebhook(legacyscheme.Registry, legacyscheme.Codecs, kubeConfigFile, groupVersions, retryBackoff) - if err != nil { - return nil, err - } - - return &GKESigner{ - webhook: webhook, - kubeConfigFile: kubeConfigFile, - retryBackoff: retryBackoff, - recorder: recorder, - client: client, - }, nil -} - -func (s *GKESigner) handle(csr *capi.CertificateSigningRequest) error { - if !certificates.IsCertificateRequestApproved(csr) { - return nil - } - csr, err := s.sign(csr) - if err != nil { - return fmt.Errorf("error auto signing csr: %v", err) - } - _, err = s.client.CertificatesV1beta1().CertificateSigningRequests().UpdateStatus(csr) - if err != nil { - return fmt.Errorf("error updating signature for csr: %v", err) - } - return nil -} - -// Sign will make an external call to GKE order to sign the given -// *capi.CertificateSigningRequest, using the GKESigner's -// kubeConfigFile. -func (s *GKESigner) sign(csr *capi.CertificateSigningRequest) (*capi.CertificateSigningRequest, error) { - result := s.webhook.WithExponentialBackoff(func() rest.Result { - return s.webhook.RestClient.Post().Body(csr).Do() - }) - - if err := result.Error(); err != nil { - if bodyErr := s.resultBodyError(result); bodyErr != nil { - return nil, s.webhookError(csr, bodyErr) - } - return nil, s.webhookError(csr, err) - } - - var statusCode int - if result.StatusCode(&statusCode); statusCode < 200 || statusCode >= 300 { - return nil, s.webhookError(csr, fmt.Errorf("received unsuccessful response code from webhook: %d", statusCode)) - } - - result_csr := &capi.CertificateSigningRequest{} - - if err := result.Into(result_csr); err != nil { - return nil, s.webhookError(result_csr, err) - } - - // Keep the original CSR intact, and only update fields we expect to change. - csr.Status.Certificate = result_csr.Status.Certificate - return csr, nil -} - -func (s *GKESigner) webhookError(csr *capi.CertificateSigningRequest, err error) error { - glog.V(2).Infof("error contacting webhook backend: %s", err) - s.recorder.Eventf(csr, "Warning", "SigningError", "error while calling GKE: %v", err) - return err -} - -// signResultError represents the structured response body of a failed call to -// GKE's SignCertificate API. -type signResultError struct { - Error struct { - Code int - Message string - Status string - } -} - -// resultBodyError attempts to extract an error out of a response body. -func (s *GKESigner) resultBodyError(result rest.Result) error { - body, _ := result.Raw() - var sre signResultError - if err := json.Unmarshal(body, &sre); err == nil { - return fmt.Errorf("server responded with error: %s", sre.Error.Message) - } - return nil -} diff --git a/cmd/gke-certificates-controller/app/gke_signer_test.go b/cmd/gke-certificates-controller/app/gke_signer_test.go deleted file mode 100644 index 5fcd54b568..0000000000 --- a/cmd/gke-certificates-controller/app/gke_signer_test.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -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 app - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - "text/template" - "time" - - certificates "k8s.io/api/certificates/v1beta1" - "k8s.io/client-go/tools/record" -) - -const kubeConfigTmpl = ` -clusters: -- cluster: - server: {{ .Server }} - name: testcluster -users: -- user: - username: admin - password: mypass -` - -func TestGKESigner(t *testing.T) { - goodResponse := &certificates.CertificateSigningRequest{ - Status: certificates.CertificateSigningRequestStatus{ - Certificate: []byte("fake certificate"), - }, - } - - invalidResponse := "{ \"status\": \"Not a properly formatted CSR response\" }" - - cases := []struct { - mockResponse interface{} - expected []byte - failCalls int - wantErr bool - }{ - { - mockResponse: goodResponse, - expected: goodResponse.Status.Certificate, - wantErr: false, - }, - { - mockResponse: goodResponse, - expected: goodResponse.Status.Certificate, - failCalls: 3, - wantErr: false, - }, - { - mockResponse: goodResponse, - failCalls: 20, - wantErr: true, - }, - { - mockResponse: invalidResponse, - wantErr: true, - }, - } - - for _, c := range cases { - server, err := newTestServer(c.mockResponse, c.failCalls) - if err != nil { - t.Fatalf("error creating test server") - } - - kubeConfig, err := ioutil.TempFile("", "kubeconfig") - if err != nil { - t.Fatalf("error creating kubeconfig tempfile: %v", err) - } - - tmpl, err := template.New("kubeconfig").Parse(kubeConfigTmpl) - if err != nil { - t.Fatalf("error creating kubeconfig template: %v", err) - } - - data := struct{ Server string }{server.httpserver.URL} - - if err := tmpl.Execute(kubeConfig, data); err != nil { - t.Fatalf("error executing kubeconfig template: %v", err) - } - - if err := kubeConfig.Close(); err != nil { - t.Fatalf("error closing kubeconfig template: %v", err) - } - - signer, err := NewGKESigner(kubeConfig.Name(), time.Duration(500)*time.Millisecond, record.NewFakeRecorder(10), nil) - if err != nil { - t.Fatalf("error creating GKESigner: %v", err) - } - - cert, err := signer.sign(&certificates.CertificateSigningRequest{}) - - if c.wantErr { - if err == nil { - t.Errorf("wanted error during GKE.Sign() call, got not none") - } - } else { - if err != nil { - t.Errorf("error while signing: %v", err) - } - - if !bytes.Equal(cert.Status.Certificate, c.expected) { - t.Errorf("response certificate didn't match expected %v: %v", c.expected, cert) - } - } - } -} - -type testServer struct { - httpserver *httptest.Server - failCalls int - response interface{} -} - -func newTestServer(response interface{}, failCalls int) (*testServer, error) { - server := &testServer{ - response: response, - failCalls: failCalls, - } - - server.httpserver = httptest.NewServer(server) - return server, nil -} - -func (s *testServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if s.failCalls > 0 { - http.Error(w, "Service unavailable", 500) - s.failCalls-- - } else { - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(s.response) - } -} diff --git a/cmd/gke-certificates-controller/app/options.go b/cmd/gke-certificates-controller/app/options.go deleted file mode 100644 index 56ce237fc7..0000000000 --- a/cmd/gke-certificates-controller/app/options.go +++ /dev/null @@ -1,54 +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 app implements a server that runs a stand-alone version of the -// certificates controller. -package app - -import ( - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/spf13/pflag" -) - -// GKECertificatesController is the main context object for the package. -type GKECertificatesController struct { - Kubeconfig string - ClusterSigningGKEKubeconfig string - ClusterSigningGKERetryBackoff metav1.Duration - ApproveAllKubeletCSRsForGroup string -} - -// Create a new instance of a GKECertificatesController with default parameters. -func NewGKECertificatesController() *GKECertificatesController { - s := &GKECertificatesController{ - ClusterSigningGKERetryBackoff: metav1.Duration{Duration: 500 * time.Millisecond}, - } - return s -} - -// AddFlags adds flags for a specific GKECertificatesController to the -// specified FlagSet. -func (s *GKECertificatesController) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") - - fs.StringVar(&s.ClusterSigningGKEKubeconfig, "cluster-signing-gke-kubeconfig", s.ClusterSigningGKEKubeconfig, "If set, use the kubeconfig file to call GKE to sign cluster-scoped certificates instead of using a local private key.") - fs.DurationVar(&s.ClusterSigningGKERetryBackoff.Duration, "cluster-signing-gke-retry-backoff", s.ClusterSigningGKERetryBackoff.Duration, "The initial backoff to use when retrying requests to GKE. Additional attempts will use exponential backoff.") - - fs.StringVar(&s.ApproveAllKubeletCSRsForGroup, "insecure-experimental-approve-all-kubelet-csrs-for-group", s.ApproveAllKubeletCSRsForGroup, "The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.") -} diff --git a/cmd/gke-certificates-controller/main.go b/cmd/gke-certificates-controller/main.go deleted file mode 100644 index a0679d95d6..0000000000 --- a/cmd/gke-certificates-controller/main.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -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. -*/ - -// The GKE certificates controller is responsible for monitoring certificate -// signing requests and (potentially) auto-approving and signing them within -// GKE. -package main - -import ( - "fmt" - "os" - - "k8s.io/apiserver/pkg/util/flag" - "k8s.io/kubernetes/cmd/gke-certificates-controller/app" - "k8s.io/kubernetes/pkg/kubectl/util/logs" - "k8s.io/kubernetes/pkg/version/verflag" - - "github.com/spf13/pflag" -) - -// TODO(pipejakob): Move this entire cmd directory into its own repo -func main() { - s := app.NewGKECertificatesController() - s.AddFlags(pflag.CommandLine) - - flag.InitFlags() - logs.InitLogs() - defer logs.FlushLogs() - - verflag.PrintAndExitIfRequested() - - if err := app.Run(s); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } -} diff --git a/hack/.golint_failures b/hack/.golint_failures index b5c306855f..b4c1413e97 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -1,5 +1,4 @@ cluster/images/etcd-version-monitor -cmd/gke-certificates-controller/app cmd/hyperkube cmd/kube-controller-manager/app cmd/kube-proxy/app diff --git a/hack/lib/golang.sh b/hack/lib/golang.sh index 1e55ee6c8f..1c234d2524 100755 --- a/hack/lib/golang.sh +++ b/hack/lib/golang.sh @@ -186,15 +186,11 @@ readonly KUBE_TEST_SERVER_PLATFORMS=("${KUBE_SERVER_PLATFORMS[@]}") # Setting to 40 to provide some headroom readonly KUBE_PARALLEL_BUILD_MEMORY=40 -# TODO(pipejakob) gke-certificates-controller is included here to exercise its -# compilation, but it doesn't need to be distributed in any of our tars. Its -# code is only living in this repo temporarily until it finds a new home. readonly KUBE_ALL_TARGETS=( "${KUBE_SERVER_TARGETS[@]}" "${KUBE_CLIENT_TARGETS[@]}" "${KUBE_TEST_TARGETS[@]}" "${KUBE_TEST_SERVER_TARGETS[@]}" - cmd/gke-certificates-controller ) readonly KUBE_ALL_BINARIES=("${KUBE_ALL_TARGETS[@]##*/}")