mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Remove unneeded deps
This commit is contained in:
parent
097f300a4d
commit
f97fdf76dc
50
Godeps/Godeps.json
generated
50
Godeps/Godeps.json
generated
@ -134,10 +134,6 @@
|
||||
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/abbot/go-http-auth",
|
||||
"Rev": "c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/armon/circbuf",
|
||||
"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
|
||||
@ -1526,11 +1522,6 @@
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/api",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
||||
"Comment": "v0.30.2",
|
||||
@ -1606,21 +1597,6 @@
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/healthz",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/http",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/http/mux",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/info/v1",
|
||||
"Comment": "v0.30.2",
|
||||
@ -1661,16 +1637,6 @@
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/pages",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/pages/static",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/storage",
|
||||
"Comment": "v0.30.2",
|
||||
@ -1721,11 +1687,6 @@
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/validate",
|
||||
"Comment": "v0.30.2",
|
||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/cadvisor/version",
|
||||
"Comment": "v0.30.2",
|
||||
@ -1738,34 +1699,42 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/asn1",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/client",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/client/configpb",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/jsonclient",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/tls",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/x509",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/certificate-transparency-go/x509/pkix",
|
||||
"Comment": "v1.0.10",
|
||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||
},
|
||||
{
|
||||
@ -2007,6 +1976,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/inconshreveable/mousetrap",
|
||||
"Comment": "v1.0",
|
||||
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
},
|
||||
{
|
||||
@ -2562,6 +2532,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/quobyte/api",
|
||||
"Comment": "v0.1.1-4-g206ef83",
|
||||
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff"
|
||||
},
|
||||
{
|
||||
@ -2876,6 +2847,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/xiang90/probing",
|
||||
"Comment": "0.0.1",
|
||||
"Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2"
|
||||
},
|
||||
{
|
||||
|
1572
Godeps/LICENSES
generated
1572
Godeps/LICENSES
generated
File diff suppressed because it is too large
Load Diff
6
vendor/BUILD
vendored
6
vendor/BUILD
vendored
@ -31,7 +31,6 @@ filegroup(
|
||||
"//vendor/github.com/Nvveen/Gotty:all-srcs",
|
||||
"//vendor/github.com/PuerkitoBio/purell:all-srcs",
|
||||
"//vendor/github.com/PuerkitoBio/urlesc:all-srcs",
|
||||
"//vendor/github.com/abbot/go-http-auth:all-srcs",
|
||||
"//vendor/github.com/armon/circbuf:all-srcs",
|
||||
"//vendor/github.com/asaskevich/govalidator:all-srcs",
|
||||
"//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
|
||||
@ -228,7 +227,6 @@ filegroup(
|
||||
"//vendor/github.com/golang/protobuf/ptypes:all-srcs",
|
||||
"//vendor/github.com/google/btree:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/accelerators:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/api:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/cache/memory:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/client/v2:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/collector:all-srcs",
|
||||
@ -236,18 +234,14 @@ filegroup(
|
||||
"//vendor/github.com/google/cadvisor/devicemapper:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/events:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/fs:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/healthz:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/http:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/info/v2:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/machine:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/manager:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/metrics:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/pages:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/storage:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/summary:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/utils:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/validate:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/version:all-srcs",
|
||||
"//vendor/github.com/google/cadvisor/zfs:all-srcs",
|
||||
"//vendor/github.com/google/certificate-transparency-go:all-srcs",
|
||||
|
5
vendor/github.com/abbot/go-http-auth/.gitignore
generated
vendored
5
vendor/github.com/abbot/go-http-auth/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
*~
|
||||
*.a
|
||||
*.6
|
||||
*.out
|
||||
_testmain.go
|
30
vendor/github.com/abbot/go-http-auth/BUILD
generated
vendored
30
vendor/github.com/abbot/go-http-auth/BUILD
generated
vendored
@ -1,30 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"auth.go",
|
||||
"basic.go",
|
||||
"digest.go",
|
||||
"md5crypt.go",
|
||||
"misc.go",
|
||||
"users.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/abbot/go-http-auth",
|
||||
importpath = "github.com/abbot/go-http-auth",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
178
vendor/github.com/abbot/go-http-auth/LICENSE
generated
vendored
178
vendor/github.com/abbot/go-http-auth/LICENSE
generated
vendored
@ -1,178 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
12
vendor/github.com/abbot/go-http-auth/Makefile
generated
vendored
12
vendor/github.com/abbot/go-http-auth/Makefile
generated
vendored
@ -1,12 +0,0 @@
|
||||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=auth_digest
|
||||
GOFILES=\
|
||||
auth.go\
|
||||
digest.go\
|
||||
basic.go\
|
||||
misc.go\
|
||||
md5crypt.go\
|
||||
users.go\
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
70
vendor/github.com/abbot/go-http-auth/README.md
generated
vendored
70
vendor/github.com/abbot/go-http-auth/README.md
generated
vendored
@ -1,70 +0,0 @@
|
||||
HTTP Authentication implementation in Go
|
||||
========================================
|
||||
|
||||
This is an implementation of HTTP Basic and HTTP Digest authentication
|
||||
in Go language. It is designed as a simple wrapper for
|
||||
http.RequestHandler functions.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Supports HTTP Basic and HTTP Digest authentication.
|
||||
* Supports htpasswd and htdigest formatted files.
|
||||
* Automatic reloading of password files.
|
||||
* Pluggable interface for user/password storage.
|
||||
* Supports MD5 and SHA1 for Basic authentication password storage.
|
||||
* Configurable Digest nonce cache size with expiration.
|
||||
* Wrapper for legacy http handlers (http.HandlerFunc interface)
|
||||
|
||||
Example usage
|
||||
-------------
|
||||
|
||||
This is a complete working example for Basic auth:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
auth "github.com/abbot/go-http-auth"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Secret(user, realm string) string {
|
||||
if user == "john" {
|
||||
// password is "hello"
|
||||
return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func handle(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
|
||||
fmt.Fprintf(w, "<html><body><h1>Hello, %s!</h1></body></html>", r.Username)
|
||||
}
|
||||
|
||||
func main() {
|
||||
authenticator := auth.NewBasicAuthenticator("example.com", Secret)
|
||||
http.HandleFunc("/", authenticator.Wrap(handle))
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
See more examples in the "examples" directory.
|
||||
|
||||
Legal
|
||||
-----
|
||||
|
||||
This module is developed under Apache 2.0 license, and can be used for
|
||||
open and proprietary projects.
|
||||
|
||||
Copyright 2012-2013 Lev Shamardin
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you
|
||||
may not use this file or any other part of this project 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.
|
48
vendor/github.com/abbot/go-http-auth/auth.go
generated
vendored
48
vendor/github.com/abbot/go-http-auth/auth.go
generated
vendored
@ -1,48 +0,0 @@
|
||||
package auth
|
||||
|
||||
import "net/http"
|
||||
|
||||
/*
|
||||
Request handlers must take AuthenticatedRequest instead of http.Request
|
||||
*/
|
||||
type AuthenticatedRequest struct {
|
||||
http.Request
|
||||
/*
|
||||
Authenticated user name. Current API implies that Username is
|
||||
never empty, which means that authentication is always done
|
||||
before calling the request handler.
|
||||
*/
|
||||
Username string
|
||||
}
|
||||
|
||||
/*
|
||||
AuthenticatedHandlerFunc is like http.HandlerFunc, but takes
|
||||
AuthenticatedRequest instead of http.Request
|
||||
*/
|
||||
type AuthenticatedHandlerFunc func(http.ResponseWriter, *AuthenticatedRequest)
|
||||
|
||||
/*
|
||||
Authenticator wraps an AuthenticatedHandlerFunc with
|
||||
authentication-checking code.
|
||||
|
||||
Typical Authenticator usage is something like:
|
||||
|
||||
authenticator := SomeAuthenticator(...)
|
||||
http.HandleFunc("/", authenticator(my_handler))
|
||||
|
||||
Authenticator wrapper checks the user authentication and calls the
|
||||
wrapped function only after authentication has succeeded. Otherwise,
|
||||
it returns a handler which initiates the authentication procedure.
|
||||
*/
|
||||
type Authenticator func(AuthenticatedHandlerFunc) http.HandlerFunc
|
||||
|
||||
type AuthenticatorInterface interface {
|
||||
Wrap(AuthenticatedHandlerFunc) http.HandlerFunc
|
||||
}
|
||||
|
||||
func JustCheck(auth AuthenticatorInterface, wrapped http.HandlerFunc) http.HandlerFunc {
|
||||
return auth.Wrap(func(w http.ResponseWriter, ar *AuthenticatedRequest) {
|
||||
ar.Header.Set("X-Authenticated-Username", ar.Username)
|
||||
wrapped(w, &ar.Request)
|
||||
})
|
||||
}
|
88
vendor/github.com/abbot/go-http-auth/basic.go
generated
vendored
88
vendor/github.com/abbot/go-http-auth/basic.go
generated
vendored
@ -1,88 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BasicAuth struct {
|
||||
Realm string
|
||||
Secrets SecretProvider
|
||||
}
|
||||
|
||||
/*
|
||||
Checks the username/password combination from the request. Returns
|
||||
either an empty string (authentication failed) or the name of the
|
||||
authenticated user.
|
||||
|
||||
Supports MD5 and SHA1 password entries
|
||||
*/
|
||||
func (a *BasicAuth) CheckAuth(r *http.Request) string {
|
||||
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
||||
if len(s) != 2 || s[0] != "Basic" {
|
||||
return ""
|
||||
}
|
||||
|
||||
b, err := base64.StdEncoding.DecodeString(s[1])
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
pair := strings.SplitN(string(b), ":", 2)
|
||||
if len(pair) != 2 {
|
||||
return ""
|
||||
}
|
||||
passwd := a.Secrets(pair[0], a.Realm)
|
||||
if passwd == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(passwd, "{SHA}") {
|
||||
d := sha1.New()
|
||||
d.Write([]byte(pair[1]))
|
||||
if passwd[5:] != base64.StdEncoding.EncodeToString(d.Sum(nil)) {
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
e := NewMD5Entry(passwd)
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
if passwd != string(MD5Crypt([]byte(pair[1]), e.Salt, e.Magic)) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return pair[0]
|
||||
}
|
||||
|
||||
/*
|
||||
http.Handler for BasicAuth which initiates the authentication process
|
||||
(or requires reauthentication).
|
||||
*/
|
||||
func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`)
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("401 Unauthorized\n"))
|
||||
}
|
||||
|
||||
/*
|
||||
BasicAuthenticator returns a function, which wraps an
|
||||
AuthenticatedHandlerFunc converting it to http.HandlerFunc. This
|
||||
wrapper function checks the authentication and either sends back
|
||||
required authentication headers, or calls the wrapped function with
|
||||
authenticated username in the AuthenticatedRequest.
|
||||
*/
|
||||
func (a *BasicAuth) Wrap(wrapped AuthenticatedHandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if username := a.CheckAuth(r); username == "" {
|
||||
a.RequireAuth(w, r)
|
||||
} else {
|
||||
ar := &AuthenticatedRequest{Request: *r, Username: username}
|
||||
wrapped(w, ar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func NewBasicAuthenticator(realm string, secrets SecretProvider) *BasicAuth {
|
||||
return &BasicAuth{Realm: realm, Secrets: secrets}
|
||||
}
|
226
vendor/github.com/abbot/go-http-auth/digest.go
generated
vendored
226
vendor/github.com/abbot/go-http-auth/digest.go
generated
vendored
@ -1,226 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type digest_client struct {
|
||||
nc uint64
|
||||
last_seen int64
|
||||
}
|
||||
|
||||
type DigestAuth struct {
|
||||
Realm string
|
||||
Opaque string
|
||||
Secrets SecretProvider
|
||||
PlainTextSecrets bool
|
||||
|
||||
/*
|
||||
Approximate size of Client's Cache. When actual number of
|
||||
tracked client nonces exceeds
|
||||
ClientCacheSize+ClientCacheTolerance, ClientCacheTolerance*2
|
||||
older entries are purged.
|
||||
*/
|
||||
ClientCacheSize int
|
||||
ClientCacheTolerance int
|
||||
|
||||
clients map[string]*digest_client
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
type digest_cache_entry struct {
|
||||
nonce string
|
||||
last_seen int64
|
||||
}
|
||||
|
||||
type digest_cache []digest_cache_entry
|
||||
|
||||
func (c digest_cache) Less(i, j int) bool {
|
||||
return c[i].last_seen < c[j].last_seen
|
||||
}
|
||||
|
||||
func (c digest_cache) Len() int {
|
||||
return len(c)
|
||||
}
|
||||
|
||||
func (c digest_cache) Swap(i, j int) {
|
||||
c[i], c[j] = c[j], c[i]
|
||||
}
|
||||
|
||||
/*
|
||||
Remove count oldest entries from DigestAuth.clients
|
||||
*/
|
||||
func (a *DigestAuth) Purge(count int) {
|
||||
entries := make([]digest_cache_entry, 0, len(a.clients))
|
||||
for nonce, client := range a.clients {
|
||||
entries = append(entries, digest_cache_entry{nonce, client.last_seen})
|
||||
}
|
||||
cache := digest_cache(entries)
|
||||
sort.Sort(cache)
|
||||
for _, client := range cache[:count] {
|
||||
delete(a.clients, client.nonce)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
http.Handler for DigestAuth which initiates the authentication process
|
||||
(or requires reauthentication).
|
||||
*/
|
||||
func (a *DigestAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
||||
if len(a.clients) > a.ClientCacheSize+a.ClientCacheTolerance {
|
||||
a.Purge(a.ClientCacheTolerance * 2)
|
||||
}
|
||||
nonce := RandomKey()
|
||||
a.clients[nonce] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
|
||||
w.Header().Set("WWW-Authenticate",
|
||||
fmt.Sprintf(`Digest realm="%s", nonce="%s", opaque="%s", algorithm="MD5", qop="auth"`,
|
||||
a.Realm, nonce, a.Opaque))
|
||||
w.WriteHeader(401)
|
||||
w.Write([]byte("401 Unauthorized\n"))
|
||||
}
|
||||
|
||||
/*
|
||||
Parse Authorization header from the http.Request. Returns a map of
|
||||
auth parameters or nil if the header is not a valid parsable Digest
|
||||
auth header.
|
||||
*/
|
||||
func DigestAuthParams(r *http.Request) map[string]string {
|
||||
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
|
||||
if len(s) != 2 || s[0] != "Digest" {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := map[string]string{}
|
||||
for _, kv := range strings.Split(s[1], ",") {
|
||||
parts := strings.SplitN(kv, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
result[strings.Trim(parts[0], "\" ")] = strings.Trim(parts[1], "\" ")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
Check if request contains valid authentication data. Returns a pair
|
||||
of username, authinfo where username is the name of the authenticated
|
||||
user or an empty string and authinfo is the contents for the optional
|
||||
Authentication-Info response header.
|
||||
*/
|
||||
func (da *DigestAuth) CheckAuth(r *http.Request) (username string, authinfo *string) {
|
||||
da.mutex.Lock()
|
||||
defer da.mutex.Unlock()
|
||||
username = ""
|
||||
authinfo = nil
|
||||
auth := DigestAuthParams(r)
|
||||
if auth == nil || da.Opaque != auth["opaque"] || auth["algorithm"] != "MD5" || auth["qop"] != "auth" {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the requested URI matches auth header
|
||||
switch u, err := url.Parse(auth["uri"]); {
|
||||
case err != nil:
|
||||
return
|
||||
case r.URL == nil:
|
||||
return
|
||||
case len(u.Path) > len(r.URL.Path):
|
||||
return
|
||||
case !strings.HasPrefix(r.URL.Path, u.Path):
|
||||
return
|
||||
}
|
||||
|
||||
HA1 := da.Secrets(auth["username"], da.Realm)
|
||||
if da.PlainTextSecrets {
|
||||
HA1 = H(auth["username"] + ":" + da.Realm + ":" + HA1)
|
||||
}
|
||||
HA2 := H(r.Method + ":" + auth["uri"])
|
||||
KD := H(strings.Join([]string{HA1, auth["nonce"], auth["nc"], auth["cnonce"], auth["qop"], HA2}, ":"))
|
||||
|
||||
if KD != auth["response"] {
|
||||
return
|
||||
}
|
||||
|
||||
// At this point crypto checks are completed and validated.
|
||||
// Now check if the session is valid.
|
||||
|
||||
nc, err := strconv.ParseUint(auth["nc"], 16, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if client, ok := da.clients[auth["nonce"]]; !ok {
|
||||
return
|
||||
} else {
|
||||
if client.nc != 0 && client.nc >= nc {
|
||||
return
|
||||
}
|
||||
client.nc = nc
|
||||
client.last_seen = time.Now().UnixNano()
|
||||
}
|
||||
|
||||
resp_HA2 := H(":" + auth["uri"])
|
||||
rspauth := H(strings.Join([]string{HA1, auth["nonce"], auth["nc"], auth["cnonce"], auth["qop"], resp_HA2}, ":"))
|
||||
|
||||
info := fmt.Sprintf(`qop="auth", rspauth="%s", cnonce="%s", nc="%s"`, rspauth, auth["cnonce"], auth["nc"])
|
||||
return auth["username"], &info
|
||||
}
|
||||
|
||||
/*
|
||||
Default values for ClientCacheSize and ClientCacheTolerance for DigestAuth
|
||||
*/
|
||||
const DefaultClientCacheSize = 1000
|
||||
const DefaultClientCacheTolerance = 100
|
||||
|
||||
/*
|
||||
Wrap returns an Authenticator which uses HTTP Digest
|
||||
authentication. Arguments:
|
||||
|
||||
realm: The authentication realm.
|
||||
|
||||
secrets: SecretProvider which must return HA1 digests for the same
|
||||
realm as above.
|
||||
*/
|
||||
func (a *DigestAuth) Wrap(wrapped AuthenticatedHandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if username, authinfo := a.CheckAuth(r); username == "" {
|
||||
a.RequireAuth(w, r)
|
||||
} else {
|
||||
ar := &AuthenticatedRequest{Request: *r, Username: username}
|
||||
if authinfo != nil {
|
||||
w.Header().Set("Authentication-Info", *authinfo)
|
||||
}
|
||||
wrapped(w, ar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
JustCheck returns function which converts an http.HandlerFunc into a
|
||||
http.HandlerFunc which requires authentication. Username is passed as
|
||||
an extra X-Authenticated-Username header.
|
||||
*/
|
||||
func (a *DigestAuth) JustCheck(wrapped http.HandlerFunc) http.HandlerFunc {
|
||||
return a.Wrap(func(w http.ResponseWriter, ar *AuthenticatedRequest) {
|
||||
ar.Header.Set("X-Authenticated-Username", ar.Username)
|
||||
wrapped(w, &ar.Request)
|
||||
})
|
||||
}
|
||||
|
||||
func NewDigestAuthenticator(realm string, secrets SecretProvider) *DigestAuth {
|
||||
da := &DigestAuth{
|
||||
Opaque: RandomKey(),
|
||||
Realm: realm,
|
||||
Secrets: secrets,
|
||||
PlainTextSecrets: false,
|
||||
ClientCacheSize: DefaultClientCacheSize,
|
||||
ClientCacheTolerance: DefaultClientCacheTolerance,
|
||||
clients: map[string]*digest_client{}}
|
||||
return da
|
||||
}
|
92
vendor/github.com/abbot/go-http-auth/md5crypt.go
generated
vendored
92
vendor/github.com/abbot/go-http-auth/md5crypt.go
generated
vendored
@ -1,92 +0,0 @@
|
||||
package auth
|
||||
|
||||
import "crypto/md5"
|
||||
import "strings"
|
||||
|
||||
const itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
var md5_crypt_swaps = [16]int{12, 6, 0, 13, 7, 1, 14, 8, 2, 15, 9, 3, 5, 10, 4, 11}
|
||||
|
||||
type MD5Entry struct {
|
||||
Magic, Salt, Hash []byte
|
||||
}
|
||||
|
||||
func NewMD5Entry(e string) *MD5Entry {
|
||||
parts := strings.SplitN(e, "$", 4)
|
||||
if len(parts) != 4 {
|
||||
return nil
|
||||
}
|
||||
return &MD5Entry{
|
||||
Magic: []byte("$" + parts[1] + "$"),
|
||||
Salt: []byte(parts[2]),
|
||||
Hash: []byte(parts[3]),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
MD5 password crypt implementation
|
||||
*/
|
||||
func MD5Crypt(password, salt, magic []byte) []byte {
|
||||
d := md5.New()
|
||||
|
||||
d.Write(password)
|
||||
d.Write(magic)
|
||||
d.Write(salt)
|
||||
|
||||
d2 := md5.New()
|
||||
d2.Write(password)
|
||||
d2.Write(salt)
|
||||
d2.Write(password)
|
||||
|
||||
for i, mixin := 0, d2.Sum(nil); i < len(password); i++ {
|
||||
d.Write([]byte{mixin[i%16]})
|
||||
}
|
||||
|
||||
for i := len(password); i != 0; i >>= 1 {
|
||||
if i&1 == 0 {
|
||||
d.Write([]byte{password[0]})
|
||||
} else {
|
||||
d.Write([]byte{0})
|
||||
}
|
||||
}
|
||||
|
||||
final := d.Sum(nil)
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
d2 := md5.New()
|
||||
if i&1 == 0 {
|
||||
d2.Write(final)
|
||||
} else {
|
||||
d2.Write(password)
|
||||
}
|
||||
|
||||
if i%3 != 0 {
|
||||
d2.Write(salt)
|
||||
}
|
||||
|
||||
if i%7 != 0 {
|
||||
d2.Write(password)
|
||||
}
|
||||
|
||||
if i&1 == 0 {
|
||||
d2.Write(password)
|
||||
} else {
|
||||
d2.Write(final)
|
||||
}
|
||||
final = d2.Sum(nil)
|
||||
}
|
||||
|
||||
result := make([]byte, 0, 22)
|
||||
v := uint(0)
|
||||
bits := uint(0)
|
||||
for _, i := range md5_crypt_swaps {
|
||||
v |= (uint(final[i]) << bits)
|
||||
for bits = bits + 8; bits > 6; bits -= 6 {
|
||||
result = append(result, itoa64[v&0x3f])
|
||||
v >>= 6
|
||||
}
|
||||
}
|
||||
result = append(result, itoa64[v&0x3f])
|
||||
|
||||
return append(append(append(magic, salt...), '$'), result...)
|
||||
}
|
30
vendor/github.com/abbot/go-http-auth/misc.go
generated
vendored
30
vendor/github.com/abbot/go-http-auth/misc.go
generated
vendored
@ -1,30 +0,0 @@
|
||||
package auth
|
||||
|
||||
import "encoding/base64"
|
||||
import "crypto/md5"
|
||||
import "crypto/rand"
|
||||
import "fmt"
|
||||
|
||||
/*
|
||||
Return a random 16-byte base64 alphabet string
|
||||
*/
|
||||
func RandomKey() string {
|
||||
k := make([]byte, 12)
|
||||
for bytes := 0; bytes < len(k); {
|
||||
n, err := rand.Read(k[bytes:])
|
||||
if err != nil {
|
||||
panic("rand.Read() failed")
|
||||
}
|
||||
bytes += n
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(k)
|
||||
}
|
||||
|
||||
/*
|
||||
H function for MD5 algorithm (returns a lower-case hex MD5 digest)
|
||||
*/
|
||||
func H(data string) string {
|
||||
digest := md5.New()
|
||||
digest.Write([]byte(data))
|
||||
return fmt.Sprintf("%x", digest.Sum(nil))
|
||||
}
|
1
vendor/github.com/abbot/go-http-auth/test.htdigest
generated
vendored
1
vendor/github.com/abbot/go-http-auth/test.htdigest
generated
vendored
@ -1 +0,0 @@
|
||||
test:example.com:aa78524fceb0e50fd8ca96dd818b8cf9
|
2
vendor/github.com/abbot/go-http-auth/test.htpasswd
generated
vendored
2
vendor/github.com/abbot/go-http-auth/test.htpasswd
generated
vendored
@ -1,2 +0,0 @@
|
||||
test:{SHA}qvTGHdzF6KLavt4PO0gs2a6pQ00=
|
||||
test2:$apr1$a0j62R97$mYqFkloXH0/UOaUnAiV2b0
|
136
vendor/github.com/abbot/go-http-auth/users.go
generated
vendored
136
vendor/github.com/abbot/go-http-auth/users.go
generated
vendored
@ -1,136 +0,0 @@
|
||||
package auth
|
||||
|
||||
import "encoding/csv"
|
||||
import "os"
|
||||
|
||||
/*
|
||||
SecretProvider is used by authenticators. Takes user name and realm
|
||||
as an argument, returns secret required for authentication (HA1 for
|
||||
digest authentication, properly encrypted password for basic).
|
||||
*/
|
||||
type SecretProvider func(user, realm string) string
|
||||
|
||||
/*
|
||||
Common functions for file auto-reloading
|
||||
*/
|
||||
type File struct {
|
||||
Path string
|
||||
Info os.FileInfo
|
||||
/* must be set in inherited types during initialization */
|
||||
Reload func()
|
||||
}
|
||||
|
||||
func (f *File) ReloadIfNeeded() {
|
||||
info, err := os.Stat(f.Path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if f.Info == nil || f.Info.ModTime() != info.ModTime() {
|
||||
f.Info = info
|
||||
f.Reload()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Structure used for htdigest file authentication. Users map realms to
|
||||
maps of users to their HA1 digests.
|
||||
*/
|
||||
type HtdigestFile struct {
|
||||
File
|
||||
Users map[string]map[string]string
|
||||
}
|
||||
|
||||
func reload_htdigest(hf *HtdigestFile) {
|
||||
r, err := os.Open(hf.Path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
csv_reader := csv.NewReader(r)
|
||||
csv_reader.Comma = ':'
|
||||
csv_reader.Comment = '#'
|
||||
csv_reader.TrimLeadingSpace = true
|
||||
|
||||
records, err := csv_reader.ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
hf.Users = make(map[string]map[string]string)
|
||||
for _, record := range records {
|
||||
_, exists := hf.Users[record[1]]
|
||||
if !exists {
|
||||
hf.Users[record[1]] = make(map[string]string)
|
||||
}
|
||||
hf.Users[record[1]][record[0]] = record[2]
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SecretProvider implementation based on htdigest-formated files. Will
|
||||
reload htdigest file on changes. Will panic on syntax errors in
|
||||
htdigest files.
|
||||
*/
|
||||
func HtdigestFileProvider(filename string) SecretProvider {
|
||||
hf := &HtdigestFile{File: File{Path: filename}}
|
||||
hf.Reload = func() { reload_htdigest(hf) }
|
||||
return func(user, realm string) string {
|
||||
hf.ReloadIfNeeded()
|
||||
_, exists := hf.Users[realm]
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
digest, exists := hf.Users[realm][user]
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
return digest
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Structure used for htdigest file authentication. Users map users to
|
||||
their salted encrypted password
|
||||
*/
|
||||
type HtpasswdFile struct {
|
||||
File
|
||||
Users map[string]string
|
||||
}
|
||||
|
||||
func reload_htpasswd(h *HtpasswdFile) {
|
||||
r, err := os.Open(h.Path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
csv_reader := csv.NewReader(r)
|
||||
csv_reader.Comma = ':'
|
||||
csv_reader.Comment = '#'
|
||||
csv_reader.TrimLeadingSpace = true
|
||||
|
||||
records, err := csv_reader.ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
h.Users = make(map[string]string)
|
||||
for _, record := range records {
|
||||
h.Users[record[0]] = record[1]
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
SecretProvider implementation based on htpasswd-formated files. Will
|
||||
reload htpasswd file on changes. Will panic on syntax errors in
|
||||
htpasswd files. Realm argument of the SecretProvider is ignored.
|
||||
*/
|
||||
func HtpasswdFileProvider(filename string) SecretProvider {
|
||||
h := &HtpasswdFile{File: File{Path: filename}}
|
||||
h.Reload = func() { reload_htpasswd(h) }
|
||||
return func(user, realm string) string {
|
||||
h.ReloadIfNeeded()
|
||||
password, exists := h.Users[user]
|
||||
if !exists {
|
||||
return ""
|
||||
}
|
||||
return password
|
||||
}
|
||||
}
|
34
vendor/github.com/google/cadvisor/api/BUILD
generated
vendored
34
vendor/github.com/google/cadvisor/api/BUILD
generated
vendored
@ -1,34 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"handler.go",
|
||||
"versions.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/api",
|
||||
importpath = "github.com/google/cadvisor/api",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/events:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/http/mux:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/manager:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
250
vendor/github.com/google/cadvisor/api/handler.go
generated
vendored
250
vendor/github.com/google/cadvisor/api/handler.go
generated
vendored
@ -1,250 +0,0 @@
|
||||
// Copyright 2014 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 api provides a handler for /api/
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/events"
|
||||
httpmux "github.com/google/cadvisor/http/mux"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/manager"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
apiResource = "/api/"
|
||||
)
|
||||
|
||||
func RegisterHandlers(mux httpmux.Mux, m manager.Manager) error {
|
||||
apiVersions := getApiVersions()
|
||||
supportedApiVersions := make(map[string]ApiVersion, len(apiVersions))
|
||||
for _, v := range apiVersions {
|
||||
supportedApiVersions[v.Version()] = v
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Captures the API version, requestType [optional], and remaining request [optional].
|
||||
var apiRegexp = regexp.MustCompile(`/api/([^/]+)/?([^/]+)?(.*)`)
|
||||
|
||||
const (
|
||||
apiVersion = iota + 1
|
||||
apiRequestType
|
||||
apiRequestArgs
|
||||
)
|
||||
|
||||
func handleRequest(supportedApiVersions map[string]ApiVersion, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
glog.V(4).Infof("Request took %s", time.Since(start))
|
||||
}()
|
||||
|
||||
request := r.URL.Path
|
||||
|
||||
const apiPrefix = "/api"
|
||||
if !strings.HasPrefix(request, apiPrefix) {
|
||||
return fmt.Errorf("incomplete API request %q", request)
|
||||
}
|
||||
|
||||
// If the request doesn't have an API version, list those.
|
||||
if request == apiPrefix || request == apiResource {
|
||||
versions := make([]string, 0, len(supportedApiVersions))
|
||||
for v := range supportedApiVersions {
|
||||
versions = append(versions, v)
|
||||
}
|
||||
sort.Strings(versions)
|
||||
http.Error(w, fmt.Sprintf("Supported API versions: %s", strings.Join(versions, ",")), http.StatusBadRequest)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify that we have all the elements we expect:
|
||||
// /<version>/<request type>[/<args...>]
|
||||
requestElements := apiRegexp.FindStringSubmatch(request)
|
||||
if len(requestElements) == 0 {
|
||||
return fmt.Errorf("malformed request %q", request)
|
||||
}
|
||||
version := requestElements[apiVersion]
|
||||
requestType := requestElements[apiRequestType]
|
||||
requestArgs := strings.Split(requestElements[apiRequestArgs], "/")
|
||||
|
||||
// Check supported versions.
|
||||
versionHandler, ok := supportedApiVersions[version]
|
||||
if !ok {
|
||||
return fmt.Errorf("unsupported API version %q", version)
|
||||
}
|
||||
|
||||
// If no request type, list possible request types.
|
||||
if requestType == "" {
|
||||
requestTypes := versionHandler.SupportedRequestTypes()
|
||||
sort.Strings(requestTypes)
|
||||
http.Error(w, fmt.Sprintf("Supported request types: %q", strings.Join(requestTypes, ",")), http.StatusBadRequest)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Trim the first empty element from the request.
|
||||
if len(requestArgs) > 0 && requestArgs[0] == "" {
|
||||
requestArgs = requestArgs[1:]
|
||||
}
|
||||
|
||||
return versionHandler.HandleRequest(requestType, requestArgs, m, w, r)
|
||||
|
||||
}
|
||||
|
||||
func writeResult(res interface{}, w http.ResponseWriter) error {
|
||||
out, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshall response %+v with error: %s", res, err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(out)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func streamResults(eventChannel *events.EventChannel, w http.ResponseWriter, r *http.Request, m manager.Manager) error {
|
||||
cn, ok := w.(http.CloseNotifier)
|
||||
if !ok {
|
||||
return errors.New("could not access http.CloseNotifier")
|
||||
}
|
||||
flusher, ok := w.(http.Flusher)
|
||||
if !ok {
|
||||
return errors.New("could not access http.Flusher")
|
||||
}
|
||||
|
||||
w.Header().Set("Transfer-Encoding", "chunked")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
flusher.Flush()
|
||||
|
||||
enc := json.NewEncoder(w)
|
||||
for {
|
||||
select {
|
||||
case <-cn.CloseNotify():
|
||||
m.CloseEventChannel(eventChannel.GetWatchId())
|
||||
return nil
|
||||
case ev := <-eventChannel.GetChannel():
|
||||
err := enc.Encode(ev)
|
||||
if err != nil {
|
||||
glog.Errorf("error encoding message %+v for result stream: %v", ev, err)
|
||||
}
|
||||
flusher.Flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getContainerInfoRequest(body io.ReadCloser) (*info.ContainerInfoRequest, error) {
|
||||
query := info.DefaultContainerInfoRequest()
|
||||
decoder := json.NewDecoder(body)
|
||||
err := decoder.Decode(&query)
|
||||
if err != nil && err != io.EOF {
|
||||
return nil, fmt.Errorf("unable to decode the json value: %s", err)
|
||||
}
|
||||
|
||||
return &query, nil
|
||||
}
|
||||
|
||||
// The user can set any or none of the following arguments in any order
|
||||
// with any twice defined arguments being assigned the first value.
|
||||
// If the value type for the argument is wrong the field will be assumed to be
|
||||
// unassigned
|
||||
// bools: stream, subcontainers, oom_events, creation_events, deletion_events
|
||||
// ints: max_events, start_time (unix timestamp), end_time (unix timestamp)
|
||||
// example r.URL: http://localhost:8080/api/v1.3/events?oom_events=true&stream=true
|
||||
func getEventRequest(r *http.Request) (*events.Request, bool, error) {
|
||||
query := events.NewRequest()
|
||||
stream := false
|
||||
|
||||
urlMap := r.URL.Query()
|
||||
|
||||
if val, ok := urlMap["stream"]; ok {
|
||||
newBool, err := strconv.ParseBool(val[0])
|
||||
if err == nil {
|
||||
stream = newBool
|
||||
}
|
||||
}
|
||||
if val, ok := urlMap["subcontainers"]; ok {
|
||||
newBool, err := strconv.ParseBool(val[0])
|
||||
if err == nil {
|
||||
query.IncludeSubcontainers = newBool
|
||||
}
|
||||
}
|
||||
eventTypes := map[string]info.EventType{
|
||||
"oom_events": info.EventOom,
|
||||
"oom_kill_events": info.EventOomKill,
|
||||
"creation_events": info.EventContainerCreation,
|
||||
"deletion_events": info.EventContainerDeletion,
|
||||
}
|
||||
allEventTypes := false
|
||||
if val, ok := urlMap["all_events"]; ok {
|
||||
newBool, err := strconv.ParseBool(val[0])
|
||||
if err == nil {
|
||||
allEventTypes = newBool
|
||||
}
|
||||
}
|
||||
for opt, eventType := range eventTypes {
|
||||
if allEventTypes {
|
||||
query.EventType[eventType] = true
|
||||
} else if val, ok := urlMap[opt]; ok {
|
||||
newBool, err := strconv.ParseBool(val[0])
|
||||
if err == nil {
|
||||
query.EventType[eventType] = newBool
|
||||
}
|
||||
}
|
||||
}
|
||||
if val, ok := urlMap["max_events"]; ok {
|
||||
newInt, err := strconv.Atoi(val[0])
|
||||
if err == nil {
|
||||
query.MaxEventsReturned = int(newInt)
|
||||
}
|
||||
}
|
||||
if val, ok := urlMap["start_time"]; ok {
|
||||
newTime, err := time.Parse(time.RFC3339, val[0])
|
||||
if err == nil {
|
||||
query.StartTime = newTime
|
||||
}
|
||||
}
|
||||
if val, ok := urlMap["end_time"]; ok {
|
||||
newTime, err := time.Parse(time.RFC3339, val[0])
|
||||
if err == nil {
|
||||
query.EndTime = newTime
|
||||
}
|
||||
}
|
||||
|
||||
return query, stream, nil
|
||||
}
|
||||
|
||||
func getContainerName(request []string) string {
|
||||
return path.Join("/", strings.Join(request, "/"))
|
||||
}
|
559
vendor/github.com/google/cadvisor/api/versions.go
generated
vendored
559
vendor/github.com/google/cadvisor/api/versions.go
generated
vendored
@ -1,559 +0,0 @@
|
||||
// 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 api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/info/v2"
|
||||
"github.com/google/cadvisor/manager"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
containersApi = "containers"
|
||||
subcontainersApi = "subcontainers"
|
||||
machineApi = "machine"
|
||||
machineStatsApi = "machinestats"
|
||||
dockerApi = "docker"
|
||||
summaryApi = "summary"
|
||||
statsApi = "stats"
|
||||
specApi = "spec"
|
||||
eventsApi = "events"
|
||||
storageApi = "storage"
|
||||
attributesApi = "attributes"
|
||||
versionApi = "version"
|
||||
psApi = "ps"
|
||||
customMetricsApi = "appmetrics"
|
||||
)
|
||||
|
||||
// Interface for a cAdvisor API version
|
||||
type ApiVersion interface {
|
||||
// Returns the version string.
|
||||
Version() string
|
||||
|
||||
// List of supported API endpoints.
|
||||
SupportedRequestTypes() []string
|
||||
|
||||
// Handles a request. The second argument is the parameters after /api/<version>/<endpoint>
|
||||
HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error
|
||||
}
|
||||
|
||||
// Gets all supported API versions.
|
||||
func getApiVersions() []ApiVersion {
|
||||
v1_0 := &version1_0{}
|
||||
v1_1 := newVersion1_1(v1_0)
|
||||
v1_2 := newVersion1_2(v1_1)
|
||||
v1_3 := newVersion1_3(v1_2)
|
||||
v2_0 := newVersion2_0()
|
||||
v2_1 := newVersion2_1(v2_0)
|
||||
|
||||
return []ApiVersion{v1_0, v1_1, v1_2, v1_3, v2_0, v2_1}
|
||||
|
||||
}
|
||||
|
||||
// API v1.0
|
||||
|
||||
type version1_0 struct {
|
||||
}
|
||||
|
||||
func (self *version1_0) Version() string {
|
||||
return "v1.0"
|
||||
}
|
||||
|
||||
func (self *version1_0) SupportedRequestTypes() []string {
|
||||
return []string{containersApi, machineApi}
|
||||
}
|
||||
|
||||
func (self *version1_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
switch requestType {
|
||||
case machineApi:
|
||||
glog.V(4).Infof("Api - Machine")
|
||||
|
||||
// Get the MachineInfo
|
||||
machineInfo, err := m.GetMachineInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeResult(machineInfo, w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case containersApi:
|
||||
containerName := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Container(%s)", containerName)
|
||||
|
||||
// Get the query request.
|
||||
query, err := getContainerInfoRequest(r.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the container.
|
||||
cont, err := m.GetContainerInfo(containerName, query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get container %q with error: %s", containerName, err)
|
||||
}
|
||||
|
||||
// Only output the container as JSON.
|
||||
err = writeResult(cont, w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown request type %q", requestType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// API v1.1
|
||||
|
||||
type version1_1 struct {
|
||||
baseVersion *version1_0
|
||||
}
|
||||
|
||||
// v1.1 builds on v1.0.
|
||||
func newVersion1_1(v *version1_0) *version1_1 {
|
||||
return &version1_1{
|
||||
baseVersion: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *version1_1) Version() string {
|
||||
return "v1.1"
|
||||
}
|
||||
|
||||
func (self *version1_1) SupportedRequestTypes() []string {
|
||||
return append(self.baseVersion.SupportedRequestTypes(), subcontainersApi)
|
||||
}
|
||||
|
||||
func (self *version1_1) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
switch requestType {
|
||||
case subcontainersApi:
|
||||
containerName := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Subcontainers(%s)", containerName)
|
||||
|
||||
// Get the query request.
|
||||
query, err := getContainerInfoRequest(r.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the subcontainers.
|
||||
containers, err := m.SubcontainersInfo(containerName, query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get subcontainers for container %q with error: %s", containerName, err)
|
||||
}
|
||||
|
||||
// Only output the containers as JSON.
|
||||
err = writeResult(containers, w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return self.baseVersion.HandleRequest(requestType, request, m, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// API v1.2
|
||||
|
||||
type version1_2 struct {
|
||||
baseVersion *version1_1
|
||||
}
|
||||
|
||||
// v1.2 builds on v1.1.
|
||||
func newVersion1_2(v *version1_1) *version1_2 {
|
||||
return &version1_2{
|
||||
baseVersion: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *version1_2) Version() string {
|
||||
return "v1.2"
|
||||
}
|
||||
|
||||
func (self *version1_2) SupportedRequestTypes() []string {
|
||||
return append(self.baseVersion.SupportedRequestTypes(), dockerApi)
|
||||
}
|
||||
|
||||
func (self *version1_2) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
switch requestType {
|
||||
case dockerApi:
|
||||
glog.V(4).Infof("Api - Docker(%v)", request)
|
||||
|
||||
// Get the query request.
|
||||
query, err := getContainerInfoRequest(r.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var containers map[string]info.ContainerInfo
|
||||
// map requests for "docker/" to "docker"
|
||||
if len(request) == 1 && len(request[0]) == 0 {
|
||||
request = request[:0]
|
||||
}
|
||||
switch len(request) {
|
||||
case 0:
|
||||
// Get all Docker containers.
|
||||
containers, err = m.AllDockerContainers(query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get all Docker containers with error: %v", err)
|
||||
}
|
||||
case 1:
|
||||
// Get one Docker container.
|
||||
var cont info.ContainerInfo
|
||||
cont, err = m.DockerContainer(request[0], query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get Docker container %q with error: %v", request[0], err)
|
||||
}
|
||||
containers = map[string]info.ContainerInfo{
|
||||
cont.Name: cont,
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unknown request for Docker container %v", request)
|
||||
}
|
||||
|
||||
// Only output the containers as JSON.
|
||||
err = writeResult(containers, w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return self.baseVersion.HandleRequest(requestType, request, m, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// API v1.3
|
||||
|
||||
type version1_3 struct {
|
||||
baseVersion *version1_2
|
||||
}
|
||||
|
||||
// v1.3 builds on v1.2.
|
||||
func newVersion1_3(v *version1_2) *version1_3 {
|
||||
return &version1_3{
|
||||
baseVersion: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *version1_3) Version() string {
|
||||
return "v1.3"
|
||||
}
|
||||
|
||||
func (self *version1_3) SupportedRequestTypes() []string {
|
||||
return append(self.baseVersion.SupportedRequestTypes(), eventsApi)
|
||||
}
|
||||
|
||||
func (self *version1_3) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
switch requestType {
|
||||
case eventsApi:
|
||||
return handleEventRequest(request, m, w, r)
|
||||
default:
|
||||
return self.baseVersion.HandleRequest(requestType, request, m, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func handleEventRequest(request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
query, stream, err := getEventRequest(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
query.ContainerName = path.Join("/", getContainerName(request))
|
||||
glog.V(4).Infof("Api - Events(%v)", query)
|
||||
if !stream {
|
||||
pastEvents, err := m.GetPastEvents(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(pastEvents, w)
|
||||
}
|
||||
eventChannel, err := m.WatchForEvents(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return streamResults(eventChannel, w, r, m)
|
||||
|
||||
}
|
||||
|
||||
// API v2.0
|
||||
|
||||
type version2_0 struct {
|
||||
}
|
||||
|
||||
func newVersion2_0() *version2_0 {
|
||||
return &version2_0{}
|
||||
}
|
||||
|
||||
func (self *version2_0) Version() string {
|
||||
return "v2.0"
|
||||
}
|
||||
|
||||
func (self *version2_0) SupportedRequestTypes() []string {
|
||||
return []string{versionApi, attributesApi, eventsApi, machineApi, summaryApi, statsApi, specApi, storageApi, psApi, customMetricsApi}
|
||||
}
|
||||
|
||||
func (self *version2_0) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
opt, err := getRequestOptions(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch requestType {
|
||||
case versionApi:
|
||||
glog.V(4).Infof("Api - Version")
|
||||
versionInfo, err := m.GetVersionInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(versionInfo.CadvisorVersion, w)
|
||||
case attributesApi:
|
||||
glog.V(4).Info("Api - Attributes")
|
||||
|
||||
machineInfo, err := m.GetMachineInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versionInfo, err := m.GetVersionInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info := v2.GetAttributes(machineInfo, versionInfo)
|
||||
return writeResult(info, w)
|
||||
case machineApi:
|
||||
glog.V(4).Info("Api - Machine")
|
||||
|
||||
// TODO(rjnagal): Move machineInfo from v1.
|
||||
machineInfo, err := m.GetMachineInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(machineInfo, w)
|
||||
case summaryApi:
|
||||
containerName := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Summary for container %q, options %+v", containerName, opt)
|
||||
|
||||
stats, err := m.GetDerivedStats(containerName, opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(stats, w)
|
||||
case statsApi:
|
||||
name := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Stats: Looking for stats for container %q, options %+v", name, opt)
|
||||
infos, err := m.GetRequestedContainersInfo(name, opt)
|
||||
if err != nil {
|
||||
if len(infos) == 0 {
|
||||
return err
|
||||
}
|
||||
glog.Errorf("Error calling GetRequestedContainersInfo: %v", err)
|
||||
}
|
||||
contStats := make(map[string][]v2.DeprecatedContainerStats, 0)
|
||||
for name, cinfo := range infos {
|
||||
contStats[name] = v2.DeprecatedStatsFromV1(cinfo)
|
||||
}
|
||||
return writeResult(contStats, w)
|
||||
case customMetricsApi:
|
||||
containerName := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Custom Metrics: Looking for metrics for container %q, options %+v", containerName, opt)
|
||||
infos, err := m.GetContainerInfoV2(containerName, opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
contMetrics := make(map[string]map[string]map[string][]info.MetricValBasic, 0)
|
||||
for _, cinfo := range infos {
|
||||
metrics := make(map[string]map[string][]info.MetricValBasic, 0)
|
||||
for _, contStat := range cinfo.Stats {
|
||||
if len(contStat.CustomMetrics) == 0 {
|
||||
continue
|
||||
}
|
||||
for name, allLabels := range contStat.CustomMetrics {
|
||||
metricLabels := make(map[string][]info.MetricValBasic, 0)
|
||||
for _, metric := range allLabels {
|
||||
if !metric.Timestamp.IsZero() {
|
||||
metVal := info.MetricValBasic{
|
||||
Timestamp: metric.Timestamp,
|
||||
IntValue: metric.IntValue,
|
||||
FloatValue: metric.FloatValue,
|
||||
}
|
||||
labels := metrics[name]
|
||||
if labels != nil {
|
||||
values := labels[metric.Label]
|
||||
values = append(values, metVal)
|
||||
labels[metric.Label] = values
|
||||
metrics[name] = labels
|
||||
} else {
|
||||
metricLabels[metric.Label] = []info.MetricValBasic{metVal}
|
||||
metrics[name] = metricLabels
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
contMetrics[containerName] = metrics
|
||||
}
|
||||
return writeResult(contMetrics, w)
|
||||
case specApi:
|
||||
containerName := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Spec for container %q, options %+v", containerName, opt)
|
||||
specs, err := m.GetContainerSpec(containerName, opt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(specs, w)
|
||||
case storageApi:
|
||||
label := r.URL.Query().Get("label")
|
||||
uuid := r.URL.Query().Get("uuid")
|
||||
switch {
|
||||
case uuid != "":
|
||||
fi, err := m.GetFsInfoByFsUUID(uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(fi, w)
|
||||
case label != "":
|
||||
// Get a specific label.
|
||||
fi, err := m.GetFsInfo(label)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(fi, w)
|
||||
default:
|
||||
// Get all global filesystems info.
|
||||
fi, err := m.GetFsInfo("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeResult(fi, w)
|
||||
}
|
||||
case eventsApi:
|
||||
return handleEventRequest(request, m, w, r)
|
||||
case psApi:
|
||||
// reuse container type from request.
|
||||
// ignore recursive.
|
||||
// TODO(rjnagal): consider count to limit ps output.
|
||||
name := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Spec for container %q, options %+v", name, opt)
|
||||
ps, err := m.GetProcessList(name, opt)
|
||||
if err != nil {
|
||||
return fmt.Errorf("process listing failed: %v", err)
|
||||
}
|
||||
return writeResult(ps, w)
|
||||
default:
|
||||
return fmt.Errorf("unknown request type %q", requestType)
|
||||
}
|
||||
}
|
||||
|
||||
type version2_1 struct {
|
||||
baseVersion *version2_0
|
||||
}
|
||||
|
||||
func newVersion2_1(v *version2_0) *version2_1 {
|
||||
return &version2_1{
|
||||
baseVersion: v,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *version2_1) Version() string {
|
||||
return "v2.1"
|
||||
}
|
||||
|
||||
func (self *version2_1) SupportedRequestTypes() []string {
|
||||
return append([]string{machineStatsApi}, self.baseVersion.SupportedRequestTypes()...)
|
||||
}
|
||||
|
||||
func (self *version2_1) HandleRequest(requestType string, request []string, m manager.Manager, w http.ResponseWriter, r *http.Request) error {
|
||||
// Get the query request.
|
||||
opt, err := getRequestOptions(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch requestType {
|
||||
case machineStatsApi:
|
||||
glog.V(4).Infof("Api - MachineStats(%v)", request)
|
||||
cont, err := m.GetRequestedContainersInfo("/", opt)
|
||||
if err != nil {
|
||||
if len(cont) == 0 {
|
||||
return err
|
||||
}
|
||||
glog.Errorf("Error calling GetRequestedContainersInfo: %v", err)
|
||||
}
|
||||
return writeResult(v2.MachineStatsFromV1(cont["/"]), w)
|
||||
case statsApi:
|
||||
name := getContainerName(request)
|
||||
glog.V(4).Infof("Api - Stats: Looking for stats for container %q, options %+v", name, opt)
|
||||
conts, err := m.GetRequestedContainersInfo(name, opt)
|
||||
if err != nil {
|
||||
if len(conts) == 0 {
|
||||
return err
|
||||
}
|
||||
glog.Errorf("Error calling GetRequestedContainersInfo: %v", err)
|
||||
}
|
||||
contStats := make(map[string]v2.ContainerInfo, len(conts))
|
||||
for name, cont := range conts {
|
||||
if name == "/" {
|
||||
// Root cgroup stats should be exposed as machine stats
|
||||
continue
|
||||
}
|
||||
contStats[name] = v2.ContainerInfo{
|
||||
Spec: v2.ContainerSpecFromV1(&cont.Spec, cont.Aliases, cont.Namespace),
|
||||
Stats: v2.ContainerStatsFromV1(name, &cont.Spec, cont.Stats),
|
||||
}
|
||||
}
|
||||
return writeResult(contStats, w)
|
||||
default:
|
||||
return self.baseVersion.HandleRequest(requestType, request, m, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func getRequestOptions(r *http.Request) (v2.RequestOptions, error) {
|
||||
supportedTypes := map[string]bool{
|
||||
v2.TypeName: true,
|
||||
v2.TypeDocker: true,
|
||||
}
|
||||
// fill in the defaults.
|
||||
opt := v2.RequestOptions{
|
||||
IdType: v2.TypeName,
|
||||
Count: 64,
|
||||
Recursive: false,
|
||||
}
|
||||
idType := r.URL.Query().Get("type")
|
||||
if len(idType) != 0 {
|
||||
if !supportedTypes[idType] {
|
||||
return opt, fmt.Errorf("unknown 'type' %q", idType)
|
||||
}
|
||||
opt.IdType = idType
|
||||
}
|
||||
count := r.URL.Query().Get("count")
|
||||
if len(count) != 0 {
|
||||
n, err := strconv.ParseUint(count, 10, 32)
|
||||
if err != nil {
|
||||
return opt, fmt.Errorf("failed to parse 'count' option: %v", count)
|
||||
}
|
||||
opt.Count = int(n)
|
||||
}
|
||||
recursive := r.URL.Query().Get("recursive")
|
||||
if recursive == "true" {
|
||||
opt.Recursive = true
|
||||
}
|
||||
return opt, nil
|
||||
}
|
24
vendor/github.com/google/cadvisor/healthz/BUILD
generated
vendored
24
vendor/github.com/google/cadvisor/healthz/BUILD
generated
vendored
@ -1,24 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["healthz.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/healthz",
|
||||
importpath = "github.com/google/cadvisor/healthz",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/github.com/google/cadvisor/http/mux:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
32
vendor/github.com/google/cadvisor/healthz/healthz.go
generated
vendored
32
vendor/github.com/google/cadvisor/healthz/healthz.go
generated
vendored
@ -1,32 +0,0 @@
|
||||
// Copyright 2014 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 healthz
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
httpmux "github.com/google/cadvisor/http/mux"
|
||||
)
|
||||
|
||||
func handleHealthz(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
// Register simple HTTP /healthz handler to return "ok".
|
||||
func RegisterHandler(mux httpmux.Mux) error {
|
||||
mux.HandleFunc("/healthz", handleHealthz)
|
||||
return nil
|
||||
}
|
40
vendor/github.com/google/cadvisor/http/BUILD
generated
vendored
40
vendor/github.com/google/cadvisor/http/BUILD
generated
vendored
@ -1,40 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["handlers.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/http",
|
||||
importpath = "github.com/google/cadvisor/http",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/abbot/go-http-auth:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/api:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/healthz:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/http/mux:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/manager:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/metrics:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/pages:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/pages/static:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/validate:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/github.com/google/cadvisor/http/mux:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
112
vendor/github.com/google/cadvisor/http/handlers.go
generated
vendored
112
vendor/github.com/google/cadvisor/http/handlers.go
generated
vendored
@ -1,112 +0,0 @@
|
||||
// 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 http
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/google/cadvisor/api"
|
||||
"github.com/google/cadvisor/healthz"
|
||||
httpmux "github.com/google/cadvisor/http/mux"
|
||||
"github.com/google/cadvisor/manager"
|
||||
"github.com/google/cadvisor/metrics"
|
||||
"github.com/google/cadvisor/pages"
|
||||
"github.com/google/cadvisor/pages/static"
|
||||
"github.com/google/cadvisor/validate"
|
||||
|
||||
auth "github.com/abbot/go-http-auth"
|
||||
"github.com/golang/glog"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
func RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAuthFile, httpAuthRealm, httpDigestFile, httpDigestRealm string) error {
|
||||
// Basic health handler.
|
||||
if err := healthz.RegisterHandler(mux); err != nil {
|
||||
return fmt.Errorf("failed to register healthz handler: %s", err)
|
||||
}
|
||||
|
||||
// Validation/Debug handler.
|
||||
mux.HandleFunc(validate.ValidatePage, func(w http.ResponseWriter, r *http.Request) {
|
||||
err := validate.HandleRequest(w, containerManager)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
})
|
||||
|
||||
// Register API handler.
|
||||
if err := api.RegisterHandlers(mux, containerManager); err != nil {
|
||||
return fmt.Errorf("failed to register API handlers: %s", err)
|
||||
}
|
||||
|
||||
// Redirect / to containers page.
|
||||
mux.Handle("/", http.RedirectHandler(pages.ContainersPage, http.StatusTemporaryRedirect))
|
||||
|
||||
var authenticated bool
|
||||
|
||||
// Setup the authenticator object
|
||||
if httpAuthFile != "" {
|
||||
glog.V(1).Infof("Using auth file %s", httpAuthFile)
|
||||
secrets := auth.HtpasswdFileProvider(httpAuthFile)
|
||||
authenticator := auth.NewBasicAuthenticator(httpAuthRealm, secrets)
|
||||
mux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler))
|
||||
if err := pages.RegisterHandlersBasic(mux, containerManager, authenticator); err != nil {
|
||||
return fmt.Errorf("failed to register pages auth handlers: %s", err)
|
||||
}
|
||||
authenticated = true
|
||||
}
|
||||
if httpAuthFile == "" && httpDigestFile != "" {
|
||||
glog.V(1).Infof("Using digest file %s", httpDigestFile)
|
||||
secrets := auth.HtdigestFileProvider(httpDigestFile)
|
||||
authenticator := auth.NewDigestAuthenticator(httpDigestRealm, secrets)
|
||||
mux.HandleFunc(static.StaticResource, authenticator.Wrap(staticHandler))
|
||||
if err := pages.RegisterHandlersDigest(mux, containerManager, authenticator); err != nil {
|
||||
return fmt.Errorf("failed to register pages digest handlers: %s", err)
|
||||
}
|
||||
authenticated = true
|
||||
}
|
||||
|
||||
// Change handler based on authenticator initalization
|
||||
if !authenticated {
|
||||
mux.HandleFunc(static.StaticResource, staticHandlerNoAuth)
|
||||
if err := pages.RegisterHandlersBasic(mux, containerManager, nil); err != nil {
|
||||
return fmt.Errorf("failed to register pages handlers: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterPrometheusHandler creates a new PrometheusCollector and configures
|
||||
// the provided HTTP mux to handle the given Prometheus endpoint.
|
||||
func RegisterPrometheusHandler(mux httpmux.Mux, containerManager manager.Manager, prometheusEndpoint string, f metrics.ContainerLabelsFunc) {
|
||||
r := prometheus.NewRegistry()
|
||||
r.MustRegister(
|
||||
metrics.NewPrometheusCollector(containerManager, f),
|
||||
prometheus.NewGoCollector(),
|
||||
prometheus.NewProcessCollector(os.Getpid(), ""),
|
||||
)
|
||||
mux.Handle(prometheusEndpoint, promhttp.HandlerFor(r, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}))
|
||||
}
|
||||
|
||||
func staticHandlerNoAuth(w http.ResponseWriter, r *http.Request) {
|
||||
static.HandleRequest(w, r.URL)
|
||||
}
|
||||
|
||||
func staticHandler(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
|
||||
static.HandleRequest(w, r.URL)
|
||||
}
|
23
vendor/github.com/google/cadvisor/http/mux/BUILD
generated
vendored
23
vendor/github.com/google/cadvisor/http/mux/BUILD
generated
vendored
@ -1,23 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["mux.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/http/mux",
|
||||
importpath = "github.com/google/cadvisor/http/mux",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
26
vendor/github.com/google/cadvisor/http/mux/mux.go
generated
vendored
26
vendor/github.com/google/cadvisor/http/mux/mux.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
// 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 mux
|
||||
|
||||
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)
|
||||
Handle(pattern string, handler http.Handler)
|
||||
}
|
39
vendor/github.com/google/cadvisor/pages/BUILD
generated
vendored
39
vendor/github.com/google/cadvisor/pages/BUILD
generated
vendored
@ -1,39 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"containers.go",
|
||||
"docker.go",
|
||||
"pages.go",
|
||||
"templates.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/pages",
|
||||
importpath = "github.com/google/cadvisor/pages",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/abbot/go-http-auth:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/container/docker:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/http/mux:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/manager:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/github.com/google/cadvisor/pages/static:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
253
vendor/github.com/google/cadvisor/pages/containers.go
generated
vendored
253
vendor/github.com/google/cadvisor/pages/containers.go
generated
vendored
@ -1,253 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Page for /containers/
|
||||
package pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/manager"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const ContainersPage = "/containers/"
|
||||
|
||||
// from http://golang.org/doc/effective_go.html#constants
|
||||
type ByteSize float64
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
// KB - kilobyte
|
||||
KB ByteSize = 1 << (10 * iota)
|
||||
// MB - megabyte
|
||||
MB
|
||||
// GB - gigabyte
|
||||
GB
|
||||
// TB - terabyte
|
||||
TB
|
||||
// PB - petabyte
|
||||
PB
|
||||
// EB - exabyte
|
||||
EB
|
||||
// ZB - zettabyte
|
||||
ZB
|
||||
// YB - yottabyte
|
||||
YB
|
||||
)
|
||||
|
||||
func (b ByteSize) Size() string {
|
||||
for _, i := range [...]ByteSize{YB, ZB, EB, PB, TB, GB, MB, KB} {
|
||||
if b >= i {
|
||||
return fmt.Sprintf("%.2f", b/i)
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%.2f", b)
|
||||
}
|
||||
|
||||
func (b ByteSize) Unit() string {
|
||||
switch {
|
||||
case b >= YB:
|
||||
return "YB"
|
||||
case b >= ZB:
|
||||
return "ZB"
|
||||
case b >= EB:
|
||||
return "EB"
|
||||
case b >= PB:
|
||||
return "PB"
|
||||
case b >= TB:
|
||||
return "TB"
|
||||
case b >= GB:
|
||||
return "GB"
|
||||
case b >= MB:
|
||||
return "MB"
|
||||
case b >= KB:
|
||||
return "KB"
|
||||
}
|
||||
return "B"
|
||||
}
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"printMask": printMask,
|
||||
"printCores": printCores,
|
||||
"printShares": printShares,
|
||||
"printSize": printSize,
|
||||
"printUnit": printUnit,
|
||||
}
|
||||
|
||||
func printMask(mask string, numCores int) interface{} {
|
||||
masks := make([]string, numCores)
|
||||
activeCores := getActiveCores(mask)
|
||||
for i := 0; i < numCores; i++ {
|
||||
coreClass := "inactive-cpu"
|
||||
if activeCores[i] {
|
||||
coreClass = "active-cpu"
|
||||
}
|
||||
masks[i] = fmt.Sprintf("<span class=\"%s\">%d</span>", coreClass, i)
|
||||
}
|
||||
return template.HTML(strings.Join(masks, " "))
|
||||
}
|
||||
|
||||
func getActiveCores(mask string) map[int]bool {
|
||||
activeCores := make(map[int]bool)
|
||||
for _, corebits := range strings.Split(mask, ",") {
|
||||
cores := strings.Split(corebits, "-")
|
||||
if len(cores) == 1 {
|
||||
index, err := strconv.Atoi(cores[0])
|
||||
if err != nil {
|
||||
// Ignore malformed strings.
|
||||
continue
|
||||
}
|
||||
activeCores[index] = true
|
||||
} else if len(cores) == 2 {
|
||||
start, err := strconv.Atoi(cores[0])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
end, err := strconv.Atoi(cores[1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for i := start; i <= end; i++ {
|
||||
activeCores[i] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return activeCores
|
||||
}
|
||||
|
||||
func printCores(millicores *uint64) string {
|
||||
cores := float64(*millicores) / 1000
|
||||
return strconv.FormatFloat(cores, 'f', 3, 64)
|
||||
}
|
||||
|
||||
func printShares(shares *uint64) string {
|
||||
return fmt.Sprintf("%d", *shares)
|
||||
}
|
||||
|
||||
// Size after which we consider memory to be "unlimited". This is not
|
||||
// MaxInt64 due to rounding by the kernel.
|
||||
const maxMemorySize = uint64(1 << 62)
|
||||
|
||||
func printSize(bytes uint64) string {
|
||||
if bytes >= maxMemorySize {
|
||||
return "unlimited"
|
||||
}
|
||||
return ByteSize(bytes).Size()
|
||||
}
|
||||
|
||||
func printUnit(bytes uint64) string {
|
||||
if bytes >= maxMemorySize {
|
||||
return ""
|
||||
}
|
||||
return ByteSize(bytes).Unit()
|
||||
}
|
||||
|
||||
func serveContainersPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {
|
||||
start := time.Now()
|
||||
|
||||
// The container name is the path after the handler
|
||||
containerName := u.Path[len(ContainersPage)-1:]
|
||||
|
||||
// Get the container.
|
||||
reqParams := info.ContainerInfoRequest{
|
||||
NumStats: 60,
|
||||
}
|
||||
cont, err := m.GetContainerInfo(containerName, &reqParams)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
displayName := getContainerDisplayName(cont.ContainerReference)
|
||||
|
||||
// Get the MachineInfo
|
||||
machineInfo, err := m.GetMachineInfo()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get machine info: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
rootDir := getRootDir(containerName)
|
||||
|
||||
// Make a list of the parent containers and their links
|
||||
pathParts := strings.Split(string(cont.Name), "/")
|
||||
parentContainers := make([]link, 0, len(pathParts))
|
||||
parentContainers = append(parentContainers, link{
|
||||
Text: "root",
|
||||
Link: path.Join(rootDir, ContainersPage),
|
||||
})
|
||||
for i := 1; i < len(pathParts); i++ {
|
||||
// Skip empty parts.
|
||||
if pathParts[i] == "" {
|
||||
continue
|
||||
}
|
||||
parentContainers = append(parentContainers, link{
|
||||
Text: pathParts[i],
|
||||
Link: path.Join(rootDir, ContainersPage, path.Join(pathParts[1:i+1]...)),
|
||||
})
|
||||
}
|
||||
|
||||
// Build the links for the subcontainers.
|
||||
subcontainerLinks := make([]link, 0, len(cont.Subcontainers))
|
||||
for _, sub := range cont.Subcontainers {
|
||||
if !m.Exists(sub.Name) {
|
||||
continue
|
||||
}
|
||||
subcontainerLinks = append(subcontainerLinks, link{
|
||||
Text: getContainerDisplayName(sub),
|
||||
Link: path.Join(rootDir, ContainersPage, sub.Name),
|
||||
})
|
||||
}
|
||||
|
||||
data := &pageData{
|
||||
DisplayName: displayName,
|
||||
ContainerName: escapeContainerName(cont.Name),
|
||||
ParentContainers: parentContainers,
|
||||
Subcontainers: subcontainerLinks,
|
||||
Spec: cont.Spec,
|
||||
Stats: cont.Stats,
|
||||
MachineInfo: machineInfo,
|
||||
IsRoot: cont.Name == "/",
|
||||
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork || cont.Spec.HasFilesystem,
|
||||
CpuAvailable: cont.Spec.HasCpu,
|
||||
MemoryAvailable: cont.Spec.HasMemory,
|
||||
NetworkAvailable: cont.Spec.HasNetwork,
|
||||
FsAvailable: cont.Spec.HasFilesystem,
|
||||
CustomMetricsAvailable: cont.Spec.HasCustomMetrics,
|
||||
SubcontainersAvailable: len(subcontainerLinks) > 0,
|
||||
Root: rootDir,
|
||||
}
|
||||
err = pageTemplate.Execute(w, data)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to apply template: %s", err)
|
||||
}
|
||||
|
||||
glog.V(5).Infof("Request took %s", time.Since(start))
|
||||
}
|
||||
|
||||
// Build a relative path to the root of the container page.
|
||||
func getRootDir(containerName string) string {
|
||||
// The root is at: container depth
|
||||
levels := (strings.Count(containerName, "/"))
|
||||
return strings.Repeat("../", levels)
|
||||
}
|
162
vendor/github.com/google/cadvisor/pages/docker.go
generated
vendored
162
vendor/github.com/google/cadvisor/pages/docker.go
generated
vendored
@ -1,162 +0,0 @@
|
||||
// Copyright 2014 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 pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/manager"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const DockerPage = "/docker/"
|
||||
|
||||
func toStatusKV(status info.DockerStatus) ([]keyVal, []keyVal) {
|
||||
ds := []keyVal{
|
||||
{Key: "Driver", Value: status.Driver},
|
||||
}
|
||||
for k, v := range status.DriverStatus {
|
||||
ds = append(ds, keyVal{Key: k, Value: v})
|
||||
}
|
||||
return []keyVal{
|
||||
{Key: "Docker Version", Value: status.Version},
|
||||
{Key: "Docker API Version", Value: status.APIVersion},
|
||||
{Key: "Kernel Version", Value: status.KernelVersion},
|
||||
{Key: "OS Version", Value: status.OS},
|
||||
{Key: "Host Name", Value: status.Hostname},
|
||||
{Key: "Docker Root Directory", Value: status.RootDir},
|
||||
{Key: "Execution Driver", Value: status.ExecDriver},
|
||||
{Key: "Number of Images", Value: strconv.Itoa(status.NumImages)},
|
||||
{Key: "Number of Containers", Value: strconv.Itoa(status.NumContainers)},
|
||||
}, ds
|
||||
}
|
||||
|
||||
func serveDockerPage(m manager.Manager, w http.ResponseWriter, u *url.URL) {
|
||||
start := time.Now()
|
||||
|
||||
// The container name is the path after the handler
|
||||
containerName := u.Path[len(DockerPage)-1:]
|
||||
rootDir := getRootDir(containerName)
|
||||
|
||||
var data *pageData
|
||||
if containerName == "/" {
|
||||
// Get the containers.
|
||||
reqParams := info.ContainerInfoRequest{
|
||||
NumStats: 0,
|
||||
}
|
||||
conts, err := m.AllDockerContainers(&reqParams)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
subcontainers := make([]link, 0, len(conts))
|
||||
for _, cont := range conts {
|
||||
subcontainers = append(subcontainers, link{
|
||||
Text: getContainerDisplayName(cont.ContainerReference),
|
||||
Link: path.Join(rootDir, DockerPage, docker.ContainerNameToDockerId(cont.ContainerReference.Name)),
|
||||
})
|
||||
}
|
||||
|
||||
// Get Docker status
|
||||
status, err := m.DockerInfo()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get docker info: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
dockerStatus, driverStatus := toStatusKV(status)
|
||||
// Get Docker Images
|
||||
images, err := m.DockerImages()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get docker images: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
dockerContainersText := "Docker Containers"
|
||||
data = &pageData{
|
||||
DisplayName: dockerContainersText,
|
||||
ParentContainers: []link{
|
||||
{
|
||||
Text: dockerContainersText,
|
||||
Link: path.Join(rootDir, DockerPage),
|
||||
}},
|
||||
Subcontainers: subcontainers,
|
||||
Root: rootDir,
|
||||
DockerStatus: dockerStatus,
|
||||
DockerDriverStatus: driverStatus,
|
||||
DockerImages: images,
|
||||
}
|
||||
} else {
|
||||
// Get the container.
|
||||
reqParams := info.ContainerInfoRequest{
|
||||
NumStats: 60,
|
||||
}
|
||||
cont, err := m.DockerContainer(containerName[1:], &reqParams)
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get container %q with error: %v", containerName, err), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
displayName := getContainerDisplayName(cont.ContainerReference)
|
||||
|
||||
// Make a list of the parent containers and their links
|
||||
var parentContainers []link
|
||||
parentContainers = append(parentContainers, link{
|
||||
Text: "Docker Containers",
|
||||
Link: path.Join(rootDir, DockerPage),
|
||||
})
|
||||
parentContainers = append(parentContainers, link{
|
||||
Text: displayName,
|
||||
Link: path.Join(rootDir, DockerPage, docker.ContainerNameToDockerId(cont.Name)),
|
||||
})
|
||||
|
||||
// Get the MachineInfo
|
||||
machineInfo, err := m.GetMachineInfo()
|
||||
if err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to get machine info: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
data = &pageData{
|
||||
DisplayName: displayName,
|
||||
ContainerName: escapeContainerName(cont.Name),
|
||||
ParentContainers: parentContainers,
|
||||
Spec: cont.Spec,
|
||||
Stats: cont.Stats,
|
||||
MachineInfo: machineInfo,
|
||||
ResourcesAvailable: cont.Spec.HasCpu || cont.Spec.HasMemory || cont.Spec.HasNetwork,
|
||||
CpuAvailable: cont.Spec.HasCpu,
|
||||
MemoryAvailable: cont.Spec.HasMemory,
|
||||
NetworkAvailable: cont.Spec.HasNetwork,
|
||||
FsAvailable: cont.Spec.HasFilesystem,
|
||||
CustomMetricsAvailable: cont.Spec.HasCustomMetrics,
|
||||
Root: rootDir,
|
||||
}
|
||||
}
|
||||
|
||||
err := pageTemplate.Execute(w, data)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to apply template: %s", err)
|
||||
}
|
||||
|
||||
glog.V(5).Infof("Request took %s", time.Since(start))
|
||||
return
|
||||
}
|
163
vendor/github.com/google/cadvisor/pages/pages.go
generated
vendored
163
vendor/github.com/google/cadvisor/pages/pages.go
generated
vendored
@ -1,163 +0,0 @@
|
||||
// Copyright 2014 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 pages
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
httpmux "github.com/google/cadvisor/http/mux"
|
||||
info "github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/manager"
|
||||
|
||||
auth "github.com/abbot/go-http-auth"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
var pageTemplate *template.Template
|
||||
|
||||
type link struct {
|
||||
// Text to show in the link.
|
||||
Text string
|
||||
|
||||
// Web address to link to.
|
||||
Link string
|
||||
}
|
||||
|
||||
type keyVal struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
type pageData struct {
|
||||
DisplayName string
|
||||
ContainerName string
|
||||
ParentContainers []link
|
||||
Subcontainers []link
|
||||
Spec info.ContainerSpec
|
||||
Stats []*info.ContainerStats
|
||||
MachineInfo *info.MachineInfo
|
||||
IsRoot bool
|
||||
ResourcesAvailable bool
|
||||
CpuAvailable bool
|
||||
MemoryAvailable bool
|
||||
NetworkAvailable bool
|
||||
FsAvailable bool
|
||||
CustomMetricsAvailable bool
|
||||
SubcontainersAvailable bool
|
||||
Root string
|
||||
DockerStatus []keyVal
|
||||
DockerDriverStatus []keyVal
|
||||
DockerImages []info.DockerImage
|
||||
}
|
||||
|
||||
func init() {
|
||||
containersHtmlTemplate, _ := Asset("pages/assets/html/containers.html")
|
||||
pageTemplate = template.New("containersTemplate").Funcs(funcMap)
|
||||
_, err := pageTemplate.Parse(string(containersHtmlTemplate))
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to parse template: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func containerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
serveContainersPage(containerManager, w, r.URL)
|
||||
}
|
||||
}
|
||||
|
||||
func containerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {
|
||||
return func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
|
||||
serveContainersPage(containerManager, w, r.URL)
|
||||
}
|
||||
}
|
||||
|
||||
func dockerHandlerNoAuth(containerManager manager.Manager) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
serveDockerPage(containerManager, w, r.URL)
|
||||
}
|
||||
}
|
||||
|
||||
func dockerHandler(containerManager manager.Manager) auth.AuthenticatedHandlerFunc {
|
||||
return func(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
|
||||
serveDockerPage(containerManager, w, r.URL)
|
||||
}
|
||||
}
|
||||
|
||||
// Register http handlers
|
||||
func RegisterHandlersDigest(mux httpmux.Mux, containerManager manager.Manager, authenticator *auth.DigestAuth) error {
|
||||
// Register the handler for the containers page.
|
||||
if authenticator != nil {
|
||||
mux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager)))
|
||||
mux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager)))
|
||||
} else {
|
||||
mux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager))
|
||||
mux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RegisterHandlersBasic(mux httpmux.Mux, containerManager manager.Manager, authenticator *auth.BasicAuth) error {
|
||||
// Register the handler for the containers and docker age.
|
||||
if authenticator != nil {
|
||||
mux.HandleFunc(ContainersPage, authenticator.Wrap(containerHandler(containerManager)))
|
||||
mux.HandleFunc(DockerPage, authenticator.Wrap(dockerHandler(containerManager)))
|
||||
} else {
|
||||
mux.HandleFunc(ContainersPage, containerHandlerNoAuth(containerManager))
|
||||
mux.HandleFunc(DockerPage, dockerHandlerNoAuth(containerManager))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getContainerDisplayName(cont info.ContainerReference) string {
|
||||
// Pick a user-added alias as display name.
|
||||
displayName := ""
|
||||
for _, alias := range cont.Aliases {
|
||||
// ignore container id as alias.
|
||||
if strings.Contains(cont.Name, alias) {
|
||||
continue
|
||||
}
|
||||
// pick shortest display name if multiple aliases are available.
|
||||
if displayName == "" || len(displayName) >= len(alias) {
|
||||
displayName = alias
|
||||
}
|
||||
}
|
||||
|
||||
if displayName == "" {
|
||||
displayName = cont.Name
|
||||
} else if len(displayName) > 50 {
|
||||
// truncate display name to fit in one line.
|
||||
displayName = displayName[:50] + "..."
|
||||
}
|
||||
|
||||
// Add the full container name to the display name.
|
||||
if displayName != cont.Name {
|
||||
displayName = fmt.Sprintf("%s (%s)", displayName, cont.Name)
|
||||
}
|
||||
|
||||
return displayName
|
||||
}
|
||||
|
||||
// Escape the non-path characters on a container name.
|
||||
func escapeContainerName(containerName string) string {
|
||||
parts := strings.Split(containerName, "/")
|
||||
for i := range parts {
|
||||
parts[i] = url.QueryEscape(parts[i])
|
||||
}
|
||||
return strings.Join(parts, "/")
|
||||
}
|
27
vendor/github.com/google/cadvisor/pages/static/BUILD
generated
vendored
27
vendor/github.com/google/cadvisor/pages/static/BUILD
generated
vendored
@ -1,27 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"assets.go",
|
||||
"static.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/pages/static",
|
||||
importpath = "github.com/google/cadvisor/pages/static",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/github.com/golang/glog:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
442
vendor/github.com/google/cadvisor/pages/static/assets.go
generated
vendored
442
vendor/github.com/google/cadvisor/pages/static/assets.go
generated
vendored
File diff suppressed because one or more lines are too long
77
vendor/github.com/google/cadvisor/pages/static/static.go
generated
vendored
77
vendor/github.com/google/cadvisor/pages/static/static.go
generated
vendored
@ -1,77 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Handler for /static content.
|
||||
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const StaticResource = "/static/"
|
||||
|
||||
var popper, _ = Asset("pages/assets/js/popper.min.js")
|
||||
var bootstrapJs, _ = Asset("pages/assets/js/bootstrap-4.0.0-beta.2.min.js")
|
||||
var containersJs, _ = Asset("pages/assets/js/containers.js")
|
||||
var gchartsJs, _ = Asset("pages/assets/js/gcharts.js")
|
||||
var googleJsapiJs, _ = Asset("pages/assets/js/google-jsapi.js")
|
||||
var jqueryJs, _ = Asset("pages/assets/js/jquery-3.0.0.min.js")
|
||||
|
||||
var bootstrapCss, _ = Asset("pages/assets/styles/bootstrap-4.0.0-beta.2.min.css")
|
||||
var bootstrapThemeCss, _ = Asset("pages/assets/styles/bootstrap-theme-3.1.1.min.css")
|
||||
var containersCss, _ = Asset("pages/assets/styles/containers.css")
|
||||
|
||||
var staticFiles = map[string][]byte{
|
||||
"popper.min.js": popper,
|
||||
"bootstrap-4.0.0-beta.2.min.css": bootstrapCss,
|
||||
"bootstrap-4.0.0-beta.2.min.js": bootstrapJs,
|
||||
"bootstrap-theme-3.1.1.min.css": bootstrapThemeCss,
|
||||
"containers.css": containersCss,
|
||||
"containers.js": containersJs,
|
||||
"gcharts.js": gchartsJs,
|
||||
"google-jsapi.js": googleJsapiJs,
|
||||
"jquery-3.0.0.min.js": jqueryJs,
|
||||
}
|
||||
|
||||
func HandleRequest(w http.ResponseWriter, u *url.URL) {
|
||||
if len(u.Path) <= len(StaticResource) {
|
||||
http.Error(w, fmt.Sprintf("unknown static resource %q", u.Path), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the static content if it exists.
|
||||
resource := u.Path[len(StaticResource):]
|
||||
content, ok := staticFiles[resource]
|
||||
if !ok {
|
||||
http.Error(w, fmt.Sprintf("unknown static resource %q", u.Path), http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// Set Content-Type if we were able to detect it.
|
||||
contentType := mime.TypeByExtension(path.Ext(resource))
|
||||
if contentType != "" {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
}
|
||||
|
||||
if _, err := w.Write(content); err != nil {
|
||||
glog.Errorf("Failed to write response: %v", err)
|
||||
}
|
||||
}
|
256
vendor/github.com/google/cadvisor/pages/templates.go
generated
vendored
256
vendor/github.com/google/cadvisor/pages/templates.go
generated
vendored
File diff suppressed because one or more lines are too long
29
vendor/github.com/google/cadvisor/validate/BUILD
generated
vendored
29
vendor/github.com/google/cadvisor/validate/BUILD
generated
vendored
@ -1,29 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["validate.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/github.com/google/cadvisor/validate",
|
||||
importpath = "github.com/google/cadvisor/validate",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/google/cadvisor/container/docker:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/manager:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/utils:go_default_library",
|
||||
"//vendor/github.com/opencontainers/runc/libcontainer/cgroups:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
324
vendor/github.com/google/cadvisor/validate/validate.go
generated
vendored
324
vendor/github.com/google/cadvisor/validate/validate.go
generated
vendored
@ -1,324 +0,0 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// Handler for /validate content.
|
||||
// Validates cadvisor dependencies - kernel, os, docker setup.
|
||||
|
||||
package validate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/google/cadvisor/container/docker"
|
||||
"github.com/google/cadvisor/manager"
|
||||
"github.com/google/cadvisor/utils"
|
||||
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
)
|
||||
|
||||
const (
|
||||
ValidatePage = "/validate/"
|
||||
Supported = "[Supported, but not recommended]"
|
||||
Unsupported = "[Unsupported]"
|
||||
Recommended = "[Supported and recommended]"
|
||||
Unknown = "[Unknown]"
|
||||
VersionFormat = "%d.%d%s"
|
||||
OutputFormat = "%s: %s\n\t%s\n\n"
|
||||
)
|
||||
|
||||
func getMajorMinor(version string) (int, int, error) {
|
||||
var major, minor int
|
||||
var ign string
|
||||
n, err := fmt.Sscanf(version, VersionFormat, &major, &minor, &ign)
|
||||
if n != 3 || err != nil {
|
||||
log.Printf("Failed to parse version for %s", version)
|
||||
return -1, -1, err
|
||||
}
|
||||
return major, minor, nil
|
||||
}
|
||||
|
||||
func validateKernelVersion(version string) (string, string) {
|
||||
desc := fmt.Sprintf("Kernel version is %s. Versions >= 2.6 are supported. 3.0+ are recommended.\n", version)
|
||||
major, minor, err := getMajorMinor(version)
|
||||
if err != nil {
|
||||
desc = fmt.Sprintf("Could not parse kernel version. %s", desc)
|
||||
return Unknown, desc
|
||||
}
|
||||
|
||||
if major < 2 {
|
||||
return Unsupported, desc
|
||||
}
|
||||
|
||||
if major == 2 && minor < 6 {
|
||||
return Unsupported, desc
|
||||
}
|
||||
|
||||
if major >= 3 {
|
||||
return Recommended, desc
|
||||
}
|
||||
|
||||
return Supported, desc
|
||||
}
|
||||
|
||||
func validateDockerVersion(version string) (string, string) {
|
||||
desc := fmt.Sprintf("Docker version is %s. Versions >= 1.0 are supported. 1.2+ are recommended.\n", version)
|
||||
major, minor, err := getMajorMinor(version)
|
||||
if err != nil {
|
||||
desc = fmt.Sprintf("Could not parse docker version. %s\n\t", desc)
|
||||
return Unknown, desc
|
||||
}
|
||||
if major < 1 {
|
||||
return Unsupported, desc
|
||||
}
|
||||
|
||||
if major == 1 && minor < 2 {
|
||||
return Supported, desc
|
||||
}
|
||||
|
||||
return Recommended, desc
|
||||
}
|
||||
|
||||
func getEnabledCgroups() (map[string]int, error) {
|
||||
out, err := ioutil.ReadFile("/proc/cgroups")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cgroups := make(map[string]int)
|
||||
for i, line := range strings.Split(string(out), "\n") {
|
||||
var cgroup string
|
||||
var ign, enabled int
|
||||
if i == 0 || line == "" {
|
||||
continue
|
||||
}
|
||||
n, err := fmt.Sscanf(line, "%s %d %d %d", &cgroup, &ign, &ign, &enabled)
|
||||
if n != 4 || err != nil {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("failed to parse /proc/cgroup entry %s", line)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
cgroups[cgroup] = enabled
|
||||
}
|
||||
return cgroups, nil
|
||||
}
|
||||
|
||||
func areCgroupsPresent(available map[string]int, desired []string) (bool, string) {
|
||||
for _, cgroup := range desired {
|
||||
enabled, ok := available[cgroup]
|
||||
if !ok {
|
||||
reason := fmt.Sprintf("Missing cgroup %s. Available cgroups: %v\n", cgroup, available)
|
||||
return false, reason
|
||||
}
|
||||
if enabled != 1 {
|
||||
reason := fmt.Sprintf("Cgroup %s not enabled. Available cgroups: %v\n", cgroup, available)
|
||||
return false, reason
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func validateCpuCfsBandwidth(available_cgroups map[string]int) string {
|
||||
ok, _ := areCgroupsPresent(available_cgroups, []string{"cpu"})
|
||||
if !ok {
|
||||
return "\tCpu cfs bandwidth status unknown: cpu cgroup not enabled.\n"
|
||||
}
|
||||
mnt, err := cgroups.FindCgroupMountpoint("cpu")
|
||||
if err != nil {
|
||||
return "\tCpu cfs bandwidth status unknown: cpu cgroup not mounted.\n"
|
||||
}
|
||||
_, err = os.Stat(path.Join(mnt, "cpu.cfs_period_us"))
|
||||
if os.IsNotExist(err) {
|
||||
return "\tCpu cfs bandwidth is disabled. Recompile kernel with \"CONFIG_CFS_BANDWIDTH\" enabled.\n"
|
||||
}
|
||||
|
||||
return "\tCpu cfs bandwidth is enabled.\n"
|
||||
}
|
||||
|
||||
func validateMemoryAccounting(available_cgroups map[string]int) string {
|
||||
ok, _ := areCgroupsPresent(available_cgroups, []string{"memory"})
|
||||
if !ok {
|
||||
return "\tHierarchical memory accounting status unknown: memory cgroup not enabled.\n"
|
||||
}
|
||||
mnt, err := cgroups.FindCgroupMountpoint("memory")
|
||||
if err != nil {
|
||||
return "\tHierarchical memory accounting status unknown: memory cgroup not mounted.\n"
|
||||
}
|
||||
hier, err := ioutil.ReadFile(path.Join(mnt, "memory.use_hierarchy"))
|
||||
if err != nil {
|
||||
return "\tHierarchical memory accounting status unknown: hierarchy interface unavailable.\n"
|
||||
}
|
||||
var enabled int
|
||||
n, err := fmt.Sscanf(string(hier), "%d", &enabled)
|
||||
if err != nil || n != 1 {
|
||||
return "\tHierarchical memory accounting status unknown: hierarchy interface unreadable.\n"
|
||||
}
|
||||
if enabled == 1 {
|
||||
return "\tHierarchical memory accounting enabled. Reported memory usage includes memory used by child containers.\n"
|
||||
}
|
||||
return "\tHierarchical memory accounting disabled. Memory usage does not include usage from child containers.\n"
|
||||
|
||||
}
|
||||
|
||||
func validateCgroups() (string, string) {
|
||||
required_cgroups := []string{"cpu", "cpuacct"}
|
||||
recommended_cgroups := []string{"memory", "blkio", "cpuset", "devices", "freezer"}
|
||||
available_cgroups, err := getEnabledCgroups()
|
||||
desc := fmt.Sprintf("\tFollowing cgroups are required: %v\n\tFollowing other cgroups are recommended: %v\n", required_cgroups, recommended_cgroups)
|
||||
if err != nil {
|
||||
desc = fmt.Sprintf("Could not parse /proc/cgroups.\n%s", desc)
|
||||
return Unknown, desc
|
||||
}
|
||||
ok, out := areCgroupsPresent(available_cgroups, required_cgroups)
|
||||
if !ok {
|
||||
out += desc
|
||||
return Unsupported, out
|
||||
}
|
||||
ok, out = areCgroupsPresent(available_cgroups, recommended_cgroups)
|
||||
if !ok {
|
||||
// supported, but not recommended.
|
||||
out += desc
|
||||
return Supported, out
|
||||
}
|
||||
out = fmt.Sprintf("Available cgroups: %v\n", available_cgroups)
|
||||
out += desc
|
||||
out += validateMemoryAccounting(available_cgroups)
|
||||
out += validateCpuCfsBandwidth(available_cgroups)
|
||||
return Recommended, out
|
||||
}
|
||||
|
||||
func validateDockerInfo() (string, string) {
|
||||
info, err := docker.ValidateInfo()
|
||||
if err != nil {
|
||||
return Unsupported, fmt.Sprintf("Docker setup is invalid: %v", err)
|
||||
}
|
||||
|
||||
desc := fmt.Sprintf("Storage driver is %s.\n", info.Driver)
|
||||
return Recommended, desc
|
||||
}
|
||||
|
||||
func validateCgroupMounts() (string, string) {
|
||||
const recommendedMount = "/sys/fs/cgroup"
|
||||
desc := fmt.Sprintf("\tAny cgroup mount point that is detectible and accessible is supported. %s is recommended as a standard location.\n", recommendedMount)
|
||||
mnt, err := cgroups.FindCgroupMountpoint("cpu")
|
||||
if err != nil {
|
||||
out := "Could not locate cgroup mount point.\n"
|
||||
out += desc
|
||||
return Unknown, out
|
||||
}
|
||||
mnt = path.Dir(mnt)
|
||||
if !utils.FileExists(mnt) {
|
||||
out := fmt.Sprintf("Cgroup mount directory %s inaccessible.\n", mnt)
|
||||
out += desc
|
||||
return Unsupported, out
|
||||
}
|
||||
mounts, err := ioutil.ReadDir(mnt)
|
||||
if err != nil {
|
||||
out := fmt.Sprintf("Could not read cgroup mount directory %s.\n", mnt)
|
||||
out += desc
|
||||
return Unsupported, out
|
||||
}
|
||||
mountNames := "\tCgroup mount directories: "
|
||||
for _, mount := range mounts {
|
||||
mountNames += mount.Name() + " "
|
||||
}
|
||||
mountNames += "\n"
|
||||
out := fmt.Sprintf("Cgroups are mounted at %s.\n", mnt)
|
||||
out += mountNames
|
||||
out += desc
|
||||
info, err := ioutil.ReadFile("/proc/mounts")
|
||||
if err != nil {
|
||||
out := fmt.Sprintf("Could not read /proc/mounts.\n")
|
||||
out += desc
|
||||
return Unsupported, out
|
||||
}
|
||||
out += "\tCgroup mounts:\n"
|
||||
for _, line := range strings.Split(string(info), "\n") {
|
||||
if strings.Contains(line, " cgroup ") {
|
||||
out += "\t" + line + "\n"
|
||||
}
|
||||
}
|
||||
if mnt == recommendedMount {
|
||||
return Recommended, out
|
||||
}
|
||||
return Supported, out
|
||||
}
|
||||
|
||||
func validateIoScheduler(containerManager manager.Manager) (string, string) {
|
||||
var desc string
|
||||
mi, err := containerManager.GetMachineInfo()
|
||||
if err != nil {
|
||||
return Unknown, "Machine info not available\n\t"
|
||||
}
|
||||
cfq := false
|
||||
for _, disk := range mi.DiskMap {
|
||||
desc += fmt.Sprintf("\t Disk %q Scheduler type %q.\n", disk.Name, disk.Scheduler)
|
||||
if disk.Scheduler == "cfq" {
|
||||
cfq = true
|
||||
}
|
||||
}
|
||||
// Since we get lot of random block devices, report recommended if
|
||||
// at least one of them is on cfq. Report Supported otherwise.
|
||||
if cfq {
|
||||
desc = "At least one device supports 'cfq' I/O scheduler. Some disk stats can be reported.\n" + desc
|
||||
return Recommended, desc
|
||||
}
|
||||
desc = "None of the devices support 'cfq' I/O scheduler. No disk stats can be reported.\n" + desc
|
||||
return Supported, desc
|
||||
}
|
||||
|
||||
func HandleRequest(w http.ResponseWriter, containerManager manager.Manager) error {
|
||||
// Get cAdvisor version Info.
|
||||
versionInfo, err := containerManager.GetVersionInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out := fmt.Sprintf("cAdvisor version: %s\n\n", versionInfo.CadvisorVersion)
|
||||
|
||||
// No OS is preferred or unsupported as of now.
|
||||
out += fmt.Sprintf("OS version: %s\n\n", versionInfo.ContainerOsVersion)
|
||||
|
||||
kernelValidation, desc := validateKernelVersion(versionInfo.KernelVersion)
|
||||
out += fmt.Sprintf(OutputFormat, "Kernel version", kernelValidation, desc)
|
||||
|
||||
cgroupValidation, desc := validateCgroups()
|
||||
out += fmt.Sprintf(OutputFormat, "Cgroup setup", cgroupValidation, desc)
|
||||
|
||||
mountsValidation, desc := validateCgroupMounts()
|
||||
out += fmt.Sprintf(OutputFormat, "Cgroup mount setup", mountsValidation, desc)
|
||||
|
||||
dockerValidation, desc := validateDockerVersion(versionInfo.DockerVersion)
|
||||
out += fmt.Sprintf(OutputFormat, "Docker version", dockerValidation, desc)
|
||||
|
||||
dockerInfoValidation, desc := validateDockerInfo()
|
||||
out += fmt.Sprintf(OutputFormat, "Docker driver setup", dockerInfoValidation, desc)
|
||||
|
||||
ioSchedulerValidation, desc := validateIoScheduler(containerManager)
|
||||
out += fmt.Sprintf(OutputFormat, "Block device setup", ioSchedulerValidation, desc)
|
||||
|
||||
// Output debug info.
|
||||
debugInfo := containerManager.DebugInfo()
|
||||
for category, lines := range debugInfo {
|
||||
out += fmt.Sprintf(OutputFormat, category, "", strings.Join(lines, "\n\t"))
|
||||
}
|
||||
|
||||
_, err = w.Write([]byte(out))
|
||||
return err
|
||||
}
|
Loading…
Reference in New Issue
Block a user