mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +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",
|
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||||
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/abbot/go-http-auth",
|
|
||||||
"Rev": "c0ef4539dfab4d21c8ef20ba2924f9fc6f186d35"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/armon/circbuf",
|
"ImportPath": "github.com/armon/circbuf",
|
||||||
"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
|
"Rev": "bbbad097214e2918d8543d5201d12bfd7bca254d"
|
||||||
@ -1526,11 +1522,6 @@
|
|||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/google/cadvisor/api",
|
|
||||||
"Comment": "v0.30.2",
|
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
"ImportPath": "github.com/google/cadvisor/cache/memory",
|
||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
@ -1606,21 +1597,6 @@
|
|||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
"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",
|
"ImportPath": "github.com/google/cadvisor/info/v1",
|
||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
@ -1661,16 +1637,6 @@
|
|||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
"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",
|
"ImportPath": "github.com/google/cadvisor/storage",
|
||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
@ -1721,11 +1687,6 @@
|
|||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/google/cadvisor/validate",
|
|
||||||
"Comment": "v0.30.2",
|
|
||||||
"Rev": "de723a090f4dd5390dc7c2acee37ba9c62f0cc09"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cadvisor/version",
|
"ImportPath": "github.com/google/cadvisor/version",
|
||||||
"Comment": "v0.30.2",
|
"Comment": "v0.30.2",
|
||||||
@ -1738,34 +1699,42 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go",
|
"ImportPath": "github.com/google/certificate-transparency-go",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/asn1",
|
"ImportPath": "github.com/google/certificate-transparency-go/asn1",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/client",
|
"ImportPath": "github.com/google/certificate-transparency-go/client",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/client/configpb",
|
"ImportPath": "github.com/google/certificate-transparency-go/client/configpb",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/jsonclient",
|
"ImportPath": "github.com/google/certificate-transparency-go/jsonclient",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/tls",
|
"ImportPath": "github.com/google/certificate-transparency-go/tls",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/x509",
|
"ImportPath": "github.com/google/certificate-transparency-go/x509",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/certificate-transparency-go/x509/pkix",
|
"ImportPath": "github.com/google/certificate-transparency-go/x509/pkix",
|
||||||
|
"Comment": "v1.0.10",
|
||||||
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
"Rev": "1bec4527572c443752ad4f2830bef88be0533236"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2007,6 +1976,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/inconshreveable/mousetrap",
|
"ImportPath": "github.com/inconshreveable/mousetrap",
|
||||||
|
"Comment": "v1.0",
|
||||||
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2562,6 +2532,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/quobyte/api",
|
"ImportPath": "github.com/quobyte/api",
|
||||||
|
"Comment": "v0.1.1-4-g206ef83",
|
||||||
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff"
|
"Rev": "206ef832283c1a0144bbc762be2634d49987b5ff"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2876,6 +2847,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/xiang90/probing",
|
"ImportPath": "github.com/xiang90/probing",
|
||||||
|
"Comment": "0.0.1",
|
||||||
"Rev": "07dd2e8dfe18522e9c447ba95f2fe95262f63bb2"
|
"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/Nvveen/Gotty:all-srcs",
|
||||||
"//vendor/github.com/PuerkitoBio/purell:all-srcs",
|
"//vendor/github.com/PuerkitoBio/purell:all-srcs",
|
||||||
"//vendor/github.com/PuerkitoBio/urlesc: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/armon/circbuf:all-srcs",
|
||||||
"//vendor/github.com/asaskevich/govalidator:all-srcs",
|
"//vendor/github.com/asaskevich/govalidator:all-srcs",
|
||||||
"//vendor/github.com/aws/aws-sdk-go/aws: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/golang/protobuf/ptypes:all-srcs",
|
||||||
"//vendor/github.com/google/btree:all-srcs",
|
"//vendor/github.com/google/btree:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/accelerators: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/cache/memory:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/client/v2:all-srcs",
|
"//vendor/github.com/google/cadvisor/client/v2:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/collector: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/devicemapper:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/events:all-srcs",
|
"//vendor/github.com/google/cadvisor/events:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/fs: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/v1:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/info/v2:all-srcs",
|
"//vendor/github.com/google/cadvisor/info/v2:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/machine:all-srcs",
|
"//vendor/github.com/google/cadvisor/machine:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/manager:all-srcs",
|
"//vendor/github.com/google/cadvisor/manager:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/metrics: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/storage:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/summary:all-srcs",
|
"//vendor/github.com/google/cadvisor/summary:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/utils: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/version:all-srcs",
|
||||||
"//vendor/github.com/google/cadvisor/zfs:all-srcs",
|
"//vendor/github.com/google/cadvisor/zfs:all-srcs",
|
||||||
"//vendor/github.com/google/certificate-transparency-go: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