diff --git a/api/handler.go b/api/handler.go index 865c9170..baf67116 100644 --- a/api/handler.go +++ b/api/handler.go @@ -32,20 +32,21 @@ import ( "github.com/google/cadvisor/events" info "github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/manager" + "github.com/google/cadvisor/utils" ) const ( apiResource = "/api/" ) -func RegisterHandlers(m manager.Manager) error { +func RegisterHandlers(mux utils.Mux, m manager.Manager) error { apiVersions := getApiVersions() supportedApiVersions := make(map[string]ApiVersion, len(apiVersions)) for _, v := range apiVersions { supportedApiVersions[v.Version()] = v } - http.HandleFunc(apiResource, func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(apiResource, func(w http.ResponseWriter, r *http.Request) { err := handleRequest(supportedApiVersions, m, w, r) if err != nil { http.Error(w, err.Error(), 500) diff --git a/cadvisor.go b/cadvisor.go index 5c4755ec..583ccf5e 100644 --- a/cadvisor.go +++ b/cadvisor.go @@ -74,13 +74,16 @@ func main() { glog.Fatalf("Failed to create a Container Manager: %s", err) } + mux := http.DefaultServeMux + + // TODO(vmarmol): Use Kubernetes'. // Basic health handler. - if err := healthz.RegisterHandler(); err != nil { + if err := healthz.RegisterHandler(mux); err != nil { glog.Fatalf("Failed to register healthz handler: %s", err) } // Validation/Debug handler. - http.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) { err := validate.HandleRequest(w, containerManager) if err != nil { fmt.Fprintf(w, "%s", err) @@ -88,12 +91,12 @@ func main() { }) // Register API handler. - if err := api.RegisterHandlers(containerManager); err != nil { + if err := api.RegisterHandlers(mux, containerManager); err != nil { glog.Fatalf("Failed to register API handlers: %s", err) } // Redirect / to containers page. - http.Handle("/", http.RedirectHandler(pages.ContainersPage, http.StatusTemporaryRedirect)) + mux.Handle("/", http.RedirectHandler(pages.ContainersPage, http.StatusTemporaryRedirect)) var authenticated bool = false @@ -102,8 +105,8 @@ func main() { glog.Infof("Using auth file %s", *httpAuthFile) secrets := auth.HtpasswdFileProvider(*httpAuthFile) authenticator := auth.NewBasicAuthenticator(*httpAuthRealm, secrets) - http.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler)) - if err := pages.RegisterHandlersBasic(containerManager, authenticator); err != nil { + mux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler)) + if err := pages.RegisterHandlersBasic(mux, containerManager, authenticator); err != nil { glog.Fatalf("Failed to register pages auth handlers: %s", err) } authenticated = true @@ -112,8 +115,8 @@ func main() { glog.Infof("Using digest file %s", *httpDigestFile) secrets := auth.HtdigestFileProvider(*httpDigestFile) authenticator := auth.NewDigestAuthenticator(*httpDigestRealm, secrets) - http.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler)) - if err := pages.RegisterHandlersDigest(containerManager, authenticator); err != nil { + mux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler)) + if err := pages.RegisterHandlersDigest(mux, containerManager, authenticator); err != nil { glog.Fatalf("Failed to register pages digest handlers: %s", err) } authenticated = true @@ -121,8 +124,8 @@ func main() { // Change handler based on authenticator initalization if !authenticated { - http.HandleFunc(static.StaticResource, staticHandlerNoAuth) - if err := pages.RegisterHandlersBasic(containerManager, nil); err != nil { + mux.HandleFunc(static.StaticResource, staticHandlerNoAuth) + if err := pages.RegisterHandlersBasic(mux, containerManager, nil); err != nil { glog.Fatalf("Failed to register pages handlers: %s", err) } } diff --git a/healthz/healthz.go b/healthz/healthz.go index 789ebea4..1289f9ba 100644 --- a/healthz/healthz.go +++ b/healthz/healthz.go @@ -16,6 +16,8 @@ package healthz import ( "net/http" + + "github.com/google/cadvisor/utils" ) func handleHealthz(w http.ResponseWriter, r *http.Request) { @@ -24,7 +26,7 @@ func handleHealthz(w http.ResponseWriter, r *http.Request) { } // Register simple HTTP /healthz handler to return "ok". -func RegisterHandler() error { - http.HandleFunc("/healthz", handleHealthz) +func RegisterHandler(mux utils.Mux) error { + mux.HandleFunc("/healthz", handleHealthz) return nil } diff --git a/pages/pages.go b/pages/pages.go index db0043cc..2a0e849f 100644 --- a/pages/pages.go +++ b/pages/pages.go @@ -24,6 +24,7 @@ import ( "github.com/golang/glog" info "github.com/google/cadvisor/info/v1" "github.com/google/cadvisor/manager" + "github.com/google/cadvisor/utils" ) var pageTemplate *template.Template @@ -97,26 +98,26 @@ func dockerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFu } // Register http handlers -func RegisterHandlersDigest(containerManager manager.Manager, authenticator *auth.DigestAuth) error { +func RegisterHandlersDigest(mux utils.Mux, containerManager manager.Manager, authenticator *auth.DigestAuth) error { // Register the handler for the containers page. if authenticator != nil { - http.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager))) - http.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager))) + mux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager))) + mux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager))) } else { - http.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager)) - http.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager)) + mux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager)) + mux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager)) } return nil } -func RegisterHandlersBasic(containerManager manager.Manager, authenticator *auth.BasicAuth) error { +func RegisterHandlersBasic(mux utils.Mux, containerManager manager.Manager, authenticator *auth.BasicAuth) error { // Register the handler for the containers and docker age. if authenticator != nil { - http.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager))) - http.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager))) + mux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager))) + mux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager))) } else { - http.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager)) - http.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager)) + mux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager)) + mux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager)) } return nil } diff --git a/utils/mux.go b/utils/mux.go new file mode 100644 index 00000000..29ebda1f --- /dev/null +++ b/utils/mux.go @@ -0,0 +1,25 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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 utils + +import ( + "net/http" +) + +// Mux interface expected by cAdvisor components. +type Mux interface { + HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) + Handler(r *http.Request) (http.Handler, string) +}