mirror of
https://github.com/kubernetes/client-go.git
synced 2026-05-15 19:53:50 +00:00
Compare commits
175 Commits
v1.5.2
...
release-3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a95edf8036 | ||
|
|
0a8b58b603 | ||
|
|
a3b7105649 | ||
|
|
291ca30083 | ||
|
|
3eed2b4ac2 | ||
|
|
cb7307007f | ||
|
|
6844dbd5e2 | ||
|
|
21300e3e11 | ||
|
|
1bf6994c7c | ||
|
|
c32e4dfc5d | ||
|
|
99c1992389 | ||
|
|
e28ebe6126 | ||
|
|
18fe241720 | ||
|
|
936b386bc7 | ||
|
|
836838f447 | ||
|
|
a8d5b7ee85 | ||
|
|
9e35ef7520 | ||
|
|
7a26c9599d | ||
|
|
14ff8c69a1 | ||
|
|
117378eef3 | ||
|
|
35b898845e | ||
|
|
1e2deb5008 | ||
|
|
9679848f28 | ||
|
|
e2272dfdf5 | ||
|
|
bf7e376fe1 | ||
|
|
eb79b53964 | ||
|
|
2622726a58 | ||
|
|
f13d806547 | ||
|
|
aafe6e0f59 | ||
|
|
66e13efc6b | ||
|
|
1e64882b98 | ||
|
|
a0dd3f74e8 | ||
|
|
e8d7cc3840 | ||
|
|
df2bb22315 | ||
|
|
06387e8a4d | ||
|
|
d257309ce8 | ||
|
|
845ec4da7b | ||
|
|
35748ed7f1 | ||
|
|
e216037602 | ||
|
|
fab6dd31b8 | ||
|
|
d55bff0e8b | ||
|
|
630b262f11 | ||
|
|
3627aeb7d4 | ||
|
|
abf9b83bc2 | ||
|
|
46f4236624 | ||
|
|
d72c2305ba | ||
|
|
196d103cc9 | ||
|
|
f0985967e7 | ||
|
|
2da1ffdb38 | ||
|
|
fd59eaee0f | ||
|
|
9efa3fc488 | ||
|
|
52cbe06e49 | ||
|
|
a6ed9d14b5 | ||
|
|
76153773ea | ||
|
|
5571124637 | ||
|
|
5f5adbd882 | ||
|
|
2cb68a18c3 | ||
|
|
22e5b7f1e5 | ||
|
|
584752ae88 | ||
|
|
6c610aff05 | ||
|
|
fd507f71e6 | ||
|
|
3426f69f71 | ||
|
|
c43b329d2e | ||
|
|
7f2b2a8d71 | ||
|
|
41b2639c6a | ||
|
|
ca95d09fc0 | ||
|
|
8fabaa8f6e | ||
|
|
338a282983 | ||
|
|
f64798435d | ||
|
|
a5e766ba6a | ||
|
|
bab65175bb | ||
|
|
ad81b3551c | ||
|
|
3f88c175ed | ||
|
|
6dab156779 | ||
|
|
7eb14114aa | ||
|
|
f2dbd57c78 | ||
|
|
54f3f67453 | ||
|
|
c11b7bc45b | ||
|
|
7395acc6da | ||
|
|
1f37358b93 | ||
|
|
012d8620e3 | ||
|
|
d04a6004ff | ||
|
|
701d3f42ac | ||
|
|
0b5e2de859 | ||
|
|
6c315a68f3 | ||
|
|
8147f564df | ||
|
|
c04eceb596 | ||
|
|
ca90456a21 | ||
|
|
af0517a86e | ||
|
|
6500775c58 | ||
|
|
04fe5faa35 | ||
|
|
65ac4e638a | ||
|
|
13a1262624 | ||
|
|
088dc4a30d | ||
|
|
5fbce75e01 | ||
|
|
416948da08 | ||
|
|
82a657e390 | ||
|
|
766a1c2983 | ||
|
|
f163222bdd | ||
|
|
b35d0cbc34 | ||
|
|
bcde30fb7e | ||
|
|
bf876db9b2 | ||
|
|
88caeea7ea | ||
|
|
02373be9d7 | ||
|
|
f98510f4d5 | ||
|
|
abc8616fc4 | ||
|
|
2f1c0eef9a | ||
|
|
0dff3f49d8 | ||
|
|
5adfdb2d35 | ||
|
|
65e34307ed | ||
|
|
1ac605be0f | ||
|
|
543d9386dd | ||
|
|
8b466d64c5 | ||
|
|
933c034a12 | ||
|
|
5614504eca | ||
|
|
c3e0964ba4 | ||
|
|
58d844e6f0 | ||
|
|
a0a777840a | ||
|
|
86a2be1b44 | ||
|
|
17c583b142 | ||
|
|
decc012434 | ||
|
|
5396c67ba4 | ||
|
|
7ac1236194 | ||
|
|
1679e38db8 | ||
|
|
a7f2cee95d | ||
|
|
69171ff7bb | ||
|
|
b7db396afa | ||
|
|
49948ae0ca | ||
|
|
b766ef93a4 | ||
|
|
a88e2b8a0e | ||
|
|
fb6075f2e0 | ||
|
|
f427d46f91 | ||
|
|
fcdf37233b | ||
|
|
687fd42903 | ||
|
|
0eb5431cb7 | ||
|
|
98aceecbfb | ||
|
|
14ee64eb52 | ||
|
|
8fa0506b26 | ||
|
|
0e140df9af | ||
|
|
204f12b1f3 | ||
|
|
8ab7dd3ce9 | ||
|
|
24a02a6d7d | ||
|
|
5fe6fc56cb | ||
|
|
dd9bc19bbb | ||
|
|
e84bb27caf | ||
|
|
b8fd850e88 | ||
|
|
243d8a9cb6 | ||
|
|
6841809cf1 | ||
|
|
124670e99d | ||
|
|
41a99d711a | ||
|
|
5d8c36c93c | ||
|
|
ecd05810bd | ||
|
|
b51b7defab | ||
|
|
e60355686b | ||
|
|
d83a7abb0c | ||
|
|
89c6009983 | ||
|
|
febd848390 | ||
|
|
ae6775eeec | ||
|
|
24b73253cd | ||
|
|
49f8f1bf91 | ||
|
|
0742ae7ca5 | ||
|
|
cf262eae7d | ||
|
|
d6263b114f | ||
|
|
6fb6707824 | ||
|
|
b22087a53b | ||
|
|
f11d57fed7 | ||
|
|
4050de67a8 | ||
|
|
19897ef4d2 | ||
|
|
75399f68c8 | ||
|
|
c72e2838b9 | ||
|
|
f7407c4f3c | ||
|
|
a6d206121d | ||
|
|
6631b2769f | ||
|
|
0092ea5359 | ||
|
|
361e608049 |
8
.travis.yml
Normal file
8
.travis.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
language: go
|
||||
|
||||
go_import_path: k8s.io/client-go
|
||||
|
||||
go:
|
||||
- 1.7.4
|
||||
|
||||
script: go build ./...
|
||||
318
1.5/Godeps/Godeps.json
generated
318
1.5/Godeps/Godeps.json
generated
@@ -1,318 +0,0 @@
|
||||
{
|
||||
"ImportPath": "k8s.io/client-go/1.5",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v74",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "cloud.google.com/go/compute/metadata",
|
||||
"Comment": "v0.1.0-115-g3b1ae45",
|
||||
"Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821"
|
||||
},
|
||||
{
|
||||
"ImportPath": "cloud.google.com/go/internal",
|
||||
"Comment": "v0.1.0-115-g3b1ae45",
|
||||
"Rev": "3b1ae45394a234c385be014e9a488f2bb6eef821"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/PuerkitoBio/purell",
|
||||
"Comment": "v1.0.0",
|
||||
"Rev": "8a290539e2e8629dbc4e6bad948158f790ec31f4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/PuerkitoBio/urlesc",
|
||||
"Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/blang/semver",
|
||||
"Comment": "v3.0.1",
|
||||
"Rev": "31b736133b98f26d5e078ec9eb591666edfd091f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-oidc/http",
|
||||
"Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-oidc/jose",
|
||||
"Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-oidc/key",
|
||||
"Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-oidc/oauth2",
|
||||
"Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/go-oidc/oidc",
|
||||
"Rev": "5644a2f50e2d2d5ba0b474bc5bc55fea1925936d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/pkg/health",
|
||||
"Comment": "v2-8-gfa29b1d",
|
||||
"Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/pkg/httputil",
|
||||
"Comment": "v2-8-gfa29b1d",
|
||||
"Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/coreos/pkg/timeutil",
|
||||
"Comment": "v2-8-gfa29b1d",
|
||||
"Rev": "fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/distribution/digest",
|
||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/distribution/reference",
|
||||
"Comment": "v2.4.0-rc.1-38-gcd27f17",
|
||||
"Rev": "cd27f179f2c10c5d300e6d09025b538c475b0d51"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful",
|
||||
"Comment": "v1.2-79-g89ef8af",
|
||||
"Rev": "89ef8af493ab468a45a42bb0d89a06fccdd2fb22"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful/log",
|
||||
"Comment": "v1.2-79-g89ef8af",
|
||||
"Rev": "89ef8af493ab468a45a42bb0d89a06fccdd2fb22"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/emicklei/go-restful/swagger",
|
||||
"Comment": "v1.2-79-g89ef8af",
|
||||
"Rev": "89ef8af493ab468a45a42bb0d89a06fccdd2fb22"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ghodss/yaml",
|
||||
"Rev": "73d445a93680fa1a78ae23a5839bad48f32ba1ee"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonpointer",
|
||||
"Rev": "46af16f9f7b149af66e5d1bd010e3574dc06de98"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/jsonreference",
|
||||
"Rev": "13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/spec",
|
||||
"Rev": "6aced65f8501fe1217321abf0749d354824ba2ff"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-openapi/swag",
|
||||
"Rev": "1d0bd113de87027671077d3c71eb3ac5d7dbba72"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||
"Comment": "v0.2-33-ge18d7aa",
|
||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gogo/protobuf/sortkeys",
|
||||
"Comment": "v0.2-33-ge18d7aa",
|
||||
"Rev": "e18d7aa8f8c624c915db340349aad4c49b10d173"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/glog",
|
||||
"Rev": "44145f04b68cf362d9c4df2182967c2275eaefed"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/groupcache/lru",
|
||||
"Rev": "02826c3e79038b59d737d3b1c0a1d937f71a4433"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "8616e8ee5e20a1704615e6c8d7afcdac06087a67"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/google/gofuzz",
|
||||
"Rev": "bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/howeyc/gopass",
|
||||
"Rev": "3ca23474a7c7203e0a0a070fd33508f6efdb9b3d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/imdario/mergo",
|
||||
"Comment": "0.1.3-8-g6633656",
|
||||
"Rev": "6633656539c1639d9d78127b7d47c622b5d7b6dc"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jonboulle/clockwork",
|
||||
"Rev": "72f9bd7c4e0c2a40055ab3d0f09654f730cce982"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/juju/ratelimit",
|
||||
"Rev": "77ed1c8a01217656d2080ad51981f6e99adaa177"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/buffer",
|
||||
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/jlexer",
|
||||
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mailru/easyjson/jwriter",
|
||||
"Rev": "d5b7844b561a7bc640052f1b935f7b800330d7e0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pborman/uuid",
|
||||
"Rev": "ca53cad383cad2479bbba7f7a1a05797ec1386e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
"Rev": "1560c1005499d61b80f865c04d39ca7505bf7f0b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/ugorji/go/codec",
|
||||
"Rev": "f1f1a805ed361a0e078bb537e4ea78cd37dcf065"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
||||
"Rev": "1f22c0103821b9390939b6776727195525381532"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/context/ctxhttp",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/http2/hpack",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/idna",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/net/lex/httplex",
|
||||
"Rev": "e90d6d0afc4c315a0d87a568ae68577cc15149a0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2",
|
||||
"Rev": "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/google",
|
||||
"Rev": "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/internal",
|
||||
"Rev": "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/jws",
|
||||
"Rev": "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/oauth2/jwt",
|
||||
"Rev": "3c3a985cb79f52a3190fbc056984415ca6763d01"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "9c60d1c508f5134d1ca726b4641db998f2523357"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/cases",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/internal/tag",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/language",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/runes",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/secure/bidirule",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/secure/precis",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/transform",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/unicode/bidi",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/unicode/norm",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/text/width",
|
||||
"Rev": "2910a502d2bf9e43193af9d68ca516529614eed3"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/app_identity",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/base",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/datastore",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/log",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/modules",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "google.golang.org/appengine/internal/remote_api",
|
||||
"Rev": "4f7eeb5305a4ba1966344836ba4af9996b7b4e05"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/inf.v0",
|
||||
"Comment": "v0.9.0",
|
||||
"Rev": "3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/yaml.v2",
|
||||
"Rev": "53feefa2559fb8dfa8d81baad31be332c97d6c77"
|
||||
}
|
||||
]
|
||||
}
|
||||
202
1.5/LICENSE
202
1.5/LICENSE
@@ -1,202 +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
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/errors"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/1.5/pkg/version"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
// DiscoveryInterface holds the methods that discover server-supported API groups,
|
||||
// versions and resources.
|
||||
type DiscoveryInterface interface {
|
||||
ServerGroupsInterface
|
||||
ServerResourcesInterface
|
||||
ServerVersionInterface
|
||||
SwaggerSchemaInterface
|
||||
}
|
||||
|
||||
// ServerGroupsInterface has methods for obtaining supported groups on the API server
|
||||
type ServerGroupsInterface interface {
|
||||
// ServerGroups returns the supported groups, with information like supported versions and the
|
||||
// preferred version.
|
||||
ServerGroups() (*unversioned.APIGroupList, error)
|
||||
}
|
||||
|
||||
// ServerResourcesInterface has methods for obtaining supported resources on the API server
|
||||
type ServerResourcesInterface interface {
|
||||
// ServerResourcesForGroupVersion returns the supported resources for a group and version.
|
||||
ServerResourcesForGroupVersion(groupVersion string) (*unversioned.APIResourceList, error)
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
ServerResources() (map[string]*unversioned.APIResourceList, error)
|
||||
// ServerPreferredResources returns the supported resources with the version preferred by the
|
||||
// server.
|
||||
ServerPreferredResources() ([]unversioned.GroupVersionResource, error)
|
||||
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
|
||||
// version preferred by the server.
|
||||
ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error)
|
||||
}
|
||||
|
||||
// ServerVersionInterface has a method for retrieving the server's version.
|
||||
type ServerVersionInterface interface {
|
||||
// ServerVersion retrieves and parses the server's version (git version).
|
||||
ServerVersion() (*version.Info, error)
|
||||
}
|
||||
|
||||
// SwaggerSchemaInterface has a method to retrieve the swagger schema.
|
||||
type SwaggerSchemaInterface interface {
|
||||
// SwaggerSchema retrieves and parses the swagger API schema the server supports.
|
||||
SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error)
|
||||
}
|
||||
|
||||
// DiscoveryClient implements the functions that discover server-supported API groups,
|
||||
// versions and resources.
|
||||
type DiscoveryClient struct {
|
||||
*rest.RESTClient
|
||||
|
||||
LegacyPrefix string
|
||||
}
|
||||
|
||||
// Convert unversioned.APIVersions to unversioned.APIGroup. APIVersions is used by legacy v1, so
|
||||
// group would be "".
|
||||
func apiVersionsToAPIGroup(apiVersions *unversioned.APIVersions) (apiGroup unversioned.APIGroup) {
|
||||
groupVersions := []unversioned.GroupVersionForDiscovery{}
|
||||
for _, version := range apiVersions.Versions {
|
||||
groupVersion := unversioned.GroupVersionForDiscovery{
|
||||
GroupVersion: version,
|
||||
Version: version,
|
||||
}
|
||||
groupVersions = append(groupVersions, groupVersion)
|
||||
}
|
||||
apiGroup.Versions = groupVersions
|
||||
// There should be only one groupVersion returned at /api
|
||||
apiGroup.PreferredVersion = groupVersions[0]
|
||||
return
|
||||
}
|
||||
|
||||
// ServerGroups returns the supported groups, with information like supported versions and the
|
||||
// preferred version.
|
||||
func (d *DiscoveryClient) ServerGroups() (apiGroupList *unversioned.APIGroupList, err error) {
|
||||
// Get the groupVersions exposed at /api
|
||||
v := &unversioned.APIVersions{}
|
||||
err = d.Get().AbsPath(d.LegacyPrefix).Do().Into(v)
|
||||
apiGroup := unversioned.APIGroup{}
|
||||
if err == nil {
|
||||
apiGroup = apiVersionsToAPIGroup(v)
|
||||
}
|
||||
if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get the groupVersions exposed at /apis
|
||||
apiGroupList = &unversioned.APIGroupList{}
|
||||
err = d.Get().AbsPath("/apis").Do().Into(apiGroupList)
|
||||
if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) {
|
||||
return nil, err
|
||||
}
|
||||
// to be compatible with a v1.0 server, if it's a 403 or 404, ignore and return whatever we got from /api
|
||||
if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) {
|
||||
apiGroupList = &unversioned.APIGroupList{}
|
||||
}
|
||||
|
||||
// append the group retrieved from /api to the list
|
||||
apiGroupList.Groups = append(apiGroupList.Groups, apiGroup)
|
||||
return apiGroupList, nil
|
||||
}
|
||||
|
||||
// ServerResourcesForGroupVersion returns the supported resources for a group and version.
|
||||
func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (resources *unversioned.APIResourceList, err error) {
|
||||
url := url.URL{}
|
||||
if len(groupVersion) == 0 {
|
||||
return nil, fmt.Errorf("groupVersion shouldn't be empty")
|
||||
}
|
||||
if len(d.LegacyPrefix) > 0 && groupVersion == "v1" {
|
||||
url.Path = d.LegacyPrefix + "/" + groupVersion
|
||||
} else {
|
||||
url.Path = "/apis/" + groupVersion
|
||||
}
|
||||
resources = &unversioned.APIResourceList{}
|
||||
err = d.Get().AbsPath(url.String()).Do().Into(resources)
|
||||
if err != nil {
|
||||
// ignore 403 or 404 error to be compatible with an v1.0 server.
|
||||
if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) {
|
||||
return resources, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
func (d *DiscoveryClient) ServerResources() (map[string]*unversioned.APIResourceList, error) {
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(apiGroups)
|
||||
result := map[string]*unversioned.APIResourceList{}
|
||||
for _, groupVersion := range groupVersions {
|
||||
resources, err := d.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[groupVersion] = resources
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ErrGroupDiscoveryFailed is returned if one or more API groups fail to load.
|
||||
type ErrGroupDiscoveryFailed struct {
|
||||
// Groups is a list of the groups that failed to load and the error cause
|
||||
Groups map[unversioned.GroupVersion]error
|
||||
}
|
||||
|
||||
// Error implements the error interface
|
||||
func (e *ErrGroupDiscoveryFailed) Error() string {
|
||||
var groups []string
|
||||
for k, v := range e.Groups {
|
||||
groups = append(groups, fmt.Sprintf("%s: %v", k, v))
|
||||
}
|
||||
sort.Strings(groups)
|
||||
return fmt.Sprintf("unable to retrieve the complete list of server APIs: %s", strings.Join(groups, ", "))
|
||||
}
|
||||
|
||||
// IsGroupDiscoveryFailedError returns true if the provided error indicates the server was unable to discover
|
||||
// a complete list of APIs for the client to use.
|
||||
func IsGroupDiscoveryFailedError(err error) bool {
|
||||
_, ok := err.(*ErrGroupDiscoveryFailed)
|
||||
return err != nil && ok
|
||||
}
|
||||
|
||||
// serverPreferredResources returns the supported resources with the version preferred by the
|
||||
// server. If namespaced is true, only namespaced resources will be returned.
|
||||
func (d *DiscoveryClient) serverPreferredResources(namespaced bool) ([]unversioned.GroupVersionResource, error) {
|
||||
results := []unversioned.GroupVersionResource{}
|
||||
serverGroupList, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
var failedGroups map[unversioned.GroupVersion]error
|
||||
for _, apiGroup := range serverGroupList.Groups {
|
||||
preferredVersion := apiGroup.PreferredVersion
|
||||
groupVersion := unversioned.GroupVersion{Group: apiGroup.Name, Version: preferredVersion.Version}
|
||||
apiResourceList, err := d.ServerResourcesForGroupVersion(preferredVersion.GroupVersion)
|
||||
if err != nil {
|
||||
if failedGroups == nil {
|
||||
failedGroups = make(map[unversioned.GroupVersion]error)
|
||||
}
|
||||
failedGroups[groupVersion] = err
|
||||
continue
|
||||
}
|
||||
for _, apiResource := range apiResourceList.APIResources {
|
||||
// ignore the root scoped resources if "namespaced" is true.
|
||||
if namespaced && !apiResource.Namespaced {
|
||||
continue
|
||||
}
|
||||
if strings.Contains(apiResource.Name, "/") {
|
||||
continue
|
||||
}
|
||||
results = append(results, groupVersion.WithResource(apiResource.Name))
|
||||
}
|
||||
}
|
||||
if len(failedGroups) > 0 {
|
||||
return results, &ErrGroupDiscoveryFailed{Groups: failedGroups}
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// ServerPreferredResources returns the supported resources with the version preferred by the
|
||||
// server.
|
||||
func (d *DiscoveryClient) ServerPreferredResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.serverPreferredResources(false)
|
||||
}
|
||||
|
||||
// ServerPreferredNamespacedResources returns the supported namespaced resources with the
|
||||
// version preferred by the server.
|
||||
func (d *DiscoveryClient) ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.serverPreferredResources(true)
|
||||
}
|
||||
|
||||
// ServerVersion retrieves and parses the server's version (git version).
|
||||
func (d *DiscoveryClient) ServerVersion() (*version.Info, error) {
|
||||
body, err := d.Get().AbsPath("/version").Do().Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var info version.Info
|
||||
err = json.Unmarshal(body, &info)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("got '%s': %v", string(body), err)
|
||||
}
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
// SwaggerSchema retrieves and parses the swagger API schema the server supports.
|
||||
func (d *DiscoveryClient) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
|
||||
if version.Empty() {
|
||||
return nil, fmt.Errorf("groupVersion cannot be empty")
|
||||
}
|
||||
|
||||
groupList, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(groupList)
|
||||
// This check also takes care the case that kubectl is newer than the running endpoint
|
||||
if stringDoesntExistIn(version.String(), groupVersions) {
|
||||
return nil, fmt.Errorf("API version: %v is not supported by the server. Use one of: %v", version, groupVersions)
|
||||
}
|
||||
var path string
|
||||
if len(d.LegacyPrefix) > 0 && version == v1.SchemeGroupVersion {
|
||||
path = "/swaggerapi" + d.LegacyPrefix + "/" + version.Version
|
||||
} else {
|
||||
path = "/swaggerapi/apis/" + version.Group + "/" + version.Version
|
||||
}
|
||||
|
||||
body, err := d.Get().AbsPath(path).Do().Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var schema swagger.ApiDeclaration
|
||||
err = json.Unmarshal(body, &schema)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("got '%s': %v", string(body), err)
|
||||
}
|
||||
return &schema, nil
|
||||
}
|
||||
|
||||
func setDiscoveryDefaults(config *rest.Config) error {
|
||||
config.APIPath = ""
|
||||
config.GroupVersion = nil
|
||||
codec := runtime.NoopEncoder{Decoder: api.Codecs.UniversalDecoder()}
|
||||
config.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(
|
||||
runtime.SerializerInfo{Serializer: codec},
|
||||
runtime.StreamSerializerInfo{},
|
||||
)
|
||||
if len(config.UserAgent) == 0 {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewDiscoveryClientForConfig creates a new DiscoveryClient for the given config. This client
|
||||
// can be used to discover supported resources in the API server.
|
||||
func NewDiscoveryClientForConfig(c *rest.Config) (*DiscoveryClient, error) {
|
||||
config := *c
|
||||
if err := setDiscoveryDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.UnversionedRESTClientFor(&config)
|
||||
return &DiscoveryClient{RESTClient: client, LegacyPrefix: "/api"}, err
|
||||
}
|
||||
|
||||
// NewDiscoveryClientForConfig creates a new DiscoveryClient for the given config. If
|
||||
// there is an error, it panics.
|
||||
func NewDiscoveryClientForConfigOrDie(c *rest.Config) *DiscoveryClient {
|
||||
client, err := NewDiscoveryClientForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
|
||||
}
|
||||
|
||||
// New creates a new DiscoveryClient for the given RESTClient.
|
||||
func NewDiscoveryClient(c *rest.RESTClient) *DiscoveryClient {
|
||||
return &DiscoveryClient{RESTClient: c, LegacyPrefix: "/api"}
|
||||
}
|
||||
|
||||
func stringDoesntExistIn(str string, slice []string) bool {
|
||||
for _, s := range slice {
|
||||
if s == str {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
||||
"k8s.io/client-go/1.5/pkg/version"
|
||||
"k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
func TestGetServerVersion(t *testing.T) {
|
||||
expect := version.Info{
|
||||
Major: "foo",
|
||||
Minor: "bar",
|
||||
GitCommit: "baz",
|
||||
}
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
output, err := json.Marshal(expect)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
|
||||
got, err := client.ServerVersion()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
}
|
||||
if e, a := expect, *got; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerGroupsWithV1Server(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &unversioned.APIVersions{
|
||||
Versions: []string{
|
||||
"v1",
|
||||
},
|
||||
}
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
// ServerGroups should not return an error even if server returns error at /api and /apis
|
||||
apiGroupList, err := client.ServerGroups()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(apiGroupList)
|
||||
if !reflect.DeepEqual(groupVersions, []string{"v1"}) {
|
||||
t.Errorf("expected: %q, got: %q", []string{"v1"}, groupVersions)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerGroupsWithBrokenServer(t *testing.T) {
|
||||
for _, statusCode := range []int{http.StatusNotFound, http.StatusForbidden} {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(statusCode)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
// ServerGroups should not return an error even if server returns Not Found or Forbidden error at all end points
|
||||
apiGroupList, err := client.ServerGroups()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(apiGroupList)
|
||||
if len(groupVersions) != 0 {
|
||||
t.Errorf("expected empty list, got: %q", groupVersions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerResourcesWithV1Server(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var obj interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api":
|
||||
obj = &unversioned.APIVersions{
|
||||
Versions: []string{
|
||||
"v1",
|
||||
},
|
||||
}
|
||||
default:
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
output, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
// ServerResources should not return an error even if server returns error at /api/v1.
|
||||
resourceMap, err := client.ServerResources()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if _, found := resourceMap["v1"]; !found {
|
||||
t.Errorf("missing v1 in resource map")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetServerResources(t *testing.T) {
|
||||
stable := unversioned.APIResourceList{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []unversioned.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
{Name: "namespaces", Namespaced: false, Kind: "Namespace"},
|
||||
},
|
||||
}
|
||||
beta := unversioned.APIResourceList{
|
||||
GroupVersion: "extensions/v1",
|
||||
APIResources: []unversioned.APIResource{
|
||||
{Name: "deployments", Namespaced: true, Kind: "Deployment"},
|
||||
{Name: "ingresses", Namespaced: true, Kind: "Ingress"},
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
resourcesList *unversioned.APIResourceList
|
||||
path string
|
||||
request string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
resourcesList: &stable,
|
||||
path: "/api/v1",
|
||||
request: "v1",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
resourcesList: &beta,
|
||||
path: "/apis/extensions/v1beta1",
|
||||
request: "extensions/v1beta1",
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
resourcesList: &stable,
|
||||
path: "/api/v1",
|
||||
request: "foobar",
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var list interface{}
|
||||
switch req.URL.Path {
|
||||
case "/api/v1":
|
||||
list = &stable
|
||||
case "/apis/extensions/v1beta1":
|
||||
list = &beta
|
||||
case "/api":
|
||||
list = &unversioned.APIVersions{
|
||||
Versions: []string{
|
||||
"v1",
|
||||
},
|
||||
}
|
||||
case "/apis":
|
||||
list = &unversioned.APIGroupList{
|
||||
Groups: []unversioned.APIGroup{
|
||||
{
|
||||
Versions: []unversioned.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
t.Logf("unexpected request: %s", req.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
output, err := json.Marshal(list)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}))
|
||||
defer server.Close()
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
for _, test := range tests {
|
||||
got, err := client.ServerResourcesForGroupVersion(test.request)
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(got, test.resourcesList) {
|
||||
t.Errorf("expected:\n%v\ngot:\n%v\n", test.resourcesList, got)
|
||||
}
|
||||
}
|
||||
|
||||
resourceMap, err := client.ServerResources()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
for _, api := range []string{"v1", "extensions/v1beta1"} {
|
||||
if _, found := resourceMap[api]; !found {
|
||||
t.Errorf("missing expected api: %s", api)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func swaggerSchemaFakeServer() (*httptest.Server, error) {
|
||||
request := 1
|
||||
var sErr error
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
var resp interface{}
|
||||
if request == 1 {
|
||||
resp = unversioned.APIVersions{Versions: []string{"v1", "v2", "v3"}}
|
||||
request++
|
||||
} else {
|
||||
resp = swagger.ApiDeclaration{}
|
||||
}
|
||||
output, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
sErr = err
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
}))
|
||||
return server, sErr
|
||||
}
|
||||
|
||||
func TestGetSwaggerSchema(t *testing.T) {
|
||||
expect := swagger.ApiDeclaration{}
|
||||
|
||||
server, err := swaggerSchemaFakeServer()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
got, err := client.SwaggerSchema(v1.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected encoding error: %v", err)
|
||||
}
|
||||
if e, a := expect, *got; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSwaggerSchemaFail(t *testing.T) {
|
||||
expErr := "API version: api.group/v4 is not supported by the server. Use one of: [v1 v2 v3]"
|
||||
|
||||
server, err := swaggerSchemaFakeServer()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
defer server.Close()
|
||||
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
got, err := client.SwaggerSchema(unversioned.GroupVersion{Group: "api.group", Version: "v4"})
|
||||
if got != nil {
|
||||
t.Fatalf("unexpected response: %v", got)
|
||||
}
|
||||
if err.Error() != expErr {
|
||||
t.Errorf("expected an error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServerPreferredResources(t *testing.T) {
|
||||
stable := unversioned.APIResourceList{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []unversioned.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
{Name: "namespaces", Namespaced: false, Kind: "Namespace"},
|
||||
},
|
||||
}
|
||||
/*beta := unversioned.APIResourceList{
|
||||
GroupVersion: "extensions/v1",
|
||||
APIResources: []unversioned.APIResource{
|
||||
{Name: "deployments", Namespaced: true, Kind: "Deployment"},
|
||||
{Name: "ingresses", Namespaced: true, Kind: "Ingress"},
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
}*/
|
||||
tests := []struct {
|
||||
resourcesList *unversioned.APIResourceList
|
||||
response func(w http.ResponseWriter, req *http.Request)
|
||||
expectErr func(err error) bool
|
||||
}{
|
||||
{
|
||||
resourcesList: &stable,
|
||||
expectErr: IsGroupDiscoveryFailedError,
|
||||
response: func(w http.ResponseWriter, req *http.Request) {
|
||||
var list interface{}
|
||||
switch req.URL.Path {
|
||||
case "/apis/extensions/v1beta1":
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
case "/api/v1":
|
||||
list = &stable
|
||||
case "/api":
|
||||
list = &unversioned.APIVersions{
|
||||
Versions: []string{
|
||||
"v1",
|
||||
},
|
||||
}
|
||||
case "/apis":
|
||||
list = &unversioned.APIGroupList{
|
||||
Groups: []unversioned.APIGroup{
|
||||
{
|
||||
Versions: []unversioned.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
t.Logf("unexpected request: %s", req.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
output, err := json.Marshal(list)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
},
|
||||
},
|
||||
{
|
||||
resourcesList: nil,
|
||||
expectErr: IsGroupDiscoveryFailedError,
|
||||
response: func(w http.ResponseWriter, req *http.Request) {
|
||||
var list interface{}
|
||||
switch req.URL.Path {
|
||||
case "/apis/extensions/v1beta1":
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
case "/api/v1":
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
case "/api":
|
||||
list = &unversioned.APIVersions{
|
||||
Versions: []string{
|
||||
"v1",
|
||||
},
|
||||
}
|
||||
case "/apis":
|
||||
list = &unversioned.APIGroupList{
|
||||
Groups: []unversioned.APIGroup{
|
||||
{
|
||||
Versions: []unversioned.GroupVersionForDiscovery{
|
||||
{GroupVersion: "extensions/v1beta1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
default:
|
||||
t.Logf("unexpected request: %s", req.URL.Path)
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
output, err := json.Marshal(list)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected encoding error: %v", err)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(output)
|
||||
},
|
||||
},
|
||||
/*{
|
||||
resourcesList: &stable,
|
||||
},*/
|
||||
}
|
||||
for _, test := range tests {
|
||||
server := httptest.NewServer(http.HandlerFunc(test.response))
|
||||
defer server.Close()
|
||||
|
||||
client := NewDiscoveryClientForConfigOrDie(&rest.Config{Host: server.URL})
|
||||
got, err := client.ServerPreferredResources()
|
||||
if test.expectErr != nil {
|
||||
if err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(got, test.resourcesList) {
|
||||
t.Errorf("expected:\n%v\ngot:\n%v\n", test.resourcesList, got)
|
||||
}
|
||||
server.Close()
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
||||
"k8s.io/client-go/1.5/pkg/version"
|
||||
"k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
type FakeDiscovery struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*unversioned.APIResourceList, error) {
|
||||
action := testing.ActionImpl{
|
||||
Verb: "get",
|
||||
Resource: unversioned.GroupVersionResource{Resource: "resource"},
|
||||
}
|
||||
c.Invokes(action, nil)
|
||||
return c.Resources[groupVersion], nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerResources() (map[string]*unversioned.APIResourceList, error) {
|
||||
action := testing.ActionImpl{
|
||||
Verb: "get",
|
||||
Resource: unversioned.GroupVersionResource{Resource: "resource"},
|
||||
}
|
||||
c.Invokes(action, nil)
|
||||
return c.Resources, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerPreferredResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerGroups() (*unversioned.APIGroupList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
|
||||
action := testing.ActionImpl{}
|
||||
action.Verb = "get"
|
||||
action.Resource = unversioned.GroupVersionResource{Resource: "version"}
|
||||
|
||||
c.Invokes(action, nil)
|
||||
versionInfo := version.Get()
|
||||
return &versionInfo, nil
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
|
||||
action := testing.ActionImpl{}
|
||||
action.Verb = "get"
|
||||
if version == v1.SchemeGroupVersion {
|
||||
action.Resource = unversioned.GroupVersionResource{Resource: "/swaggerapi/api/" + version.Version}
|
||||
} else {
|
||||
action.Resource = unversioned.GroupVersionResource{Resource: "/swaggerapi/apis/" + version.Group + "/" + version.Version}
|
||||
}
|
||||
|
||||
c.Invokes(action, nil)
|
||||
return &swagger.ApiDeclaration{}, nil
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package discovery
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
func TestRESTMapper(t *testing.T) {
|
||||
resources := []*APIGroupResources{
|
||||
{
|
||||
Group: unversioned.APIGroup{
|
||||
Versions: []unversioned.GroupVersionForDiscovery{
|
||||
{Version: "v1"},
|
||||
{Version: "v2"},
|
||||
},
|
||||
PreferredVersion: unversioned.GroupVersionForDiscovery{Version: "v1"},
|
||||
},
|
||||
VersionedResources: map[string][]unversioned.APIResource{
|
||||
"v1": {
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
},
|
||||
"v2": {
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Group: unversioned.APIGroup{
|
||||
Name: "extensions",
|
||||
Versions: []unversioned.GroupVersionForDiscovery{
|
||||
{Version: "v1beta"},
|
||||
},
|
||||
PreferredVersion: unversioned.GroupVersionForDiscovery{Version: "v1beta"},
|
||||
},
|
||||
VersionedResources: map[string][]unversioned.APIResource{
|
||||
"v1beta": {
|
||||
{Name: "jobs", Namespaced: true, Kind: "Job"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
restMapper := NewRESTMapper(resources, nil)
|
||||
|
||||
kindTCs := []struct {
|
||||
input unversioned.GroupVersionResource
|
||||
want unversioned.GroupVersionKind
|
||||
}{
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionKind{
|
||||
Version: "v1",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Version: "v2",
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionKind{
|
||||
Version: "v2",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionKind{
|
||||
Version: "v1",
|
||||
Kind: "Pod",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Resource: "jobs",
|
||||
},
|
||||
want: unversioned.GroupVersionKind{
|
||||
Group: "extensions",
|
||||
Version: "v1beta",
|
||||
Kind: "Job",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range kindTCs {
|
||||
got, err := restMapper.KindFor(tc.input)
|
||||
if err != nil {
|
||||
t.Errorf("KindFor(%#v) unexpected error: %v", tc.input, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("KindFor(%#v) = %#v, want %#v", tc.input, got, tc.want)
|
||||
}
|
||||
}
|
||||
|
||||
resourceTCs := []struct {
|
||||
input unversioned.GroupVersionResource
|
||||
want unversioned.GroupVersionResource
|
||||
}{
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionResource{
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Version: "v2",
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionResource{
|
||||
Version: "v2",
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Resource: "pods",
|
||||
},
|
||||
want: unversioned.GroupVersionResource{
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
{
|
||||
input: unversioned.GroupVersionResource{
|
||||
Resource: "jobs",
|
||||
},
|
||||
want: unversioned.GroupVersionResource{
|
||||
Group: "extensions",
|
||||
Version: "v1beta",
|
||||
Resource: "jobs",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range resourceTCs {
|
||||
got, err := restMapper.ResourceFor(tc.input)
|
||||
if err != nil {
|
||||
t.Errorf("ResourceFor(%#v) unexpected error: %v", tc.input, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("ResourceFor(%#v) = %#v, want %#v", tc.input, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
discovery "k8s.io/client-go/1.5/discovery"
|
||||
v1alpha1apps "k8s.io/client-go/1.5/kubernetes/typed/apps/v1alpha1"
|
||||
v1beta1authentication "k8s.io/client-go/1.5/kubernetes/typed/authentication/v1beta1"
|
||||
v1beta1authorization "k8s.io/client-go/1.5/kubernetes/typed/authorization/v1beta1"
|
||||
v1autoscaling "k8s.io/client-go/1.5/kubernetes/typed/autoscaling/v1"
|
||||
v1batch "k8s.io/client-go/1.5/kubernetes/typed/batch/v1"
|
||||
v1alpha1certificates "k8s.io/client-go/1.5/kubernetes/typed/certificates/v1alpha1"
|
||||
v1core "k8s.io/client-go/1.5/kubernetes/typed/core/v1"
|
||||
v1beta1extensions "k8s.io/client-go/1.5/kubernetes/typed/extensions/v1beta1"
|
||||
v1alpha1policy "k8s.io/client-go/1.5/kubernetes/typed/policy/v1alpha1"
|
||||
v1alpha1rbac "k8s.io/client-go/1.5/kubernetes/typed/rbac/v1alpha1"
|
||||
v1beta1storage "k8s.io/client-go/1.5/kubernetes/typed/storage/v1beta1"
|
||||
"k8s.io/client-go/1.5/pkg/util/flowcontrol"
|
||||
_ "k8s.io/client-go/1.5/plugin/pkg/client/auth"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
Core() v1core.CoreInterface
|
||||
Apps() v1alpha1apps.AppsInterface
|
||||
Authentication() v1beta1authentication.AuthenticationInterface
|
||||
Authorization() v1beta1authorization.AuthorizationInterface
|
||||
Autoscaling() v1autoscaling.AutoscalingInterface
|
||||
Batch() v1batch.BatchInterface
|
||||
Certificates() v1alpha1certificates.CertificatesInterface
|
||||
Extensions() v1beta1extensions.ExtensionsInterface
|
||||
Policy() v1alpha1policy.PolicyInterface
|
||||
Rbac() v1alpha1rbac.RbacInterface
|
||||
Storage() v1beta1storage.StorageInterface
|
||||
}
|
||||
|
||||
// Clientset contains the clients for groups. Each group has exactly one
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
*v1core.CoreClient
|
||||
*v1alpha1apps.AppsClient
|
||||
*v1beta1authentication.AuthenticationClient
|
||||
*v1beta1authorization.AuthorizationClient
|
||||
*v1autoscaling.AutoscalingClient
|
||||
*v1batch.BatchClient
|
||||
*v1alpha1certificates.CertificatesClient
|
||||
*v1beta1extensions.ExtensionsClient
|
||||
*v1alpha1policy.PolicyClient
|
||||
*v1alpha1rbac.RbacClient
|
||||
*v1beta1storage.StorageClient
|
||||
}
|
||||
|
||||
// Core retrieves the CoreClient
|
||||
func (c *Clientset) Core() v1core.CoreInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.CoreClient
|
||||
}
|
||||
|
||||
// Apps retrieves the AppsClient
|
||||
func (c *Clientset) Apps() v1alpha1apps.AppsInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.AppsClient
|
||||
}
|
||||
|
||||
// Authentication retrieves the AuthenticationClient
|
||||
func (c *Clientset) Authentication() v1beta1authentication.AuthenticationInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.AuthenticationClient
|
||||
}
|
||||
|
||||
// Authorization retrieves the AuthorizationClient
|
||||
func (c *Clientset) Authorization() v1beta1authorization.AuthorizationInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.AuthorizationClient
|
||||
}
|
||||
|
||||
// Autoscaling retrieves the AutoscalingClient
|
||||
func (c *Clientset) Autoscaling() v1autoscaling.AutoscalingInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.AutoscalingClient
|
||||
}
|
||||
|
||||
// Batch retrieves the BatchClient
|
||||
func (c *Clientset) Batch() v1batch.BatchInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.BatchClient
|
||||
}
|
||||
|
||||
// Certificates retrieves the CertificatesClient
|
||||
func (c *Clientset) Certificates() v1alpha1certificates.CertificatesInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.CertificatesClient
|
||||
}
|
||||
|
||||
// Extensions retrieves the ExtensionsClient
|
||||
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.ExtensionsClient
|
||||
}
|
||||
|
||||
// Policy retrieves the PolicyClient
|
||||
func (c *Clientset) Policy() v1alpha1policy.PolicyInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.PolicyClient
|
||||
}
|
||||
|
||||
// Rbac retrieves the RbacClient
|
||||
func (c *Clientset) Rbac() v1alpha1rbac.RbacInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RbacClient
|
||||
}
|
||||
|
||||
// Storage retrieves the StorageClient
|
||||
func (c *Clientset) Storage() v1beta1storage.StorageInterface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.StorageClient
|
||||
}
|
||||
|
||||
// Discovery retrieves the DiscoveryClient
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return c.DiscoveryClient
|
||||
}
|
||||
|
||||
// NewForConfig creates a new Clientset for the given config.
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
|
||||
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
|
||||
}
|
||||
var clientset Clientset
|
||||
var err error
|
||||
clientset.CoreClient, err = v1core.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.AppsClient, err = v1alpha1apps.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.AuthenticationClient, err = v1beta1authentication.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.AuthorizationClient, err = v1beta1authorization.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.AutoscalingClient, err = v1autoscaling.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.BatchClient, err = v1batch.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.CertificatesClient, err = v1alpha1certificates.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.ExtensionsClient, err = v1beta1extensions.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.PolicyClient, err = v1alpha1policy.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.RbacClient, err = v1alpha1rbac.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clientset.StorageClient, err = v1beta1storage.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clientset.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
glog.Errorf("failed to create the DiscoveryClient: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
return &clientset, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new Clientset for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var clientset Clientset
|
||||
clientset.CoreClient = v1core.NewForConfigOrDie(c)
|
||||
clientset.AppsClient = v1alpha1apps.NewForConfigOrDie(c)
|
||||
clientset.AuthenticationClient = v1beta1authentication.NewForConfigOrDie(c)
|
||||
clientset.AuthorizationClient = v1beta1authorization.NewForConfigOrDie(c)
|
||||
clientset.AutoscalingClient = v1autoscaling.NewForConfigOrDie(c)
|
||||
clientset.BatchClient = v1batch.NewForConfigOrDie(c)
|
||||
clientset.CertificatesClient = v1alpha1certificates.NewForConfigOrDie(c)
|
||||
clientset.ExtensionsClient = v1beta1extensions.NewForConfigOrDie(c)
|
||||
clientset.PolicyClient = v1alpha1policy.NewForConfigOrDie(c)
|
||||
clientset.RbacClient = v1alpha1rbac.NewForConfigOrDie(c)
|
||||
clientset.StorageClient = v1beta1storage.NewForConfigOrDie(c)
|
||||
|
||||
clientset.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
return &clientset
|
||||
}
|
||||
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *Clientset {
|
||||
var clientset Clientset
|
||||
clientset.CoreClient = v1core.New(c)
|
||||
clientset.AppsClient = v1alpha1apps.New(c)
|
||||
clientset.AuthenticationClient = v1beta1authentication.New(c)
|
||||
clientset.AuthorizationClient = v1beta1authorization.New(c)
|
||||
clientset.AutoscalingClient = v1autoscaling.New(c)
|
||||
clientset.BatchClient = v1batch.New(c)
|
||||
clientset.CertificatesClient = v1alpha1certificates.New(c)
|
||||
clientset.ExtensionsClient = v1beta1extensions.New(c)
|
||||
clientset.PolicyClient = v1alpha1policy.New(c)
|
||||
clientset.RbacClient = v1alpha1rbac.New(c)
|
||||
clientset.StorageClient = v1beta1storage.New(c)
|
||||
|
||||
clientset.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
return &clientset
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated clientset.
|
||||
package kubernetes
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/discovery"
|
||||
fakediscovery "k8s.io/client-go/1.5/discovery/fake"
|
||||
clientset "k8s.io/client-go/1.5/kubernetes"
|
||||
v1alpha1apps "k8s.io/client-go/1.5/kubernetes/typed/apps/v1alpha1"
|
||||
fakev1alpha1apps "k8s.io/client-go/1.5/kubernetes/typed/apps/v1alpha1/fake"
|
||||
v1beta1authentication "k8s.io/client-go/1.5/kubernetes/typed/authentication/v1beta1"
|
||||
fakev1beta1authentication "k8s.io/client-go/1.5/kubernetes/typed/authentication/v1beta1/fake"
|
||||
v1beta1authorization "k8s.io/client-go/1.5/kubernetes/typed/authorization/v1beta1"
|
||||
fakev1beta1authorization "k8s.io/client-go/1.5/kubernetes/typed/authorization/v1beta1/fake"
|
||||
v1autoscaling "k8s.io/client-go/1.5/kubernetes/typed/autoscaling/v1"
|
||||
fakev1autoscaling "k8s.io/client-go/1.5/kubernetes/typed/autoscaling/v1/fake"
|
||||
v1batch "k8s.io/client-go/1.5/kubernetes/typed/batch/v1"
|
||||
fakev1batch "k8s.io/client-go/1.5/kubernetes/typed/batch/v1/fake"
|
||||
v1alpha1certificates "k8s.io/client-go/1.5/kubernetes/typed/certificates/v1alpha1"
|
||||
fakev1alpha1certificates "k8s.io/client-go/1.5/kubernetes/typed/certificates/v1alpha1/fake"
|
||||
v1core "k8s.io/client-go/1.5/kubernetes/typed/core/v1"
|
||||
fakev1core "k8s.io/client-go/1.5/kubernetes/typed/core/v1/fake"
|
||||
v1beta1extensions "k8s.io/client-go/1.5/kubernetes/typed/extensions/v1beta1"
|
||||
fakev1beta1extensions "k8s.io/client-go/1.5/kubernetes/typed/extensions/v1beta1/fake"
|
||||
v1alpha1policy "k8s.io/client-go/1.5/kubernetes/typed/policy/v1alpha1"
|
||||
fakev1alpha1policy "k8s.io/client-go/1.5/kubernetes/typed/policy/v1alpha1/fake"
|
||||
v1alpha1rbac "k8s.io/client-go/1.5/kubernetes/typed/rbac/v1alpha1"
|
||||
fakev1alpha1rbac "k8s.io/client-go/1.5/kubernetes/typed/rbac/v1alpha1/fake"
|
||||
v1beta1storage "k8s.io/client-go/1.5/kubernetes/typed/storage/v1beta1"
|
||||
fakev1beta1storage "k8s.io/client-go/1.5/kubernetes/typed/storage/v1beta1/fake"
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/watch"
|
||||
"k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
// It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
|
||||
// without applying any validations and/or defaults. It shouldn't be considered a replacement
|
||||
// for a real clientset and is mostly useful in simple unit tests.
|
||||
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
|
||||
o := testing.NewObjectTracker(api.Scheme, api.Codecs.UniversalDecoder())
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
fakePtr := testing.Fake{}
|
||||
fakePtr.AddReactor("*", "*", testing.ObjectReaction(o, registered.RESTMapper()))
|
||||
|
||||
fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil))
|
||||
|
||||
return &Clientset{fakePtr}
|
||||
}
|
||||
|
||||
// Clientset implements clientset.Interface. Meant to be embedded into a
|
||||
// struct to get a default implementation. This makes faking out just the method
|
||||
// you want to test easier.
|
||||
type Clientset struct {
|
||||
testing.Fake
|
||||
}
|
||||
|
||||
func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
return &fakediscovery.FakeDiscovery{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// Core retrieves the CoreClient
|
||||
func (c *Clientset) Core() v1core.CoreInterface {
|
||||
return &fakev1core.FakeCore{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Apps retrieves the AppsClient
|
||||
func (c *Clientset) Apps() v1alpha1apps.AppsInterface {
|
||||
return &fakev1alpha1apps.FakeApps{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Authentication retrieves the AuthenticationClient
|
||||
func (c *Clientset) Authentication() v1beta1authentication.AuthenticationInterface {
|
||||
return &fakev1beta1authentication.FakeAuthentication{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Authorization retrieves the AuthorizationClient
|
||||
func (c *Clientset) Authorization() v1beta1authorization.AuthorizationInterface {
|
||||
return &fakev1beta1authorization.FakeAuthorization{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Autoscaling retrieves the AutoscalingClient
|
||||
func (c *Clientset) Autoscaling() v1autoscaling.AutoscalingInterface {
|
||||
return &fakev1autoscaling.FakeAutoscaling{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Batch retrieves the BatchClient
|
||||
func (c *Clientset) Batch() v1batch.BatchInterface {
|
||||
return &fakev1batch.FakeBatch{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Certificates retrieves the CertificatesClient
|
||||
func (c *Clientset) Certificates() v1alpha1certificates.CertificatesInterface {
|
||||
return &fakev1alpha1certificates.FakeCertificates{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Extensions retrieves the ExtensionsClient
|
||||
func (c *Clientset) Extensions() v1beta1extensions.ExtensionsInterface {
|
||||
return &fakev1beta1extensions.FakeExtensions{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Policy retrieves the PolicyClient
|
||||
func (c *Clientset) Policy() v1alpha1policy.PolicyInterface {
|
||||
return &fakev1alpha1policy.FakePolicy{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Rbac retrieves the RbacClient
|
||||
func (c *Clientset) Rbac() v1alpha1rbac.RbacInterface {
|
||||
return &fakev1alpha1rbac.FakeRbac{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// Storage retrieves the StorageClient
|
||||
func (c *Clientset) Storage() v1beta1storage.StorageInterface {
|
||||
return &fakev1beta1storage.FakeStorage{Fake: &c.Fake}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated fake clientset.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type AppsInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
PetSetsGetter
|
||||
}
|
||||
|
||||
// AppsClient is used to interact with features provided by the Apps group.
|
||||
type AppsClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *AppsClient) PetSets(namespace string) PetSetInterface {
|
||||
return newPetSets(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AppsClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AppsClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AppsClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AppsClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AppsClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AppsClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *AppsClient {
|
||||
return &AppsClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if apps group is not registered, return an error
|
||||
g, err := registered.Group("apps")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AppsClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
unversioned "k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
v1alpha1 "k8s.io/client-go/1.5/pkg/apis/apps/v1alpha1"
|
||||
labels "k8s.io/client-go/1.5/pkg/labels"
|
||||
watch "k8s.io/client-go/1.5/pkg/watch"
|
||||
testing "k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
// FakePetSets implements PetSetInterface
|
||||
type FakePetSets struct {
|
||||
Fake *FakeApps
|
||||
ns string
|
||||
}
|
||||
|
||||
var petsetsResource = unversioned.GroupVersionResource{Group: "apps", Version: "v1alpha1", Resource: "petsets"}
|
||||
|
||||
func (c *FakePetSets) Create(petSet *v1alpha1.PetSet) (result *v1alpha1.PetSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(petsetsResource, c.ns, petSet), &v1alpha1.PetSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PetSet), err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) Update(petSet *v1alpha1.PetSet) (result *v1alpha1.PetSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(petsetsResource, c.ns, petSet), &v1alpha1.PetSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PetSet), err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) UpdateStatus(petSet *v1alpha1.PetSet) (*v1alpha1.PetSet, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(petsetsResource, "status", c.ns, petSet), &v1alpha1.PetSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PetSet), err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(petsetsResource, c.ns, name), &v1alpha1.PetSet{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(petsetsResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.PetSetList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) Get(name string) (result *v1alpha1.PetSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(petsetsResource, c.ns, name), &v1alpha1.PetSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PetSet), err
|
||||
}
|
||||
|
||||
func (c *FakePetSets) List(opts api.ListOptions) (result *v1alpha1.PetSetList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(petsetsResource, c.ns, opts), &v1alpha1.PetSetList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.PetSetList{}
|
||||
for _, item := range obj.(*v1alpha1.PetSetList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested petSets.
|
||||
func (c *FakePetSets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(petsetsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched petSet.
|
||||
func (c *FakePetSets) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.PetSet, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(petsetsResource, c.ns, name, data, subresources...), &v1alpha1.PetSet{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.PetSet), err
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
v1alpha1 "k8s.io/client-go/1.5/pkg/apis/apps/v1alpha1"
|
||||
watch "k8s.io/client-go/1.5/pkg/watch"
|
||||
)
|
||||
|
||||
// PetSetsGetter has a method to return a PetSetInterface.
|
||||
// A group's client should implement this interface.
|
||||
type PetSetsGetter interface {
|
||||
PetSets(namespace string) PetSetInterface
|
||||
}
|
||||
|
||||
// PetSetInterface has methods to work with PetSet resources.
|
||||
type PetSetInterface interface {
|
||||
Create(*v1alpha1.PetSet) (*v1alpha1.PetSet, error)
|
||||
Update(*v1alpha1.PetSet) (*v1alpha1.PetSet, error)
|
||||
UpdateStatus(*v1alpha1.PetSet) (*v1alpha1.PetSet, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*v1alpha1.PetSet, error)
|
||||
List(opts api.ListOptions) (*v1alpha1.PetSetList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.PetSet, err error)
|
||||
PetSetExpansion
|
||||
}
|
||||
|
||||
// petSets implements PetSetInterface
|
||||
type petSets struct {
|
||||
client *AppsClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newPetSets returns a PetSets
|
||||
func newPetSets(c *AppsClient, namespace string) *petSets {
|
||||
return &petSets{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a petSet and creates it. Returns the server's representation of the petSet, and an error, if there is any.
|
||||
func (c *petSets) Create(petSet *v1alpha1.PetSet) (result *v1alpha1.PetSet, err error) {
|
||||
result = &v1alpha1.PetSet{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
Body(petSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a petSet and updates it. Returns the server's representation of the petSet, and an error, if there is any.
|
||||
func (c *petSets) Update(petSet *v1alpha1.PetSet) (result *v1alpha1.PetSet, err error) {
|
||||
result = &v1alpha1.PetSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
Name(petSet.Name).
|
||||
Body(petSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *petSets) UpdateStatus(petSet *v1alpha1.PetSet) (result *v1alpha1.PetSet, err error) {
|
||||
result = &v1alpha1.PetSet{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
Name(petSet.Name).
|
||||
SubResource("status").
|
||||
Body(petSet).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the petSet and deletes it. Returns an error if one occurs.
|
||||
func (c *petSets) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *petSets) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the petSet, and returns the corresponding petSet object, and an error if there is any.
|
||||
func (c *petSets) Get(name string) (result *v1alpha1.PetSet, err error) {
|
||||
result = &v1alpha1.PetSet{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of PetSets that match those selectors.
|
||||
func (c *petSets) List(opts api.ListOptions) (result *v1alpha1.PetSetList, err error) {
|
||||
result = &v1alpha1.PetSetList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested petSets.
|
||||
func (c *petSets) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched petSet.
|
||||
func (c *petSets) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.PetSet, err error) {
|
||||
result = &v1alpha1.PetSet{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("petsets").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type AuthenticationInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
TokenReviewsGetter
|
||||
}
|
||||
|
||||
// AuthenticationClient is used to interact with features provided by the Authentication group.
|
||||
type AuthenticationClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *AuthenticationClient) TokenReviews() TokenReviewInterface {
|
||||
return newTokenReviews(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AuthenticationClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AuthenticationClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AuthenticationClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AuthenticationClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AuthenticationClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AuthenticationClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *AuthenticationClient {
|
||||
return &AuthenticationClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if authentication group is not registered, return an error
|
||||
g, err := registered.Group("authentication.k8s.io")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AuthenticationClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type AuthorizationInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
LocalSubjectAccessReviewsGetter
|
||||
SelfSubjectAccessReviewsGetter
|
||||
SubjectAccessReviewsGetter
|
||||
}
|
||||
|
||||
// AuthorizationClient is used to interact with features provided by the Authorization group.
|
||||
type AuthorizationClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *AuthorizationClient) LocalSubjectAccessReviews(namespace string) LocalSubjectAccessReviewInterface {
|
||||
return newLocalSubjectAccessReviews(c, namespace)
|
||||
}
|
||||
|
||||
func (c *AuthorizationClient) SelfSubjectAccessReviews() SelfSubjectAccessReviewInterface {
|
||||
return newSelfSubjectAccessReviews(c)
|
||||
}
|
||||
|
||||
func (c *AuthorizationClient) SubjectAccessReviews() SubjectAccessReviewInterface {
|
||||
return newSubjectAccessReviews(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AuthorizationClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AuthorizationClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AuthorizationClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AuthorizationClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AuthorizationClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AuthorizationClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *AuthorizationClient {
|
||||
return &AuthorizationClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if authorization group is not registered, return an error
|
||||
g, err := registered.Group("authorization.k8s.io")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AuthorizationClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type AutoscalingInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
HorizontalPodAutoscalersGetter
|
||||
}
|
||||
|
||||
// AutoscalingClient is used to interact with features provided by the Autoscaling group.
|
||||
type AutoscalingClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *AutoscalingClient) HorizontalPodAutoscalers(namespace string) HorizontalPodAutoscalerInterface {
|
||||
return newHorizontalPodAutoscalers(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AutoscalingClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AutoscalingClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AutoscalingClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AutoscalingClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AutoscalingClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AutoscalingClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *AutoscalingClient {
|
||||
return &AutoscalingClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if autoscaling group is not registered, return an error
|
||||
g, err := registered.Group("autoscaling")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *AutoscalingClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type BatchInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
JobsGetter
|
||||
}
|
||||
|
||||
// BatchClient is used to interact with features provided by the Batch group.
|
||||
type BatchClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *BatchClient) Jobs(namespace string) JobInterface {
|
||||
return newJobs(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new BatchClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*BatchClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &BatchClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new BatchClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *BatchClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new BatchClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *BatchClient {
|
||||
return &BatchClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if batch group is not registered, return an error
|
||||
g, err := registered.Group("batch")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *BatchClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type CertificatesInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
CertificateSigningRequestsGetter
|
||||
}
|
||||
|
||||
// CertificatesClient is used to interact with features provided by the Certificates group.
|
||||
type CertificatesClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *CertificatesClient) CertificateSigningRequests() CertificateSigningRequestInterface {
|
||||
return newCertificateSigningRequests(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new CertificatesClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*CertificatesClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CertificatesClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new CertificatesClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *CertificatesClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new CertificatesClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *CertificatesClient {
|
||||
return &CertificatesClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if certificates group is not registered, return an error
|
||||
g, err := registered.Group("certificates.k8s.io")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *CertificatesClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
unversioned "k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
v1alpha1 "k8s.io/client-go/1.5/pkg/apis/certificates/v1alpha1"
|
||||
labels "k8s.io/client-go/1.5/pkg/labels"
|
||||
watch "k8s.io/client-go/1.5/pkg/watch"
|
||||
testing "k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
// FakeCertificateSigningRequests implements CertificateSigningRequestInterface
|
||||
type FakeCertificateSigningRequests struct {
|
||||
Fake *FakeCertificates
|
||||
}
|
||||
|
||||
var certificatesigningrequestsResource = unversioned.GroupVersionResource{Group: "certificates.k8s.io", Version: "v1alpha1", Resource: "certificatesigningrequests"}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) Create(certificateSigningRequest *v1alpha1.CertificateSigningRequest) (result *v1alpha1.CertificateSigningRequest, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootCreateAction(certificatesigningrequestsResource, certificateSigningRequest), &v1alpha1.CertificateSigningRequest{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.CertificateSigningRequest), err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) Update(certificateSigningRequest *v1alpha1.CertificateSigningRequest) (result *v1alpha1.CertificateSigningRequest, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateAction(certificatesigningrequestsResource, certificateSigningRequest), &v1alpha1.CertificateSigningRequest{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.CertificateSigningRequest), err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) UpdateStatus(certificateSigningRequest *v1alpha1.CertificateSigningRequest) (*v1alpha1.CertificateSigningRequest, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootUpdateSubresourceAction(certificatesigningrequestsResource, "status", certificateSigningRequest), &v1alpha1.CertificateSigningRequest{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.CertificateSigningRequest), err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewRootDeleteAction(certificatesigningrequestsResource, name), &v1alpha1.CertificateSigningRequest{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := testing.NewRootDeleteCollectionAction(certificatesigningrequestsResource, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1alpha1.CertificateSigningRequestList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) Get(name string) (result *v1alpha1.CertificateSigningRequest, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootGetAction(certificatesigningrequestsResource, name), &v1alpha1.CertificateSigningRequest{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.CertificateSigningRequest), err
|
||||
}
|
||||
|
||||
func (c *FakeCertificateSigningRequests) List(opts api.ListOptions) (result *v1alpha1.CertificateSigningRequestList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootListAction(certificatesigningrequestsResource, opts), &v1alpha1.CertificateSigningRequestList{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1alpha1.CertificateSigningRequestList{}
|
||||
for _, item := range obj.(*v1alpha1.CertificateSigningRequestList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested certificateSigningRequests.
|
||||
func (c *FakeCertificateSigningRequests) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewRootWatchAction(certificatesigningrequestsResource, opts))
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched certificateSigningRequest.
|
||||
func (c *FakeCertificateSigningRequests) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1alpha1.CertificateSigningRequest, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(certificatesigningrequestsResource, name, data, subresources...), &v1alpha1.CertificateSigningRequest{})
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1alpha1.CertificateSigningRequest), err
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type CoreInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
ComponentStatusesGetter
|
||||
ConfigMapsGetter
|
||||
EndpointsGetter
|
||||
EventsGetter
|
||||
LimitRangesGetter
|
||||
NamespacesGetter
|
||||
NodesGetter
|
||||
PersistentVolumesGetter
|
||||
PersistentVolumeClaimsGetter
|
||||
PodsGetter
|
||||
PodTemplatesGetter
|
||||
ReplicationControllersGetter
|
||||
ResourceQuotasGetter
|
||||
SecretsGetter
|
||||
ServicesGetter
|
||||
ServiceAccountsGetter
|
||||
}
|
||||
|
||||
// CoreClient is used to interact with features provided by the Core group.
|
||||
type CoreClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *CoreClient) ComponentStatuses() ComponentStatusInterface {
|
||||
return newComponentStatuses(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ConfigMaps(namespace string) ConfigMapInterface {
|
||||
return newConfigMaps(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Endpoints(namespace string) EndpointsInterface {
|
||||
return newEndpoints(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Events(namespace string) EventInterface {
|
||||
return newEvents(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) LimitRanges(namespace string) LimitRangeInterface {
|
||||
return newLimitRanges(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Namespaces() NamespaceInterface {
|
||||
return newNamespaces(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Nodes() NodeInterface {
|
||||
return newNodes(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PersistentVolumes() PersistentVolumeInterface {
|
||||
return newPersistentVolumes(c)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PersistentVolumeClaims(namespace string) PersistentVolumeClaimInterface {
|
||||
return newPersistentVolumeClaims(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Pods(namespace string) PodInterface {
|
||||
return newPods(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) PodTemplates(namespace string) PodTemplateInterface {
|
||||
return newPodTemplates(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ReplicationControllers(namespace string) ReplicationControllerInterface {
|
||||
return newReplicationControllers(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ResourceQuotas(namespace string) ResourceQuotaInterface {
|
||||
return newResourceQuotas(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Secrets(namespace string) SecretInterface {
|
||||
return newSecrets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) Services(namespace string) ServiceInterface {
|
||||
return newServices(c, namespace)
|
||||
}
|
||||
|
||||
func (c *CoreClient) ServiceAccounts(namespace string) ServiceAccountInterface {
|
||||
return newServiceAccounts(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new CoreClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*CoreClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CoreClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new CoreClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *CoreClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new CoreClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *CoreClient {
|
||||
return &CoreClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if core group is not registered, return an error
|
||||
g, err := registered.Group("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/api"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *CoreClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1 "k8s.io/client-go/1.5/kubernetes/typed/core/v1"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
testing "k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
type FakeCore struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeCore) ComponentStatuses() v1.ComponentStatusInterface {
|
||||
return &FakeComponentStatuses{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ConfigMaps(namespace string) v1.ConfigMapInterface {
|
||||
return &FakeConfigMaps{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Endpoints(namespace string) v1.EndpointsInterface {
|
||||
return &FakeEndpoints{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Events(namespace string) v1.EventInterface {
|
||||
return &FakeEvents{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) LimitRanges(namespace string) v1.LimitRangeInterface {
|
||||
return &FakeLimitRanges{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Namespaces() v1.NamespaceInterface {
|
||||
return &FakeNamespaces{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Nodes() v1.NodeInterface {
|
||||
return &FakeNodes{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PersistentVolumes() v1.PersistentVolumeInterface {
|
||||
return &FakePersistentVolumes{c}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PersistentVolumeClaims(namespace string) v1.PersistentVolumeClaimInterface {
|
||||
return &FakePersistentVolumeClaims{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Pods(namespace string) v1.PodInterface {
|
||||
return &FakePods{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) PodTemplates(namespace string) v1.PodTemplateInterface {
|
||||
return &FakePodTemplates{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ReplicationControllers(namespace string) v1.ReplicationControllerInterface {
|
||||
return &FakeReplicationControllers{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ResourceQuotas(namespace string) v1.ResourceQuotaInterface {
|
||||
return &FakeResourceQuotas{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Secrets(namespace string) v1.SecretInterface {
|
||||
return &FakeSecrets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) Services(namespace string) v1.ServiceInterface {
|
||||
return &FakeServices{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeCore) ServiceAccounts(namespace string) v1.ServiceAccountInterface {
|
||||
return &FakeServiceAccounts{c, namespace}
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeCore) GetRESTClient() *rest.RESTClient {
|
||||
return nil
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type ExtensionsInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
DaemonSetsGetter
|
||||
DeploymentsGetter
|
||||
IngressesGetter
|
||||
JobsGetter
|
||||
PodSecurityPoliciesGetter
|
||||
ReplicaSetsGetter
|
||||
ScalesGetter
|
||||
ThirdPartyResourcesGetter
|
||||
}
|
||||
|
||||
// ExtensionsClient is used to interact with features provided by the Extensions group.
|
||||
type ExtensionsClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) DaemonSets(namespace string) DaemonSetInterface {
|
||||
return newDaemonSets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Deployments(namespace string) DeploymentInterface {
|
||||
return newDeployments(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Ingresses(namespace string) IngressInterface {
|
||||
return newIngresses(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Jobs(namespace string) JobInterface {
|
||||
return newJobs(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) PodSecurityPolicies() PodSecurityPolicyInterface {
|
||||
return newPodSecurityPolicies(c)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) ReplicaSets(namespace string) ReplicaSetInterface {
|
||||
return newReplicaSets(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) Scales(namespace string) ScaleInterface {
|
||||
return newScales(c, namespace)
|
||||
}
|
||||
|
||||
func (c *ExtensionsClient) ThirdPartyResources() ThirdPartyResourceInterface {
|
||||
return newThirdPartyResources(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ExtensionsClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*ExtensionsClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ExtensionsClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ExtensionsClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ExtensionsClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ExtensionsClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *ExtensionsClient {
|
||||
return &ExtensionsClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if extensions group is not registered, return an error
|
||||
g, err := registered.Group("extensions")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ExtensionsClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/client-go/1.5/kubernetes/typed/extensions/v1beta1"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
testing "k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
type FakeExtensions struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) DaemonSets(namespace string) v1beta1.DaemonSetInterface {
|
||||
return &FakeDaemonSets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Deployments(namespace string) v1beta1.DeploymentInterface {
|
||||
return &FakeDeployments{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Ingresses(namespace string) v1beta1.IngressInterface {
|
||||
return &FakeIngresses{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Jobs(namespace string) v1beta1.JobInterface {
|
||||
return &FakeJobs{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) PodSecurityPolicies() v1beta1.PodSecurityPolicyInterface {
|
||||
return &FakePodSecurityPolicies{c}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) ReplicaSets(namespace string) v1beta1.ReplicaSetInterface {
|
||||
return &FakeReplicaSets{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) Scales(namespace string) v1beta1.ScaleInterface {
|
||||
return &FakeScales{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeExtensions) ThirdPartyResources() v1beta1.ThirdPartyResourceInterface {
|
||||
return &FakeThirdPartyResources{c}
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeExtensions) GetRESTClient() *rest.RESTClient {
|
||||
return nil
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
unversioned "k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
v1beta1 "k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
|
||||
labels "k8s.io/client-go/1.5/pkg/labels"
|
||||
watch "k8s.io/client-go/1.5/pkg/watch"
|
||||
testing "k8s.io/client-go/1.5/testing"
|
||||
)
|
||||
|
||||
// FakeJobs implements JobInterface
|
||||
type FakeJobs struct {
|
||||
Fake *FakeExtensions
|
||||
ns string
|
||||
}
|
||||
|
||||
var jobsResource = unversioned.GroupVersionResource{Group: "extensions", Version: "v1beta1", Resource: "jobs"}
|
||||
|
||||
func (c *FakeJobs) Create(job *v1beta1.Job) (result *v1beta1.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(jobsResource, c.ns, job), &v1beta1.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Update(job *v1beta1.Job) (result *v1beta1.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(jobsResource, c.ns, job), &v1beta1.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) UpdateStatus(job *v1beta1.Job) (*v1beta1.Job, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(jobsResource, "status", c.ns, job), &v1beta1.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Delete(name string, options *api.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(jobsResource, c.ns, name), &v1beta1.Job{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(jobsResource, c.ns, listOptions)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.JobList{})
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) Get(name string) (result *v1beta1.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(jobsResource, c.ns, name), &v1beta1.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Job), err
|
||||
}
|
||||
|
||||
func (c *FakeJobs) List(opts api.ListOptions) (result *v1beta1.JobList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(jobsResource, c.ns, opts), &v1beta1.JobList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := opts.LabelSelector
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.JobList{}
|
||||
for _, item := range obj.(*v1beta1.JobList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested jobs.
|
||||
func (c *FakeJobs) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(jobsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched job.
|
||||
func (c *FakeJobs) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1beta1.Job, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(jobsResource, c.ns, name, data, subresources...), &v1beta1.Job{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.Job), err
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
v1beta1 "k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
|
||||
watch "k8s.io/client-go/1.5/pkg/watch"
|
||||
)
|
||||
|
||||
// JobsGetter has a method to return a JobInterface.
|
||||
// A group's client should implement this interface.
|
||||
type JobsGetter interface {
|
||||
Jobs(namespace string) JobInterface
|
||||
}
|
||||
|
||||
// JobInterface has methods to work with Job resources.
|
||||
type JobInterface interface {
|
||||
Create(*v1beta1.Job) (*v1beta1.Job, error)
|
||||
Update(*v1beta1.Job) (*v1beta1.Job, error)
|
||||
UpdateStatus(*v1beta1.Job) (*v1beta1.Job, error)
|
||||
Delete(name string, options *api.DeleteOptions) error
|
||||
DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error
|
||||
Get(name string) (*v1beta1.Job, error)
|
||||
List(opts api.ListOptions) (*v1beta1.JobList, error)
|
||||
Watch(opts api.ListOptions) (watch.Interface, error)
|
||||
Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1beta1.Job, err error)
|
||||
JobExpansion
|
||||
}
|
||||
|
||||
// jobs implements JobInterface
|
||||
type jobs struct {
|
||||
client *ExtensionsClient
|
||||
ns string
|
||||
}
|
||||
|
||||
// newJobs returns a Jobs
|
||||
func newJobs(c *ExtensionsClient, namespace string) *jobs {
|
||||
return &jobs{
|
||||
client: c,
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Create takes the representation of a job and creates it. Returns the server's representation of the job, and an error, if there is any.
|
||||
func (c *jobs) Create(job *v1beta1.Job) (result *v1beta1.Job, err error) {
|
||||
result = &v1beta1.Job{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
Body(job).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a job and updates it. Returns the server's representation of the job, and an error, if there is any.
|
||||
func (c *jobs) Update(job *v1beta1.Job) (result *v1beta1.Job, err error) {
|
||||
result = &v1beta1.Job{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
Name(job.Name).
|
||||
Body(job).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *jobs) UpdateStatus(job *v1beta1.Job) (result *v1beta1.Job, err error) {
|
||||
result = &v1beta1.Job{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
Name(job.Name).
|
||||
SubResource("status").
|
||||
Body(job).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the job and deletes it. Returns an error if one occurs.
|
||||
func (c *jobs) Delete(name string, options *api.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
Name(name).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *jobs) DeleteCollection(options *api.DeleteOptions, listOptions api.ListOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
VersionedParams(&listOptions, api.ParameterCodec).
|
||||
Body(options).
|
||||
Do().
|
||||
Error()
|
||||
}
|
||||
|
||||
// Get takes name of the job, and returns the corresponding job object, and an error if there is any.
|
||||
func (c *jobs) Get(name string) (result *v1beta1.Job, err error) {
|
||||
result = &v1beta1.Job{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
Name(name).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of Jobs that match those selectors.
|
||||
func (c *jobs) List(opts api.ListOptions) (result *v1beta1.JobList, err error) {
|
||||
result = &v1beta1.JobList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested jobs.
|
||||
func (c *jobs) Watch(opts api.ListOptions) (watch.Interface, error) {
|
||||
return c.client.Get().
|
||||
Prefix("watch").
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
VersionedParams(&opts, api.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched job.
|
||||
func (c *jobs) Patch(name string, pt api.PatchType, data []byte, subresources ...string) (result *v1beta1.Job, err error) {
|
||||
result = &v1beta1.Job{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("jobs").
|
||||
SubResource(subresources...).
|
||||
Name(name).
|
||||
Body(data).
|
||||
Do().
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type PolicyInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
PodDisruptionBudgetsGetter
|
||||
}
|
||||
|
||||
// PolicyClient is used to interact with features provided by the Policy group.
|
||||
type PolicyClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *PolicyClient) PodDisruptionBudgets(namespace string) PodDisruptionBudgetInterface {
|
||||
return newPodDisruptionBudgets(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new PolicyClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*PolicyClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PolicyClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new PolicyClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *PolicyClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new PolicyClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *PolicyClient {
|
||||
return &PolicyClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if policy group is not registered, return an error
|
||||
g, err := registered.Group("policy")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *PolicyClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1alpha1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type RbacInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
ClusterRolesGetter
|
||||
ClusterRoleBindingsGetter
|
||||
RolesGetter
|
||||
RoleBindingsGetter
|
||||
}
|
||||
|
||||
// RbacClient is used to interact with features provided by the Rbac group.
|
||||
type RbacClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *RbacClient) ClusterRoles() ClusterRoleInterface {
|
||||
return newClusterRoles(c)
|
||||
}
|
||||
|
||||
func (c *RbacClient) ClusterRoleBindings() ClusterRoleBindingInterface {
|
||||
return newClusterRoleBindings(c)
|
||||
}
|
||||
|
||||
func (c *RbacClient) Roles(namespace string) RoleInterface {
|
||||
return newRoles(c, namespace)
|
||||
}
|
||||
|
||||
func (c *RbacClient) RoleBindings(namespace string) RoleBindingInterface {
|
||||
return newRoleBindings(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new RbacClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*RbacClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &RbacClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new RbacClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *RbacClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new RbacClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *RbacClient {
|
||||
return &RbacClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if rbac group is not registered, return an error
|
||||
g, err := registered.Group("rbac.authorization.k8s.io")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *RbacClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This package is generated by client-gen with arguments: --clientset-name=release_1_5 --input=[api/v1,apps/v1alpha1,authentication/v1beta1,authorization/v1beta1,autoscaling/v1,batch/v1,certificates/v1alpha1,extensions/v1beta1,policy/v1alpha1,rbac/v1alpha1,storage/v1beta1]
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
api "k8s.io/client-go/1.5/pkg/api"
|
||||
registered "k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
serializer "k8s.io/client-go/1.5/pkg/runtime/serializer"
|
||||
rest "k8s.io/client-go/1.5/rest"
|
||||
)
|
||||
|
||||
type StorageInterface interface {
|
||||
GetRESTClient() *rest.RESTClient
|
||||
StorageClassesGetter
|
||||
}
|
||||
|
||||
// StorageClient is used to interact with features provided by the Storage group.
|
||||
type StorageClient struct {
|
||||
*rest.RESTClient
|
||||
}
|
||||
|
||||
func (c *StorageClient) StorageClasses() StorageClassInterface {
|
||||
return newStorageClasses(c)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new StorageClient for the given config.
|
||||
func NewForConfig(c *rest.Config) (*StorageClient, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &StorageClient{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new StorageClient for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *StorageClient {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new StorageClient for the given RESTClient.
|
||||
func New(c *rest.RESTClient) *StorageClient {
|
||||
return &StorageClient{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
// if storage group is not registered, return an error
|
||||
g, err := registered.Group("storage.k8s.io")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.APIPath = "/apis"
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
// TODO: Unconditionally set the config.Version, until we fix the config.
|
||||
//if config.Version == "" {
|
||||
copyGroupVersion := g.GroupVersion
|
||||
config.GroupVersion = ©GroupVersion
|
||||
//}
|
||||
|
||||
config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: api.Codecs}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *StorageClient) GetRESTClient() *rest.RESTClient {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.RESTClient
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
assignees:
|
||||
- bgrant0607
|
||||
- erictune
|
||||
- lavalamp
|
||||
- smarterclayton
|
||||
- thockin
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
stderrs "errors"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/client-go/1.5/pkg/auth/user"
|
||||
"k8s.io/client-go/1.5/pkg/types"
|
||||
)
|
||||
|
||||
// Context carries values across API boundaries.
|
||||
// This context matches the context.Context interface
|
||||
// (https://blog.golang.org/context), for the purposes
|
||||
// of passing the api.Context through to the storage tier.
|
||||
// TODO: Determine the extent that this abstraction+interface
|
||||
// is used by the api, and whether we can remove.
|
||||
type Context interface {
|
||||
// Value returns the value associated with key or nil if none.
|
||||
Value(key interface{}) interface{}
|
||||
|
||||
// Deadline returns the time when this Context will be canceled, if any.
|
||||
Deadline() (deadline time.Time, ok bool)
|
||||
|
||||
// Done returns a channel that is closed when this Context is canceled
|
||||
// or times out.
|
||||
Done() <-chan struct{}
|
||||
|
||||
// Err indicates why this context was canceled, after the Done channel
|
||||
// is closed.
|
||||
Err() error
|
||||
}
|
||||
|
||||
// The key type is unexported to prevent collisions
|
||||
type key int
|
||||
|
||||
const (
|
||||
// namespaceKey is the context key for the request namespace.
|
||||
namespaceKey key = iota
|
||||
|
||||
// userKey is the context key for the request user.
|
||||
userKey
|
||||
|
||||
// uidKey is the context key for the uid to assign to an object on create.
|
||||
uidKey
|
||||
|
||||
// userAgentKey is the context key for the request user agent.
|
||||
userAgentKey
|
||||
)
|
||||
|
||||
// NewContext instantiates a base context object for request flows.
|
||||
func NewContext() Context {
|
||||
return context.TODO()
|
||||
}
|
||||
|
||||
// NewDefaultContext instantiates a base context object for request flows in the default namespace
|
||||
func NewDefaultContext() Context {
|
||||
return WithNamespace(NewContext(), NamespaceDefault)
|
||||
}
|
||||
|
||||
// WithValue returns a copy of parent in which the value associated with key is val.
|
||||
func WithValue(parent Context, key interface{}, val interface{}) Context {
|
||||
internalCtx, ok := parent.(context.Context)
|
||||
if !ok {
|
||||
panic(stderrs.New("Invalid context type"))
|
||||
}
|
||||
return context.WithValue(internalCtx, key, val)
|
||||
}
|
||||
|
||||
// WithNamespace returns a copy of parent in which the namespace value is set
|
||||
func WithNamespace(parent Context, namespace string) Context {
|
||||
return WithValue(parent, namespaceKey, namespace)
|
||||
}
|
||||
|
||||
// NamespaceFrom returns the value of the namespace key on the ctx
|
||||
func NamespaceFrom(ctx Context) (string, bool) {
|
||||
namespace, ok := ctx.Value(namespaceKey).(string)
|
||||
return namespace, ok
|
||||
}
|
||||
|
||||
// NamespaceValue returns the value of the namespace key on the ctx, or the empty string if none
|
||||
func NamespaceValue(ctx Context) string {
|
||||
namespace, _ := NamespaceFrom(ctx)
|
||||
return namespace
|
||||
}
|
||||
|
||||
// ValidNamespace returns false if the namespace on the context differs from the resource. If the resource has no namespace, it is set to the value in the context.
|
||||
func ValidNamespace(ctx Context, resource *ObjectMeta) bool {
|
||||
ns, ok := NamespaceFrom(ctx)
|
||||
if len(resource.Namespace) == 0 {
|
||||
resource.Namespace = ns
|
||||
}
|
||||
return ns == resource.Namespace && ok
|
||||
}
|
||||
|
||||
// WithNamespaceDefaultIfNone returns a context whose namespace is the default if and only if the parent context has no namespace value
|
||||
func WithNamespaceDefaultIfNone(parent Context) Context {
|
||||
namespace, ok := NamespaceFrom(parent)
|
||||
if !ok || len(namespace) == 0 {
|
||||
return WithNamespace(parent, NamespaceDefault)
|
||||
}
|
||||
return parent
|
||||
}
|
||||
|
||||
// WithUser returns a copy of parent in which the user value is set
|
||||
func WithUser(parent Context, user user.Info) Context {
|
||||
return WithValue(parent, userKey, user)
|
||||
}
|
||||
|
||||
// UserFrom returns the value of the user key on the ctx
|
||||
func UserFrom(ctx Context) (user.Info, bool) {
|
||||
user, ok := ctx.Value(userKey).(user.Info)
|
||||
return user, ok
|
||||
}
|
||||
|
||||
// WithUID returns a copy of parent in which the uid value is set
|
||||
func WithUID(parent Context, uid types.UID) Context {
|
||||
return WithValue(parent, uidKey, uid)
|
||||
}
|
||||
|
||||
// UIDFrom returns the value of the uid key on the ctx
|
||||
func UIDFrom(ctx Context) (types.UID, bool) {
|
||||
uid, ok := ctx.Value(uidKey).(types.UID)
|
||||
return uid, ok
|
||||
}
|
||||
|
||||
// WithUserAgent returns a copy of parent in which the user value is set
|
||||
func WithUserAgent(parent Context, userAgent string) Context {
|
||||
return WithValue(parent, userAgentKey, userAgent)
|
||||
}
|
||||
|
||||
// UserAgentFrom returns the value of the userAgent key on the ctx
|
||||
func UserAgentFrom(ctx Context) (string, bool) {
|
||||
userAgent, ok := ctx.Value(userAgentKey).(string)
|
||||
return userAgent, ok
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/resource"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/conversion"
|
||||
"k8s.io/client-go/1.5/pkg/fields"
|
||||
"k8s.io/client-go/1.5/pkg/labels"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/util/intstr"
|
||||
utillabels "k8s.io/client-go/1.5/pkg/util/labels"
|
||||
"k8s.io/client-go/1.5/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
return scheme.AddConversionFuncs(
|
||||
Convert_unversioned_TypeMeta_To_unversioned_TypeMeta,
|
||||
|
||||
Convert_unversioned_ListMeta_To_unversioned_ListMeta,
|
||||
|
||||
Convert_intstr_IntOrString_To_intstr_IntOrString,
|
||||
|
||||
Convert_unversioned_Time_To_unversioned_Time,
|
||||
|
||||
Convert_Slice_string_To_unversioned_Time,
|
||||
|
||||
Convert_resource_Quantity_To_resource_Quantity,
|
||||
|
||||
Convert_string_To_labels_Selector,
|
||||
Convert_labels_Selector_To_string,
|
||||
|
||||
Convert_string_To_fields_Selector,
|
||||
Convert_fields_Selector_To_string,
|
||||
|
||||
Convert_Pointer_bool_To_bool,
|
||||
Convert_bool_To_Pointer_bool,
|
||||
|
||||
Convert_Pointer_string_To_string,
|
||||
Convert_string_To_Pointer_string,
|
||||
|
||||
Convert_Pointer_int64_To_int,
|
||||
Convert_int_To_Pointer_int64,
|
||||
|
||||
Convert_Pointer_int32_To_int32,
|
||||
Convert_int32_To_Pointer_int32,
|
||||
|
||||
Convert_Pointer_float64_To_float64,
|
||||
Convert_float64_To_Pointer_float64,
|
||||
|
||||
Convert_map_to_unversioned_LabelSelector,
|
||||
Convert_unversioned_LabelSelector_to_map,
|
||||
)
|
||||
}
|
||||
|
||||
func Convert_Pointer_float64_To_float64(in **float64, out *float64, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = float64(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_float64_To_Pointer_float64(in *float64, out **float64, s conversion.Scope) error {
|
||||
temp := float64(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_int32_To_int32(in **int32, out *int32, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = int32(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_int32_To_Pointer_int32(in *int32, out **int32, s conversion.Scope) error {
|
||||
temp := int32(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_int64_To_int(in **int64, out *int, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = 0
|
||||
return nil
|
||||
}
|
||||
*out = int(**in)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_int_To_Pointer_int64(in *int, out **int64, s conversion.Scope) error {
|
||||
temp := int64(*in)
|
||||
*out = &temp
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_string_To_string(in **string, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = ""
|
||||
return nil
|
||||
}
|
||||
*out = **in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_string_To_Pointer_string(in *string, out **string, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
stringVar := ""
|
||||
*out = &stringVar
|
||||
return nil
|
||||
}
|
||||
*out = in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_Pointer_bool_To_bool(in **bool, out *bool, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
*out = false
|
||||
return nil
|
||||
}
|
||||
*out = **in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_bool_To_Pointer_bool(in *bool, out **bool, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
boolVar := false
|
||||
*out = &boolVar
|
||||
return nil
|
||||
}
|
||||
*out = in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_TypeMeta_To_unversioned_TypeMeta(in, out *unversioned.TypeMeta, s conversion.Scope) error {
|
||||
// These values are explicitly not copied
|
||||
//out.APIVersion = in.APIVersion
|
||||
//out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_ListMeta_To_unversioned_ListMeta(in, out *unversioned.ListMeta, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_intstr_IntOrString_To_intstr_IntOrString(in, out *intstr.IntOrString, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_Time_To_unversioned_Time(in *unversioned.Time, out *unversioned.Time, s conversion.Scope) error {
|
||||
// Cannot deep copy these, because time.Time has unexported fields.
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_Slice_string_To_unversioned_Time allows converting a URL query parameter value
|
||||
func Convert_Slice_string_To_unversioned_Time(input *[]string, out *unversioned.Time, s conversion.Scope) error {
|
||||
str := ""
|
||||
if len(*input) > 0 {
|
||||
str = (*input)[0]
|
||||
}
|
||||
return out.UnmarshalQueryParameter(str)
|
||||
}
|
||||
|
||||
func Convert_string_To_labels_Selector(in *string, out *labels.Selector, s conversion.Scope) error {
|
||||
selector, err := labels.Parse(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_string_To_fields_Selector(in *string, out *fields.Selector, s conversion.Scope) error {
|
||||
selector, err := fields.ParseSelector(*in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*out = selector
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_labels_Selector_To_string(in *labels.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_fields_Selector_To_string(in *fields.Selector, out *string, s conversion.Scope) error {
|
||||
if *in == nil {
|
||||
return nil
|
||||
}
|
||||
*out = (*in).String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_resource_Quantity_To_resource_Quantity(in *resource.Quantity, out *resource.Quantity, s conversion.Scope) error {
|
||||
*out = *in
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_map_to_unversioned_LabelSelector(in *map[string]string, out *unversioned.LabelSelector, s conversion.Scope) error {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out = new(unversioned.LabelSelector)
|
||||
for labelKey, labelValue := range *in {
|
||||
utillabels.AddLabelToSelector(out, labelKey, labelValue)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_unversioned_LabelSelector_to_map(in *unversioned.LabelSelector, out *map[string]string, s conversion.Scope) error {
|
||||
var err error
|
||||
*out, err = unversioned.LabelSelectorAsMap(in)
|
||||
if err != nil {
|
||||
err = field.Invalid(field.NewPath("labelSelector"), *in, fmt.Sprintf("cannot convert to old selector: %v", err))
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package errors provides detailed error types for api field validation.
|
||||
package errors
|
||||
@@ -1,461 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// HTTP Status codes not in the golang http package.
|
||||
const (
|
||||
StatusUnprocessableEntity = 422
|
||||
StatusTooManyRequests = 429
|
||||
// HTTP recommendations are for servers to define 5xx error codes
|
||||
// for scenarios not covered by behavior. In this case, ServerTimeout
|
||||
// is an indication that a transient server error has occurred and the
|
||||
// client *should* retry, with an optional Retry-After header to specify
|
||||
// the back off window.
|
||||
StatusServerTimeout = 504
|
||||
)
|
||||
|
||||
// StatusError is an error intended for consumption by a REST API server; it can also be
|
||||
// reconstructed by clients from a REST response. Public to allow easy type switches.
|
||||
type StatusError struct {
|
||||
ErrStatus unversioned.Status
|
||||
}
|
||||
|
||||
// APIStatus is exposed by errors that can be converted to an api.Status object
|
||||
// for finer grained details.
|
||||
type APIStatus interface {
|
||||
Status() unversioned.Status
|
||||
}
|
||||
|
||||
var _ error = &StatusError{}
|
||||
|
||||
// Error implements the Error interface.
|
||||
func (e *StatusError) Error() string {
|
||||
return e.ErrStatus.Message
|
||||
}
|
||||
|
||||
// Status allows access to e's status without having to know the detailed workings
|
||||
// of StatusError. Used by pkg/apiserver.
|
||||
func (e *StatusError) Status() unversioned.Status {
|
||||
return e.ErrStatus
|
||||
}
|
||||
|
||||
// DebugError reports extended info about the error to debug output.
|
||||
func (e *StatusError) DebugError() (string, []interface{}) {
|
||||
if out, err := json.MarshalIndent(e.ErrStatus, "", " "); err == nil {
|
||||
return "server response object: %s", []interface{}{string(out)}
|
||||
}
|
||||
return "server response object: %#v", []interface{}{e.ErrStatus}
|
||||
}
|
||||
|
||||
// UnexpectedObjectError can be returned by FromObject if it's passed a non-status object.
|
||||
type UnexpectedObjectError struct {
|
||||
Object runtime.Object
|
||||
}
|
||||
|
||||
// Error returns an error message describing 'u'.
|
||||
func (u *UnexpectedObjectError) Error() string {
|
||||
return fmt.Sprintf("unexpected object: %v", u.Object)
|
||||
}
|
||||
|
||||
// FromObject generates an StatusError from an unversioned.Status, if that is the type of obj; otherwise,
|
||||
// returns an UnexpecteObjectError.
|
||||
func FromObject(obj runtime.Object) error {
|
||||
switch t := obj.(type) {
|
||||
case *unversioned.Status:
|
||||
return &StatusError{*t}
|
||||
}
|
||||
return &UnexpectedObjectError{obj}
|
||||
}
|
||||
|
||||
// NewNotFound returns a new error which indicates that the resource of the kind and the name was not found.
|
||||
func NewNotFound(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusNotFound,
|
||||
Reason: unversioned.StatusReasonNotFound,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q not found", qualifiedResource.String(), name),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewAlreadyExists returns an error indicating the item requested exists by that identifier.
|
||||
func NewAlreadyExists(qualifiedResource unversioned.GroupResource, name string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusConflict,
|
||||
Reason: unversioned.StatusReasonAlreadyExists,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q already exists", qualifiedResource.String(), name),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewUnauthorized returns an error indicating the client is not authorized to perform the requested
|
||||
// action.
|
||||
func NewUnauthorized(reason string) *StatusError {
|
||||
message := reason
|
||||
if len(message) == 0 {
|
||||
message = "not authorized"
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusUnauthorized,
|
||||
Reason: unversioned.StatusReasonUnauthorized,
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewForbidden returns an error indicating the requested action was forbidden
|
||||
func NewForbidden(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusForbidden,
|
||||
Reason: unversioned.StatusReasonForbidden,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q is forbidden: %v", qualifiedResource.String(), name, err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewConflict returns an error indicating the item can't be updated as provided.
|
||||
func NewConflict(qualifiedResource unversioned.GroupResource, name string, err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusConflict,
|
||||
Reason: unversioned.StatusReasonConflict,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
},
|
||||
Message: fmt.Sprintf("Operation cannot be fulfilled on %s %q: %v", qualifiedResource.String(), name, err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewGone returns an error indicating the item no longer available at the server and no forwarding address is known.
|
||||
func NewGone(message string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusGone,
|
||||
Reason: unversioned.StatusReasonGone,
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewInvalid returns an error indicating the item is invalid and cannot be processed.
|
||||
func NewInvalid(qualifiedKind unversioned.GroupKind, name string, errs field.ErrorList) *StatusError {
|
||||
causes := make([]unversioned.StatusCause, 0, len(errs))
|
||||
for i := range errs {
|
||||
err := errs[i]
|
||||
causes = append(causes, unversioned.StatusCause{
|
||||
Type: unversioned.CauseType(err.Type),
|
||||
Message: err.ErrorBody(),
|
||||
Field: err.Field,
|
||||
})
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: StatusUnprocessableEntity, // RFC 4918: StatusUnprocessableEntity
|
||||
Reason: unversioned.StatusReasonInvalid,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedKind.Group,
|
||||
Kind: qualifiedKind.Kind,
|
||||
Name: name,
|
||||
Causes: causes,
|
||||
},
|
||||
Message: fmt.Sprintf("%s %q is invalid: %v", qualifiedKind.String(), name, errs.ToAggregate()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewBadRequest creates an error that indicates that the request is invalid and can not be processed.
|
||||
func NewBadRequest(reason string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusBadRequest,
|
||||
Reason: unversioned.StatusReasonBadRequest,
|
||||
Message: reason,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServiceUnavailable creates an error that indicates that the requested service is unavailable.
|
||||
func NewServiceUnavailable(reason string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusServiceUnavailable,
|
||||
Reason: unversioned.StatusReasonServiceUnavailable,
|
||||
Message: reason,
|
||||
}}
|
||||
}
|
||||
|
||||
// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
|
||||
func NewMethodNotSupported(qualifiedResource unversioned.GroupResource, action string) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusMethodNotAllowed,
|
||||
Reason: unversioned.StatusReasonMethodNotAllowed,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
},
|
||||
Message: fmt.Sprintf("%s is not supported on resources of kind %q", action, qualifiedResource.String()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServerTimeout returns an error indicating the requested action could not be completed due to a
|
||||
// transient error, and the client should try again.
|
||||
func NewServerTimeout(qualifiedResource unversioned.GroupResource, operation string, retryAfterSeconds int) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusInternalServerError,
|
||||
Reason: unversioned.StatusReasonServerTimeout,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: operation,
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
Message: fmt.Sprintf("The %s operation against %s could not be completed at this time, please try again.", operation, qualifiedResource.String()),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewServerTimeoutForKind should not exist. Server timeouts happen when accessing resources, the Kind is just what we
|
||||
// happened to be looking at when the request failed. This delegates to keep code sane, but we should work towards removing this.
|
||||
func NewServerTimeoutForKind(qualifiedKind unversioned.GroupKind, operation string, retryAfterSeconds int) *StatusError {
|
||||
return NewServerTimeout(unversioned.GroupResource{Group: qualifiedKind.Group, Resource: qualifiedKind.Kind}, operation, retryAfterSeconds)
|
||||
}
|
||||
|
||||
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
|
||||
func NewInternalError(err error) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: http.StatusInternalServerError,
|
||||
Reason: unversioned.StatusReasonInternalError,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Causes: []unversioned.StatusCause{{Message: err.Error()}},
|
||||
},
|
||||
Message: fmt.Sprintf("Internal error occurred: %v", err),
|
||||
}}
|
||||
}
|
||||
|
||||
// NewTimeoutError returns an error indicating that a timeout occurred before the request
|
||||
// could be completed. Clients may retry, but the operation may still complete.
|
||||
func NewTimeoutError(message string, retryAfterSeconds int) *StatusError {
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: StatusServerTimeout,
|
||||
Reason: unversioned.StatusReasonTimeout,
|
||||
Message: fmt.Sprintf("Timeout: %s", message),
|
||||
Details: &unversioned.StatusDetails{
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
// NewGenericServerResponse returns a new error for server responses that are not in a recognizable form.
|
||||
func NewGenericServerResponse(code int, verb string, qualifiedResource unversioned.GroupResource, name, serverMessage string, retryAfterSeconds int, isUnexpectedResponse bool) *StatusError {
|
||||
reason := unversioned.StatusReasonUnknown
|
||||
message := fmt.Sprintf("the server responded with the status code %d but did not return more information", code)
|
||||
switch code {
|
||||
case http.StatusConflict:
|
||||
if verb == "POST" {
|
||||
reason = unversioned.StatusReasonAlreadyExists
|
||||
} else {
|
||||
reason = unversioned.StatusReasonConflict
|
||||
}
|
||||
message = "the server reported a conflict"
|
||||
case http.StatusNotFound:
|
||||
reason = unversioned.StatusReasonNotFound
|
||||
message = "the server could not find the requested resource"
|
||||
case http.StatusBadRequest:
|
||||
reason = unversioned.StatusReasonBadRequest
|
||||
message = "the server rejected our request for an unknown reason"
|
||||
case http.StatusUnauthorized:
|
||||
reason = unversioned.StatusReasonUnauthorized
|
||||
message = "the server has asked for the client to provide credentials"
|
||||
case http.StatusForbidden:
|
||||
reason = unversioned.StatusReasonForbidden
|
||||
message = "the server does not allow access to the requested resource"
|
||||
case http.StatusMethodNotAllowed:
|
||||
reason = unversioned.StatusReasonMethodNotAllowed
|
||||
message = "the server does not allow this method on the requested resource"
|
||||
case StatusUnprocessableEntity:
|
||||
reason = unversioned.StatusReasonInvalid
|
||||
message = "the server rejected our request due to an error in our request"
|
||||
case StatusServerTimeout:
|
||||
reason = unversioned.StatusReasonServerTimeout
|
||||
message = "the server cannot complete the requested operation at this time, try again later"
|
||||
case StatusTooManyRequests:
|
||||
reason = unversioned.StatusReasonTimeout
|
||||
message = "the server has received too many requests and has asked us to try again later"
|
||||
default:
|
||||
if code >= 500 {
|
||||
reason = unversioned.StatusReasonInternalError
|
||||
message = fmt.Sprintf("an error on the server (%q) has prevented the request from succeeding", serverMessage)
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case !qualifiedResource.Empty() && len(name) > 0:
|
||||
message = fmt.Sprintf("%s (%s %s %s)", message, strings.ToLower(verb), qualifiedResource.String(), name)
|
||||
case !qualifiedResource.Empty():
|
||||
message = fmt.Sprintf("%s (%s %s)", message, strings.ToLower(verb), qualifiedResource.String())
|
||||
}
|
||||
var causes []unversioned.StatusCause
|
||||
if isUnexpectedResponse {
|
||||
causes = []unversioned.StatusCause{
|
||||
{
|
||||
Type: unversioned.CauseTypeUnexpectedServerResponse,
|
||||
Message: serverMessage,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
causes = nil
|
||||
}
|
||||
return &StatusError{unversioned.Status{
|
||||
Status: unversioned.StatusFailure,
|
||||
Code: int32(code),
|
||||
Reason: reason,
|
||||
Details: &unversioned.StatusDetails{
|
||||
Group: qualifiedResource.Group,
|
||||
Kind: qualifiedResource.Resource,
|
||||
Name: name,
|
||||
|
||||
Causes: causes,
|
||||
RetryAfterSeconds: int32(retryAfterSeconds),
|
||||
},
|
||||
Message: message,
|
||||
}}
|
||||
}
|
||||
|
||||
// IsNotFound returns true if the specified error was created by NewNotFound.
|
||||
func IsNotFound(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonNotFound
|
||||
}
|
||||
|
||||
// IsAlreadyExists determines if the err is an error which indicates that a specified resource already exists.
|
||||
func IsAlreadyExists(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonAlreadyExists
|
||||
}
|
||||
|
||||
// IsConflict determines if the err is an error which indicates the provided update conflicts.
|
||||
func IsConflict(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonConflict
|
||||
}
|
||||
|
||||
// IsInvalid determines if the err is an error which indicates the provided resource is not valid.
|
||||
func IsInvalid(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonInvalid
|
||||
}
|
||||
|
||||
// IsMethodNotSupported determines if the err is an error which indicates the provided action could not
|
||||
// be performed because it is not supported by the server.
|
||||
func IsMethodNotSupported(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonMethodNotAllowed
|
||||
}
|
||||
|
||||
// IsBadRequest determines if err is an error which indicates that the request is invalid.
|
||||
func IsBadRequest(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonBadRequest
|
||||
}
|
||||
|
||||
// IsUnauthorized determines if err is an error which indicates that the request is unauthorized and
|
||||
// requires authentication by the user.
|
||||
func IsUnauthorized(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonUnauthorized
|
||||
}
|
||||
|
||||
// IsForbidden determines if err is an error which indicates that the request is forbidden and cannot
|
||||
// be completed as requested.
|
||||
func IsForbidden(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonForbidden
|
||||
}
|
||||
|
||||
// IsServerTimeout determines if err is an error which indicates that the request needs to be retried
|
||||
// by the client.
|
||||
func IsServerTimeout(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonServerTimeout
|
||||
}
|
||||
|
||||
// IsInternalError determines if err is an error which indicates an internal server error.
|
||||
func IsInternalError(err error) bool {
|
||||
return reasonForError(err) == unversioned.StatusReasonInternalError
|
||||
}
|
||||
|
||||
// IsUnexpectedServerError returns true if the server response was not in the expected API format,
|
||||
// and may be the result of another HTTP actor.
|
||||
func IsUnexpectedServerError(err error) bool {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
if d := t.Status().Details; d != nil {
|
||||
for _, cause := range d.Causes {
|
||||
if cause.Type == unversioned.CauseTypeUnexpectedServerResponse {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsUnexpectedObjectError determines if err is due to an unexpected object from the master.
|
||||
func IsUnexpectedObjectError(err error) bool {
|
||||
_, ok := err.(*UnexpectedObjectError)
|
||||
return err != nil && ok
|
||||
}
|
||||
|
||||
// SuggestsClientDelay returns true if this error suggests a client delay as well as the
|
||||
// suggested seconds to wait, or false if the error does not imply a wait.
|
||||
func SuggestsClientDelay(err error) (int, bool) {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
if t.Status().Details != nil {
|
||||
switch t.Status().Reason {
|
||||
case unversioned.StatusReasonServerTimeout, unversioned.StatusReasonTimeout:
|
||||
return int(t.Status().Details.RetryAfterSeconds), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func reasonForError(err error) unversioned.StatusReason {
|
||||
switch t := err.(type) {
|
||||
case APIStatus:
|
||||
return t.Status().Reason
|
||||
}
|
||||
return unversioned.StatusReasonUnknown
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package install installs the v1 monolithic api, making it available as an
|
||||
// option to all of the API encoding/decoding machinery.
|
||||
package install
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
const importPrefix = "k8s.io/client-go/1.5/pkg/api"
|
||||
|
||||
var accessor = meta.NewAccessor()
|
||||
|
||||
// availableVersions lists all known external versions for this group from most preferred to least preferred
|
||||
var availableVersions = []unversioned.GroupVersion{v1.SchemeGroupVersion}
|
||||
|
||||
func init() {
|
||||
registered.RegisterVersions(availableVersions)
|
||||
externalVersions := []unversioned.GroupVersion{}
|
||||
for _, v := range availableVersions {
|
||||
if registered.IsAllowedVersion(v) {
|
||||
externalVersions = append(externalVersions, v)
|
||||
}
|
||||
}
|
||||
if len(externalVersions) == 0 {
|
||||
glog.V(4).Infof("No version is registered for group %v", api.GroupName)
|
||||
return
|
||||
}
|
||||
|
||||
if err := registered.EnableVersions(externalVersions...); err != nil {
|
||||
glog.V(4).Infof("%v", err)
|
||||
return
|
||||
}
|
||||
if err := enableVersions(externalVersions); err != nil {
|
||||
glog.V(4).Infof("%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: enableVersions should be centralized rather than spread in each API
|
||||
// group.
|
||||
// We can combine registered.RegisterVersions, registered.EnableVersions and
|
||||
// registered.RegisterGroup once we have moved enableVersions there.
|
||||
func enableVersions(externalVersions []unversioned.GroupVersion) error {
|
||||
addVersionsToScheme(externalVersions...)
|
||||
preferredExternalVersion := externalVersions[0]
|
||||
|
||||
groupMeta := apimachinery.GroupMeta{
|
||||
GroupVersion: preferredExternalVersion,
|
||||
GroupVersions: externalVersions,
|
||||
RESTMapper: newRESTMapper(externalVersions),
|
||||
SelfLinker: runtime.SelfLinker(accessor),
|
||||
InterfacesFor: interfacesFor,
|
||||
}
|
||||
|
||||
if err := registered.RegisterGroup(groupMeta); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper {
|
||||
// the list of kinds that are scoped at the root of the api hierarchy
|
||||
// if a kind is not enumerated here, it is assumed to have a namespace scope
|
||||
rootScoped := sets.NewString(
|
||||
"Node",
|
||||
"Namespace",
|
||||
"PersistentVolume",
|
||||
"ComponentStatus",
|
||||
)
|
||||
|
||||
// these kinds should be excluded from the list of resources
|
||||
ignoredKinds := sets.NewString(
|
||||
"ListOptions",
|
||||
"DeleteOptions",
|
||||
"Status",
|
||||
"PodLogOptions",
|
||||
"PodExecOptions",
|
||||
"PodAttachOptions",
|
||||
"PodProxyOptions",
|
||||
"NodeProxyOptions",
|
||||
"ServiceProxyOptions",
|
||||
"ThirdPartyResource",
|
||||
"ThirdPartyResourceData",
|
||||
"ThirdPartyResourceList")
|
||||
|
||||
mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped)
|
||||
|
||||
return mapper
|
||||
}
|
||||
|
||||
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
// string, or an error if the version is not known.
|
||||
func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
switch version {
|
||||
case v1.SchemeGroupVersion:
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: api.Scheme,
|
||||
MetadataAccessor: accessor,
|
||||
}, nil
|
||||
default:
|
||||
g, _ := registered.Group(api.GroupName)
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, g.GroupVersions)
|
||||
}
|
||||
}
|
||||
|
||||
func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) {
|
||||
// add the internal version to Scheme
|
||||
if err := api.AddToScheme(api.Scheme); err != nil {
|
||||
// Programmer error, detect immediately
|
||||
panic(err)
|
||||
}
|
||||
// add the enabled external versions to Scheme
|
||||
for _, v := range externalVersions {
|
||||
if !registered.IsEnabledVersion(v) {
|
||||
glog.Errorf("Version %s is not enabled, so it will not be added to the Scheme.", v)
|
||||
continue
|
||||
}
|
||||
switch v {
|
||||
case v1.SchemeGroupVersion:
|
||||
if err := v1.AddToScheme(api.Scheme); err != nil {
|
||||
// Programmer error, detect immediately
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
// Instantiates a DefaultRESTMapper based on types registered in api.Scheme
|
||||
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
||||
importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper {
|
||||
return NewDefaultRESTMapperFromScheme(defaultGroupVersions, interfacesFunc, importPathPrefix, ignoredKinds, rootScoped, Scheme)
|
||||
}
|
||||
|
||||
// Instantiates a DefaultRESTMapper based on types registered in the given scheme.
|
||||
func NewDefaultRESTMapperFromScheme(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc,
|
||||
importPathPrefix string, ignoredKinds, rootScoped sets.String, scheme *runtime.Scheme) *meta.DefaultRESTMapper {
|
||||
|
||||
mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc)
|
||||
// enumerate all supported versions, get the kinds, and register with the mapper how to address
|
||||
// our resources.
|
||||
for _, gv := range defaultGroupVersions {
|
||||
for kind, oType := range scheme.KnownTypes(gv) {
|
||||
gvk := gv.WithKind(kind)
|
||||
// TODO: Remove import path check.
|
||||
// We check the import path because we currently stuff both "api" and "extensions" objects
|
||||
// into the same group within Scheme since Scheme has no notion of groups yet.
|
||||
if !strings.Contains(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) {
|
||||
continue
|
||||
}
|
||||
scope := meta.RESTScopeNamespace
|
||||
if rootScoped.Has(kind) {
|
||||
scope = meta.RESTScopeRoot
|
||||
}
|
||||
mapper.Add(gvk, scope)
|
||||
}
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/conversion"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/types"
|
||||
"k8s.io/client-go/1.5/pkg/util/uuid"
|
||||
)
|
||||
|
||||
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
|
||||
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
|
||||
meta.CreationTimestamp = unversioned.Now()
|
||||
// allows admission controllers to assign a UID earlier in the request processing
|
||||
// to support tracking resources pending creation.
|
||||
uid, found := UIDFrom(ctx)
|
||||
if !found {
|
||||
uid = uuid.NewUUID()
|
||||
}
|
||||
meta.UID = uid
|
||||
meta.SelfLink = ""
|
||||
}
|
||||
|
||||
// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
|
||||
func HasObjectMetaSystemFieldValues(meta *ObjectMeta) bool {
|
||||
return !meta.CreationTimestamp.Time.IsZero() ||
|
||||
len(meta.UID) != 0
|
||||
}
|
||||
|
||||
// ObjectMetaFor returns a pointer to a provided object's ObjectMeta.
|
||||
// TODO: allow runtime.Unknown to extract this object
|
||||
// TODO: Remove this function and use meta.Accessor() instead.
|
||||
func ObjectMetaFor(obj runtime.Object) (*ObjectMeta, error) {
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var meta *ObjectMeta
|
||||
err = runtime.FieldPtr(v, "ObjectMeta", &meta)
|
||||
return meta, err
|
||||
}
|
||||
|
||||
// ListMetaFor returns a pointer to a provided object's ListMeta,
|
||||
// or an error if the object does not have that pointer.
|
||||
// TODO: allow runtime.Unknown to extract this object
|
||||
func ListMetaFor(obj runtime.Object) (*unversioned.ListMeta, error) {
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var meta *unversioned.ListMeta
|
||||
err = runtime.FieldPtr(v, "ListMeta", &meta)
|
||||
return meta, err
|
||||
}
|
||||
|
||||
func (obj *ObjectMeta) GetObjectMeta() meta.Object { return obj }
|
||||
|
||||
// Namespace implements meta.Object for any object with an ObjectMeta typed field. Allows
|
||||
// fast, direct access to metadata fields for API objects.
|
||||
func (meta *ObjectMeta) GetNamespace() string { return meta.Namespace }
|
||||
func (meta *ObjectMeta) SetNamespace(namespace string) { meta.Namespace = namespace }
|
||||
func (meta *ObjectMeta) GetName() string { return meta.Name }
|
||||
func (meta *ObjectMeta) SetName(name string) { meta.Name = name }
|
||||
func (meta *ObjectMeta) GetGenerateName() string { return meta.GenerateName }
|
||||
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
|
||||
func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
|
||||
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
|
||||
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
|
||||
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
|
||||
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
|
||||
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
|
||||
func (meta *ObjectMeta) GetCreationTimestamp() unversioned.Time { return meta.CreationTimestamp }
|
||||
func (meta *ObjectMeta) SetCreationTimestamp(creationTimestamp unversioned.Time) {
|
||||
meta.CreationTimestamp = creationTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetDeletionTimestamp() *unversioned.Time { return meta.DeletionTimestamp }
|
||||
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *unversioned.Time) {
|
||||
meta.DeletionTimestamp = deletionTimestamp
|
||||
}
|
||||
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
|
||||
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
|
||||
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
|
||||
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }
|
||||
func (meta *ObjectMeta) GetFinalizers() []string { return meta.Finalizers }
|
||||
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
|
||||
|
||||
func (meta *ObjectMeta) GetOwnerReferences() []metatypes.OwnerReference {
|
||||
ret := make([]metatypes.OwnerReference, len(meta.OwnerReferences))
|
||||
for i := 0; i < len(meta.OwnerReferences); i++ {
|
||||
ret[i].Kind = meta.OwnerReferences[i].Kind
|
||||
ret[i].Name = meta.OwnerReferences[i].Name
|
||||
ret[i].UID = meta.OwnerReferences[i].UID
|
||||
ret[i].APIVersion = meta.OwnerReferences[i].APIVersion
|
||||
if meta.OwnerReferences[i].Controller != nil {
|
||||
value := *meta.OwnerReferences[i].Controller
|
||||
ret[i].Controller = &value
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference) {
|
||||
newReferences := make([]OwnerReference, len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
newReferences[i].Kind = references[i].Kind
|
||||
newReferences[i].Name = references[i].Name
|
||||
newReferences[i].UID = references[i].UID
|
||||
newReferences[i].APIVersion = references[i].APIVersion
|
||||
if references[i].Controller != nil {
|
||||
value := *references[i].Controller
|
||||
newReferences[i].Controller = &value
|
||||
}
|
||||
}
|
||||
meta.OwnerReferences = newReferences
|
||||
}
|
||||
|
||||
func (meta *ObjectMeta) GetClusterName() string {
|
||||
return meta.ClusterName
|
||||
}
|
||||
func (meta *ObjectMeta) SetClusterName(clusterName string) {
|
||||
meta.ClusterName = clusterName
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package meta provides functions for retrieving API metadata from objects
|
||||
// belonging to the Kubernetes API
|
||||
package meta
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource
|
||||
type AmbiguousResourceError struct {
|
||||
PartialResource unversioned.GroupVersionResource
|
||||
|
||||
MatchingResources []unversioned.GroupVersionResource
|
||||
MatchingKinds []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousResourceError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialResource, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialResource, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialResource, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialResource)
|
||||
}
|
||||
|
||||
// AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind
|
||||
type AmbiguousKindError struct {
|
||||
PartialKind unversioned.GroupVersionKind
|
||||
|
||||
MatchingResources []unversioned.GroupVersionResource
|
||||
MatchingKinds []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousKindError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialKind, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialKind, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialKind, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialKind)
|
||||
}
|
||||
|
||||
func IsAmbiguousError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *AmbiguousResourceError, *AmbiguousKindError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// NoResourceMatchError is returned if the RESTMapper can't find any match for a resource
|
||||
type NoResourceMatchError struct {
|
||||
PartialResource unversioned.GroupVersionResource
|
||||
}
|
||||
|
||||
func (e *NoResourceMatchError) Error() string {
|
||||
return fmt.Sprintf("no matches for %v", e.PartialResource)
|
||||
}
|
||||
|
||||
// NoKindMatchError is returned if the RESTMapper can't find any match for a kind
|
||||
type NoKindMatchError struct {
|
||||
PartialKind unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *NoKindMatchError) Error() string {
|
||||
return fmt.Sprintf("no matches for %v", e.PartialKind)
|
||||
}
|
||||
|
||||
func IsNoMatchError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *NoResourceMatchError, *NoKindMatchError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
|
||||
)
|
||||
|
||||
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
||||
// first successful result for the singular requests
|
||||
type FirstHitRESTMapper struct {
|
||||
MultiRESTMapper
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) String() string {
|
||||
return fmt.Sprintf("FirstHitRESTMapper{\n\t%v\n}", m.MultiRESTMapper)
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.ResourceFor(resource)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.KindFor(resource)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
// RESTMapping provides the REST mapping for the resource based on the
|
||||
// kind and version. This implementation supports multiple REST schemas and
|
||||
// return the first match.
|
||||
func (m FirstHitRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.RESTMapping(gk, versions...)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return nil, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
// collapseAggregateErrors returns the minimal errors. it handles empty as nil, handles one item in a list
|
||||
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
|
||||
func collapseAggregateErrors(errors []error) error {
|
||||
if len(errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(errors) == 1 {
|
||||
return errors[0]
|
||||
}
|
||||
|
||||
allNoMatchErrors := true
|
||||
for _, err := range errors {
|
||||
allNoMatchErrors = allNoMatchErrors && IsNoMatchError(err)
|
||||
}
|
||||
if allNoMatchErrors {
|
||||
return errors[0]
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errors)
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/conversion"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
)
|
||||
|
||||
// IsListType returns true if the provided Object has a slice called Items
|
||||
func IsListType(obj runtime.Object) bool {
|
||||
_, err := GetItemsPtr(obj)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// GetItemsPtr returns a pointer to the list object's Items member.
|
||||
// If 'list' doesn't have an Items member, it's not really a list type
|
||||
// and an error will be returned.
|
||||
// This function will either return a pointer to a slice, or an error, but not both.
|
||||
func GetItemsPtr(list runtime.Object) (interface{}, error) {
|
||||
v, err := conversion.EnforcePtr(list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := v.FieldByName("Items")
|
||||
if !items.IsValid() {
|
||||
return nil, fmt.Errorf("no Items field in %#v", list)
|
||||
}
|
||||
switch items.Kind() {
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
target := reflect.TypeOf(items.Interface()).Elem()
|
||||
if target.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", target.Kind())
|
||||
}
|
||||
return items.Interface(), nil
|
||||
case reflect.Slice:
|
||||
return items.Addr().Interface(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", items.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractList returns obj's Items element as an array of runtime.Objects.
|
||||
// Returns an error if obj is not a List type (does not have an Items member).
|
||||
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
|
||||
itemsPtr, err := GetItemsPtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := make([]runtime.Object, items.Len())
|
||||
for i := range list {
|
||||
raw := items.Index(i)
|
||||
switch item := raw.Interface().(type) {
|
||||
case runtime.RawExtension:
|
||||
switch {
|
||||
case item.Object != nil:
|
||||
list[i] = item.Object
|
||||
case item.Raw != nil:
|
||||
// TODO: Set ContentEncoding and ContentType correctly.
|
||||
list[i] = &runtime.Unknown{Raw: item.Raw}
|
||||
default:
|
||||
list[i] = nil
|
||||
}
|
||||
case runtime.Object:
|
||||
list[i] = item
|
||||
default:
|
||||
var found bool
|
||||
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {
|
||||
return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// objectSliceType is the type of a slice of Objects
|
||||
var objectSliceType = reflect.TypeOf([]runtime.Object{})
|
||||
|
||||
// SetList sets the given list object's Items member have the elements given in
|
||||
// objects.
|
||||
// Returns an error if list is not a List type (does not have an Items member),
|
||||
// or if any of the objects are not of the right type.
|
||||
func SetList(list runtime.Object, objects []runtime.Object) error {
|
||||
itemsPtr, err := GetItemsPtr(list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if items.Type() == objectSliceType {
|
||||
items.Set(reflect.ValueOf(objects))
|
||||
return nil
|
||||
}
|
||||
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
|
||||
for i := range objects {
|
||||
dest := slice.Index(i)
|
||||
src, err := conversion.EnforcePtr(objects[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if src.Type().AssignableTo(dest.Type()) {
|
||||
dest.Set(src)
|
||||
} else if src.Type().ConvertibleTo(dest.Type()) {
|
||||
dest.Set(src.Convert(dest.Type()))
|
||||
} else {
|
||||
return fmt.Errorf("item[%d]: can't assign or convert %v into %v", i, src.Type(), dest.Type())
|
||||
}
|
||||
}
|
||||
items.Set(slice)
|
||||
return nil
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/types"
|
||||
)
|
||||
|
||||
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
||||
type VersionInterfaces struct {
|
||||
runtime.ObjectConvertor
|
||||
MetadataAccessor
|
||||
}
|
||||
|
||||
type ObjectMetaAccessor interface {
|
||||
GetObjectMeta() Object
|
||||
}
|
||||
|
||||
// Object lets you work with object metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
||||
// a default value.
|
||||
type Object interface {
|
||||
GetNamespace() string
|
||||
SetNamespace(namespace string)
|
||||
GetName() string
|
||||
SetName(name string)
|
||||
GetGenerateName() string
|
||||
SetGenerateName(name string)
|
||||
GetUID() types.UID
|
||||
SetUID(uid types.UID)
|
||||
GetResourceVersion() string
|
||||
SetResourceVersion(version string)
|
||||
GetSelfLink() string
|
||||
SetSelfLink(selfLink string)
|
||||
GetCreationTimestamp() unversioned.Time
|
||||
SetCreationTimestamp(timestamp unversioned.Time)
|
||||
GetDeletionTimestamp() *unversioned.Time
|
||||
SetDeletionTimestamp(timestamp *unversioned.Time)
|
||||
GetLabels() map[string]string
|
||||
SetLabels(labels map[string]string)
|
||||
GetAnnotations() map[string]string
|
||||
SetAnnotations(annotations map[string]string)
|
||||
GetFinalizers() []string
|
||||
SetFinalizers(finalizers []string)
|
||||
GetOwnerReferences() []metatypes.OwnerReference
|
||||
SetOwnerReferences([]metatypes.OwnerReference)
|
||||
GetClusterName() string
|
||||
SetClusterName(clusterName string)
|
||||
}
|
||||
|
||||
var _ Object = &runtime.Unstructured{}
|
||||
|
||||
type ListMetaAccessor interface {
|
||||
GetListMeta() List
|
||||
}
|
||||
|
||||
// List lets you work with list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field will be a no-op and return a default value.
|
||||
type List unversioned.List
|
||||
|
||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||
type Type unversioned.Type
|
||||
|
||||
// MetadataAccessor lets you work with object and list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
||||
// a default value.
|
||||
//
|
||||
// MetadataAccessor exposes Interface in a way that can be used with multiple objects.
|
||||
type MetadataAccessor interface {
|
||||
APIVersion(obj runtime.Object) (string, error)
|
||||
SetAPIVersion(obj runtime.Object, version string) error
|
||||
|
||||
Kind(obj runtime.Object) (string, error)
|
||||
SetKind(obj runtime.Object, kind string) error
|
||||
|
||||
Namespace(obj runtime.Object) (string, error)
|
||||
SetNamespace(obj runtime.Object, namespace string) error
|
||||
|
||||
Name(obj runtime.Object) (string, error)
|
||||
SetName(obj runtime.Object, name string) error
|
||||
|
||||
GenerateName(obj runtime.Object) (string, error)
|
||||
SetGenerateName(obj runtime.Object, name string) error
|
||||
|
||||
UID(obj runtime.Object) (types.UID, error)
|
||||
SetUID(obj runtime.Object, uid types.UID) error
|
||||
|
||||
SelfLink(obj runtime.Object) (string, error)
|
||||
SetSelfLink(obj runtime.Object, selfLink string) error
|
||||
|
||||
Labels(obj runtime.Object) (map[string]string, error)
|
||||
SetLabels(obj runtime.Object, labels map[string]string) error
|
||||
|
||||
Annotations(obj runtime.Object) (map[string]string, error)
|
||||
SetAnnotations(obj runtime.Object, annotations map[string]string) error
|
||||
|
||||
runtime.ResourceVersioner
|
||||
}
|
||||
|
||||
type RESTScopeName string
|
||||
|
||||
const (
|
||||
RESTScopeNameNamespace RESTScopeName = "namespace"
|
||||
RESTScopeNameRoot RESTScopeName = "root"
|
||||
)
|
||||
|
||||
// RESTScope contains the information needed to deal with REST resources that are in a resource hierarchy
|
||||
type RESTScope interface {
|
||||
// Name of the scope
|
||||
Name() RESTScopeName
|
||||
// ParamName is the optional name of the parameter that should be inserted in the resource url
|
||||
// If empty, no param will be inserted
|
||||
ParamName() string
|
||||
// ArgumentName is the optional name that should be used for the variable holding the value.
|
||||
ArgumentName() string
|
||||
// ParamDescription is the optional description to use to document the parameter in api documentation
|
||||
ParamDescription() string
|
||||
}
|
||||
|
||||
// RESTMapping contains the information needed to deal with objects of a specific
|
||||
// resource and kind in a RESTful manner.
|
||||
type RESTMapping struct {
|
||||
// Resource is a string representing the name of this resource as a REST client would see it
|
||||
Resource string
|
||||
|
||||
GroupVersionKind unversioned.GroupVersionKind
|
||||
|
||||
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||
Scope RESTScope
|
||||
|
||||
runtime.ObjectConvertor
|
||||
MetadataAccessor
|
||||
}
|
||||
|
||||
// RESTMapper allows clients to map resources to kind, and map kind and version
|
||||
// to interfaces for manipulating those objects. It is primarily intended for
|
||||
// consumers of Kubernetes compatible REST APIs as defined in docs/devel/api-conventions.md.
|
||||
//
|
||||
// The Kubernetes API provides versioned resources and object kinds which are scoped
|
||||
// to API groups. In other words, kinds and resources should not be assumed to be
|
||||
// unique across groups.
|
||||
//
|
||||
// TODO: split into sub-interfaces
|
||||
type RESTMapper interface {
|
||||
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error)
|
||||
|
||||
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
|
||||
KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error)
|
||||
|
||||
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
ResourceFor(input unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error)
|
||||
|
||||
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
|
||||
ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error)
|
||||
|
||||
// RESTMapping identifies a preferred resource mapping for the provided group kind.
|
||||
RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error)
|
||||
// RESTMappings returns all resource mappings for the provided group kind.
|
||||
RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error)
|
||||
|
||||
AliasesForResource(resource string) ([]string, bool)
|
||||
ResourceSingularizer(resource string) (singular string, err error)
|
||||
}
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/meta/metatypes"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/conversion"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/types"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// errNotList is returned when an object implements the Object style interfaces but not the List style
|
||||
// interfaces.
|
||||
var errNotList = fmt.Errorf("object does not implement the List interfaces")
|
||||
|
||||
// ListAccessor returns a List interface for the provided object or an error if the object does
|
||||
// not provide List.
|
||||
// IMPORTANT: Objects are a superset of lists, so all Objects return List metadata. Do not use this
|
||||
// check to determine whether an object *is* a List.
|
||||
// TODO: return bool instead of error
|
||||
func ListAccessor(obj interface{}) (List, error) {
|
||||
switch t := obj.(type) {
|
||||
case List:
|
||||
return t, nil
|
||||
case unversioned.List:
|
||||
return t, nil
|
||||
case ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
case unversioned.ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
case Object:
|
||||
return t, nil
|
||||
case ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
default:
|
||||
return nil, errNotList
|
||||
}
|
||||
}
|
||||
|
||||
// errNotObject is returned when an object implements the List style interfaces but not the Object style
|
||||
// interfaces.
|
||||
var errNotObject = fmt.Errorf("object does not implement the Object interfaces")
|
||||
|
||||
// Accessor takes an arbitrary object pointer and returns meta.Interface.
|
||||
// obj must be a pointer to an API type. An error is returned if the minimum
|
||||
// required fields are missing. Fields that are not required return the default
|
||||
// value and are a no-op if set.
|
||||
// TODO: return bool instead of error
|
||||
func Accessor(obj interface{}) (Object, error) {
|
||||
switch t := obj.(type) {
|
||||
case Object:
|
||||
return t, nil
|
||||
case ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotObject
|
||||
case List, unversioned.List, ListMetaAccessor, unversioned.ListMetaAccessor:
|
||||
return nil, errNotObject
|
||||
default:
|
||||
return nil, errNotObject
|
||||
}
|
||||
}
|
||||
|
||||
// TypeAccessor returns an interface that allows retrieving and modifying the APIVersion
|
||||
// and Kind of an in-memory internal object.
|
||||
// TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
|
||||
// in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
|
||||
// api conventions).
|
||||
func TypeAccessor(obj interface{}) (Type, error) {
|
||||
if typed, ok := obj.(runtime.Object); ok {
|
||||
return objectAccessor{typed}, nil
|
||||
}
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := v.Type()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface())
|
||||
}
|
||||
|
||||
typeMeta := v.FieldByName("TypeMeta")
|
||||
if !typeMeta.IsValid() {
|
||||
return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t)
|
||||
}
|
||||
a := &genericAccessor{}
|
||||
if err := extractFromTypeMeta(typeMeta, a); err != nil {
|
||||
return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err)
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
type objectAccessor struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetKind() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().Kind
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetKind(kind string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gvk.Kind = kind
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetAPIVersion() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().GroupVersion().String()
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetAPIVersion(version string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
gv = unversioned.GroupVersion{Version: version}
|
||||
}
|
||||
gvk.Group, gvk.Version = gv.Group, gv.Version
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
// NewAccessor returns a MetadataAccessor that can retrieve
|
||||
// or manipulate resource version on objects derived from core API
|
||||
// metadata concepts.
|
||||
func NewAccessor() MetadataAccessor {
|
||||
return resourceAccessor{}
|
||||
}
|
||||
|
||||
// resourceAccessor implements ResourceVersioner and SelfLinker.
|
||||
type resourceAccessor struct{}
|
||||
|
||||
func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetKind(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
|
||||
objectAccessor{obj}.SetKind(kind)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetAPIVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
|
||||
objectAccessor{obj}.SetAPIVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetNamespace(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetNamespace(namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Name(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetGenerateName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetGenerateName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetUID(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetUID(uid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetSelfLink(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetSelfLink(selfLink)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetLabels(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetLabels(labels)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetAnnotations(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetAnnotations(annotations)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetResourceVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetResourceVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object.
|
||||
func extractFromOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error {
|
||||
if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Kind", &o.Kind); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Name", &o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "UID", &o.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
var controllerPtr *bool
|
||||
if err := runtime.Field(v, "Controller", &controllerPtr); err != nil {
|
||||
return err
|
||||
}
|
||||
if controllerPtr != nil {
|
||||
controller := *controllerPtr
|
||||
o.Controller = &controller
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setOwnerReference sets v to o. v is the OwnerReferences field of an object.
|
||||
func setOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error {
|
||||
if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Kind, v, "Kind"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Name, v, "Name"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.UID, v, "UID"); err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Controller != nil {
|
||||
controller := *(o.Controller)
|
||||
if err := runtime.SetField(&controller, v, "Controller"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// genericAccessor contains pointers to strings that can modify an arbitrary
|
||||
// struct and implements the Accessor interface.
|
||||
type genericAccessor struct {
|
||||
namespace *string
|
||||
name *string
|
||||
generateName *string
|
||||
uid *types.UID
|
||||
apiVersion *string
|
||||
kind *string
|
||||
resourceVersion *string
|
||||
selfLink *string
|
||||
creationTimestamp *unversioned.Time
|
||||
deletionTimestamp **unversioned.Time
|
||||
labels *map[string]string
|
||||
annotations *map[string]string
|
||||
ownerReferences reflect.Value
|
||||
finalizers *[]string
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetNamespace() string {
|
||||
if a.namespace == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetNamespace(namespace string) {
|
||||
if a.namespace == nil {
|
||||
return
|
||||
}
|
||||
*a.namespace = namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetName() string {
|
||||
if a.name == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.name
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetName(name string) {
|
||||
if a.name == nil {
|
||||
return
|
||||
}
|
||||
*a.name = name
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetGenerateName() string {
|
||||
if a.generateName == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetGenerateName(generateName string) {
|
||||
if a.generateName == nil {
|
||||
return
|
||||
}
|
||||
*a.generateName = generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetUID() types.UID {
|
||||
if a.uid == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetUID(uid types.UID) {
|
||||
if a.uid == nil {
|
||||
return
|
||||
}
|
||||
*a.uid = uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAPIVersion() string {
|
||||
return *a.apiVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAPIVersion(version string) {
|
||||
*a.apiVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetKind() string {
|
||||
return *a.kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetKind(kind string) {
|
||||
*a.kind = kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetResourceVersion() string {
|
||||
return *a.resourceVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetResourceVersion(version string) {
|
||||
*a.resourceVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetSelfLink() string {
|
||||
return *a.selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetSelfLink(selfLink string) {
|
||||
*a.selfLink = selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetCreationTimestamp() unversioned.Time {
|
||||
return *a.creationTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetCreationTimestamp(timestamp unversioned.Time) {
|
||||
*a.creationTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetDeletionTimestamp() *unversioned.Time {
|
||||
return *a.deletionTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetDeletionTimestamp(timestamp *unversioned.Time) {
|
||||
*a.deletionTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetLabels() map[string]string {
|
||||
if a.labels == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetLabels(labels map[string]string) {
|
||||
*a.labels = labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAnnotations() map[string]string {
|
||||
if a.annotations == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAnnotations(annotations map[string]string) {
|
||||
if a.annotations == nil {
|
||||
emptyAnnotations := make(map[string]string)
|
||||
a.annotations = &emptyAnnotations
|
||||
}
|
||||
*a.annotations = annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetFinalizers() []string {
|
||||
if a.finalizers == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetFinalizers(finalizers []string) {
|
||||
*a.finalizers = finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetOwnerReferences() []metatypes.OwnerReference {
|
||||
var ret []metatypes.OwnerReference
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
return ret
|
||||
}
|
||||
s = s.Elem()
|
||||
// Set the capacity to one element greater to avoid copy if the caller later append an element.
|
||||
ret = make([]metatypes.OwnerReference, s.Len(), s.Len()+1)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
|
||||
glog.Errorf("extractFromOwnerReference failed: %v", err)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetOwnerReferences(references []metatypes.OwnerReference) {
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
}
|
||||
s = s.Elem()
|
||||
newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
|
||||
glog.Errorf("setOwnerReference failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Set(newReferences)
|
||||
}
|
||||
|
||||
// extractFromTypeMeta extracts pointers to version and kind fields from an object
|
||||
func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error {
|
||||
if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// The types defined in this package are used by the meta package to represent
|
||||
// the in-memory version of objects. We cannot reuse the __internal version of
|
||||
// API objects because it causes import cycle.
|
||||
package metatypes
|
||||
|
||||
import "k8s.io/client-go/1.5/pkg/types"
|
||||
|
||||
type OwnerReference struct {
|
||||
APIVersion string
|
||||
Kind string
|
||||
UID types.UID
|
||||
Name string
|
||||
Controller *bool
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
utilerrors "k8s.io/client-go/1.5/pkg/util/errors"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
||||
type MultiRESTMapper []RESTMapper
|
||||
|
||||
func (m MultiRESTMapper) String() string {
|
||||
nested := []string{}
|
||||
for _, t := range m {
|
||||
currString := fmt.Sprintf("%v", t)
|
||||
splitStrings := strings.Split(currString, "\n")
|
||||
nested = append(nested, strings.Join(splitStrings, "\n\t"))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t"))
|
||||
}
|
||||
|
||||
// ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod)
|
||||
// This implementation supports multiple REST schemas and return the first match.
|
||||
func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
for _, t := range m {
|
||||
singular, err = t.ResourceSingularizer(resource)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
allGVRs := []unversioned.GroupVersionResource{}
|
||||
for _, t := range m {
|
||||
gvrs, err := t.ResourcesFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvrs {
|
||||
found := false
|
||||
for _, existing := range allGVRs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVRs = append(allGVRs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVRs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVRs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindsFor(resource unversioned.GroupVersionResource) (gvk []unversioned.GroupVersionKind, err error) {
|
||||
allGVKs := []unversioned.GroupVersionKind{}
|
||||
for _, t := range m {
|
||||
gvks, err := t.KindsFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvks {
|
||||
found := false
|
||||
for _, existing := range allGVKs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVKs = append(allGVKs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVKs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVKs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
// RESTMapping provides the REST mapping for the resource based on the
|
||||
// kind and version. This implementation supports multiple REST schemas and
|
||||
// return the first match.
|
||||
func (m MultiRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
allMappings := []*RESTMapping{}
|
||||
errors := []error{}
|
||||
|
||||
for _, t := range m {
|
||||
currMapping, err := t.RESTMapping(gk, versions...)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
allMappings = append(allMappings, currMapping)
|
||||
}
|
||||
|
||||
// if we got exactly one mapping, then use it even if other requested failed
|
||||
if len(allMappings) == 1 {
|
||||
return allMappings[0], nil
|
||||
}
|
||||
if len(allMappings) > 1 {
|
||||
var kinds []unversioned.GroupVersionKind
|
||||
for _, m := range allMappings {
|
||||
kinds = append(kinds, m.GroupVersionKind)
|
||||
}
|
||||
return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
|
||||
// RESTMappings returns all possible RESTMappings for the provided group kind, or an error
|
||||
// if the type is not recognized.
|
||||
func (m MultiRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
var allMappings []*RESTMapping
|
||||
var errors []error
|
||||
|
||||
for _, t := range m {
|
||||
currMappings, err := t.RESTMappings(gk)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
allMappings = append(allMappings, currMappings...)
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
if len(allMappings) == 0 {
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
return allMappings, nil
|
||||
}
|
||||
|
||||
// AliasesForResource finds the first alias response for the provided mappers.
|
||||
func (m MultiRESTMapper) AliasesForResource(alias string) ([]string, bool) {
|
||||
seenAliases := sets.NewString()
|
||||
allAliases := []string{}
|
||||
handled := false
|
||||
|
||||
for _, t := range m {
|
||||
if currAliases, currOk := t.AliasesForResource(alias); currOk {
|
||||
for _, currAlias := range currAliases {
|
||||
if !seenAliases.Has(currAlias) {
|
||||
allAliases = append(allAliases, currAlias)
|
||||
seenAliases.Insert(currAlias)
|
||||
}
|
||||
}
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
return allAliases, handled
|
||||
}
|
||||
@@ -1,226 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
const (
|
||||
AnyGroup = "*"
|
||||
AnyVersion = "*"
|
||||
AnyResource = "*"
|
||||
AnyKind = "*"
|
||||
)
|
||||
|
||||
// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
|
||||
// when multiple matches are possible
|
||||
type PriorityRESTMapper struct {
|
||||
// Delegate is the RESTMapper to use to locate all the Kind and Resource matches
|
||||
Delegate RESTMapper
|
||||
|
||||
// ResourcePriority is a list of priority patterns to apply to matching resources.
|
||||
// The list of all matching resources is narrowed based on the patterns until only one remains.
|
||||
// A pattern with no matches is skipped. A pattern with more than one match uses its
|
||||
// matches as the list to continue matching against.
|
||||
ResourcePriority []unversioned.GroupVersionResource
|
||||
|
||||
// KindPriority is a list of priority patterns to apply to matching kinds.
|
||||
// The list of all matching kinds is narrowed based on the patterns until only one remains.
|
||||
// A pattern with no matches is skipped. A pattern with more than one match uses its
|
||||
// matches as the list to continue matching against.
|
||||
KindPriority []unversioned.GroupVersionKind
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) String() string {
|
||||
return fmt.Sprintf("PriorityRESTMapper{\n\t%v\n\t%v\n\t%v\n}", m.ResourcePriority, m.KindPriority, m.Delegate)
|
||||
}
|
||||
|
||||
// ResourceFor finds all resources, then passes them through the ResourcePriority patterns to find a single matching hit.
|
||||
func (m PriorityRESTMapper) ResourceFor(partiallySpecifiedResource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
originalGVRs, err := m.Delegate.ResourcesFor(partiallySpecifiedResource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(originalGVRs) == 1 {
|
||||
return originalGVRs[0], nil
|
||||
}
|
||||
|
||||
remainingGVRs := append([]unversioned.GroupVersionResource{}, originalGVRs...)
|
||||
for _, pattern := range m.ResourcePriority {
|
||||
matchedGVRs := []unversioned.GroupVersionResource{}
|
||||
for _, gvr := range remainingGVRs {
|
||||
if resourceMatches(pattern, gvr) {
|
||||
matchedGVRs = append(matchedGVRs, gvr)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matchedGVRs) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matchedGVRs[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remainingGVRs = matchedGVRs
|
||||
}
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingResources: originalGVRs}
|
||||
}
|
||||
|
||||
// KindFor finds all kinds, then passes them through the KindPriority patterns to find a single matching hit.
|
||||
func (m PriorityRESTMapper) KindFor(partiallySpecifiedResource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
originalGVKs, err := m.Delegate.KindsFor(partiallySpecifiedResource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(originalGVKs) == 1 {
|
||||
return originalGVKs[0], nil
|
||||
}
|
||||
|
||||
remainingGVKs := append([]unversioned.GroupVersionKind{}, originalGVKs...)
|
||||
for _, pattern := range m.KindPriority {
|
||||
matchedGVKs := []unversioned.GroupVersionKind{}
|
||||
for _, gvr := range remainingGVKs {
|
||||
if kindMatches(pattern, gvr) {
|
||||
matchedGVKs = append(matchedGVKs, gvr)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matchedGVKs) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matchedGVKs[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remainingGVKs = matchedGVKs
|
||||
}
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingKinds: originalGVKs}
|
||||
}
|
||||
|
||||
func resourceMatches(pattern unversioned.GroupVersionResource, resource unversioned.GroupVersionResource) bool {
|
||||
if pattern.Group != AnyGroup && pattern.Group != resource.Group {
|
||||
return false
|
||||
}
|
||||
if pattern.Version != AnyVersion && pattern.Version != resource.Version {
|
||||
return false
|
||||
}
|
||||
if pattern.Resource != AnyResource && pattern.Resource != resource.Resource {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func kindMatches(pattern unversioned.GroupVersionKind, kind unversioned.GroupVersionKind) bool {
|
||||
if pattern.Group != AnyGroup && pattern.Group != kind.Group {
|
||||
return false
|
||||
}
|
||||
if pattern.Version != AnyVersion && pattern.Version != kind.Version {
|
||||
return false
|
||||
}
|
||||
if pattern.Kind != AnyKind && pattern.Kind != kind.Kind {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (mapping *RESTMapping, err error) {
|
||||
mappings, err := m.Delegate.RESTMappings(gk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// any versions the user provides take priority
|
||||
priorities := m.KindPriority
|
||||
if len(versions) > 0 {
|
||||
priorities = make([]unversioned.GroupVersionKind, 0, len(m.KindPriority)+len(versions))
|
||||
for _, version := range versions {
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priorities = append(priorities, gv.WithKind(AnyKind))
|
||||
}
|
||||
priorities = append(priorities, m.KindPriority...)
|
||||
}
|
||||
|
||||
remaining := append([]*RESTMapping{}, mappings...)
|
||||
for _, pattern := range priorities {
|
||||
var matching []*RESTMapping
|
||||
for _, m := range remaining {
|
||||
if kindMatches(pattern, m.GroupVersionKind) {
|
||||
matching = append(matching, m)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(matching) {
|
||||
case 0:
|
||||
// if you have no matches, then nothing matched this pattern just move to the next
|
||||
continue
|
||||
case 1:
|
||||
// one match, return
|
||||
return matching[0], nil
|
||||
default:
|
||||
// more than one match, use the matched hits as the list moving to the next pattern.
|
||||
// this way you can have a series of selection criteria
|
||||
remaining = matching
|
||||
}
|
||||
}
|
||||
if len(remaining) == 1 {
|
||||
return remaining[0], nil
|
||||
}
|
||||
|
||||
var kinds []unversioned.GroupVersionKind
|
||||
for _, m := range mappings {
|
||||
kinds = append(kinds, m.GroupVersionKind)
|
||||
}
|
||||
return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
return m.Delegate.RESTMappings(gk)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) AliasesForResource(alias string) (aliases []string, ok bool) {
|
||||
return m.Delegate.AliasesForResource(alias)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
return m.Delegate.ResourceSingularizer(resource)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
return m.Delegate.ResourcesFor(partiallySpecifiedResource)
|
||||
}
|
||||
|
||||
func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource unversioned.GroupVersionResource) (gvk []unversioned.GroupVersionKind, err error) {
|
||||
return m.Delegate.KindsFor(partiallySpecifiedResource)
|
||||
}
|
||||
@@ -1,601 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO: move everything in this file to pkg/api/rest
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
)
|
||||
|
||||
// Implements RESTScope interface
|
||||
type restScope struct {
|
||||
name RESTScopeName
|
||||
paramName string
|
||||
argumentName string
|
||||
paramDescription string
|
||||
}
|
||||
|
||||
func (r *restScope) Name() RESTScopeName {
|
||||
return r.name
|
||||
}
|
||||
func (r *restScope) ParamName() string {
|
||||
return r.paramName
|
||||
}
|
||||
func (r *restScope) ArgumentName() string {
|
||||
return r.argumentName
|
||||
}
|
||||
func (r *restScope) ParamDescription() string {
|
||||
return r.paramDescription
|
||||
}
|
||||
|
||||
var RESTScopeNamespace = &restScope{
|
||||
name: RESTScopeNameNamespace,
|
||||
paramName: "namespaces",
|
||||
argumentName: "namespace",
|
||||
paramDescription: "object name and auth scope, such as for teams and projects",
|
||||
}
|
||||
|
||||
var RESTScopeRoot = &restScope{
|
||||
name: RESTScopeNameRoot,
|
||||
}
|
||||
|
||||
// DefaultRESTMapper exposes mappings between the types defined in a
|
||||
// runtime.Scheme. It assumes that all types defined the provided scheme
|
||||
// can be mapped with the provided MetadataAccessor and Codec interfaces.
|
||||
//
|
||||
// The resource name of a Kind is defined as the lowercase,
|
||||
// English-plural version of the Kind string.
|
||||
// When converting from resource to Kind, the singular version of the
|
||||
// resource name is also accepted for convenience.
|
||||
//
|
||||
// TODO: Only accept plural for some operations for increased control?
|
||||
// (`get pod bar` vs `get pods bar`)
|
||||
type DefaultRESTMapper struct {
|
||||
defaultGroupVersions []unversioned.GroupVersion
|
||||
|
||||
resourceToKind map[unversioned.GroupVersionResource]unversioned.GroupVersionKind
|
||||
kindToPluralResource map[unversioned.GroupVersionKind]unversioned.GroupVersionResource
|
||||
kindToScope map[unversioned.GroupVersionKind]RESTScope
|
||||
singularToPlural map[unversioned.GroupVersionResource]unversioned.GroupVersionResource
|
||||
pluralToSingular map[unversioned.GroupVersionResource]unversioned.GroupVersionResource
|
||||
|
||||
interfacesFunc VersionInterfacesFunc
|
||||
|
||||
// aliasToResource is used for mapping aliases to resources
|
||||
aliasToResource map[string][]string
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) String() string {
|
||||
return fmt.Sprintf("DefaultRESTMapper{kindToPluralResource=%v}", m.kindToPluralResource)
|
||||
}
|
||||
|
||||
var _ RESTMapper = &DefaultRESTMapper{}
|
||||
|
||||
// VersionInterfacesFunc returns the appropriate typer, and metadata accessor for a
|
||||
// given api version, or an error if no such api version exists.
|
||||
type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInterfaces, error)
|
||||
|
||||
// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
|
||||
// to a resource name and back based on the objects in a runtime.Scheme
|
||||
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions
|
||||
// to search when an object has no default version (set empty to return an error),
|
||||
// and a function that retrieves the correct metadata for a given version.
|
||||
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper {
|
||||
resourceToKind := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionKind)
|
||||
kindToPluralResource := make(map[unversioned.GroupVersionKind]unversioned.GroupVersionResource)
|
||||
kindToScope := make(map[unversioned.GroupVersionKind]RESTScope)
|
||||
singularToPlural := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionResource)
|
||||
pluralToSingular := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionResource)
|
||||
aliasToResource := make(map[string][]string)
|
||||
// TODO: verify name mappings work correctly when versions differ
|
||||
|
||||
return &DefaultRESTMapper{
|
||||
resourceToKind: resourceToKind,
|
||||
kindToPluralResource: kindToPluralResource,
|
||||
kindToScope: kindToScope,
|
||||
defaultGroupVersions: defaultGroupVersions,
|
||||
singularToPlural: singularToPlural,
|
||||
pluralToSingular: pluralToSingular,
|
||||
aliasToResource: aliasToResource,
|
||||
interfacesFunc: f,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) Add(kind unversioned.GroupVersionKind, scope RESTScope) {
|
||||
plural, singular := KindToResource(kind)
|
||||
|
||||
m.singularToPlural[singular] = plural
|
||||
m.pluralToSingular[plural] = singular
|
||||
|
||||
m.resourceToKind[singular] = kind
|
||||
m.resourceToKind[plural] = kind
|
||||
|
||||
m.kindToPluralResource[kind] = plural
|
||||
m.kindToScope[kind] = scope
|
||||
}
|
||||
|
||||
// unpluralizedSuffixes is a list of resource suffixes that are the same plural and singular
|
||||
// This is only is only necessary because some bits of code are lazy and don't actually use the RESTMapper like they should.
|
||||
// TODO eliminate this so that different callers can correctly map to resources. This probably means updating all
|
||||
// callers to use the RESTMapper they mean.
|
||||
var unpluralizedSuffixes = []string{
|
||||
"endpoints",
|
||||
}
|
||||
|
||||
// KindToResource converts Kind to a resource name.
|
||||
// Broken. This method only "sort of" works when used outside of this package. It assumes that Kinds and Resources match
|
||||
// and they aren't guaranteed to do so.
|
||||
func KindToResource(kind unversioned.GroupVersionKind) ( /*plural*/ unversioned.GroupVersionResource /*singular*/, unversioned.GroupVersionResource) {
|
||||
kindName := kind.Kind
|
||||
if len(kindName) == 0 {
|
||||
return unversioned.GroupVersionResource{}, unversioned.GroupVersionResource{}
|
||||
}
|
||||
singularName := strings.ToLower(kindName)
|
||||
singular := kind.GroupVersion().WithResource(singularName)
|
||||
|
||||
for _, skip := range unpluralizedSuffixes {
|
||||
if strings.HasSuffix(singularName, skip) {
|
||||
return singular, singular
|
||||
}
|
||||
}
|
||||
|
||||
switch string(singularName[len(singularName)-1]) {
|
||||
case "s":
|
||||
return kind.GroupVersion().WithResource(singularName + "es"), singular
|
||||
case "y":
|
||||
return kind.GroupVersion().WithResource(strings.TrimSuffix(singularName, "y") + "ies"), singular
|
||||
}
|
||||
|
||||
return kind.GroupVersion().WithResource(singularName + "s"), singular
|
||||
}
|
||||
|
||||
// ResourceSingularizer implements RESTMapper
|
||||
// It converts a resource name from plural to singular (e.g., from pods to pod)
|
||||
func (m *DefaultRESTMapper) ResourceSingularizer(resourceType string) (string, error) {
|
||||
partialResource := unversioned.GroupVersionResource{Resource: resourceType}
|
||||
resources, err := m.ResourcesFor(partialResource)
|
||||
if err != nil {
|
||||
return resourceType, err
|
||||
}
|
||||
|
||||
singular := unversioned.GroupVersionResource{}
|
||||
for _, curr := range resources {
|
||||
currSingular, ok := m.pluralToSingular[curr]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if singular.Empty() {
|
||||
singular = currSingular
|
||||
continue
|
||||
}
|
||||
|
||||
if currSingular.Resource != singular.Resource {
|
||||
return resourceType, fmt.Errorf("multiple possible singular resources (%v) found for %v", resources, resourceType)
|
||||
}
|
||||
}
|
||||
|
||||
if singular.Empty() {
|
||||
return resourceType, fmt.Errorf("no singular of resource %v has been defined", resourceType)
|
||||
}
|
||||
|
||||
return singular.Resource, nil
|
||||
}
|
||||
|
||||
// coerceResourceForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior)
|
||||
func coerceResourceForMatching(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
|
||||
resource.Resource = strings.ToLower(resource.Resource)
|
||||
if resource.Version == runtime.APIVersionInternal {
|
||||
resource.Version = ""
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourcesFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []unversioned.GroupVersionResource{}
|
||||
switch {
|
||||
case hasGroup && hasVersion:
|
||||
// fully qualified. Find the exact match
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
if plural == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
// given a group, prefer an exact match. If you don't find one, resort to a prefix match on group
|
||||
foundExactMatch := false
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
|
||||
// storageclass.storage.k8s.io
|
||||
if !foundExactMatch {
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if !strings.HasPrefix(plural.Group, requestedGroupResource.Group) {
|
||||
continue
|
||||
}
|
||||
if singular.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Version == resource.Version && singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Version == resource.Version && plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
sort.Sort(resourceByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindsFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []unversioned.GroupVersionKind{}
|
||||
switch {
|
||||
// fully qualified. Find the exact match
|
||||
case hasGroup && hasVersion:
|
||||
kind, exists := m.resourceToKind[resource]
|
||||
if exists {
|
||||
ret = append(ret, kind)
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
foundExactMatch := false
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
|
||||
// storageclass.storage.k8s.io
|
||||
if !foundExactMatch {
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if !strings.HasPrefix(currResource.Group, requestedGroupResource.Group) {
|
||||
continue
|
||||
}
|
||||
if currResource.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Version == resource.Version && currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: input}
|
||||
}
|
||||
|
||||
sort.Sort(kindByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return unversioned.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return unversioned.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
type kindByPreferredGroupVersion struct {
|
||||
list []unversioned.GroupVersionKind
|
||||
sortOrder []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
func (o kindByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o kindByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o kindByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Kind < rhs.Kind
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
type resourceByPreferredGroupVersion struct {
|
||||
list []unversioned.GroupVersionResource
|
||||
sortOrder []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
func (o resourceByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o resourceByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o resourceByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Resource < rhs.Resource
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
// RESTMapping returns a struct representing the resource path and conversion interfaces a
|
||||
// RESTClient should use to operate on the provided group/kind in order of versions. If a version search
|
||||
// order is not provided, the search order provided to DefaultRESTMapper will be used to resolve which
|
||||
// version should be used to access the named group/kind.
|
||||
// TODO: consider refactoring to use RESTMappings in a way that preserves version ordering and preference
|
||||
func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
// Pick an appropriate version
|
||||
var gvk *unversioned.GroupVersionKind
|
||||
hadVersion := false
|
||||
for _, version := range versions {
|
||||
if len(version) == 0 || version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
|
||||
currGVK := gk.WithVersion(version)
|
||||
hadVersion = true
|
||||
if _, ok := m.kindToPluralResource[currGVK]; ok {
|
||||
gvk = &currGVK
|
||||
break
|
||||
}
|
||||
}
|
||||
// Use the default preferred versions
|
||||
if !hadVersion && (gvk == nil) {
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if gv.Group != gk.Group {
|
||||
continue
|
||||
}
|
||||
|
||||
currGVK := gk.WithVersion(gv.Version)
|
||||
if _, ok := m.kindToPluralResource[currGVK]; ok {
|
||||
gvk = &currGVK
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if gvk == nil {
|
||||
return nil, &NoKindMatchError{PartialKind: gk.WithVersion("")}
|
||||
}
|
||||
|
||||
// Ensure we have a REST mapping
|
||||
resource, ok := m.kindToPluralResource[*gvk]
|
||||
if !ok {
|
||||
found := []unversioned.GroupVersion{}
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if _, ok := m.kindToPluralResource[*gvk]; ok {
|
||||
found = append(found, gv)
|
||||
}
|
||||
}
|
||||
if len(found) > 0 {
|
||||
return nil, fmt.Errorf("object with kind %q exists in versions %v, not %v", gvk.Kind, found, gvk.GroupVersion().String())
|
||||
}
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported object", gvk.GroupVersion().String(), gvk.Kind)
|
||||
}
|
||||
|
||||
// Ensure we have a REST scope
|
||||
scope, ok := m.kindToScope[*gvk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion().String(), gvk.Kind)
|
||||
}
|
||||
|
||||
interfaces, err := m.interfacesFunc(gvk.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided version %q has no relevant versions: %v", gvk.GroupVersion().String(), err)
|
||||
}
|
||||
|
||||
retVal := &RESTMapping{
|
||||
Resource: resource.Resource,
|
||||
GroupVersionKind: *gvk,
|
||||
Scope: scope,
|
||||
|
||||
ObjectConvertor: interfaces.ObjectConvertor,
|
||||
MetadataAccessor: interfaces.MetadataAccessor,
|
||||
}
|
||||
|
||||
return retVal, nil
|
||||
}
|
||||
|
||||
// RESTMappings returns the RESTMappings for the provided group kind in a rough internal preferred order. If no
|
||||
// kind is found it will return a NoResourceMatchError.
|
||||
func (m *DefaultRESTMapper) RESTMappings(gk unversioned.GroupKind) ([]*RESTMapping, error) {
|
||||
// Use the default preferred versions
|
||||
var mappings []*RESTMapping
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if gv.Group != gk.Group {
|
||||
continue
|
||||
}
|
||||
|
||||
gvk := gk.WithVersion(gv.Version)
|
||||
gvr, ok := m.kindToPluralResource[gvk]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure we have a REST scope
|
||||
scope, ok := m.kindToScope[gvk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion(), gvk.Kind)
|
||||
}
|
||||
|
||||
interfaces, err := m.interfacesFunc(gvk.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the provided version %q has no relevant versions: %v", gvk.GroupVersion().String(), err)
|
||||
}
|
||||
|
||||
mappings = append(mappings, &RESTMapping{
|
||||
Resource: gvr.Resource,
|
||||
GroupVersionKind: gvk,
|
||||
Scope: scope,
|
||||
|
||||
ObjectConvertor: interfaces.ObjectConvertor,
|
||||
MetadataAccessor: interfaces.MetadataAccessor,
|
||||
})
|
||||
}
|
||||
|
||||
if len(mappings) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: unversioned.GroupVersionResource{Group: gk.Group, Resource: gk.Kind}}
|
||||
}
|
||||
return mappings, nil
|
||||
}
|
||||
|
||||
// AddResourceAlias maps aliases to resources
|
||||
func (m *DefaultRESTMapper) AddResourceAlias(alias string, resources ...string) {
|
||||
if len(resources) == 0 {
|
||||
return
|
||||
}
|
||||
m.aliasToResource[alias] = resources
|
||||
}
|
||||
|
||||
// AliasesForResource returns whether a resource has an alias or not
|
||||
func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) {
|
||||
if res, ok := m.aliasToResource[alias]; ok {
|
||||
return res, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
)
|
||||
|
||||
// InterfacesForUnstructured returns VersionInterfaces suitable for
|
||||
// dealing with runtime.Unstructured objects.
|
||||
func InterfacesForUnstructured(unversioned.GroupVersion) (*VersionInterfaces, error) {
|
||||
return &VersionInterfaces{
|
||||
ObjectConvertor: &runtime.UnstructuredObjectConverter{},
|
||||
MetadataAccessor: NewAccessor(),
|
||||
}, nil
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// RequestContextMapper keeps track of the context associated with a particular request
|
||||
type RequestContextMapper interface {
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
Get(req *http.Request) (Context, bool)
|
||||
// Update maps the request to the given context. If no context was previously associated with the request, an error is returned.
|
||||
// Update should only be called with a descendant context of the previously associated context.
|
||||
// Updating to an unrelated context may return an error in the future.
|
||||
// The context associated with a request should only be updated by a limited set of callers.
|
||||
// Valid examples include the authentication layer, or an audit/tracing layer.
|
||||
Update(req *http.Request, context Context) error
|
||||
}
|
||||
|
||||
type requestContextMap struct {
|
||||
contexts map[*http.Request]Context
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// NewRequestContextMapper returns a new RequestContextMapper.
|
||||
// The returned mapper must be added as a request filter using NewRequestContextFilter.
|
||||
func NewRequestContextMapper() RequestContextMapper {
|
||||
return &requestContextMap{
|
||||
contexts: make(map[*http.Request]Context),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns the context associated with the given request (if any), and true if the request has an associated context, and false if it does not.
|
||||
// Get will only return a valid context when called from inside the filter chain set up by NewRequestContextFilter()
|
||||
func (c *requestContextMap) Get(req *http.Request) (Context, bool) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
context, ok := c.contexts[req]
|
||||
return context, ok
|
||||
}
|
||||
|
||||
// Update maps the request to the given context.
|
||||
// If no context was previously associated with the request, an error is returned and the context is ignored.
|
||||
func (c *requestContextMap) Update(req *http.Request, context Context) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, ok := c.contexts[req]; !ok {
|
||||
return errors.New("No context associated")
|
||||
}
|
||||
// TODO: ensure the new context is a descendant of the existing one
|
||||
c.contexts[req] = context
|
||||
return nil
|
||||
}
|
||||
|
||||
// init maps the request to the given context and returns true if there was no context associated with the request already.
|
||||
// if a context was already associated with the request, it ignores the given context and returns false.
|
||||
// init is intentionally unexported to ensure that all init calls are paired with a remove after a request is handled
|
||||
func (c *requestContextMap) init(req *http.Request, context Context) bool {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if _, exists := c.contexts[req]; exists {
|
||||
return false
|
||||
}
|
||||
c.contexts[req] = context
|
||||
return true
|
||||
}
|
||||
|
||||
// remove is intentionally unexported to ensure that the context is not removed until a request is handled
|
||||
func (c *requestContextMap) remove(req *http.Request) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
delete(c.contexts, req)
|
||||
}
|
||||
|
||||
// WithRequestContext ensures there is a Context object associated with the request before calling the passed handler.
|
||||
// After the passed handler runs, the context is cleaned up.
|
||||
func WithRequestContext(handler http.Handler, mapper RequestContextMapper) http.Handler {
|
||||
rcMap, ok := mapper.(*requestContextMap)
|
||||
if !ok {
|
||||
glog.Fatal("Unknown RequestContextMapper implementation.")
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
if rcMap.init(req, NewContext()) {
|
||||
// If we were the ones to successfully initialize, pair with a remove
|
||||
defer rcMap.remove(req)
|
||||
}
|
||||
handler.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
// IsEmpty returns true if there are no contexts registered, or an error if it could not be determined. Intended for use by tests.
|
||||
func IsEmpty(requestsToContexts RequestContextMapper) (bool, error) {
|
||||
if requestsToContexts, ok := requestsToContexts.(*requestContextMap); ok {
|
||||
return len(requestsToContexts.contexts) == 0, nil
|
||||
}
|
||||
return true, errors.New("Unknown RequestContextMapper implementation")
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
// Scale is used for getting and setting the base-10 scaled value.
|
||||
// Base-2 scales are omitted for mathematical simplicity.
|
||||
// See Quantity.ScaledValue for more details.
|
||||
type Scale int32
|
||||
|
||||
// infScale adapts a Scale value to an inf.Scale value.
|
||||
func (s Scale) infScale() inf.Scale {
|
||||
return inf.Scale(-s) // inf.Scale is upside-down
|
||||
}
|
||||
|
||||
const (
|
||||
Nano Scale = -9
|
||||
Micro Scale = -6
|
||||
Milli Scale = -3
|
||||
Kilo Scale = 3
|
||||
Mega Scale = 6
|
||||
Giga Scale = 9
|
||||
Tera Scale = 12
|
||||
Peta Scale = 15
|
||||
Exa Scale = 18
|
||||
)
|
||||
|
||||
var (
|
||||
Zero = int64Amount{}
|
||||
|
||||
// Used by quantity strings - treat as read only
|
||||
zeroBytes = []byte("0")
|
||||
)
|
||||
|
||||
// int64Amount represents a fixed precision numerator and arbitrary scale exponent. It is faster
|
||||
// than operations on inf.Dec for values that can be represented as int64.
|
||||
// +k8s:openapi-gen=true
|
||||
type int64Amount struct {
|
||||
value int64
|
||||
scale Scale
|
||||
}
|
||||
|
||||
// Sign returns 0 if the value is zero, -1 if it is less than 0, or 1 if it is greater than 0.
|
||||
func (a int64Amount) Sign() int {
|
||||
switch {
|
||||
case a.value == 0:
|
||||
return 0
|
||||
case a.value > 0:
|
||||
return 1
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
// AsInt64 returns the current amount as an int64 at scale 0, or false if the value cannot be
|
||||
// represented in an int64 OR would result in a loss of precision. This method is intended as
|
||||
// an optimization to avoid calling AsDec.
|
||||
func (a int64Amount) AsInt64() (int64, bool) {
|
||||
if a.scale == 0 {
|
||||
return a.value, true
|
||||
}
|
||||
if a.scale < 0 {
|
||||
// TODO: attempt to reduce factors, although it is assumed that factors are reduced prior
|
||||
// to the int64Amount being created.
|
||||
return 0, false
|
||||
}
|
||||
return positiveScaleInt64(a.value, a.scale)
|
||||
}
|
||||
|
||||
// AsScaledInt64 returns an int64 representing the value of this amount at the specified scale,
|
||||
// rounding up, or false if that would result in overflow. (1e20).AsScaledInt64(1) would result
|
||||
// in overflow because 1e19 is not representable as an int64. Note that setting a scale larger
|
||||
// than the current value may result in loss of precision - i.e. (1e-6).AsScaledInt64(0) would
|
||||
// return 1, because 0.000001 is rounded up to 1.
|
||||
func (a int64Amount) AsScaledInt64(scale Scale) (result int64, ok bool) {
|
||||
if a.scale < scale {
|
||||
result, _ = negativeScaleInt64(a.value, scale-a.scale)
|
||||
return result, true
|
||||
}
|
||||
return positiveScaleInt64(a.value, a.scale-scale)
|
||||
}
|
||||
|
||||
// AsDec returns an inf.Dec representation of this value.
|
||||
func (a int64Amount) AsDec() *inf.Dec {
|
||||
var base inf.Dec
|
||||
base.SetUnscaled(a.value)
|
||||
base.SetScale(inf.Scale(-a.scale))
|
||||
return &base
|
||||
}
|
||||
|
||||
// Cmp returns 0 if a and b are equal, 1 if a is greater than b, or -1 if a is less than b.
|
||||
func (a int64Amount) Cmp(b int64Amount) int {
|
||||
switch {
|
||||
case a.scale == b.scale:
|
||||
// compare only the unscaled portion
|
||||
case a.scale > b.scale:
|
||||
result, remainder, exact := divideByScaleInt64(b.value, a.scale-b.scale)
|
||||
if !exact {
|
||||
return a.AsDec().Cmp(b.AsDec())
|
||||
}
|
||||
if result == a.value {
|
||||
switch {
|
||||
case remainder == 0:
|
||||
return 0
|
||||
case remainder > 0:
|
||||
return -1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
b.value = result
|
||||
default:
|
||||
result, remainder, exact := divideByScaleInt64(a.value, b.scale-a.scale)
|
||||
if !exact {
|
||||
return a.AsDec().Cmp(b.AsDec())
|
||||
}
|
||||
if result == b.value {
|
||||
switch {
|
||||
case remainder == 0:
|
||||
return 0
|
||||
case remainder > 0:
|
||||
return 1
|
||||
default:
|
||||
return -1
|
||||
}
|
||||
}
|
||||
a.value = result
|
||||
}
|
||||
|
||||
switch {
|
||||
case a.value == b.value:
|
||||
return 0
|
||||
case a.value < b.value:
|
||||
return -1
|
||||
default:
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
// Add adds two int64Amounts together, matching scales. It will return false and not mutate
|
||||
// a if overflow or underflow would result.
|
||||
func (a *int64Amount) Add(b int64Amount) bool {
|
||||
switch {
|
||||
case b.value == 0:
|
||||
return true
|
||||
case a.value == 0:
|
||||
a.value = b.value
|
||||
a.scale = b.scale
|
||||
return true
|
||||
case a.scale == b.scale:
|
||||
c, ok := int64Add(a.value, b.value)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
case a.scale > b.scale:
|
||||
c, ok := positiveScaleInt64(a.value, a.scale-b.scale)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Add(c, b.value)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.scale = b.scale
|
||||
a.value = c
|
||||
default:
|
||||
c, ok := positiveScaleInt64(b.value, b.scale-a.scale)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
c, ok = int64Add(a.value, c)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
a.value = c
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Sub removes the value of b from the current amount, or returns false if underflow would result.
|
||||
func (a *int64Amount) Sub(b int64Amount) bool {
|
||||
return a.Add(int64Amount{value: -b.value, scale: b.scale})
|
||||
}
|
||||
|
||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||
func (a int64Amount) AsScale(scale Scale) (int64Amount, bool) {
|
||||
if a.scale >= scale {
|
||||
return a, true
|
||||
}
|
||||
result, exact := negativeScaleInt64(a.value, scale-a.scale)
|
||||
return int64Amount{value: result, scale: scale}, exact
|
||||
}
|
||||
|
||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||
func (a int64Amount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
mantissa := a.value
|
||||
exponent = int32(a.scale)
|
||||
|
||||
amount, times := removeInt64Factors(mantissa, 10)
|
||||
exponent += int32(times)
|
||||
|
||||
// make sure exponent is a multiple of 3
|
||||
var ok bool
|
||||
switch exponent % 3 {
|
||||
case 1, -2:
|
||||
amount, ok = int64MultiplyScale10(amount)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||
}
|
||||
exponent = exponent - 1
|
||||
case 2, -1:
|
||||
amount, ok = int64MultiplyScale100(amount)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBytes(out)
|
||||
}
|
||||
exponent = exponent - 2
|
||||
}
|
||||
return strconv.AppendInt(out, amount, 10), exponent
|
||||
}
|
||||
|
||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||
// return []byte("2048"), 1.
|
||||
func (a int64Amount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||
value, ok := a.AsScaledInt64(0)
|
||||
if !ok {
|
||||
return infDecAmount{a.AsDec()}.AsCanonicalBase1024Bytes(out)
|
||||
}
|
||||
amount, exponent := removeInt64Factors(value, 1024)
|
||||
return strconv.AppendInt(out, amount, 10), exponent
|
||||
}
|
||||
|
||||
// infDecAmount implements common operations over an inf.Dec that are specific to the quantity
|
||||
// representation.
|
||||
type infDecAmount struct {
|
||||
*inf.Dec
|
||||
}
|
||||
|
||||
// AsScale adjusts this amount to set a minimum scale, rounding up, and returns true iff no precision
|
||||
// was lost. (1.1e5).AsScale(5) would return 1.1e5, but (1.1e5).AsScale(6) would return 1e6.
|
||||
func (a infDecAmount) AsScale(scale Scale) (infDecAmount, bool) {
|
||||
tmp := &inf.Dec{}
|
||||
tmp.Round(a.Dec, scale.infScale(), inf.RoundUp)
|
||||
return infDecAmount{tmp}, tmp.Cmp(a.Dec) == 0
|
||||
}
|
||||
|
||||
// AsCanonicalBytes accepts a buffer to write the base-10 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. The value is adjusted
|
||||
// until the exponent is a multiple of 3 - i.e. 1.1e5 would return "110", 3.
|
||||
func (a infDecAmount) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
mantissa := a.Dec.UnscaledBig()
|
||||
exponent = int32(-a.Dec.Scale())
|
||||
amount := big.NewInt(0).Set(mantissa)
|
||||
// move all factors of 10 into the exponent for easy reasoning
|
||||
amount, times := removeBigIntFactors(amount, bigTen)
|
||||
exponent += times
|
||||
|
||||
// make sure exponent is a multiple of 3
|
||||
for exponent%3 != 0 {
|
||||
amount.Mul(amount, bigTen)
|
||||
exponent--
|
||||
}
|
||||
|
||||
return append(out, amount.String()...), exponent
|
||||
}
|
||||
|
||||
// AsCanonicalBase1024Bytes accepts a buffer to write the base-1024 string value of this field to, and returns
|
||||
// either that buffer or a larger buffer and the current exponent of the value. 2048 is 2 * 1024 ^ 1 and would
|
||||
// return []byte("2048"), 1.
|
||||
func (a infDecAmount) AsCanonicalBase1024Bytes(out []byte) (result []byte, exponent int32) {
|
||||
tmp := &inf.Dec{}
|
||||
tmp.Round(a.Dec, 0, inf.RoundUp)
|
||||
amount, exponent := removeBigIntFactors(tmp.UnscaledBig(), big1024)
|
||||
return append(out, amount.String()...), exponent
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// source: k8s.io/kubernetes/pkg/api/resource/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package resource is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
k8s.io/kubernetes/pkg/api/resource/generated.proto
|
||||
|
||||
It has these top-level messages:
|
||||
Quantity
|
||||
*/
|
||||
package resource
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
const _ = proto.GoGoProtoPackageIsVersion1
|
||||
|
||||
func (m *Quantity) Reset() { *m = Quantity{} }
|
||||
func (*Quantity) ProtoMessage() {}
|
||||
func (*Quantity) Descriptor() ([]byte, []int) { return fileDescriptorGenerated, []int{0} }
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Quantity)(nil), "k8s.io.client-go.1.5.pkg.api.resource.Quantity")
|
||||
}
|
||||
|
||||
var fileDescriptorGenerated = []byte{
|
||||
// 222 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x32, 0xca, 0xb6, 0x28, 0xd6,
|
||||
0xcb, 0xcc, 0xd7, 0xcf, 0x2e, 0x4d, 0x4a, 0x2d, 0xca, 0x4b, 0x2d, 0x49, 0x2d, 0xd6, 0x2f, 0xc8,
|
||||
0x4e, 0xd7, 0x4f, 0x2c, 0xc8, 0xd4, 0x2f, 0x4a, 0x2d, 0xce, 0x2f, 0x2d, 0x4a, 0x4e, 0xd5, 0x4f,
|
||||
0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52,
|
||||
0x82, 0xe8, 0xd1, 0x43, 0xe8, 0xd1, 0x03, 0xea, 0xd1, 0x03, 0xea, 0xd1, 0x83, 0xe9, 0x91, 0xd2,
|
||||
0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0x4f, 0xcf, 0xd7,
|
||||
0x07, 0x6b, 0x4d, 0x2a, 0x4d, 0x03, 0xf3, 0xc0, 0x1c, 0x30, 0x0b, 0x62, 0xa4, 0x94, 0x21, 0x76,
|
||||
0x67, 0x94, 0x96, 0x64, 0xe6, 0xe8, 0x67, 0xe6, 0x95, 0x14, 0x97, 0x14, 0xa1, 0xbb, 0x42, 0xc9,
|
||||
0x82, 0x8b, 0x23, 0xb0, 0x34, 0x31, 0xaf, 0x24, 0xb3, 0xa4, 0x52, 0x48, 0x8c, 0x8b, 0x0d, 0xa8,
|
||||
0x24, 0x33, 0x2f, 0x5d, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0xca, 0xb3, 0x12, 0x99, 0xb1,
|
||||
0x40, 0x9e, 0xa1, 0x63, 0xa1, 0x3c, 0xc3, 0x04, 0x20, 0x5e, 0x00, 0xc4, 0x0d, 0x77, 0x14, 0x18,
|
||||
0x9c, 0xb4, 0x4e, 0x3c, 0x94, 0x63, 0xb8, 0x00, 0xc4, 0x37, 0x80, 0xb8, 0xe1, 0x91, 0x1c, 0xe3,
|
||||
0x09, 0x20, 0xbe, 0x00, 0xc4, 0x0f, 0x80, 0x78, 0xc2, 0x63, 0x39, 0x86, 0x28, 0x0e, 0x98, 0x3f,
|
||||
0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x90, 0x1c, 0x7f, 0xff, 0x20, 0x01, 0x00, 0x00,
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = 'proto2';
|
||||
|
||||
package k8s.io.kubernetes.pkg.api.resource;
|
||||
|
||||
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "resource";
|
||||
|
||||
// Quantity is a fixed-point representation of a number.
|
||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
|
||||
// in addition to String() and Int64() accessors.
|
||||
//
|
||||
// The serialization format is:
|
||||
//
|
||||
// <quantity> ::= <signedNumber><suffix>
|
||||
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
|
||||
// <digit> ::= 0 | 1 | ... | 9
|
||||
// <digits> ::= <digit> | <digit><digits>
|
||||
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
|
||||
// <sign> ::= "+" | "-"
|
||||
// <signedNumber> ::= <number> | <sign><number>
|
||||
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
|
||||
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
|
||||
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
|
||||
// <decimalSI> ::= m | "" | k | M | G | T | P | E
|
||||
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
|
||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
|
||||
//
|
||||
// No matter which of the three exponent forms is used, no quantity may represent
|
||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
|
||||
// places. Numbers larger or more precise will be capped or rounded up.
|
||||
// (E.g.: 0.1m will rounded up to 1m.)
|
||||
// This may be extended in the future if we require larger or smaller quantities.
|
||||
//
|
||||
// When a Quantity is parsed from a string, it will remember the type of suffix
|
||||
// it had, and will use the same type again when it is serialized.
|
||||
//
|
||||
// Before serializing, Quantity will be put in "canonical form".
|
||||
// This means that Exponent/suffix will be adjusted up or down (with a
|
||||
// corresponding increase or decrease in Mantissa) such that:
|
||||
// a. No precision is lost
|
||||
// b. No fractional digits will be emitted
|
||||
// c. The exponent (or suffix) is as large as possible.
|
||||
// The sign will be omitted unless the number is negative.
|
||||
//
|
||||
// Examples:
|
||||
// 1.5 will be serialized as "1500m"
|
||||
// 1.5Gi will be serialized as "1536Mi"
|
||||
//
|
||||
// NOTE: We reserve the right to amend this canonical format, perhaps to
|
||||
// allow 1.5 to be canonical.
|
||||
// TODO: Remove above disclaimer after all bikeshedding about format is over,
|
||||
// or after March 2015.
|
||||
//
|
||||
// Note that the quantity will NEVER be internally represented by a
|
||||
// floating point number. That is the whole point of this exercise.
|
||||
//
|
||||
// Non-canonical values will still parse as long as they are well formed,
|
||||
// but will be re-emitted in their canonical form. (So always use canonical
|
||||
// form, or don't diff.)
|
||||
//
|
||||
// This format is intended to make it difficult to use these numbers without
|
||||
// writing some sort of special handling code in the hopes that that will
|
||||
// cause implementors to also use a fixed point implementation.
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.embed=string
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
// +k8s:openapi-gen=true
|
||||
message Quantity {
|
||||
optional string string = 1;
|
||||
}
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
inf "gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxInt64Factors is the highest value that will be checked when removing factors of 10 from an int64.
|
||||
// It is also the maximum decimal digits that can be represented with an int64.
|
||||
maxInt64Factors = 18
|
||||
)
|
||||
|
||||
var (
|
||||
// Commonly needed big.Int values-- treat as read only!
|
||||
bigTen = big.NewInt(10)
|
||||
bigZero = big.NewInt(0)
|
||||
bigOne = big.NewInt(1)
|
||||
bigThousand = big.NewInt(1000)
|
||||
big1024 = big.NewInt(1024)
|
||||
|
||||
// Commonly needed inf.Dec values-- treat as read only!
|
||||
decZero = inf.NewDec(0, 0)
|
||||
decOne = inf.NewDec(1, 0)
|
||||
decMinusOne = inf.NewDec(-1, 0)
|
||||
decThousand = inf.NewDec(1000, 0)
|
||||
dec1024 = inf.NewDec(1024, 0)
|
||||
decMinus1024 = inf.NewDec(-1024, 0)
|
||||
|
||||
// Largest (in magnitude) number allowed.
|
||||
maxAllowed = infDecAmount{inf.NewDec((1<<63)-1, 0)} // == max int64
|
||||
|
||||
// The maximum value we can represent milli-units for.
|
||||
// Compare with the return value of Quantity.Value() to
|
||||
// see if it's safe to use Quantity.MilliValue().
|
||||
MaxMilliValue = int64(((1 << 63) - 1) / 1000)
|
||||
)
|
||||
|
||||
const mostNegative = -(mostPositive + 1)
|
||||
const mostPositive = 1<<63 - 1
|
||||
|
||||
// int64Add returns a+b, or false if that would overflow int64.
|
||||
func int64Add(a, b int64) (int64, bool) {
|
||||
c := a + b
|
||||
switch {
|
||||
case a > 0 && b > 0:
|
||||
if c < 0 {
|
||||
return 0, false
|
||||
}
|
||||
case a < 0 && b < 0:
|
||||
if c > 0 {
|
||||
return 0, false
|
||||
}
|
||||
if a == mostNegative && b == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
return c, true
|
||||
}
|
||||
|
||||
// int64Multiply returns a*b, or false if that would overflow or underflow int64.
|
||||
func int64Multiply(a, b int64) (int64, bool) {
|
||||
if a == 0 || b == 0 || a == 1 || b == 1 {
|
||||
return a * b, true
|
||||
}
|
||||
if a == mostNegative || b == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * b
|
||||
return c, c/b == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale returns a*b, assuming b is greater than one, or false if that would overflow or underflow int64.
|
||||
// Use when b is known to be greater than one.
|
||||
func int64MultiplyScale(a int64, b int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * b, true
|
||||
}
|
||||
if a == mostNegative && b != 1 {
|
||||
return 0, false
|
||||
}
|
||||
c := a * b
|
||||
return c, c/b == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale10 multiplies a by 10, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 10) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale10(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 10, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 10
|
||||
return c, c/10 == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale100 multiplies a by 100, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 100) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale100(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 100, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 100
|
||||
return c, c/100 == a
|
||||
}
|
||||
|
||||
// int64MultiplyScale1000 multiplies a by 1000, or returns false if that would overflow. This method is faster than
|
||||
// int64Multiply(a, 1000) because the compiler can optimize constant factor multiplication.
|
||||
func int64MultiplyScale1000(a int64) (int64, bool) {
|
||||
if a == 0 || a == 1 {
|
||||
return a * 1000, true
|
||||
}
|
||||
if a == mostNegative {
|
||||
return 0, false
|
||||
}
|
||||
c := a * 1000
|
||||
return c, c/1000 == a
|
||||
}
|
||||
|
||||
// positiveScaleInt64 multiplies base by 10^scale, returning false if the
|
||||
// value overflows. Passing a negative scale is undefined.
|
||||
func positiveScaleInt64(base int64, scale Scale) (int64, bool) {
|
||||
switch scale {
|
||||
case 0:
|
||||
return base, true
|
||||
case 1:
|
||||
return int64MultiplyScale10(base)
|
||||
case 2:
|
||||
return int64MultiplyScale100(base)
|
||||
case 3:
|
||||
return int64MultiplyScale1000(base)
|
||||
case 6:
|
||||
return int64MultiplyScale(base, 1000000)
|
||||
case 9:
|
||||
return int64MultiplyScale(base, 1000000000)
|
||||
default:
|
||||
value := base
|
||||
var ok bool
|
||||
for i := Scale(0); i < scale; i++ {
|
||||
if value, ok = int64MultiplyScale(value, 10); !ok {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
return value, true
|
||||
}
|
||||
}
|
||||
|
||||
// negativeScaleInt64 reduces base by the provided scale, rounding up, until the
|
||||
// value is zero or the scale is reached. Passing a negative scale is undefined.
|
||||
// The value returned, if not exact, is rounded away from zero.
|
||||
func negativeScaleInt64(base int64, scale Scale) (result int64, exact bool) {
|
||||
if scale == 0 {
|
||||
return base, true
|
||||
}
|
||||
|
||||
value := base
|
||||
var fraction bool
|
||||
for i := Scale(0); i < scale; i++ {
|
||||
if !fraction && value%10 != 0 {
|
||||
fraction = true
|
||||
}
|
||||
value = value / 10
|
||||
if value == 0 {
|
||||
if fraction {
|
||||
if base > 0 {
|
||||
return 1, false
|
||||
}
|
||||
return -1, false
|
||||
}
|
||||
return 0, true
|
||||
}
|
||||
}
|
||||
if fraction {
|
||||
if base > 0 {
|
||||
value += 1
|
||||
} else {
|
||||
value += -1
|
||||
}
|
||||
}
|
||||
return value, !fraction
|
||||
}
|
||||
|
||||
func pow10Int64(b int64) int64 {
|
||||
switch b {
|
||||
case 0:
|
||||
return 1
|
||||
case 1:
|
||||
return 10
|
||||
case 2:
|
||||
return 100
|
||||
case 3:
|
||||
return 1000
|
||||
case 4:
|
||||
return 10000
|
||||
case 5:
|
||||
return 100000
|
||||
case 6:
|
||||
return 1000000
|
||||
case 7:
|
||||
return 10000000
|
||||
case 8:
|
||||
return 100000000
|
||||
case 9:
|
||||
return 1000000000
|
||||
case 10:
|
||||
return 10000000000
|
||||
case 11:
|
||||
return 100000000000
|
||||
case 12:
|
||||
return 1000000000000
|
||||
case 13:
|
||||
return 10000000000000
|
||||
case 14:
|
||||
return 100000000000000
|
||||
case 15:
|
||||
return 1000000000000000
|
||||
case 16:
|
||||
return 10000000000000000
|
||||
case 17:
|
||||
return 100000000000000000
|
||||
case 18:
|
||||
return 1000000000000000000
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// powInt64 raises a to the bth power. Is not overflow aware.
|
||||
func powInt64(a, b int64) int64 {
|
||||
p := int64(1)
|
||||
for b > 0 {
|
||||
if b&1 != 0 {
|
||||
p *= a
|
||||
}
|
||||
b >>= 1
|
||||
a *= a
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// negativeScaleInt64 returns the result of dividing base by scale * 10 and the remainder, or
|
||||
// false if no such division is possible. Dividing by negative scales is undefined.
|
||||
func divideByScaleInt64(base int64, scale Scale) (result, remainder int64, exact bool) {
|
||||
if scale == 0 {
|
||||
return base, 0, true
|
||||
}
|
||||
// the max scale representable in base 10 in an int64 is 18 decimal places
|
||||
if scale >= 18 {
|
||||
return 0, base, false
|
||||
}
|
||||
divisor := pow10Int64(int64(scale))
|
||||
return base / divisor, base % divisor, true
|
||||
}
|
||||
|
||||
// removeInt64Factors divides in a loop; the return values have the property that
|
||||
// value == result * base ^ scale
|
||||
func removeInt64Factors(value int64, base int64) (result int64, times int32) {
|
||||
times = 0
|
||||
result = value
|
||||
negative := result < 0
|
||||
if negative {
|
||||
result = -result
|
||||
}
|
||||
switch base {
|
||||
// allow the compiler to optimize the common cases
|
||||
case 10:
|
||||
for result >= 10 && result%10 == 0 {
|
||||
times++
|
||||
result = result / 10
|
||||
}
|
||||
// allow the compiler to optimize the common cases
|
||||
case 1024:
|
||||
for result >= 1024 && result%1024 == 0 {
|
||||
times++
|
||||
result = result / 1024
|
||||
}
|
||||
default:
|
||||
for result >= base && result%base == 0 {
|
||||
times++
|
||||
result = result / base
|
||||
}
|
||||
}
|
||||
if negative {
|
||||
result = -result
|
||||
}
|
||||
return result, times
|
||||
}
|
||||
|
||||
// removeBigIntFactors divides in a loop; the return values have the property that
|
||||
// d == result * factor ^ times
|
||||
// d may be modified in place.
|
||||
// If d == 0, then the return values will be (0, 0)
|
||||
func removeBigIntFactors(d, factor *big.Int) (result *big.Int, times int32) {
|
||||
q := big.NewInt(0)
|
||||
m := big.NewInt(0)
|
||||
for d.Cmp(bigZero) != 0 {
|
||||
q.DivMod(d, factor, m)
|
||||
if m.Cmp(bigZero) != 0 {
|
||||
break
|
||||
}
|
||||
times++
|
||||
d, q = q, d
|
||||
}
|
||||
return d, times
|
||||
}
|
||||
@@ -1,792 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
inf "gopkg.in/inf.v0"
|
||||
"k8s.io/client-go/1.5/pkg/genericapiserver/openapi/common"
|
||||
)
|
||||
|
||||
// Quantity is a fixed-point representation of a number.
|
||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
|
||||
// in addition to String() and Int64() accessors.
|
||||
//
|
||||
// The serialization format is:
|
||||
//
|
||||
// <quantity> ::= <signedNumber><suffix>
|
||||
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
|
||||
// <digit> ::= 0 | 1 | ... | 9
|
||||
// <digits> ::= <digit> | <digit><digits>
|
||||
// <number> ::= <digits> | <digits>.<digits> | <digits>. | .<digits>
|
||||
// <sign> ::= "+" | "-"
|
||||
// <signedNumber> ::= <number> | <sign><number>
|
||||
// <suffix> ::= <binarySI> | <decimalExponent> | <decimalSI>
|
||||
// <binarySI> ::= Ki | Mi | Gi | Ti | Pi | Ei
|
||||
// (International System of units; See: http://physics.nist.gov/cuu/Units/binary.html)
|
||||
// <decimalSI> ::= m | "" | k | M | G | T | P | E
|
||||
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
|
||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
|
||||
//
|
||||
// No matter which of the three exponent forms is used, no quantity may represent
|
||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
|
||||
// places. Numbers larger or more precise will be capped or rounded up.
|
||||
// (E.g.: 0.1m will rounded up to 1m.)
|
||||
// This may be extended in the future if we require larger or smaller quantities.
|
||||
//
|
||||
// When a Quantity is parsed from a string, it will remember the type of suffix
|
||||
// it had, and will use the same type again when it is serialized.
|
||||
//
|
||||
// Before serializing, Quantity will be put in "canonical form".
|
||||
// This means that Exponent/suffix will be adjusted up or down (with a
|
||||
// corresponding increase or decrease in Mantissa) such that:
|
||||
// a. No precision is lost
|
||||
// b. No fractional digits will be emitted
|
||||
// c. The exponent (or suffix) is as large as possible.
|
||||
// The sign will be omitted unless the number is negative.
|
||||
//
|
||||
// Examples:
|
||||
// 1.5 will be serialized as "1500m"
|
||||
// 1.5Gi will be serialized as "1536Mi"
|
||||
//
|
||||
// NOTE: We reserve the right to amend this canonical format, perhaps to
|
||||
// allow 1.5 to be canonical.
|
||||
// TODO: Remove above disclaimer after all bikeshedding about format is over,
|
||||
// or after March 2015.
|
||||
//
|
||||
// Note that the quantity will NEVER be internally represented by a
|
||||
// floating point number. That is the whole point of this exercise.
|
||||
//
|
||||
// Non-canonical values will still parse as long as they are well formed,
|
||||
// but will be re-emitted in their canonical form. (So always use canonical
|
||||
// form, or don't diff.)
|
||||
//
|
||||
// This format is intended to make it difficult to use these numbers without
|
||||
// writing some sort of special handling code in the hopes that that will
|
||||
// cause implementors to also use a fixed point implementation.
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.embed=string
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
// +k8s:openapi-gen=true
|
||||
type Quantity struct {
|
||||
// i is the quantity in int64 scaled form, if d.Dec == nil
|
||||
i int64Amount
|
||||
// d is the quantity in inf.Dec form if d.Dec != nil
|
||||
d infDecAmount
|
||||
// s is the generated value of this quantity to avoid recalculation
|
||||
s string
|
||||
|
||||
// Change Format at will. See the comment for Canonicalize for
|
||||
// more details.
|
||||
Format
|
||||
}
|
||||
|
||||
// CanonicalValue allows a quantity amount to be converted to a string.
|
||||
type CanonicalValue interface {
|
||||
// AsCanonicalBytes returns a byte array representing the string representation
|
||||
// of the value mantissa and an int32 representing its exponent in base-10. Callers may
|
||||
// pass a byte slice to the method to avoid allocations.
|
||||
AsCanonicalBytes(out []byte) ([]byte, int32)
|
||||
// AsCanonicalBase1024Bytes returns a byte array representing the string representation
|
||||
// of the value mantissa and an int32 representing its exponent in base-1024. Callers
|
||||
// may pass a byte slice to the method to avoid allocations.
|
||||
AsCanonicalBase1024Bytes(out []byte) ([]byte, int32)
|
||||
}
|
||||
|
||||
// Format lists the three possible formattings of a quantity.
|
||||
type Format string
|
||||
|
||||
const (
|
||||
DecimalExponent = Format("DecimalExponent") // e.g., 12e6
|
||||
BinarySI = Format("BinarySI") // e.g., 12Mi (12 * 2^20)
|
||||
DecimalSI = Format("DecimalSI") // e.g., 12M (12 * 10^6)
|
||||
)
|
||||
|
||||
// MustParse turns the given string into a quantity or panics; for tests
|
||||
// or others cases where you know the string is valid.
|
||||
func MustParse(str string) Quantity {
|
||||
q, err := ParseQuantity(str)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot parse '%v': %v", str, err))
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
const (
|
||||
// splitREString is used to separate a number from its suffix; as such,
|
||||
// this is overly permissive, but that's OK-- it will be checked later.
|
||||
splitREString = "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"
|
||||
)
|
||||
|
||||
var (
|
||||
// splitRE is used to get the various parts of a number.
|
||||
splitRE = regexp.MustCompile(splitREString)
|
||||
|
||||
// Errors that could happen while parsing a string.
|
||||
ErrFormatWrong = errors.New("quantities must match the regular expression '" + splitREString + "'")
|
||||
ErrNumeric = errors.New("unable to parse numeric part of quantity")
|
||||
ErrSuffix = errors.New("unable to parse quantity's suffix")
|
||||
)
|
||||
|
||||
// parseQuantityString is a fast scanner for quantity values.
|
||||
func parseQuantityString(str string) (positive bool, value, num, denom, suffix string, err error) {
|
||||
positive = true
|
||||
pos := 0
|
||||
end := len(str)
|
||||
|
||||
// handle leading sign
|
||||
if pos < end {
|
||||
switch str[0] {
|
||||
case '-':
|
||||
positive = false
|
||||
pos++
|
||||
case '+':
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
// strip leading zeros
|
||||
Zeroes:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
num = "0"
|
||||
value = num
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0':
|
||||
pos++
|
||||
default:
|
||||
break Zeroes
|
||||
}
|
||||
}
|
||||
|
||||
// extract the numerator
|
||||
Num:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
num = str[pos:end]
|
||||
value = str[0:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
num = str[pos:i]
|
||||
pos = i
|
||||
break Num
|
||||
}
|
||||
}
|
||||
|
||||
// if we stripped all numerator positions, always return 0
|
||||
if len(num) == 0 {
|
||||
num = "0"
|
||||
}
|
||||
|
||||
// handle a denominator
|
||||
if pos < end && str[pos] == '.' {
|
||||
pos++
|
||||
Denom:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
denom = str[pos:end]
|
||||
value = str[0:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
denom = str[pos:i]
|
||||
pos = i
|
||||
break Denom
|
||||
}
|
||||
}
|
||||
// TODO: we currently allow 1.G, but we may not want to in the future.
|
||||
// if len(denom) == 0 {
|
||||
// err = ErrFormatWrong
|
||||
// return
|
||||
// }
|
||||
}
|
||||
value = str[0:pos]
|
||||
|
||||
// grab the elements of the suffix
|
||||
suffixStart := pos
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
suffix = str[suffixStart:end]
|
||||
return
|
||||
}
|
||||
if !strings.ContainsAny(str[i:i+1], "eEinumkKMGTP") {
|
||||
pos = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if pos < end {
|
||||
switch str[pos] {
|
||||
case '-', '+':
|
||||
pos++
|
||||
}
|
||||
}
|
||||
Suffix:
|
||||
for i := pos; ; i++ {
|
||||
if i >= end {
|
||||
suffix = str[suffixStart:end]
|
||||
return
|
||||
}
|
||||
switch str[i] {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||
default:
|
||||
break Suffix
|
||||
}
|
||||
}
|
||||
// we encountered a non decimal in the Suffix loop, but the last character
|
||||
// was not a valid exponent
|
||||
err = ErrFormatWrong
|
||||
return
|
||||
}
|
||||
|
||||
// ParseQuantity turns str into a Quantity, or returns an error.
|
||||
func ParseQuantity(str string) (Quantity, error) {
|
||||
if len(str) == 0 {
|
||||
return Quantity{}, ErrFormatWrong
|
||||
}
|
||||
if str == "0" {
|
||||
return Quantity{Format: DecimalSI, s: str}, nil
|
||||
}
|
||||
|
||||
positive, value, num, denom, suf, err := parseQuantityString(str)
|
||||
if err != nil {
|
||||
return Quantity{}, err
|
||||
}
|
||||
|
||||
base, exponent, format, ok := quantitySuffixer.interpret(suffix(suf))
|
||||
if !ok {
|
||||
return Quantity{}, ErrSuffix
|
||||
}
|
||||
|
||||
precision := int32(0)
|
||||
scale := int32(0)
|
||||
mantissa := int64(1)
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
scale = exponent
|
||||
precision = maxInt64Factors - int32(len(num)+len(denom))
|
||||
case BinarySI:
|
||||
scale = 0
|
||||
switch {
|
||||
case exponent >= 0 && len(denom) == 0:
|
||||
// only handle positive binary numbers with the fast path
|
||||
mantissa = int64(int64(mantissa) << uint64(exponent))
|
||||
// 1Mi (2^20) has ~6 digits of decimal precision, so exponent*3/10 -1 is roughly the precision
|
||||
precision = 15 - int32(len(num)) - int32(float32(exponent)*3/10) - 1
|
||||
default:
|
||||
precision = -1
|
||||
}
|
||||
}
|
||||
|
||||
if precision >= 0 {
|
||||
// if we have a denominator, shift the entire value to the left by the number of places in the
|
||||
// denominator
|
||||
scale -= int32(len(denom))
|
||||
if scale >= int32(Nano) {
|
||||
shifted := num + denom
|
||||
|
||||
var value int64
|
||||
value, err := strconv.ParseInt(shifted, 10, 64)
|
||||
if err != nil {
|
||||
return Quantity{}, ErrNumeric
|
||||
}
|
||||
if result, ok := int64Multiply(value, int64(mantissa)); ok {
|
||||
if !positive {
|
||||
result = -result
|
||||
}
|
||||
// if the number is in canonical form, reuse the string
|
||||
switch format {
|
||||
case BinarySI:
|
||||
if exponent%10 == 0 && (value&0x07 != 0) {
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
|
||||
}
|
||||
default:
|
||||
if scale%3 == 0 && !strings.HasSuffix(shifted, "000") && shifted[0] != '0' {
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format, s: str}, nil
|
||||
}
|
||||
}
|
||||
return Quantity{i: int64Amount{value: result, scale: Scale(scale)}, Format: format}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amount := new(inf.Dec)
|
||||
if _, ok := amount.SetString(value); !ok {
|
||||
return Quantity{}, ErrNumeric
|
||||
}
|
||||
|
||||
// So that no one but us has to think about suffixes, remove it.
|
||||
if base == 10 {
|
||||
amount.SetScale(amount.Scale() + Scale(exponent).infScale())
|
||||
} else if base == 2 {
|
||||
// numericSuffix = 2 ** exponent
|
||||
numericSuffix := big.NewInt(1).Lsh(bigOne, uint(exponent))
|
||||
ub := amount.UnscaledBig()
|
||||
amount.SetUnscaledBig(ub.Mul(ub, numericSuffix))
|
||||
}
|
||||
|
||||
// Cap at min/max bounds.
|
||||
sign := amount.Sign()
|
||||
if sign == -1 {
|
||||
amount.Neg(amount)
|
||||
}
|
||||
|
||||
// This rounds non-zero values up to the minimum representable value, under the theory that
|
||||
// if you want some resources, you should get some resources, even if you asked for way too small
|
||||
// of an amount. Arguably, this should be inf.RoundHalfUp (normal rounding), but that would have
|
||||
// the side effect of rounding values < .5n to zero.
|
||||
if v, ok := amount.Unscaled(); v != int64(0) || !ok {
|
||||
amount.Round(amount, Nano.infScale(), inf.RoundUp)
|
||||
}
|
||||
|
||||
// The max is just a simple cap.
|
||||
// TODO: this prevents accumulating quantities greater than int64, for instance quota across a cluster
|
||||
if format == BinarySI && amount.Cmp(maxAllowed.Dec) > 0 {
|
||||
amount.Set(maxAllowed.Dec)
|
||||
}
|
||||
|
||||
if format == BinarySI && amount.Cmp(decOne) < 0 && amount.Cmp(decZero) > 0 {
|
||||
// This avoids rounding and hopefully confusion, too.
|
||||
format = DecimalSI
|
||||
}
|
||||
if sign == -1 {
|
||||
amount.Neg(amount)
|
||||
}
|
||||
|
||||
return Quantity{d: infDecAmount{amount}, Format: format}, nil
|
||||
}
|
||||
|
||||
// DeepCopy returns a deep-copy of the Quantity value. Note that the method
|
||||
// receiver is a value, so we can mutate it in-place and return it.
|
||||
func (q Quantity) DeepCopy() Quantity {
|
||||
if q.d.Dec != nil {
|
||||
tmp := &inf.Dec{}
|
||||
q.d.Dec = tmp.Set(q.d.Dec)
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// OpenAPIDefinition returns openAPI definition for this type.
|
||||
func (_ Quantity) OpenAPIDefinition() common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CanonicalizeBytes returns the canonical form of q and its suffix (see comment on Quantity).
|
||||
//
|
||||
// Note about BinarySI:
|
||||
// * If q.Format is set to BinarySI and q.Amount represents a non-zero value between
|
||||
// -1 and +1, it will be emitted as if q.Format were DecimalSI.
|
||||
// * Otherwise, if q.Format is set to BinarySI, frational parts of q.Amount will be
|
||||
// rounded up. (1.1i becomes 2i.)
|
||||
func (q *Quantity) CanonicalizeBytes(out []byte) (result, suffix []byte) {
|
||||
if q.IsZero() {
|
||||
return zeroBytes, nil
|
||||
}
|
||||
|
||||
var rounded CanonicalValue
|
||||
format := q.Format
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
case BinarySI:
|
||||
if q.CmpInt64(-1024) > 0 && q.CmpInt64(1024) < 0 {
|
||||
// This avoids rounding and hopefully confusion, too.
|
||||
format = DecimalSI
|
||||
} else {
|
||||
var exact bool
|
||||
if rounded, exact = q.AsScale(0); !exact {
|
||||
// Don't lose precision-- show as DecimalSI
|
||||
format = DecimalSI
|
||||
}
|
||||
}
|
||||
default:
|
||||
format = DecimalExponent
|
||||
}
|
||||
|
||||
// TODO: If BinarySI formatting is requested but would cause rounding, upgrade to
|
||||
// one of the other formats.
|
||||
switch format {
|
||||
case DecimalExponent, DecimalSI:
|
||||
number, exponent := q.AsCanonicalBytes(out)
|
||||
suffix, _ := quantitySuffixer.constructBytes(10, exponent, format)
|
||||
return number, suffix
|
||||
default:
|
||||
// format must be BinarySI
|
||||
number, exponent := rounded.AsCanonicalBase1024Bytes(out)
|
||||
suffix, _ := quantitySuffixer.constructBytes(2, exponent*10, format)
|
||||
return number, suffix
|
||||
}
|
||||
}
|
||||
|
||||
// AsInt64 returns a representation of the current value as an int64 if a fast conversion
|
||||
// is possible. If false is returned, callers must use the inf.Dec form of this quantity.
|
||||
func (q *Quantity) AsInt64() (int64, bool) {
|
||||
if q.d.Dec != nil {
|
||||
return 0, false
|
||||
}
|
||||
return q.i.AsInt64()
|
||||
}
|
||||
|
||||
// ToDec promotes the quantity in place to use an inf.Dec representation and returns itself.
|
||||
func (q *Quantity) ToDec() *Quantity {
|
||||
if q.d.Dec == nil {
|
||||
q.d.Dec = q.i.AsDec()
|
||||
q.i = int64Amount{}
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
// AsDec returns the quantity as represented by a scaled inf.Dec.
|
||||
func (q *Quantity) AsDec() *inf.Dec {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec
|
||||
}
|
||||
q.d.Dec = q.i.AsDec()
|
||||
q.i = int64Amount{}
|
||||
return q.d.Dec
|
||||
}
|
||||
|
||||
// AsCanonicalBytes returns the canonical byte representation of this quantity as a mantissa
|
||||
// and base 10 exponent. The out byte slice may be passed to the method to avoid an extra
|
||||
// allocation.
|
||||
func (q *Quantity) AsCanonicalBytes(out []byte) (result []byte, exponent int32) {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.AsCanonicalBytes(out)
|
||||
}
|
||||
return q.i.AsCanonicalBytes(out)
|
||||
}
|
||||
|
||||
// IsZero returns true if the quantity is equal to zero.
|
||||
func (q *Quantity) IsZero() bool {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Sign() == 0
|
||||
}
|
||||
return q.i.value == 0
|
||||
}
|
||||
|
||||
// Sign returns 0 if the quantity is zero, -1 if the quantity is less than zero, or 1 if the
|
||||
// quantity is greater than zero.
|
||||
func (q *Quantity) Sign() int {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Sign()
|
||||
}
|
||||
return q.i.Sign()
|
||||
}
|
||||
|
||||
// AsScaled returns the current value, rounded up to the provided scale, and returns
|
||||
// false if the scale resulted in a loss of precision.
|
||||
func (q *Quantity) AsScale(scale Scale) (CanonicalValue, bool) {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.AsScale(scale)
|
||||
}
|
||||
return q.i.AsScale(scale)
|
||||
}
|
||||
|
||||
// RoundUp updates the quantity to the provided scale, ensuring that the value is at
|
||||
// least 1. False is returned if the rounding operation resulted in a loss of precision.
|
||||
// Negative numbers are rounded away from zero (-9 scale 1 rounds to -10).
|
||||
func (q *Quantity) RoundUp(scale Scale) bool {
|
||||
if q.d.Dec != nil {
|
||||
q.s = ""
|
||||
d, exact := q.d.AsScale(scale)
|
||||
q.d = d
|
||||
return exact
|
||||
}
|
||||
// avoid clearing the string value if we have already calculated it
|
||||
if q.i.scale >= scale {
|
||||
return true
|
||||
}
|
||||
q.s = ""
|
||||
i, exact := q.i.AsScale(scale)
|
||||
q.i = i
|
||||
return exact
|
||||
}
|
||||
|
||||
// Add adds the provide y quantity to the current value. If the current value is zero,
|
||||
// the format of the quantity will be updated to the format of y.
|
||||
func (q *Quantity) Add(y Quantity) {
|
||||
q.s = ""
|
||||
if q.d.Dec == nil && y.d.Dec == nil {
|
||||
if q.i.value == 0 {
|
||||
q.Format = y.Format
|
||||
}
|
||||
if q.i.Add(y.i) {
|
||||
return
|
||||
}
|
||||
} else if q.IsZero() {
|
||||
q.Format = y.Format
|
||||
}
|
||||
q.ToDec().d.Dec.Add(q.d.Dec, y.AsDec())
|
||||
}
|
||||
|
||||
// Sub subtracts the provided quantity from the current value in place. If the current
|
||||
// value is zero, the format of the quantity will be updated to the format of y.
|
||||
func (q *Quantity) Sub(y Quantity) {
|
||||
q.s = ""
|
||||
if q.IsZero() {
|
||||
q.Format = y.Format
|
||||
}
|
||||
if q.d.Dec == nil && y.d.Dec == nil && q.i.Sub(y.i) {
|
||||
return
|
||||
}
|
||||
q.ToDec().d.Dec.Sub(q.d.Dec, y.AsDec())
|
||||
}
|
||||
|
||||
// Cmp returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
|
||||
// quantity is greater than y.
|
||||
func (q *Quantity) Cmp(y Quantity) int {
|
||||
if q.d.Dec == nil && y.d.Dec == nil {
|
||||
return q.i.Cmp(y.i)
|
||||
}
|
||||
return q.AsDec().Cmp(y.AsDec())
|
||||
}
|
||||
|
||||
// CmpInt64 returns 0 if the quantity is equal to y, -1 if the quantity is less than y, or 1 if the
|
||||
// quantity is greater than y.
|
||||
func (q *Quantity) CmpInt64(y int64) int {
|
||||
if q.d.Dec != nil {
|
||||
return q.d.Dec.Cmp(inf.NewDec(y, inf.Scale(0)))
|
||||
}
|
||||
return q.i.Cmp(int64Amount{value: y})
|
||||
}
|
||||
|
||||
// Neg sets quantity to be the negative value of itself.
|
||||
func (q *Quantity) Neg() {
|
||||
q.s = ""
|
||||
if q.d.Dec == nil {
|
||||
q.i.value = -q.i.value
|
||||
return
|
||||
}
|
||||
q.d.Dec.Neg(q.d.Dec)
|
||||
}
|
||||
|
||||
// int64QuantityExpectedBytes is the expected width in bytes of the canonical string representation
|
||||
// of most Quantity values.
|
||||
const int64QuantityExpectedBytes = 18
|
||||
|
||||
// String formats the Quantity as a string, caching the result if not calculated.
|
||||
// String is an expensive operation and caching this result significantly reduces the cost of
|
||||
// normal parse / marshal operations on Quantity.
|
||||
func (q *Quantity) String() string {
|
||||
if len(q.s) == 0 {
|
||||
result := make([]byte, 0, int64QuantityExpectedBytes)
|
||||
number, suffix := q.CanonicalizeBytes(result)
|
||||
number = append(number, suffix...)
|
||||
q.s = string(number)
|
||||
}
|
||||
return q.s
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (q Quantity) MarshalJSON() ([]byte, error) {
|
||||
if len(q.s) > 0 {
|
||||
out := make([]byte, len(q.s)+2)
|
||||
out[0], out[len(out)-1] = '"', '"'
|
||||
copy(out[1:], q.s)
|
||||
return out, nil
|
||||
}
|
||||
result := make([]byte, int64QuantityExpectedBytes, int64QuantityExpectedBytes)
|
||||
result[0] = '"'
|
||||
number, suffix := q.CanonicalizeBytes(result[1:1])
|
||||
// if the same slice was returned to us that we passed in, avoid another allocation by copying number into
|
||||
// the source slice and returning that
|
||||
if len(number) > 0 && &number[0] == &result[1] && (len(number)+len(suffix)+2) <= int64QuantityExpectedBytes {
|
||||
number = append(number, suffix...)
|
||||
number = append(number, '"')
|
||||
return result[:1+len(number)], nil
|
||||
}
|
||||
// if CanonicalizeBytes needed more space than our slice provided, we may need to allocate again so use
|
||||
// append
|
||||
result = result[:1]
|
||||
result = append(result, number...)
|
||||
result = append(result, suffix...)
|
||||
result = append(result, '"')
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
// TODO: Remove support for leading/trailing whitespace
|
||||
func (q *Quantity) UnmarshalJSON(value []byte) error {
|
||||
l := len(value)
|
||||
if l == 4 && bytes.Equal(value, []byte("null")) {
|
||||
q.d.Dec = nil
|
||||
q.i = int64Amount{}
|
||||
return nil
|
||||
}
|
||||
if l >= 2 && value[0] == '"' && value[l-1] == '"' {
|
||||
value = value[1 : l-1]
|
||||
}
|
||||
|
||||
parsed, err := ParseQuantity(strings.TrimSpace(string(value)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// This copy is safe because parsed will not be referred to again.
|
||||
*q = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewQuantity returns a new Quantity representing the given
|
||||
// value in the given format.
|
||||
func NewQuantity(value int64, format Format) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value},
|
||||
Format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// NewMilliQuantity returns a new Quantity representing the given
|
||||
// value * 1/1000 in the given format. Note that BinarySI formatting
|
||||
// will round fractional values, and will be changed to DecimalSI for
|
||||
// values x where (-1 < x < 1) && (x != 0).
|
||||
func NewMilliQuantity(value int64, format Format) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value, scale: -3},
|
||||
Format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// NewScaledQuantity returns a new Quantity representing the given
|
||||
// value * 10^scale in DecimalSI format.
|
||||
func NewScaledQuantity(value int64, scale Scale) *Quantity {
|
||||
return &Quantity{
|
||||
i: int64Amount{value: value, scale: scale},
|
||||
Format: DecimalSI,
|
||||
}
|
||||
}
|
||||
|
||||
// Value returns the value of q; any fractional part will be lost.
|
||||
func (q *Quantity) Value() int64 {
|
||||
return q.ScaledValue(0)
|
||||
}
|
||||
|
||||
// MilliValue returns the value of ceil(q * 1000); this could overflow an int64;
|
||||
// if that's a concern, call Value() first to verify the number is small enough.
|
||||
func (q *Quantity) MilliValue() int64 {
|
||||
return q.ScaledValue(Milli)
|
||||
}
|
||||
|
||||
// ScaledValue returns the value of ceil(q * 10^scale); this could overflow an int64.
|
||||
// To detect overflow, call Value() first and verify the expected magnitude.
|
||||
func (q *Quantity) ScaledValue(scale Scale) int64 {
|
||||
if q.d.Dec == nil {
|
||||
i, _ := q.i.AsScaledInt64(scale)
|
||||
return i
|
||||
}
|
||||
dec := q.d.Dec
|
||||
return scaledValue(dec.UnscaledBig(), int(dec.Scale()), int(scale.infScale()))
|
||||
}
|
||||
|
||||
// Set sets q's value to be value.
|
||||
func (q *Quantity) Set(value int64) {
|
||||
q.SetScaled(value, 0)
|
||||
}
|
||||
|
||||
// SetMilli sets q's value to be value * 1/1000.
|
||||
func (q *Quantity) SetMilli(value int64) {
|
||||
q.SetScaled(value, Milli)
|
||||
}
|
||||
|
||||
// SetScaled sets q's value to be value * 10^scale
|
||||
func (q *Quantity) SetScaled(value int64, scale Scale) {
|
||||
q.s = ""
|
||||
q.d.Dec = nil
|
||||
q.i = int64Amount{value: value, scale: scale}
|
||||
}
|
||||
|
||||
// Copy is a convenience function that makes a deep copy for you. Non-deep
|
||||
// copies of quantities share pointers and you will regret that.
|
||||
func (q *Quantity) Copy() *Quantity {
|
||||
if q.d.Dec == nil {
|
||||
return &Quantity{
|
||||
s: q.s,
|
||||
i: q.i,
|
||||
Format: q.Format,
|
||||
}
|
||||
}
|
||||
tmp := &inf.Dec{}
|
||||
return &Quantity{
|
||||
s: q.s,
|
||||
d: infDecAmount{tmp.Set(q.d.Dec)},
|
||||
Format: q.Format,
|
||||
}
|
||||
}
|
||||
|
||||
// qFlag is a helper type for the Flag function
|
||||
type qFlag struct {
|
||||
dest *Quantity
|
||||
}
|
||||
|
||||
// Sets the value of the internal Quantity. (used by flag & pflag)
|
||||
func (qf qFlag) Set(val string) error {
|
||||
q, err := ParseQuantity(val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// This copy is OK because q will not be referenced again.
|
||||
*qf.dest = q
|
||||
return nil
|
||||
}
|
||||
|
||||
// Converts the value of the internal Quantity to a string. (used by flag & pflag)
|
||||
func (qf qFlag) String() string {
|
||||
return qf.dest.String()
|
||||
}
|
||||
|
||||
// States the type of flag this is (Quantity). (used by pflag)
|
||||
func (qf qFlag) Type() string {
|
||||
return "quantity"
|
||||
}
|
||||
|
||||
// QuantityFlag is a helper that makes a quantity flag (using standard flag package).
|
||||
// Will panic if defaultValue is not a valid quantity.
|
||||
func QuantityFlag(flagName, defaultValue, description string) *Quantity {
|
||||
q := MustParse(defaultValue)
|
||||
flag.Var(NewQuantityFlagValue(&q), flagName, description)
|
||||
return &q
|
||||
}
|
||||
|
||||
// NewQuantityFlagValue returns an object that can be used to back a flag,
|
||||
// pointing at the given Quantity variable.
|
||||
func NewQuantityFlagValue(q *Quantity) flag.Value {
|
||||
return qFlag{q}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
var _ proto.Sizer = &Quantity{}
|
||||
|
||||
func (m *Quantity) Marshal() (data []byte, err error) {
|
||||
size := m.Size()
|
||||
data = make([]byte, size)
|
||||
n, err := m.MarshalTo(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data[:n], nil
|
||||
}
|
||||
|
||||
// MarshalTo is a customized version of the generated Protobuf unmarshaler for a struct
|
||||
// with a single string field.
|
||||
func (m *Quantity) MarshalTo(data []byte) (int, error) {
|
||||
var i int
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
|
||||
data[i] = 0xa
|
||||
i++
|
||||
// BEGIN CUSTOM MARSHAL
|
||||
out := m.String()
|
||||
i = encodeVarintGenerated(data, i, uint64(len(out)))
|
||||
i += copy(data[i:], out)
|
||||
// END CUSTOM MARSHAL
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenerated(data []byte, offset int, v uint64) int {
|
||||
for v >= 1<<7 {
|
||||
data[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
data[offset] = uint8(v)
|
||||
return offset + 1
|
||||
}
|
||||
|
||||
func (m *Quantity) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
|
||||
// BEGIN CUSTOM SIZE
|
||||
l = len(m.String())
|
||||
// END CUSTOM SIZE
|
||||
|
||||
n += 1 + l + sovGenerated(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenerated(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Unmarshal is a customized version of the generated Protobuf unmarshaler for a struct
|
||||
// with a single string field.
|
||||
func (m *Quantity) Unmarshal(data []byte) error {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Quantity: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Quantity: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field String_", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
s := string(data[iNdEx:postIndex])
|
||||
|
||||
// BEGIN CUSTOM DECODE
|
||||
p, err := ParseQuantity(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = p
|
||||
// END CUSTOM DECODE
|
||||
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenerated(data[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthGenerated
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func skipGenerated(data []byte) (n int, err error) {
|
||||
l := len(data)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if data[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
return iNdEx, nil
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
iNdEx += length
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenerated
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 3:
|
||||
for {
|
||||
var innerWire uint64
|
||||
var start int = iNdEx
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenerated
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := data[iNdEx]
|
||||
iNdEx++
|
||||
innerWire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
innerWireType := int(innerWire & 0x7)
|
||||
if innerWireType == 4 {
|
||||
break
|
||||
}
|
||||
next, err := skipGenerated(data[start:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
iNdEx = start + next
|
||||
}
|
||||
return iNdEx, nil
|
||||
case 4:
|
||||
return iNdEx, nil
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
return iNdEx, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenerated = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenerated = fmt.Errorf("proto: integer overflow")
|
||||
)
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// A sync pool to reduce allocation.
|
||||
intPool sync.Pool
|
||||
maxInt64 = big.NewInt(math.MaxInt64)
|
||||
)
|
||||
|
||||
func init() {
|
||||
intPool.New = func() interface{} {
|
||||
return &big.Int{}
|
||||
}
|
||||
}
|
||||
|
||||
// scaledValue scales given unscaled value from scale to new Scale and returns
|
||||
// an int64. It ALWAYS rounds up the result when scale down. The final result might
|
||||
// overflow.
|
||||
//
|
||||
// scale, newScale represents the scale of the unscaled decimal.
|
||||
// The mathematical value of the decimal is unscaled * 10**(-scale).
|
||||
func scaledValue(unscaled *big.Int, scale, newScale int) int64 {
|
||||
dif := scale - newScale
|
||||
if dif == 0 {
|
||||
return unscaled.Int64()
|
||||
}
|
||||
|
||||
// Handle scale up
|
||||
// This is an easy case, we do not need to care about rounding and overflow.
|
||||
// If any intermediate operation causes overflow, the result will overflow.
|
||||
if dif < 0 {
|
||||
return unscaled.Int64() * int64(math.Pow10(-dif))
|
||||
}
|
||||
|
||||
// Handle scale down
|
||||
// We have to be careful about the intermediate operations.
|
||||
|
||||
// fast path when unscaled < max.Int64 and exp(10,dif) < max.Int64
|
||||
const log10MaxInt64 = 19
|
||||
if unscaled.Cmp(maxInt64) < 0 && dif < log10MaxInt64 {
|
||||
divide := int64(math.Pow10(dif))
|
||||
result := unscaled.Int64() / divide
|
||||
mod := unscaled.Int64() % divide
|
||||
if mod != 0 {
|
||||
return result + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// We should only convert back to int64 when getting the result.
|
||||
divisor := intPool.Get().(*big.Int)
|
||||
exp := intPool.Get().(*big.Int)
|
||||
result := intPool.Get().(*big.Int)
|
||||
defer func() {
|
||||
intPool.Put(divisor)
|
||||
intPool.Put(exp)
|
||||
intPool.Put(result)
|
||||
}()
|
||||
|
||||
// divisor = 10^(dif)
|
||||
// TODO: create loop up table if exp costs too much.
|
||||
divisor.Exp(bigTen, exp.SetInt64(int64(dif)), nil)
|
||||
// reuse exp
|
||||
remainder := exp
|
||||
|
||||
// result = unscaled / divisor
|
||||
// remainder = unscaled % divisor
|
||||
result.DivMod(unscaled, divisor, remainder)
|
||||
if remainder.Sign() != 0 {
|
||||
return result.Int64() + 1
|
||||
}
|
||||
|
||||
return result.Int64()
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type suffix string
|
||||
|
||||
// suffixer can interpret and construct suffixes.
|
||||
type suffixer interface {
|
||||
interpret(suffix) (base, exponent int32, fmt Format, ok bool)
|
||||
construct(base, exponent int32, fmt Format) (s suffix, ok bool)
|
||||
constructBytes(base, exponent int32, fmt Format) (s []byte, ok bool)
|
||||
}
|
||||
|
||||
// quantitySuffixer handles suffixes for all three formats that quantity
|
||||
// can handle.
|
||||
var quantitySuffixer = newSuffixer()
|
||||
|
||||
type bePair struct {
|
||||
base, exponent int32
|
||||
}
|
||||
|
||||
type listSuffixer struct {
|
||||
suffixToBE map[suffix]bePair
|
||||
beToSuffix map[bePair]suffix
|
||||
beToSuffixBytes map[bePair][]byte
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) addSuffix(s suffix, pair bePair) {
|
||||
if ls.suffixToBE == nil {
|
||||
ls.suffixToBE = map[suffix]bePair{}
|
||||
}
|
||||
if ls.beToSuffix == nil {
|
||||
ls.beToSuffix = map[bePair]suffix{}
|
||||
}
|
||||
if ls.beToSuffixBytes == nil {
|
||||
ls.beToSuffixBytes = map[bePair][]byte{}
|
||||
}
|
||||
ls.suffixToBE[s] = pair
|
||||
ls.beToSuffix[pair] = s
|
||||
ls.beToSuffixBytes[pair] = []byte(s)
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) lookup(s suffix) (base, exponent int32, ok bool) {
|
||||
pair, ok := ls.suffixToBE[s]
|
||||
if !ok {
|
||||
return 0, 0, false
|
||||
}
|
||||
return pair.base, pair.exponent, true
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) construct(base, exponent int32) (s suffix, ok bool) {
|
||||
s, ok = ls.beToSuffix[bePair{base, exponent}]
|
||||
return
|
||||
}
|
||||
|
||||
func (ls *listSuffixer) constructBytes(base, exponent int32) (s []byte, ok bool) {
|
||||
s, ok = ls.beToSuffixBytes[bePair{base, exponent}]
|
||||
return
|
||||
}
|
||||
|
||||
type suffixHandler struct {
|
||||
decSuffixes listSuffixer
|
||||
binSuffixes listSuffixer
|
||||
}
|
||||
|
||||
type fastLookup struct {
|
||||
*suffixHandler
|
||||
}
|
||||
|
||||
func (l fastLookup) interpret(s suffix) (base, exponent int32, format Format, ok bool) {
|
||||
switch s {
|
||||
case "":
|
||||
return 10, 0, DecimalSI, true
|
||||
case "n":
|
||||
return 10, -9, DecimalSI, true
|
||||
case "u":
|
||||
return 10, -6, DecimalSI, true
|
||||
case "m":
|
||||
return 10, -3, DecimalSI, true
|
||||
case "k":
|
||||
return 10, 3, DecimalSI, true
|
||||
case "M":
|
||||
return 10, 6, DecimalSI, true
|
||||
case "G":
|
||||
return 10, 9, DecimalSI, true
|
||||
}
|
||||
return l.suffixHandler.interpret(s)
|
||||
}
|
||||
|
||||
func newSuffixer() suffixer {
|
||||
sh := &suffixHandler{}
|
||||
|
||||
// IMPORTANT: if you change this section you must change fastLookup
|
||||
|
||||
sh.binSuffixes.addSuffix("Ki", bePair{2, 10})
|
||||
sh.binSuffixes.addSuffix("Mi", bePair{2, 20})
|
||||
sh.binSuffixes.addSuffix("Gi", bePair{2, 30})
|
||||
sh.binSuffixes.addSuffix("Ti", bePair{2, 40})
|
||||
sh.binSuffixes.addSuffix("Pi", bePair{2, 50})
|
||||
sh.binSuffixes.addSuffix("Ei", bePair{2, 60})
|
||||
// Don't emit an error when trying to produce
|
||||
// a suffix for 2^0.
|
||||
sh.decSuffixes.addSuffix("", bePair{2, 0})
|
||||
|
||||
sh.decSuffixes.addSuffix("n", bePair{10, -9})
|
||||
sh.decSuffixes.addSuffix("u", bePair{10, -6})
|
||||
sh.decSuffixes.addSuffix("m", bePair{10, -3})
|
||||
sh.decSuffixes.addSuffix("", bePair{10, 0})
|
||||
sh.decSuffixes.addSuffix("k", bePair{10, 3})
|
||||
sh.decSuffixes.addSuffix("M", bePair{10, 6})
|
||||
sh.decSuffixes.addSuffix("G", bePair{10, 9})
|
||||
sh.decSuffixes.addSuffix("T", bePair{10, 12})
|
||||
sh.decSuffixes.addSuffix("P", bePair{10, 15})
|
||||
sh.decSuffixes.addSuffix("E", bePair{10, 18})
|
||||
|
||||
return fastLookup{sh}
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) construct(base, exponent int32, fmt Format) (s suffix, ok bool) {
|
||||
switch fmt {
|
||||
case DecimalSI:
|
||||
return sh.decSuffixes.construct(base, exponent)
|
||||
case BinarySI:
|
||||
return sh.binSuffixes.construct(base, exponent)
|
||||
case DecimalExponent:
|
||||
if base != 10 {
|
||||
return "", false
|
||||
}
|
||||
if exponent == 0 {
|
||||
return "", true
|
||||
}
|
||||
return suffix("e" + strconv.FormatInt(int64(exponent), 10)), true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) constructBytes(base, exponent int32, format Format) (s []byte, ok bool) {
|
||||
switch format {
|
||||
case DecimalSI:
|
||||
return sh.decSuffixes.constructBytes(base, exponent)
|
||||
case BinarySI:
|
||||
return sh.binSuffixes.constructBytes(base, exponent)
|
||||
case DecimalExponent:
|
||||
if base != 10 {
|
||||
return nil, false
|
||||
}
|
||||
if exponent == 0 {
|
||||
return nil, true
|
||||
}
|
||||
result := make([]byte, 8, 8)
|
||||
result[0] = 'e'
|
||||
number := strconv.AppendInt(result[1:1], int64(exponent), 10)
|
||||
if &result[1] == &number[0] {
|
||||
return result[:1+len(number)], true
|
||||
}
|
||||
result = append(result[:1], number...)
|
||||
return result, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (sh *suffixHandler) interpret(suffix suffix) (base, exponent int32, fmt Format, ok bool) {
|
||||
// Try lookup tables first
|
||||
if b, e, ok := sh.decSuffixes.lookup(suffix); ok {
|
||||
return b, e, DecimalSI, true
|
||||
}
|
||||
if b, e, ok := sh.binSuffixes.lookup(suffix); ok {
|
||||
return b, e, BinarySI, true
|
||||
}
|
||||
|
||||
if len(suffix) > 1 && (suffix[0] == 'E' || suffix[0] == 'e') {
|
||||
parsed, err := strconv.ParseInt(string(suffix[1:]), 10, 64)
|
||||
if err != nil {
|
||||
return 0, 0, DecimalExponent, false
|
||||
}
|
||||
return 10, int32(parsed), DecimalExponent, true
|
||||
}
|
||||
|
||||
return 0, 0, DecimalExponent, false
|
||||
}
|
||||
@@ -1,456 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package testapi provides a helper for retrieving the KUBE_TEST_API environment variable.
|
||||
//
|
||||
// TODO(lavalamp): this package is a huge disaster at the moment. I intend to
|
||||
// refactor. All code currently using this package should change:
|
||||
// 1. Declare your own registered.APIGroupRegistrationManager in your own test code.
|
||||
// 2. Import the relevant install packages.
|
||||
// 3. Register the types you need, from the announced.APIGroupAnnouncementManager.
|
||||
package testapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.5/pkg/apis/apps"
|
||||
"k8s.io/client-go/1.5/pkg/apis/autoscaling"
|
||||
"k8s.io/client-go/1.5/pkg/apis/batch"
|
||||
"k8s.io/client-go/1.5/pkg/apis/certificates"
|
||||
"k8s.io/client-go/1.5/pkg/apis/extensions"
|
||||
"k8s.io/client-go/1.5/pkg/apis/imagepolicy"
|
||||
"k8s.io/client-go/1.5/pkg/apis/policy"
|
||||
"k8s.io/client-go/1.5/pkg/apis/rbac"
|
||||
"k8s.io/client-go/1.5/pkg/apis/storage"
|
||||
"k8s.io/client-go/1.5/pkg/federation/apis/federation"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/runtime/serializer/recognizer"
|
||||
|
||||
_ "k8s.io/client-go/1.5/pkg/api/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/apps/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/authentication/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/authorization/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/autoscaling/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/batch/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/certificates/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/componentconfig/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/extensions/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/imagepolicy/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/policy/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/rbac/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/apis/storage/install"
|
||||
_ "k8s.io/client-go/1.5/pkg/federation/apis/federation/install"
|
||||
)
|
||||
|
||||
var (
|
||||
Groups = make(map[string]TestGroup)
|
||||
Default TestGroup
|
||||
Autoscaling TestGroup
|
||||
Batch TestGroup
|
||||
Extensions TestGroup
|
||||
Apps TestGroup
|
||||
Policy TestGroup
|
||||
Federation TestGroup
|
||||
Rbac TestGroup
|
||||
Certificates TestGroup
|
||||
Storage TestGroup
|
||||
ImagePolicy TestGroup
|
||||
|
||||
serializer runtime.SerializerInfo
|
||||
storageSerializer runtime.SerializerInfo
|
||||
)
|
||||
|
||||
type TestGroup struct {
|
||||
externalGroupVersion unversioned.GroupVersion
|
||||
internalGroupVersion unversioned.GroupVersion
|
||||
internalTypes map[string]reflect.Type
|
||||
externalTypes map[string]reflect.Type
|
||||
}
|
||||
|
||||
func init() {
|
||||
if apiMediaType := os.Getenv("KUBE_TEST_API_TYPE"); len(apiMediaType) > 0 {
|
||||
var ok bool
|
||||
mediaType, options, err := mime.ParseMediaType(apiMediaType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
serializer, ok = api.Codecs.SerializerForMediaType(mediaType, options)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("no serializer for %s", apiMediaType))
|
||||
}
|
||||
}
|
||||
|
||||
if storageMediaType := StorageMediaType(); len(storageMediaType) > 0 {
|
||||
var ok bool
|
||||
mediaType, options, err := mime.ParseMediaType(storageMediaType)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
storageSerializer, ok = api.Codecs.SerializerForMediaType(mediaType, options)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("no serializer for %s", storageMediaType))
|
||||
}
|
||||
}
|
||||
|
||||
kubeTestAPI := os.Getenv("KUBE_TEST_API")
|
||||
if len(kubeTestAPI) != 0 {
|
||||
// priority is "first in list preferred", so this has to run in reverse order
|
||||
testGroupVersions := strings.Split(kubeTestAPI, ",")
|
||||
for i := len(testGroupVersions) - 1; i >= 0; i-- {
|
||||
gvString := testGroupVersions[i]
|
||||
groupVersion, err := unversioned.ParseGroupVersion(gvString)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("Error parsing groupversion %v: %v", gvString, err))
|
||||
}
|
||||
|
||||
internalGroupVersion := unversioned.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal}
|
||||
Groups[groupVersion.Group] = TestGroup{
|
||||
externalGroupVersion: groupVersion,
|
||||
internalGroupVersion: internalGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(internalGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(groupVersion),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := Groups[api.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: api.GroupName, Version: registered.GroupOrDie(api.GroupName).GroupVersion.Version}
|
||||
Groups[api.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: api.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(api.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[extensions.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: extensions.GroupName, Version: registered.GroupOrDie(extensions.GroupName).GroupVersion.Version}
|
||||
Groups[extensions.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: extensions.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[autoscaling.GroupName]; !ok {
|
||||
internalTypes := make(map[string]reflect.Type)
|
||||
for k, t := range api.Scheme.KnownTypes(extensions.SchemeGroupVersion) {
|
||||
if k == "Scale" {
|
||||
continue
|
||||
}
|
||||
internalTypes[k] = t
|
||||
}
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}
|
||||
Groups[autoscaling.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: extensions.SchemeGroupVersion,
|
||||
internalTypes: internalTypes,
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[autoscaling.GroupName+"IntraGroup"]; !ok {
|
||||
internalTypes := make(map[string]reflect.Type)
|
||||
for k, t := range api.Scheme.KnownTypes(extensions.SchemeGroupVersion) {
|
||||
if k == "Scale" {
|
||||
internalTypes[k] = t
|
||||
break
|
||||
}
|
||||
}
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: autoscaling.GroupName, Version: registered.GroupOrDie(autoscaling.GroupName).GroupVersion.Version}
|
||||
Groups[autoscaling.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: autoscaling.SchemeGroupVersion,
|
||||
internalTypes: internalTypes,
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[batch.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: batch.GroupName, Version: registered.GroupOrDie(batch.GroupName).GroupVersion.Version}
|
||||
Groups[batch.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: batch.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(batch.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[apps.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: apps.GroupName, Version: registered.GroupOrDie(apps.GroupName).GroupVersion.Version}
|
||||
Groups[apps.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: extensions.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(extensions.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[policy.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: policy.GroupName, Version: registered.GroupOrDie(policy.GroupName).GroupVersion.Version}
|
||||
Groups[policy.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: policy.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(policy.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[federation.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: federation.GroupName, Version: registered.GroupOrDie(federation.GroupName).GroupVersion.Version}
|
||||
Groups[federation.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: federation.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(federation.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[rbac.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: rbac.GroupName, Version: registered.GroupOrDie(rbac.GroupName).GroupVersion.Version}
|
||||
Groups[rbac.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: rbac.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(rbac.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[storage.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: storage.GroupName, Version: registered.GroupOrDie(storage.GroupName).GroupVersion.Version}
|
||||
Groups[storage.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: storage.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(storage.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
if _, ok := Groups[certificates.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: certificates.GroupName, Version: registered.GroupOrDie(certificates.GroupName).GroupVersion.Version}
|
||||
Groups[certificates.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: certificates.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(certificates.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := Groups[imagepolicy.GroupName]; !ok {
|
||||
externalGroupVersion := unversioned.GroupVersion{Group: imagepolicy.GroupName, Version: registered.GroupOrDie(imagepolicy.GroupName).GroupVersion.Version}
|
||||
Groups[imagepolicy.GroupName] = TestGroup{
|
||||
externalGroupVersion: externalGroupVersion,
|
||||
internalGroupVersion: imagepolicy.SchemeGroupVersion,
|
||||
internalTypes: api.Scheme.KnownTypes(imagepolicy.SchemeGroupVersion),
|
||||
externalTypes: api.Scheme.KnownTypes(externalGroupVersion),
|
||||
}
|
||||
}
|
||||
|
||||
Default = Groups[api.GroupName]
|
||||
Autoscaling = Groups[autoscaling.GroupName]
|
||||
Batch = Groups[batch.GroupName]
|
||||
Apps = Groups[apps.GroupName]
|
||||
Policy = Groups[policy.GroupName]
|
||||
Certificates = Groups[certificates.GroupName]
|
||||
Extensions = Groups[extensions.GroupName]
|
||||
Federation = Groups[federation.GroupName]
|
||||
Rbac = Groups[rbac.GroupName]
|
||||
Storage = Groups[storage.GroupName]
|
||||
ImagePolicy = Groups[imagepolicy.GroupName]
|
||||
}
|
||||
|
||||
func (g TestGroup) ContentConfig() (string, *unversioned.GroupVersion, runtime.Codec) {
|
||||
return "application/json", g.GroupVersion(), g.Codec()
|
||||
}
|
||||
|
||||
func (g TestGroup) GroupVersion() *unversioned.GroupVersion {
|
||||
copyOfGroupVersion := g.externalGroupVersion
|
||||
return ©OfGroupVersion
|
||||
}
|
||||
|
||||
// InternalGroupVersion returns the group,version used to identify the internal
|
||||
// types for this API
|
||||
func (g TestGroup) InternalGroupVersion() unversioned.GroupVersion {
|
||||
return g.internalGroupVersion
|
||||
}
|
||||
|
||||
// InternalTypes returns a map of internal API types' kind names to their Go types.
|
||||
func (g TestGroup) InternalTypes() map[string]reflect.Type {
|
||||
return g.internalTypes
|
||||
}
|
||||
|
||||
// ExternalTypes returns a map of external API types' kind names to their Go types.
|
||||
func (g TestGroup) ExternalTypes() map[string]reflect.Type {
|
||||
return g.externalTypes
|
||||
}
|
||||
|
||||
// Codec returns the codec for the API version to test against, as set by the
|
||||
// KUBE_TEST_API_TYPE env var.
|
||||
func (g TestGroup) Codec() runtime.Codec {
|
||||
if serializer.Serializer == nil {
|
||||
return api.Codecs.LegacyCodec(g.externalGroupVersion)
|
||||
}
|
||||
return api.Codecs.CodecForVersions(serializer, api.Codecs.UniversalDeserializer(), unversioned.GroupVersions{g.externalGroupVersion}, nil)
|
||||
}
|
||||
|
||||
// NegotiatedSerializer returns the negotiated serializer for the server.
|
||||
func (g TestGroup) NegotiatedSerializer() runtime.NegotiatedSerializer {
|
||||
return api.Codecs
|
||||
}
|
||||
|
||||
func StorageMediaType() string {
|
||||
return os.Getenv("KUBE_TEST_API_STORAGE_TYPE")
|
||||
}
|
||||
|
||||
// StorageCodec returns the codec for the API version to store in etcd, as set by the
|
||||
// KUBE_TEST_API_STORAGE_TYPE env var.
|
||||
func (g TestGroup) StorageCodec() runtime.Codec {
|
||||
s := storageSerializer.Serializer
|
||||
|
||||
if s == nil {
|
||||
return api.Codecs.LegacyCodec(g.externalGroupVersion)
|
||||
}
|
||||
|
||||
// etcd2 only supports string data - we must wrap any result before returning
|
||||
// TODO: remove for etcd3 / make parameterizable
|
||||
if !storageSerializer.EncodesAsText {
|
||||
s = runtime.NewBase64Serializer(s)
|
||||
}
|
||||
ds := recognizer.NewDecoder(s, api.Codecs.UniversalDeserializer())
|
||||
|
||||
return api.Codecs.CodecForVersions(s, ds, unversioned.GroupVersions{g.externalGroupVersion}, nil)
|
||||
}
|
||||
|
||||
// Converter returns the api.Scheme for the API version to test against, as set by the
|
||||
// KUBE_TEST_API env var.
|
||||
func (g TestGroup) Converter() runtime.ObjectConvertor {
|
||||
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return interfaces.ObjectConvertor
|
||||
}
|
||||
|
||||
// MetadataAccessor returns the MetadataAccessor for the API version to test against,
|
||||
// as set by the KUBE_TEST_API env var.
|
||||
func (g TestGroup) MetadataAccessor() meta.MetadataAccessor {
|
||||
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return interfaces.MetadataAccessor
|
||||
}
|
||||
|
||||
// SelfLink returns a self link that will appear to be for the version Version().
|
||||
// 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be
|
||||
// empty for lists.
|
||||
func (g TestGroup) SelfLink(resource, name string) string {
|
||||
if g.externalGroupVersion.Group == api.GroupName {
|
||||
if name == "" {
|
||||
return fmt.Sprintf("/api/%s/%s", g.externalGroupVersion.Version, resource)
|
||||
}
|
||||
return fmt.Sprintf("/api/%s/%s/%s", g.externalGroupVersion.Version, resource, name)
|
||||
} else {
|
||||
// TODO: will need a /apis prefix once we have proper multi-group
|
||||
// support
|
||||
if name == "" {
|
||||
return fmt.Sprintf("/apis/%s/%s/%s", g.externalGroupVersion.Group, g.externalGroupVersion.Version, resource)
|
||||
}
|
||||
return fmt.Sprintf("/apis/%s/%s/%s/%s", g.externalGroupVersion.Group, g.externalGroupVersion.Version, resource, name)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the appropriate path for the given prefix (watch, proxy, redirect, etc), resource, namespace and name.
|
||||
// For ex, this is of the form:
|
||||
// /api/v1/watch/namespaces/foo/pods/pod0 for v1.
|
||||
func (g TestGroup) ResourcePathWithPrefix(prefix, resource, namespace, name string) string {
|
||||
var path string
|
||||
if g.externalGroupVersion.Group == api.GroupName {
|
||||
path = "/api/" + g.externalGroupVersion.Version
|
||||
} else {
|
||||
// TODO: switch back once we have proper multiple group support
|
||||
// path = "/apis/" + g.Group + "/" + Version(group...)
|
||||
path = "/apis/" + g.externalGroupVersion.Group + "/" + g.externalGroupVersion.Version
|
||||
}
|
||||
|
||||
if prefix != "" {
|
||||
path = path + "/" + prefix
|
||||
}
|
||||
if namespace != "" {
|
||||
path = path + "/namespaces/" + namespace
|
||||
}
|
||||
// Resource names are lower case.
|
||||
resource = strings.ToLower(resource)
|
||||
if resource != "" {
|
||||
path = path + "/" + resource
|
||||
}
|
||||
if name != "" {
|
||||
path = path + "/" + name
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// Returns the appropriate path for the given resource, namespace and name.
|
||||
// For example, this is of the form:
|
||||
// /api/v1/namespaces/foo/pods/pod0 for v1.
|
||||
func (g TestGroup) ResourcePath(resource, namespace, name string) string {
|
||||
return g.ResourcePathWithPrefix("", resource, namespace, name)
|
||||
}
|
||||
|
||||
func (g TestGroup) RESTMapper() meta.RESTMapper {
|
||||
return registered.RESTMapper()
|
||||
}
|
||||
|
||||
// ExternalGroupVersions returns all external group versions allowed for the server.
|
||||
func ExternalGroupVersions() unversioned.GroupVersions {
|
||||
versions := []unversioned.GroupVersion{}
|
||||
for _, g := range Groups {
|
||||
gv := g.GroupVersion()
|
||||
versions = append(versions, *gv)
|
||||
}
|
||||
return versions
|
||||
}
|
||||
|
||||
// Get codec based on runtime.Object
|
||||
func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) {
|
||||
kinds, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected encoding error: %v", err)
|
||||
}
|
||||
kind := kinds[0]
|
||||
|
||||
for _, group := range Groups {
|
||||
if group.GroupVersion().Group != kind.Group {
|
||||
continue
|
||||
}
|
||||
|
||||
if api.Scheme.Recognizes(kind) {
|
||||
return group.Codec(), nil
|
||||
}
|
||||
}
|
||||
// Codec used for unversioned types
|
||||
if api.Scheme.Recognizes(kind) {
|
||||
serializer, ok := api.Codecs.SerializerForFileExtension("json")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no serializer registered for json")
|
||||
}
|
||||
return serializer, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected kind: %v", kind)
|
||||
}
|
||||
|
||||
func NewTestGroup(external, internal unversioned.GroupVersion, internalTypes map[string]reflect.Type, externalTypes map[string]reflect.Type) TestGroup {
|
||||
return TestGroup{external, internal, internalTypes, externalTypes}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Duration is a wrapper around time.Duration which supports correct
|
||||
// marshaling to YAML and JSON. In particular, it marshals into strings, which
|
||||
// can be used as map keys in json.
|
||||
type Duration struct {
|
||||
time.Duration `protobuf:"varint,1,opt,name=duration,casttype=time.Duration"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
var str string
|
||||
json.Unmarshal(b, &str)
|
||||
|
||||
pd, err := time.ParseDuration(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.Duration = pd
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(d.Duration.String())
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,378 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
|
||||
|
||||
syntax = 'proto2';
|
||||
|
||||
package k8s.io.kubernetes.pkg.api.unversioned;
|
||||
|
||||
import "k8s.io/kubernetes/pkg/runtime/generated.proto";
|
||||
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
|
||||
|
||||
// Package-wide variables from generator "generated".
|
||||
option go_package = "unversioned";
|
||||
|
||||
// APIGroup contains the name, the supported versions, and the preferred version
|
||||
// of a group.
|
||||
message APIGroup {
|
||||
// name is the name of the group.
|
||||
optional string name = 1;
|
||||
|
||||
// versions are the versions supported in this group.
|
||||
repeated GroupVersionForDiscovery versions = 2;
|
||||
|
||||
// preferredVersion is the version preferred by the API server, which
|
||||
// probably is the storage version.
|
||||
optional GroupVersionForDiscovery preferredVersion = 3;
|
||||
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 4;
|
||||
}
|
||||
|
||||
// APIGroupList is a list of APIGroup, to allow clients to discover the API at
|
||||
// /apis.
|
||||
message APIGroupList {
|
||||
// groups is a list of APIGroup.
|
||||
repeated APIGroup groups = 1;
|
||||
}
|
||||
|
||||
// APIResource specifies the name of a resource and whether it is namespaced.
|
||||
message APIResource {
|
||||
// name is the name of the resource.
|
||||
optional string name = 1;
|
||||
|
||||
// namespaced indicates if a resource is namespaced or not.
|
||||
optional bool namespaced = 2;
|
||||
|
||||
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
|
||||
optional string kind = 3;
|
||||
}
|
||||
|
||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||
// resources supported in a specific group and version, and if the resource
|
||||
// is namespaced.
|
||||
message APIResourceList {
|
||||
// groupVersion is the group and version this APIResourceList is for.
|
||||
optional string groupVersion = 1;
|
||||
|
||||
// resources contains the name of the resources and if they are namespaced.
|
||||
repeated APIResource resources = 2;
|
||||
}
|
||||
|
||||
// APIVersions lists the versions that are available, to allow clients to
|
||||
// discover the API at /api, which is the root path of the legacy v1 API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message APIVersions {
|
||||
// versions are the api versions that are available.
|
||||
repeated string versions = 1;
|
||||
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
repeated ServerAddressByClientCIDR serverAddressByClientCIDRs = 2;
|
||||
}
|
||||
|
||||
// Duration is a wrapper around time.Duration which supports correct
|
||||
// marshaling to YAML and JSON. In particular, it marshals into strings, which
|
||||
// can be used as map keys in json.
|
||||
message Duration {
|
||||
optional int64 duration = 1;
|
||||
}
|
||||
|
||||
// ExportOptions is the query options to the standard REST get call.
|
||||
message ExportOptions {
|
||||
// Should this value be exported. Export strips fields that a user can not specify.`
|
||||
optional bool export = 1;
|
||||
|
||||
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'
|
||||
optional bool exact = 2;
|
||||
}
|
||||
|
||||
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupKind {
|
||||
optional string group = 1;
|
||||
|
||||
optional string kind = 2;
|
||||
}
|
||||
|
||||
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupResource {
|
||||
optional string group = 1;
|
||||
|
||||
optional string resource = 2;
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersion {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group/version" and "version" string of a version.
|
||||
// It is made a struct to keep extensibility.
|
||||
message GroupVersionForDiscovery {
|
||||
// groupVersion specifies the API group and version in the form "group/version"
|
||||
optional string groupVersion = 1;
|
||||
|
||||
// version specifies the version in the form of "version". This is to save
|
||||
// the clients the trouble of splitting the GroupVersion.
|
||||
optional string version = 2;
|
||||
}
|
||||
|
||||
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersionKind {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
|
||||
optional string kind = 3;
|
||||
}
|
||||
|
||||
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message GroupVersionResource {
|
||||
optional string group = 1;
|
||||
|
||||
optional string version = 2;
|
||||
|
||||
optional string resource = 3;
|
||||
}
|
||||
|
||||
// A label selector is a label query over a set of resources. The result of matchLabels and
|
||||
// matchExpressions are ANDed. An empty label selector matches all objects. A null
|
||||
// label selector matches no objects.
|
||||
message LabelSelector {
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
// operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
map<string, string> matchLabels = 1;
|
||||
|
||||
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
repeated LabelSelectorRequirement matchExpressions = 2;
|
||||
}
|
||||
|
||||
// A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
// relates the key and values.
|
||||
message LabelSelectorRequirement {
|
||||
// key is the label key that the selector applies to.
|
||||
optional string key = 1;
|
||||
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators ard In, NotIn, Exists and DoesNotExist.
|
||||
optional string operator = 2;
|
||||
|
||||
// values is an array of string values. If the operator is In or NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a strategic
|
||||
// merge patch.
|
||||
repeated string values = 3;
|
||||
}
|
||||
|
||||
// ListMeta describes metadata that synthetic resources must have, including lists and
|
||||
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
|
||||
message ListMeta {
|
||||
// SelfLink is a URL representing this object.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
optional string selfLink = 1;
|
||||
|
||||
// String that identifies the server's internal version of this object that
|
||||
// can be used by clients to determine when objects have changed.
|
||||
// Value must be treated as opaque by clients and passed unmodified back to the server.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency
|
||||
optional string resourceVersion = 2;
|
||||
}
|
||||
|
||||
// RootPaths lists the paths available at root.
|
||||
// For example: "/healthz", "/apis".
|
||||
message RootPaths {
|
||||
// paths are the paths available at root.
|
||||
repeated string paths = 1;
|
||||
}
|
||||
|
||||
// ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.
|
||||
message ServerAddressByClientCIDR {
|
||||
// The CIDR with which clients can match their IP to figure out the server address that they should use.
|
||||
optional string clientCIDR = 1;
|
||||
|
||||
// Address of this server, suitable for a client that matches the above CIDR.
|
||||
// This can be a hostname, hostname:port, IP or IP:port.
|
||||
optional string serverAddress = 2;
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
message Status {
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional ListMeta metadata = 1;
|
||||
|
||||
// Status of the operation.
|
||||
// One of: "Success" or "Failure".
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
optional string status = 2;
|
||||
|
||||
// A human-readable description of the status of this operation.
|
||||
optional string message = 3;
|
||||
|
||||
// A machine-readable description of why this operation is in the
|
||||
// "Failure" status. If this value is empty there
|
||||
// is no information available. A Reason clarifies an HTTP status
|
||||
// code but does not override it.
|
||||
optional string reason = 4;
|
||||
|
||||
// Extended data associated with the reason. Each reason may define its
|
||||
// own extended details. This field is optional and the data returned
|
||||
// is not guaranteed to conform to any schema except that defined by
|
||||
// the reason type.
|
||||
optional StatusDetails details = 5;
|
||||
|
||||
// Suggested HTTP return code for this status, 0 if not set.
|
||||
optional int32 code = 6;
|
||||
}
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
// cases when multiple errors are encountered.
|
||||
message StatusCause {
|
||||
// A machine-readable description of the cause of the error. If this value is
|
||||
// empty there is no information available.
|
||||
optional string reason = 1;
|
||||
|
||||
// A human-readable description of the cause of the error. This field may be
|
||||
// presented as-is to a reader.
|
||||
optional string message = 2;
|
||||
|
||||
// The field of the resource that has caused this error, as named by its JSON
|
||||
// serialization. May include dot and postfix notation for nested attributes.
|
||||
// Arrays are zero-indexed. Fields may appear more than once in an array of
|
||||
// causes due to fields having multiple errors.
|
||||
// Optional.
|
||||
//
|
||||
// Examples:
|
||||
// "name" - the field "name" on the current resource
|
||||
// "items[0].name" - the field "name" on the first array entry in "items"
|
||||
optional string field = 3;
|
||||
}
|
||||
|
||||
// StatusDetails is a set of additional properties that MAY be set by the
|
||||
// server to provide additional information about a response. The Reason
|
||||
// field of a Status object defines what attributes will be set. Clients
|
||||
// must ignore fields that do not match the defined type of each attribute,
|
||||
// and should assume that any attribute may be empty, invalid, or under
|
||||
// defined.
|
||||
message StatusDetails {
|
||||
// The name attribute of the resource associated with the status StatusReason
|
||||
// (when there is a single name which can be described).
|
||||
optional string name = 1;
|
||||
|
||||
// The group attribute of the resource associated with the status StatusReason.
|
||||
optional string group = 2;
|
||||
|
||||
// The kind attribute of the resource associated with the status StatusReason.
|
||||
// On some operations may differ from the requested resource Kind.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional string kind = 3;
|
||||
|
||||
// The Causes array includes more details associated with the StatusReason
|
||||
// failure. Not all StatusReasons may provide detailed causes.
|
||||
repeated StatusCause causes = 4;
|
||||
|
||||
// If specified, the time in seconds before the operation should be retried.
|
||||
optional int32 retryAfterSeconds = 5;
|
||||
}
|
||||
|
||||
// Time is a wrapper around time.Time which supports correct
|
||||
// marshaling to YAML and JSON. Wrappers are provided for many
|
||||
// of the factory methods that the time package offers.
|
||||
//
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.as=Timestamp
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
message Time {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
optional int64 seconds = 1;
|
||||
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
optional int32 nanos = 2;
|
||||
}
|
||||
|
||||
// Timestamp is a struct that is equivalent to Time, but intended for
|
||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
||||
// that matches Time. Do not use in Go structs.
|
||||
message Timestamp {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
optional int64 seconds = 1;
|
||||
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
optional int32 nanos = 2;
|
||||
}
|
||||
|
||||
// TypeMeta describes an individual object in an API response or request
|
||||
// with strings representing the type of the object and its API schema version.
|
||||
// Structures that are versioned or persisted should inline TypeMeta.
|
||||
message TypeMeta {
|
||||
// Kind is a string value representing the REST resource this object represents.
|
||||
// Servers may infer this from the endpoint the client submits requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
optional string kind = 1;
|
||||
|
||||
// APIVersion defines the versioned schema of this representation of an object.
|
||||
// Servers should convert recognized schemas to the latest internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources
|
||||
optional string apiVersion = 2;
|
||||
}
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseResourceArg takes the common style of string which may be either `resource.group.com` or `resource.version.group.com`
|
||||
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
|
||||
// but with a knowledge of all GroupVersions, calling code can take a very good guess. If there are only two segments, then
|
||||
// `*GroupVersionResource` is nil.
|
||||
// `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource`
|
||||
func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
|
||||
var gvr *GroupVersionResource
|
||||
if strings.Count(arg, ".") >= 2 {
|
||||
s := strings.SplitN(arg, ".", 3)
|
||||
gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]}
|
||||
}
|
||||
|
||||
return gvr, ParseGroupResource(arg)
|
||||
}
|
||||
|
||||
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupResource struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Resource string `protobuf:"bytes,2,opt,name=resource"`
|
||||
}
|
||||
|
||||
func (gr GroupResource) WithVersion(version string) GroupVersionResource {
|
||||
return GroupVersionResource{Group: gr.Group, Version: version, Resource: gr.Resource}
|
||||
}
|
||||
|
||||
func (gr GroupResource) Empty() bool {
|
||||
return len(gr.Group) == 0 && len(gr.Resource) == 0
|
||||
}
|
||||
|
||||
func (gr *GroupResource) String() string {
|
||||
if len(gr.Group) == 0 {
|
||||
return gr.Resource
|
||||
}
|
||||
return gr.Resource + "." + gr.Group
|
||||
}
|
||||
|
||||
// ParseGroupResource turns "resource.group" string into a GroupResource struct. Empty strings are allowed
|
||||
// for each field.
|
||||
func ParseGroupResource(gr string) GroupResource {
|
||||
if i := strings.Index(gr, "."); i == -1 {
|
||||
return GroupResource{Resource: gr}
|
||||
} else {
|
||||
return GroupResource{Group: gr[i+1:], Resource: gr[:i]}
|
||||
}
|
||||
}
|
||||
|
||||
// GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersionResource struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
Resource string `protobuf:"bytes,3,opt,name=resource"`
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) Empty() bool {
|
||||
return len(gvr.Group) == 0 && len(gvr.Version) == 0 && len(gvr.Resource) == 0
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) GroupResource() GroupResource {
|
||||
return GroupResource{Group: gvr.Group, Resource: gvr.Resource}
|
||||
}
|
||||
|
||||
func (gvr GroupVersionResource) GroupVersion() GroupVersion {
|
||||
return GroupVersion{Group: gvr.Group, Version: gvr.Version}
|
||||
}
|
||||
|
||||
func (gvr *GroupVersionResource) String() string {
|
||||
return strings.Join([]string{gvr.Group, "/", gvr.Version, ", Resource=", gvr.Resource}, "")
|
||||
}
|
||||
|
||||
// GroupKind specifies a Group and a Kind, but does not force a version. This is useful for identifying
|
||||
// concepts during lookup stages without having partially valid types
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupKind struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Kind string `protobuf:"bytes,2,opt,name=kind"`
|
||||
}
|
||||
|
||||
func (gk GroupKind) Empty() bool {
|
||||
return len(gk.Group) == 0 && len(gk.Kind) == 0
|
||||
}
|
||||
|
||||
func (gk GroupKind) WithVersion(version string) GroupVersionKind {
|
||||
return GroupVersionKind{Group: gk.Group, Version: version, Kind: gk.Kind}
|
||||
}
|
||||
|
||||
func (gk *GroupKind) String() string {
|
||||
if len(gk.Group) == 0 {
|
||||
return gk.Kind
|
||||
}
|
||||
return gk.Kind + "." + gk.Group
|
||||
}
|
||||
|
||||
// GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion
|
||||
// to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersionKind struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
Kind string `protobuf:"bytes,3,opt,name=kind"`
|
||||
}
|
||||
|
||||
// Empty returns true if group, version, and kind are empty
|
||||
func (gvk GroupVersionKind) Empty() bool {
|
||||
return len(gvk.Group) == 0 && len(gvk.Version) == 0 && len(gvk.Kind) == 0
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) GroupKind() GroupKind {
|
||||
return GroupKind{Group: gvk.Group, Kind: gvk.Kind}
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) GroupVersion() GroupVersion {
|
||||
return GroupVersion{Group: gvk.Group, Version: gvk.Version}
|
||||
}
|
||||
|
||||
func (gvk GroupVersionKind) String() string {
|
||||
return gvk.Group + "/" + gvk.Version + ", Kind=" + gvk.Kind
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type GroupVersion struct {
|
||||
Group string `protobuf:"bytes,1,opt,name=group"`
|
||||
Version string `protobuf:"bytes,2,opt,name=version"`
|
||||
}
|
||||
|
||||
// Empty returns true if group and version are empty
|
||||
func (gv GroupVersion) Empty() bool {
|
||||
return len(gv.Group) == 0 && len(gv.Version) == 0
|
||||
}
|
||||
|
||||
// String puts "group" and "version" into a single "group/version" string. For the legacy v1
|
||||
// it returns "v1".
|
||||
func (gv GroupVersion) String() string {
|
||||
// special case the internal apiVersion for the legacy kube types
|
||||
if gv.Empty() {
|
||||
return ""
|
||||
}
|
||||
|
||||
// special case of "v1" for backward compatibility
|
||||
if len(gv.Group) == 0 && gv.Version == "v1" {
|
||||
return gv.Version
|
||||
}
|
||||
if len(gv.Group) > 0 {
|
||||
return gv.Group + "/" + gv.Version
|
||||
}
|
||||
return gv.Version
|
||||
}
|
||||
|
||||
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
|
||||
// if none of the options match the group. It prefers a match to group and version over just group.
|
||||
// TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme.
|
||||
// TODO: Introduce an adapter type between GroupVersion and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
|
||||
// in fewer places.
|
||||
func (gv GroupVersion) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
|
||||
for _, gvk := range kinds {
|
||||
if gvk.Group == gv.Group && gvk.Version == gv.Version {
|
||||
return gvk, true
|
||||
}
|
||||
}
|
||||
for _, gvk := range kinds {
|
||||
if gvk.Group == gv.Group {
|
||||
return gv.WithKind(gvk.Kind), true
|
||||
}
|
||||
}
|
||||
return GroupVersionKind{}, false
|
||||
}
|
||||
|
||||
// ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error
|
||||
// if it cannot parse the string.
|
||||
func ParseGroupVersion(gv string) (GroupVersion, error) {
|
||||
// this can be the internal version for the legacy kube types
|
||||
// TODO once we've cleared the last uses as strings, this special case should be removed.
|
||||
if (len(gv) == 0) || (gv == "/") {
|
||||
return GroupVersion{}, nil
|
||||
}
|
||||
|
||||
switch strings.Count(gv, "/") {
|
||||
case 0:
|
||||
return GroupVersion{"", gv}, nil
|
||||
case 1:
|
||||
i := strings.Index(gv, "/")
|
||||
return GroupVersion{gv[:i], gv[i+1:]}, nil
|
||||
default:
|
||||
return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv)
|
||||
}
|
||||
}
|
||||
|
||||
// WithKind creates a GroupVersionKind based on the method receiver's GroupVersion and the passed Kind.
|
||||
func (gv GroupVersion) WithKind(kind string) GroupVersionKind {
|
||||
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
|
||||
}
|
||||
|
||||
// WithResource creates a GroupVersionResource based on the method receiver's GroupVersion and the passed Resource.
|
||||
func (gv GroupVersion) WithResource(resource string) GroupVersionResource {
|
||||
return GroupVersionResource{Group: gv.Group, Version: gv.Version, Resource: resource}
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (gv GroupVersion) MarshalJSON() ([]byte, error) {
|
||||
s := gv.String()
|
||||
if strings.Count(s, "/") > 1 {
|
||||
return []byte{}, fmt.Errorf("illegal GroupVersion %v: contains more than one /", s)
|
||||
}
|
||||
return json.Marshal(s)
|
||||
}
|
||||
|
||||
func (gv *GroupVersion) unmarshal(value []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(value, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
parsed, err := ParseGroupVersion(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*gv = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (gv *GroupVersion) UnmarshalJSON(value []byte) error {
|
||||
return gv.unmarshal(value)
|
||||
}
|
||||
|
||||
// UnmarshalTEXT implements the Ugorji's encoding.TextUnmarshaler interface.
|
||||
func (gv *GroupVersion) UnmarshalText(value []byte) error {
|
||||
return gv.unmarshal(value)
|
||||
}
|
||||
|
||||
// GroupVersions can be used to represent a set of desired group versions.
|
||||
// TODO: Move GroupVersions to a package under pkg/runtime, since it's used by scheme.
|
||||
// TODO: Introduce an adapter type between GroupVersions and runtime.GroupVersioner, and use LegacyCodec(GroupVersion)
|
||||
// in fewer places.
|
||||
type GroupVersions []GroupVersion
|
||||
|
||||
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
|
||||
// if none of the options match the group.
|
||||
func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) {
|
||||
for _, gv := range gvs {
|
||||
target, ok := gv.KindForGroupVersionKinds(kinds)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
return target, true
|
||||
}
|
||||
return GroupVersionKind{}, false
|
||||
}
|
||||
|
||||
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
|
||||
// do not use TypeMeta.
|
||||
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {
|
||||
if gvk == nil {
|
||||
return "", ""
|
||||
}
|
||||
return gvk.GroupVersion().String(), gvk.Kind
|
||||
}
|
||||
|
||||
// FromAPIVersionAndKind returns a GVK representing the provided fields for types that
|
||||
// do not use TypeMeta. This method exists to support test types and legacy serializations
|
||||
// that have a distinct group and kind.
|
||||
// TODO: further reduce usage of this method.
|
||||
func FromAPIVersionAndKind(apiVersion, kind string) GroupVersionKind {
|
||||
if gv, err := ParseGroupVersion(apiVersion); err == nil {
|
||||
return GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
|
||||
}
|
||||
return GroupVersionKind{Kind: kind}
|
||||
}
|
||||
|
||||
// All objects that are serialized from a Scheme encode their type information. This interface is used
|
||||
// by serialization to set type information from the Scheme onto the serialized version of an object.
|
||||
// For objects that cannot be serialized or have unique requirements, this interface may be a no-op.
|
||||
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
|
||||
type ObjectKind interface {
|
||||
// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil
|
||||
// should clear the current setting.
|
||||
SetGroupVersionKind(kind GroupVersionKind)
|
||||
// GroupVersionKind returns the stored group, version, and kind of an object, or nil if the object does
|
||||
// not expose or provide these fields.
|
||||
GroupVersionKind() GroupVersionKind
|
||||
}
|
||||
|
||||
// EmptyObjectKind implements the ObjectKind interface as a noop
|
||||
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
|
||||
var EmptyObjectKind = emptyObjectKind{}
|
||||
|
||||
type emptyObjectKind struct{}
|
||||
|
||||
// SetGroupVersionKind implements the ObjectKind interface
|
||||
func (emptyObjectKind) SetGroupVersionKind(gvk GroupVersionKind) {}
|
||||
|
||||
// GroupVersionKind implements the ObjectKind interface
|
||||
func (emptyObjectKind) GroupVersionKind() GroupVersionKind { return GroupVersionKind{} }
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/labels"
|
||||
"k8s.io/client-go/1.5/pkg/selection"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
|
||||
// labels.Selector
|
||||
// Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go
|
||||
func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
|
||||
if ps == nil {
|
||||
return labels.Nothing(), nil
|
||||
}
|
||||
if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
|
||||
return labels.Everything(), nil
|
||||
}
|
||||
selector := labels.NewSelector()
|
||||
for k, v := range ps.MatchLabels {
|
||||
r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
for _, expr := range ps.MatchExpressions {
|
||||
var op selection.Operator
|
||||
switch expr.Operator {
|
||||
case LabelSelectorOpIn:
|
||||
op = selection.In
|
||||
case LabelSelectorOpNotIn:
|
||||
op = selection.NotIn
|
||||
case LabelSelectorOpExists:
|
||||
op = selection.Exists
|
||||
case LabelSelectorOpDoesNotExist:
|
||||
op = selection.DoesNotExist
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
|
||||
}
|
||||
r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector = selector.Add(*r)
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// LabelSelectorAsMap converts the LabelSelector api type into a map of strings, ie. the
|
||||
// original structure of a label selector. Operators that cannot be converted into plain
|
||||
// labels (Exists, DoesNotExist, NotIn, and In with more than one value) will result in
|
||||
// an error.
|
||||
func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
|
||||
if ps == nil {
|
||||
return nil, nil
|
||||
}
|
||||
selector := map[string]string{}
|
||||
for k, v := range ps.MatchLabels {
|
||||
selector[k] = v
|
||||
}
|
||||
for _, expr := range ps.MatchExpressions {
|
||||
switch expr.Operator {
|
||||
case LabelSelectorOpIn:
|
||||
if len(expr.Values) != 1 {
|
||||
return selector, fmt.Errorf("operator %q without a single value cannot be converted into the old label selector format", expr.Operator)
|
||||
}
|
||||
// Should we do anything in case this will override a previous key-value pair?
|
||||
selector[expr.Key] = expr.Values[0]
|
||||
case LabelSelectorOpNotIn, LabelSelectorOpExists, LabelSelectorOpDoesNotExist:
|
||||
return selector, fmt.Errorf("operator %q cannot be converted into the old label selector format", expr.Operator)
|
||||
default:
|
||||
return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
|
||||
}
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// ParseToLabelSelector parses a string representing a selector into a LabelSelector object.
|
||||
// Note: This function should be kept in sync with the parser in pkg/labels/selector.go
|
||||
func ParseToLabelSelector(selector string) (*LabelSelector, error) {
|
||||
reqs, err := labels.ParseToRequirements(selector)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err)
|
||||
}
|
||||
|
||||
labelSelector := &LabelSelector{
|
||||
MatchLabels: map[string]string{},
|
||||
MatchExpressions: []LabelSelectorRequirement{},
|
||||
}
|
||||
for _, req := range reqs {
|
||||
var op LabelSelectorOperator
|
||||
switch req.Operator() {
|
||||
case selection.Equals, selection.DoubleEquals:
|
||||
vals := req.Values()
|
||||
if vals.Len() != 1 {
|
||||
return nil, fmt.Errorf("equals operator must have exactly one value")
|
||||
}
|
||||
val, ok := vals.PopAny()
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved")
|
||||
}
|
||||
labelSelector.MatchLabels[req.Key()] = val
|
||||
continue
|
||||
case selection.In:
|
||||
op = LabelSelectorOpIn
|
||||
case selection.NotIn:
|
||||
op = LabelSelectorOpNotIn
|
||||
case selection.Exists:
|
||||
op = LabelSelectorOpExists
|
||||
case selection.DoesNotExist:
|
||||
op = LabelSelectorOpDoesNotExist
|
||||
case selection.GreaterThan, selection.LessThan:
|
||||
// Adding a separate case for these operators to indicate that this is deliberate
|
||||
return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
|
||||
default:
|
||||
return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator())
|
||||
}
|
||||
labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{
|
||||
Key: req.Key(),
|
||||
Operator: op,
|
||||
Values: req.Values().List(),
|
||||
})
|
||||
}
|
||||
return labelSelector, nil
|
||||
}
|
||||
|
||||
// SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
|
||||
func SetAsLabelSelector(ls labels.Set) *LabelSelector {
|
||||
if ls == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
selector := &LabelSelector{
|
||||
MatchLabels: make(map[string]string),
|
||||
}
|
||||
for label, value := range ls {
|
||||
selector.MatchLabels[label] = value
|
||||
}
|
||||
|
||||
return selector
|
||||
}
|
||||
|
||||
// FormatLabelSelector convert labelSelector into plain string
|
||||
func FormatLabelSelector(labelSelector *LabelSelector) string {
|
||||
selector, err := LabelSelectorAsSelector(labelSelector)
|
||||
if err != nil {
|
||||
return "<error>"
|
||||
}
|
||||
|
||||
l := selector.String()
|
||||
if len(l) == 0 {
|
||||
l = "<none>"
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func ExtractGroupVersions(l *APIGroupList) []string {
|
||||
var groupVersions []string
|
||||
for _, g := range l.Groups {
|
||||
for _, gv := range g.Versions {
|
||||
groupVersions = append(groupVersions, gv.GroupVersion)
|
||||
}
|
||||
}
|
||||
return groupVersions
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
// ListMetaAccessor retrieves the list interface from an object
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type ListMetaAccessor interface {
|
||||
GetListMeta() List
|
||||
}
|
||||
|
||||
// List lets you work with list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field will be a no-op and return a default value.
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type List interface {
|
||||
GetResourceVersion() string
|
||||
SetResourceVersion(version string)
|
||||
GetSelfLink() string
|
||||
SetSelfLink(selfLink string)
|
||||
}
|
||||
|
||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||
// TODO: move this, and TypeMeta and ListMeta, to a different package
|
||||
type Type interface {
|
||||
GetAPIVersion() string
|
||||
SetAPIVersion(version string)
|
||||
GetKind() string
|
||||
SetKind(kind string)
|
||||
}
|
||||
|
||||
func (meta *ListMeta) GetResourceVersion() string { return meta.ResourceVersion }
|
||||
func (meta *ListMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
|
||||
func (meta *ListMeta) GetSelfLink() string { return meta.SelfLink }
|
||||
func (meta *ListMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
|
||||
|
||||
func (obj *TypeMeta) GetObjectKind() ObjectKind { return obj }
|
||||
|
||||
// SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
|
||||
func (obj *TypeMeta) SetGroupVersionKind(gvk GroupVersionKind) {
|
||||
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
|
||||
}
|
||||
|
||||
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
|
||||
func (obj *TypeMeta) GroupVersionKind() GroupVersionKind {
|
||||
return FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
|
||||
}
|
||||
|
||||
func (obj *ListMeta) GetListMeta() List { return obj }
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = GroupVersion{Group: "", Version: ""}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/genericapiserver/openapi/common"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
// Time is a wrapper around time.Time which supports correct
|
||||
// marshaling to YAML and JSON. Wrappers are provided for many
|
||||
// of the factory methods that the time package offers.
|
||||
//
|
||||
// +protobuf.options.marshal=false
|
||||
// +protobuf.as=Timestamp
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type Time struct {
|
||||
time.Time `protobuf:"-"`
|
||||
}
|
||||
|
||||
// DeepCopy returns a deep-copy of the Time value. The underlying time.Time
|
||||
// type is effectively immutable in the time API, so it is safe to
|
||||
// copy-by-assign, despite the presence of (unexported) Pointer fields.
|
||||
func (t Time) DeepCopy() Time {
|
||||
return t
|
||||
}
|
||||
|
||||
// String returns the representation of the time.
|
||||
func (t Time) String() string {
|
||||
return t.Time.String()
|
||||
}
|
||||
|
||||
// NewTime returns a wrapped instance of the provided time
|
||||
func NewTime(time time.Time) Time {
|
||||
return Time{time}
|
||||
}
|
||||
|
||||
// Date returns the Time corresponding to the supplied parameters
|
||||
// by wrapping time.Date.
|
||||
func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) Time {
|
||||
return Time{time.Date(year, month, day, hour, min, sec, nsec, loc)}
|
||||
}
|
||||
|
||||
// Now returns the current local time.
|
||||
func Now() Time {
|
||||
return Time{time.Now()}
|
||||
}
|
||||
|
||||
// IsZero returns true if the value is nil or time is zero.
|
||||
func (t *Time) IsZero() bool {
|
||||
if t == nil {
|
||||
return true
|
||||
}
|
||||
return t.Time.IsZero()
|
||||
}
|
||||
|
||||
// Before reports whether the time instant t is before u.
|
||||
func (t Time) Before(u Time) bool {
|
||||
return t.Time.Before(u.Time)
|
||||
}
|
||||
|
||||
// Equal reports whether the time instant t is equal to u.
|
||||
func (t Time) Equal(u Time) bool {
|
||||
return t.Time.Equal(u.Time)
|
||||
}
|
||||
|
||||
// Unix returns the local time corresponding to the given Unix time
|
||||
// by wrapping time.Unix.
|
||||
func Unix(sec int64, nsec int64) Time {
|
||||
return Time{time.Unix(sec, nsec)}
|
||||
}
|
||||
|
||||
// Rfc3339Copy returns a copy of the Time at second-level precision.
|
||||
func (t Time) Rfc3339Copy() Time {
|
||||
copied, _ := time.Parse(time.RFC3339, t.Format(time.RFC3339))
|
||||
return Time{copied}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (t *Time) UnmarshalJSON(b []byte) error {
|
||||
if len(b) == 4 && string(b) == "null" {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
var str string
|
||||
json.Unmarshal(b, &str)
|
||||
|
||||
pt, err := time.Parse(time.RFC3339, str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Time = pt.Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalQueryParameter converts from a URL query parameter value to an object
|
||||
func (t *Time) UnmarshalQueryParameter(str string) error {
|
||||
if len(str) == 0 {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
// Tolerate requests from older clients that used JSON serialization to build query params
|
||||
if len(str) == 4 && str == "null" {
|
||||
t.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
pt, err := time.Parse(time.RFC3339, str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.Time = pt.Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
if t.IsZero() {
|
||||
// Encode unset/nil objects as JSON's "null".
|
||||
return []byte("null"), nil
|
||||
}
|
||||
|
||||
return json.Marshal(t.UTC().Format(time.RFC3339))
|
||||
}
|
||||
|
||||
func (_ Time) OpenAPIDefinition() common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "date-time",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalQueryParameter converts to a URL query parameter value
|
||||
func (t Time) MarshalQueryParameter() (string, error) {
|
||||
if t.IsZero() {
|
||||
// Encode unset/nil objects as an empty string
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return t.UTC().Format(time.RFC3339), nil
|
||||
}
|
||||
|
||||
// Fuzz satisfies fuzz.Interface.
|
||||
func (t *Time) Fuzz(c fuzz.Continue) {
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
// Allow for about 1000 years of randomness. Leave off nanoseconds
|
||||
// because JSON doesn't represent them so they can't round-trip
|
||||
// properly.
|
||||
t.Time = time.Unix(c.Rand.Int63n(1000*365*24*60*60), 0)
|
||||
}
|
||||
|
||||
var _ fuzz.Interface = &Time{}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp is a struct that is equivalent to Time, but intended for
|
||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
||||
// that matches Time. Do not use in Go structs.
|
||||
type Timestamp struct {
|
||||
// Represents seconds of UTC time since Unix epoch
|
||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||
// 9999-12-31T23:59:59Z inclusive.
|
||||
Seconds int64 `json:"seconds" protobuf:"varint,1,opt,name=seconds"`
|
||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||
// second values with fractions must still have non-negative nanos values
|
||||
// that count forward in time. Must be from 0 to 999,999,999
|
||||
// inclusive. This field may be limited in precision depending on context.
|
||||
Nanos int32 `json:"nanos" protobuf:"varint,2,opt,name=nanos"`
|
||||
}
|
||||
|
||||
// Timestamp returns the Time as a new Timestamp value.
|
||||
func (m *Time) ProtoTime() *Timestamp {
|
||||
if m == nil {
|
||||
return &Timestamp{}
|
||||
}
|
||||
return &Timestamp{
|
||||
Seconds: m.Time.Unix(),
|
||||
Nanos: int32(m.Time.Nanosecond()),
|
||||
}
|
||||
}
|
||||
|
||||
// Size implements the protobuf marshalling interface.
|
||||
func (m *Time) Size() (n int) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return 0
|
||||
}
|
||||
return m.ProtoTime().Size()
|
||||
}
|
||||
|
||||
// Reset implements the protobuf marshalling interface.
|
||||
func (m *Time) Unmarshal(data []byte) error {
|
||||
if len(data) == 0 {
|
||||
m.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
p := Timestamp{}
|
||||
if err := p.Unmarshal(data); err != nil {
|
||||
return err
|
||||
}
|
||||
m.Time = time.Unix(p.Seconds, int64(p.Nanos)).Local()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Marshal implements the protobuf marshalling interface.
|
||||
func (m *Time) Marshal() (data []byte, err error) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
return m.ProtoTime().Marshal()
|
||||
}
|
||||
|
||||
// MarshalTo implements the protobuf marshalling interface.
|
||||
func (m *Time) MarshalTo(data []byte) (int, error) {
|
||||
if m == nil || m.Time.IsZero() {
|
||||
return 0, nil
|
||||
}
|
||||
return m.ProtoTime().MarshalTo(data)
|
||||
}
|
||||
@@ -1,460 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package unversioned contains API types that are common to all versions.
|
||||
//
|
||||
// The package contains two categories of types:
|
||||
// - external (serialized) types that lack their own version (e.g TypeMeta)
|
||||
// - internal (never-serialized) types that are needed by several different
|
||||
// api groups, and so live here, to avoid duplication and/or import loops
|
||||
// (e.g. LabelSelector).
|
||||
// In the future, we will probably move these categories of objects into
|
||||
// separate packages.
|
||||
package unversioned
|
||||
|
||||
import "strings"
|
||||
|
||||
// TypeMeta describes an individual object in an API response or request
|
||||
// with strings representing the type of the object and its API schema version.
|
||||
// Structures that are versioned or persisted should inline TypeMeta.
|
||||
type TypeMeta struct {
|
||||
// Kind is a string value representing the REST resource this object represents.
|
||||
// Servers may infer this from the endpoint the client submits requests to.
|
||||
// Cannot be updated.
|
||||
// In CamelCase.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
|
||||
|
||||
// APIVersion defines the versioned schema of this representation of an object.
|
||||
// Servers should convert recognized schemas to the latest internal value, and
|
||||
// may reject unrecognized values.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources
|
||||
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
|
||||
}
|
||||
|
||||
// ListMeta describes metadata that synthetic resources must have, including lists and
|
||||
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
|
||||
type ListMeta struct {
|
||||
// SelfLink is a URL representing this object.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,1,opt,name=selfLink"`
|
||||
|
||||
// String that identifies the server's internal version of this object that
|
||||
// can be used by clients to determine when objects have changed.
|
||||
// Value must be treated as opaque by clients and passed unmodified back to the server.
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency
|
||||
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,2,opt,name=resourceVersion"`
|
||||
}
|
||||
|
||||
// ExportOptions is the query options to the standard REST get call.
|
||||
type ExportOptions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Should this value be exported. Export strips fields that a user can not specify.`
|
||||
Export bool `json:"export" protobuf:"varint,1,opt,name=export"`
|
||||
// Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'
|
||||
Exact bool `json:"exact" protobuf:"varint,2,opt,name=exact"`
|
||||
}
|
||||
|
||||
// Status is a return value for calls that don't return other objects.
|
||||
type Status struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// Standard list metadata.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
// Status of the operation.
|
||||
// One of: "Success" or "Failure".
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status
|
||||
Status string `json:"status,omitempty" protobuf:"bytes,2,opt,name=status"`
|
||||
// A human-readable description of the status of this operation.
|
||||
Message string `json:"message,omitempty" protobuf:"bytes,3,opt,name=message"`
|
||||
// A machine-readable description of why this operation is in the
|
||||
// "Failure" status. If this value is empty there
|
||||
// is no information available. A Reason clarifies an HTTP status
|
||||
// code but does not override it.
|
||||
Reason StatusReason `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason,casttype=StatusReason"`
|
||||
// Extended data associated with the reason. Each reason may define its
|
||||
// own extended details. This field is optional and the data returned
|
||||
// is not guaranteed to conform to any schema except that defined by
|
||||
// the reason type.
|
||||
Details *StatusDetails `json:"details,omitempty" protobuf:"bytes,5,opt,name=details"`
|
||||
// Suggested HTTP return code for this status, 0 if not set.
|
||||
Code int32 `json:"code,omitempty" protobuf:"varint,6,opt,name=code"`
|
||||
}
|
||||
|
||||
// StatusDetails is a set of additional properties that MAY be set by the
|
||||
// server to provide additional information about a response. The Reason
|
||||
// field of a Status object defines what attributes will be set. Clients
|
||||
// must ignore fields that do not match the defined type of each attribute,
|
||||
// and should assume that any attribute may be empty, invalid, or under
|
||||
// defined.
|
||||
type StatusDetails struct {
|
||||
// The name attribute of the resource associated with the status StatusReason
|
||||
// (when there is a single name which can be described).
|
||||
Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
|
||||
// The group attribute of the resource associated with the status StatusReason.
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,2,opt,name=group"`
|
||||
// The kind attribute of the resource associated with the status StatusReason.
|
||||
// On some operations may differ from the requested resource Kind.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds
|
||||
Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"`
|
||||
// The Causes array includes more details associated with the StatusReason
|
||||
// failure. Not all StatusReasons may provide detailed causes.
|
||||
Causes []StatusCause `json:"causes,omitempty" protobuf:"bytes,4,rep,name=causes"`
|
||||
// If specified, the time in seconds before the operation should be retried.
|
||||
RetryAfterSeconds int32 `json:"retryAfterSeconds,omitempty" protobuf:"varint,5,opt,name=retryAfterSeconds"`
|
||||
}
|
||||
|
||||
// Values of Status.Status
|
||||
const (
|
||||
StatusSuccess = "Success"
|
||||
StatusFailure = "Failure"
|
||||
)
|
||||
|
||||
// StatusReason is an enumeration of possible failure causes. Each StatusReason
|
||||
// must map to a single HTTP status code, but multiple reasons may map
|
||||
// to the same HTTP status code.
|
||||
// TODO: move to apiserver
|
||||
type StatusReason string
|
||||
|
||||
const (
|
||||
// StatusReasonUnknown means the server has declined to indicate a specific reason.
|
||||
// The details field may contain other information about this error.
|
||||
// Status code 500.
|
||||
StatusReasonUnknown StatusReason = ""
|
||||
|
||||
// StatusReasonUnauthorized means the server can be reached and understood the request, but requires
|
||||
// the user to present appropriate authorization credentials (identified by the WWW-Authenticate header)
|
||||
// in order for the action to be completed. If the user has specified credentials on the request, the
|
||||
// server considers them insufficient.
|
||||
// Status code 401
|
||||
StatusReasonUnauthorized StatusReason = "Unauthorized"
|
||||
|
||||
// StatusReasonForbidden means the server can be reached and understood the request, but refuses
|
||||
// to take any further action. It is the result of the server being configured to deny access for some reason
|
||||
// to the requested resource by the client.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the forbidden resource
|
||||
// on some operations may differ from the requested
|
||||
// resource.
|
||||
// "id" string - the identifier of the forbidden resource
|
||||
// Status code 403
|
||||
StatusReasonForbidden StatusReason = "Forbidden"
|
||||
|
||||
// StatusReasonNotFound means one or more resources required for this operation
|
||||
// could not be found.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the missing resource
|
||||
// on some operations may differ from the requested
|
||||
// resource.
|
||||
// "id" string - the identifier of the missing resource
|
||||
// Status code 404
|
||||
StatusReasonNotFound StatusReason = "NotFound"
|
||||
|
||||
// StatusReasonAlreadyExists means the resource you are creating already exists.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the conflicting resource
|
||||
// "id" string - the identifier of the conflicting resource
|
||||
// Status code 409
|
||||
StatusReasonAlreadyExists StatusReason = "AlreadyExists"
|
||||
|
||||
// StatusReasonConflict means the requested operation cannot be completed
|
||||
// due to a conflict in the operation. The client may need to alter the
|
||||
// request. Each resource may define custom details that indicate the
|
||||
// nature of the conflict.
|
||||
// Status code 409
|
||||
StatusReasonConflict StatusReason = "Conflict"
|
||||
|
||||
// StatusReasonGone means the item is no longer available at the server and no
|
||||
// forwarding address is known.
|
||||
// Status code 410
|
||||
StatusReasonGone StatusReason = "Gone"
|
||||
|
||||
// StatusReasonInvalid means the requested create or update operation cannot be
|
||||
// completed due to invalid data provided as part of the request. The client may
|
||||
// need to alter the request. When set, the client may use the StatusDetails
|
||||
// message field as a summary of the issues encountered.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the invalid resource
|
||||
// "id" string - the identifier of the invalid resource
|
||||
// "causes" - one or more StatusCause entries indicating the data in the
|
||||
// provided resource that was invalid. The code, message, and
|
||||
// field attributes will be set.
|
||||
// Status code 422
|
||||
StatusReasonInvalid StatusReason = "Invalid"
|
||||
|
||||
// StatusReasonServerTimeout means the server can be reached and understood the request,
|
||||
// but cannot complete the action in a reasonable time. The client should retry the request.
|
||||
// This is may be due to temporary server load or a transient communication issue with
|
||||
// another server. Status code 500 is used because the HTTP spec provides no suitable
|
||||
// server-requested client retry and the 5xx class represents actionable errors.
|
||||
// Details (optional):
|
||||
// "kind" string - the kind attribute of the resource being acted on.
|
||||
// "id" string - the operation that is being attempted.
|
||||
// "retryAfterSeconds" int32 - the number of seconds before the operation should be retried
|
||||
// Status code 500
|
||||
StatusReasonServerTimeout StatusReason = "ServerTimeout"
|
||||
|
||||
// StatusReasonTimeout means that the request could not be completed within the given time.
|
||||
// Clients can get this response only when they specified a timeout param in the request,
|
||||
// or if the server cannot complete the operation within a reasonable amount of time.
|
||||
// The request might succeed with an increased value of timeout param. The client *should*
|
||||
// wait at least the number of seconds specified by the retryAfterSeconds field.
|
||||
// Details (optional):
|
||||
// "retryAfterSeconds" int32 - the number of seconds before the operation should be retried
|
||||
// Status code 504
|
||||
StatusReasonTimeout StatusReason = "Timeout"
|
||||
|
||||
// StatusReasonBadRequest means that the request itself was invalid, because the request
|
||||
// doesn't make any sense, for example deleting a read-only object. This is different than
|
||||
// StatusReasonInvalid above which indicates that the API call could possibly succeed, but the
|
||||
// data was invalid. API calls that return BadRequest can never succeed.
|
||||
StatusReasonBadRequest StatusReason = "BadRequest"
|
||||
|
||||
// StatusReasonMethodNotAllowed means that the action the client attempted to perform on the
|
||||
// resource was not supported by the code - for instance, attempting to delete a resource that
|
||||
// can only be created. API calls that return MethodNotAllowed can never succeed.
|
||||
StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed"
|
||||
|
||||
// StatusReasonInternalError indicates that an internal error occurred, it is unexpected
|
||||
// and the outcome of the call is unknown.
|
||||
// Details (optional):
|
||||
// "causes" - The original error
|
||||
// Status code 500
|
||||
StatusReasonInternalError StatusReason = "InternalError"
|
||||
|
||||
// StatusReasonExpired indicates that the request is invalid because the content you are requesting
|
||||
// has expired and is no longer available. It is typically associated with watches that can't be
|
||||
// serviced.
|
||||
// Status code 410 (gone)
|
||||
StatusReasonExpired StatusReason = "Expired"
|
||||
|
||||
// StatusReasonServiceUnavailable means that the request itself was valid,
|
||||
// but the requested service is unavailable at this time.
|
||||
// Retrying the request after some time might succeed.
|
||||
// Status code 503
|
||||
StatusReasonServiceUnavailable StatusReason = "ServiceUnavailable"
|
||||
)
|
||||
|
||||
// StatusCause provides more information about an api.Status failure, including
|
||||
// cases when multiple errors are encountered.
|
||||
type StatusCause struct {
|
||||
// A machine-readable description of the cause of the error. If this value is
|
||||
// empty there is no information available.
|
||||
Type CauseType `json:"reason,omitempty" protobuf:"bytes,1,opt,name=reason,casttype=CauseType"`
|
||||
// A human-readable description of the cause of the error. This field may be
|
||||
// presented as-is to a reader.
|
||||
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
|
||||
// The field of the resource that has caused this error, as named by its JSON
|
||||
// serialization. May include dot and postfix notation for nested attributes.
|
||||
// Arrays are zero-indexed. Fields may appear more than once in an array of
|
||||
// causes due to fields having multiple errors.
|
||||
// Optional.
|
||||
//
|
||||
// Examples:
|
||||
// "name" - the field "name" on the current resource
|
||||
// "items[0].name" - the field "name" on the first array entry in "items"
|
||||
Field string `json:"field,omitempty" protobuf:"bytes,3,opt,name=field"`
|
||||
}
|
||||
|
||||
// CauseType is a machine readable value providing more detail about what
|
||||
// occurred in a status response. An operation may have multiple causes for a
|
||||
// status (whether Failure or Success).
|
||||
type CauseType string
|
||||
|
||||
const (
|
||||
// CauseTypeFieldValueNotFound is used to report failure to find a requested value
|
||||
// (e.g. looking up an ID).
|
||||
CauseTypeFieldValueNotFound CauseType = "FieldValueNotFound"
|
||||
// CauseTypeFieldValueRequired is used to report required values that are not
|
||||
// provided (e.g. empty strings, null values, or empty arrays).
|
||||
CauseTypeFieldValueRequired CauseType = "FieldValueRequired"
|
||||
// CauseTypeFieldValueDuplicate is used to report collisions of values that must be
|
||||
// unique (e.g. unique IDs).
|
||||
CauseTypeFieldValueDuplicate CauseType = "FieldValueDuplicate"
|
||||
// CauseTypeFieldValueInvalid is used to report malformed values (e.g. failed regex
|
||||
// match).
|
||||
CauseTypeFieldValueInvalid CauseType = "FieldValueInvalid"
|
||||
// CauseTypeFieldValueNotSupported is used to report valid (as per formatting rules)
|
||||
// values that can not be handled (e.g. an enumerated string).
|
||||
CauseTypeFieldValueNotSupported CauseType = "FieldValueNotSupported"
|
||||
// CauseTypeUnexpectedServerResponse is used to report when the server responded to the client
|
||||
// without the expected return type. The presence of this cause indicates the error may be
|
||||
// due to an intervening proxy or the server software malfunctioning.
|
||||
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
|
||||
)
|
||||
|
||||
// APIVersions lists the versions that are available, to allow clients to
|
||||
// discover the API at /api, which is the root path of the legacy v1 API.
|
||||
//
|
||||
// +protobuf.options.(gogoproto.goproto_stringer)=false
|
||||
type APIVersions struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// versions are the api versions that are available.
|
||||
Versions []string `json:"versions" protobuf:"bytes,1,rep,name=versions"`
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,2,rep,name=serverAddressByClientCIDRs"`
|
||||
}
|
||||
|
||||
// APIGroupList is a list of APIGroup, to allow clients to discover the API at
|
||||
// /apis.
|
||||
type APIGroupList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// groups is a list of APIGroup.
|
||||
Groups []APIGroup `json:"groups" protobuf:"bytes,1,rep,name=groups"`
|
||||
}
|
||||
|
||||
// APIGroup contains the name, the supported versions, and the preferred version
|
||||
// of a group.
|
||||
type APIGroup struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// name is the name of the group.
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
// versions are the versions supported in this group.
|
||||
Versions []GroupVersionForDiscovery `json:"versions" protobuf:"bytes,2,rep,name=versions"`
|
||||
// preferredVersion is the version preferred by the API server, which
|
||||
// probably is the storage version.
|
||||
PreferredVersion GroupVersionForDiscovery `json:"preferredVersion,omitempty" protobuf:"bytes,3,opt,name=preferredVersion"`
|
||||
// a map of client CIDR to server address that is serving this group.
|
||||
// This is to help clients reach servers in the most network-efficient way possible.
|
||||
// Clients can use the appropriate server address as per the CIDR that they match.
|
||||
// In case of multiple matches, clients should use the longest matching CIDR.
|
||||
// The server returns only those CIDRs that it thinks that the client can match.
|
||||
// For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP.
|
||||
// Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.
|
||||
ServerAddressByClientCIDRs []ServerAddressByClientCIDR `json:"serverAddressByClientCIDRs" protobuf:"bytes,4,rep,name=serverAddressByClientCIDRs"`
|
||||
}
|
||||
|
||||
// ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.
|
||||
type ServerAddressByClientCIDR struct {
|
||||
// The CIDR with which clients can match their IP to figure out the server address that they should use.
|
||||
ClientCIDR string `json:"clientCIDR" protobuf:"bytes,1,opt,name=clientCIDR"`
|
||||
// Address of this server, suitable for a client that matches the above CIDR.
|
||||
// This can be a hostname, hostname:port, IP or IP:port.
|
||||
ServerAddress string `json:"serverAddress" protobuf:"bytes,2,opt,name=serverAddress"`
|
||||
}
|
||||
|
||||
// GroupVersion contains the "group/version" and "version" string of a version.
|
||||
// It is made a struct to keep extensibility.
|
||||
type GroupVersionForDiscovery struct {
|
||||
// groupVersion specifies the API group and version in the form "group/version"
|
||||
GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"`
|
||||
// version specifies the version in the form of "version". This is to save
|
||||
// the clients the trouble of splitting the GroupVersion.
|
||||
Version string `json:"version" protobuf:"bytes,2,opt,name=version"`
|
||||
}
|
||||
|
||||
// APIResource specifies the name of a resource and whether it is namespaced.
|
||||
type APIResource struct {
|
||||
// name is the name of the resource.
|
||||
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
|
||||
// namespaced indicates if a resource is namespaced or not.
|
||||
Namespaced bool `json:"namespaced" protobuf:"varint,2,opt,name=namespaced"`
|
||||
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
|
||||
Kind string `json:"kind" protobuf:"bytes,3,opt,name=kind"`
|
||||
}
|
||||
|
||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||
// resources supported in a specific group and version, and if the resource
|
||||
// is namespaced.
|
||||
type APIResourceList struct {
|
||||
TypeMeta `json:",inline"`
|
||||
// groupVersion is the group and version this APIResourceList is for.
|
||||
GroupVersion string `json:"groupVersion" protobuf:"bytes,1,opt,name=groupVersion"`
|
||||
// resources contains the name of the resources and if they are namespaced.
|
||||
APIResources []APIResource `json:"resources" protobuf:"bytes,2,rep,name=resources"`
|
||||
}
|
||||
|
||||
// RootPaths lists the paths available at root.
|
||||
// For example: "/healthz", "/apis".
|
||||
type RootPaths struct {
|
||||
// paths are the paths available at root.
|
||||
Paths []string `json:"paths" protobuf:"bytes,1,rep,name=paths"`
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func LabelSelectorQueryParam(version string) string {
|
||||
return "labelSelector"
|
||||
}
|
||||
|
||||
// TODO: remove me when watch is refactored
|
||||
func FieldSelectorQueryParam(version string) string {
|
||||
return "fieldSelector"
|
||||
}
|
||||
|
||||
// String returns available api versions as a human-friendly version string.
|
||||
func (apiVersions APIVersions) String() string {
|
||||
return strings.Join(apiVersions.Versions, ",")
|
||||
}
|
||||
|
||||
func (apiVersions APIVersions) GoString() string {
|
||||
return apiVersions.String()
|
||||
}
|
||||
|
||||
// Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.
|
||||
type Patch struct{}
|
||||
|
||||
// Note:
|
||||
// There are two different styles of label selectors used in versioned types:
|
||||
// an older style which is represented as just a string in versioned types, and a
|
||||
// newer style that is structured. LabelSelector is an internal representation for the
|
||||
// latter style.
|
||||
|
||||
// A label selector is a label query over a set of resources. The result of matchLabels and
|
||||
// matchExpressions are ANDed. An empty label selector matches all objects. A null
|
||||
// label selector matches no objects.
|
||||
type LabelSelector struct {
|
||||
// matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
// map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
// operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
|
||||
// matchExpressions is a list of label selector requirements. The requirements are ANDed.
|
||||
MatchExpressions []LabelSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"`
|
||||
}
|
||||
|
||||
// A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
// relates the key and values.
|
||||
type LabelSelectorRequirement struct {
|
||||
// key is the label key that the selector applies to.
|
||||
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
|
||||
// operator represents a key's relationship to a set of values.
|
||||
// Valid operators ard In, NotIn, Exists and DoesNotExist.
|
||||
Operator LabelSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"`
|
||||
// values is an array of string values. If the operator is In or NotIn,
|
||||
// the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
// the values array must be empty. This array is replaced during a strategic
|
||||
// merge patch.
|
||||
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
|
||||
}
|
||||
|
||||
// A label selector operator is the set of operators that can be used in a selector requirement.
|
||||
type LabelSelectorOperator string
|
||||
|
||||
const (
|
||||
LabelSelectorOpIn LabelSelectorOperator = "In"
|
||||
LabelSelectorOpNotIn LabelSelectorOperator = "NotIn"
|
||||
LabelSelectorOpExists LabelSelectorOperator = "Exists"
|
||||
LabelSelectorOpDoesNotExist LabelSelectorOperator = "DoesNotExist"
|
||||
)
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
// This file contains a collection of methods that can be used from go-restful to
|
||||
// generate Swagger API documentation for its models. Please read this PR for more
|
||||
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
|
||||
//
|
||||
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
|
||||
// they are on one line! For multiple line or blocks that you want to ignore use ---.
|
||||
// Any context after a --- is ignored.
|
||||
//
|
||||
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS START HERE
|
||||
var map_APIGroup = map[string]string{
|
||||
"": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"name": "name is the name of the group.",
|
||||
"versions": "versions are the versions supported in this group.",
|
||||
"preferredVersion": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"serverAddressByClientCIDRs": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
}
|
||||
|
||||
func (APIGroup) SwaggerDoc() map[string]string {
|
||||
return map_APIGroup
|
||||
}
|
||||
|
||||
var map_APIGroupList = map[string]string{
|
||||
"": "APIGroupList is a list of APIGroup, to allow clients to discover the API at /apis.",
|
||||
"groups": "groups is a list of APIGroup.",
|
||||
}
|
||||
|
||||
func (APIGroupList) SwaggerDoc() map[string]string {
|
||||
return map_APIGroupList
|
||||
}
|
||||
|
||||
var map_APIResource = map[string]string{
|
||||
"": "APIResource specifies the name of a resource and whether it is namespaced.",
|
||||
"name": "name is the name of the resource.",
|
||||
"namespaced": "namespaced indicates if a resource is namespaced or not.",
|
||||
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
|
||||
}
|
||||
|
||||
func (APIResource) SwaggerDoc() map[string]string {
|
||||
return map_APIResource
|
||||
}
|
||||
|
||||
var map_APIResourceList = map[string]string{
|
||||
"": "APIResourceList is a list of APIResource, it is used to expose the name of the resources supported in a specific group and version, and if the resource is namespaced.",
|
||||
"groupVersion": "groupVersion is the group and version this APIResourceList is for.",
|
||||
"resources": "resources contains the name of the resources and if they are namespaced.",
|
||||
}
|
||||
|
||||
func (APIResourceList) SwaggerDoc() map[string]string {
|
||||
return map_APIResourceList
|
||||
}
|
||||
|
||||
var map_APIVersions = map[string]string{
|
||||
"": "APIVersions lists the versions that are available, to allow clients to discover the API at /api, which is the root path of the legacy v1 API.",
|
||||
"versions": "versions are the api versions that are available.",
|
||||
"serverAddressByClientCIDRs": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
}
|
||||
|
||||
func (APIVersions) SwaggerDoc() map[string]string {
|
||||
return map_APIVersions
|
||||
}
|
||||
|
||||
var map_ExportOptions = map[string]string{
|
||||
"": "ExportOptions is the query options to the standard REST get call.",
|
||||
"export": "Should this value be exported. Export strips fields that a user can not specify.`",
|
||||
"exact": "Should the export be exact. Exact export maintains cluster-specific fields like 'Namespace'",
|
||||
}
|
||||
|
||||
func (ExportOptions) SwaggerDoc() map[string]string {
|
||||
return map_ExportOptions
|
||||
}
|
||||
|
||||
var map_GroupVersionForDiscovery = map[string]string{
|
||||
"": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"groupVersion": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"version": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
}
|
||||
|
||||
func (GroupVersionForDiscovery) SwaggerDoc() map[string]string {
|
||||
return map_GroupVersionForDiscovery
|
||||
}
|
||||
|
||||
var map_LabelSelector = map[string]string{
|
||||
"": "A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.",
|
||||
"matchLabels": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.",
|
||||
"matchExpressions": "matchExpressions is a list of label selector requirements. The requirements are ANDed.",
|
||||
}
|
||||
|
||||
func (LabelSelector) SwaggerDoc() map[string]string {
|
||||
return map_LabelSelector
|
||||
}
|
||||
|
||||
var map_LabelSelectorRequirement = map[string]string{
|
||||
"": "A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values.",
|
||||
"key": "key is the label key that the selector applies to.",
|
||||
"operator": "operator represents a key's relationship to a set of values. Valid operators ard In, NotIn, Exists and DoesNotExist.",
|
||||
"values": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.",
|
||||
}
|
||||
|
||||
func (LabelSelectorRequirement) SwaggerDoc() map[string]string {
|
||||
return map_LabelSelectorRequirement
|
||||
}
|
||||
|
||||
var map_ListMeta = map[string]string{
|
||||
"": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.",
|
||||
"selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.",
|
||||
"resourceVersion": "String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#concurrency-control-and-consistency",
|
||||
}
|
||||
|
||||
func (ListMeta) SwaggerDoc() map[string]string {
|
||||
return map_ListMeta
|
||||
}
|
||||
|
||||
var map_Patch = map[string]string{
|
||||
"": "Patch is provided to give a concrete name and type to the Kubernetes PATCH request body.",
|
||||
}
|
||||
|
||||
func (Patch) SwaggerDoc() map[string]string {
|
||||
return map_Patch
|
||||
}
|
||||
|
||||
var map_RootPaths = map[string]string{
|
||||
"": "RootPaths lists the paths available at root. For example: \"/healthz\", \"/apis\".",
|
||||
"paths": "paths are the paths available at root.",
|
||||
}
|
||||
|
||||
func (RootPaths) SwaggerDoc() map[string]string {
|
||||
return map_RootPaths
|
||||
}
|
||||
|
||||
var map_ServerAddressByClientCIDR = map[string]string{
|
||||
"": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"clientCIDR": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"serverAddress": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
}
|
||||
|
||||
func (ServerAddressByClientCIDR) SwaggerDoc() map[string]string {
|
||||
return map_ServerAddressByClientCIDR
|
||||
}
|
||||
|
||||
var map_Status = map[string]string{
|
||||
"": "Status is a return value for calls that don't return other objects.",
|
||||
"metadata": "Standard list metadata. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"status": "Status of the operation. One of: \"Success\" or \"Failure\". More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#spec-and-status",
|
||||
"message": "A human-readable description of the status of this operation.",
|
||||
"reason": "A machine-readable description of why this operation is in the \"Failure\" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it.",
|
||||
"details": "Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type.",
|
||||
"code": "Suggested HTTP return code for this status, 0 if not set.",
|
||||
}
|
||||
|
||||
func (Status) SwaggerDoc() map[string]string {
|
||||
return map_Status
|
||||
}
|
||||
|
||||
var map_StatusCause = map[string]string{
|
||||
"": "StatusCause provides more information about an api.Status failure, including cases when multiple errors are encountered.",
|
||||
"reason": "A machine-readable description of the cause of the error. If this value is empty there is no information available.",
|
||||
"message": "A human-readable description of the cause of the error. This field may be presented as-is to a reader.",
|
||||
"field": "The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional.\n\nExamples:\n \"name\" - the field \"name\" on the current resource\n \"items[0].name\" - the field \"name\" on the first array entry in \"items\"",
|
||||
}
|
||||
|
||||
func (StatusCause) SwaggerDoc() map[string]string {
|
||||
return map_StatusCause
|
||||
}
|
||||
|
||||
var map_StatusDetails = map[string]string{
|
||||
"": "StatusDetails is a set of additional properties that MAY be set by the server to provide additional information about a response. The Reason field of a Status object defines what attributes will be set. Clients must ignore fields that do not match the defined type of each attribute, and should assume that any attribute may be empty, invalid, or under defined.",
|
||||
"name": "The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described).",
|
||||
"group": "The group attribute of the resource associated with the status StatusReason.",
|
||||
"kind": "The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"causes": "The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes.",
|
||||
"retryAfterSeconds": "If specified, the time in seconds before the operation should be retried.",
|
||||
}
|
||||
|
||||
func (StatusDetails) SwaggerDoc() map[string]string {
|
||||
return map_StatusDetails
|
||||
}
|
||||
|
||||
var map_TypeMeta = map[string]string{
|
||||
"": "TypeMeta describes an individual object in an API response or request with strings representing the type of the object and its API schema version. Structures that are versioned or persisted should inline TypeMeta.",
|
||||
"kind": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds",
|
||||
"apiVersion": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#resources",
|
||||
}
|
||||
|
||||
func (TypeMeta) SwaggerDoc() map[string]string {
|
||||
return map_TypeMeta
|
||||
}
|
||||
|
||||
// AUTO-GENERATED FUNCTIONS END HERE
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unversioned
|
||||
|
||||
const (
|
||||
// If you add a new topology domain here, also consider adding it to the set of default values
|
||||
// for the scheduler's --failure-domain command-line argument.
|
||||
LabelHostname = "kubernetes.io/hostname"
|
||||
LabelZoneFailureDomain = "failure-domain.beta.kubernetes.io/zone"
|
||||
LabelZoneRegion = "failure-domain.beta.kubernetes.io/region"
|
||||
|
||||
LabelInstanceType = "beta.kubernetes.io/instance-type"
|
||||
|
||||
LabelOS = "beta.kubernetes.io/os"
|
||||
LabelArch = "beta.kubernetes.io/arch"
|
||||
)
|
||||
@@ -1,390 +0,0 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package unversioned
|
||||
|
||||
import (
|
||||
conversion "k8s.io/client-go/1.5/pkg/conversion"
|
||||
time "time"
|
||||
)
|
||||
|
||||
func DeepCopy_unversioned_APIGroup(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIGroup)
|
||||
out := out.(*APIGroup)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.Name = in.Name
|
||||
if in.Versions != nil {
|
||||
in, out := &in.Versions, &out.Versions
|
||||
*out = make([]GroupVersionForDiscovery, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.Versions = nil
|
||||
}
|
||||
out.PreferredVersion = in.PreferredVersion
|
||||
if in.ServerAddressByClientCIDRs != nil {
|
||||
in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
|
||||
*out = make([]ServerAddressByClientCIDR, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.ServerAddressByClientCIDRs = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIGroupList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIGroupList)
|
||||
out := out.(*APIGroupList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Groups != nil {
|
||||
in, out := &in.Groups, &out.Groups
|
||||
*out = make([]APIGroup, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_unversioned_APIGroup(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.Groups = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIResource)
|
||||
out := out.(*APIResource)
|
||||
out.Name = in.Name
|
||||
out.Namespaced = in.Namespaced
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIResourceList(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIResourceList)
|
||||
out := out.(*APIResourceList)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.GroupVersion = in.GroupVersion
|
||||
if in.APIResources != nil {
|
||||
in, out := &in.APIResources, &out.APIResources
|
||||
*out = make([]APIResource, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.APIResources = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_APIVersions(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*APIVersions)
|
||||
out := out.(*APIVersions)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Versions != nil {
|
||||
in, out := &in.Versions, &out.Versions
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Versions = nil
|
||||
}
|
||||
if in.ServerAddressByClientCIDRs != nil {
|
||||
in, out := &in.ServerAddressByClientCIDRs, &out.ServerAddressByClientCIDRs
|
||||
*out = make([]ServerAddressByClientCIDR, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.ServerAddressByClientCIDRs = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Duration(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Duration)
|
||||
out := out.(*Duration)
|
||||
out.Duration = in.Duration
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ExportOptions(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ExportOptions)
|
||||
out := out.(*ExportOptions)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.Export = in.Export
|
||||
out.Exact = in.Exact
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupKind(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupKind)
|
||||
out := out.(*GroupKind)
|
||||
out.Group = in.Group
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupResource)
|
||||
out := out.(*GroupResource)
|
||||
out.Group = in.Group
|
||||
out.Resource = in.Resource
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersion(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersion)
|
||||
out := out.(*GroupVersion)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionForDiscovery(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionForDiscovery)
|
||||
out := out.(*GroupVersionForDiscovery)
|
||||
out.GroupVersion = in.GroupVersion
|
||||
out.Version = in.Version
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionKind(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionKind)
|
||||
out := out.(*GroupVersionKind)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
out.Kind = in.Kind
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_GroupVersionResource(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*GroupVersionResource)
|
||||
out := out.(*GroupVersionResource)
|
||||
out.Group = in.Group
|
||||
out.Version = in.Version
|
||||
out.Resource = in.Resource
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_LabelSelector(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*LabelSelector)
|
||||
out := out.(*LabelSelector)
|
||||
if in.MatchLabels != nil {
|
||||
in, out := &in.MatchLabels, &out.MatchLabels
|
||||
*out = make(map[string]string)
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
} else {
|
||||
out.MatchLabels = nil
|
||||
}
|
||||
if in.MatchExpressions != nil {
|
||||
in, out := &in.MatchExpressions, &out.MatchExpressions
|
||||
*out = make([]LabelSelectorRequirement, len(*in))
|
||||
for i := range *in {
|
||||
if err := DeepCopy_unversioned_LabelSelectorRequirement(&(*in)[i], &(*out)[i], c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.MatchExpressions = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_LabelSelectorRequirement(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*LabelSelectorRequirement)
|
||||
out := out.(*LabelSelectorRequirement)
|
||||
out.Key = in.Key
|
||||
out.Operator = in.Operator
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Values = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ListMeta(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ListMeta)
|
||||
out := out.(*ListMeta)
|
||||
out.SelfLink = in.SelfLink
|
||||
out.ResourceVersion = in.ResourceVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Patch(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Patch)
|
||||
out := out.(*Patch)
|
||||
_ = in
|
||||
_ = out
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_RootPaths(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*RootPaths)
|
||||
out := out.(*RootPaths)
|
||||
if in.Paths != nil {
|
||||
in, out := &in.Paths, &out.Paths
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
} else {
|
||||
out.Paths = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_ServerAddressByClientCIDR(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*ServerAddressByClientCIDR)
|
||||
out := out.(*ServerAddressByClientCIDR)
|
||||
out.ClientCIDR = in.ClientCIDR
|
||||
out.ServerAddress = in.ServerAddress
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Status(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Status)
|
||||
out := out.(*Status)
|
||||
out.TypeMeta = in.TypeMeta
|
||||
out.ListMeta = in.ListMeta
|
||||
out.Status = in.Status
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
if in.Details != nil {
|
||||
in, out := &in.Details, &out.Details
|
||||
*out = new(StatusDetails)
|
||||
if err := DeepCopy_unversioned_StatusDetails(*in, *out, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.Details = nil
|
||||
}
|
||||
out.Code = in.Code
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_StatusCause(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatusCause)
|
||||
out := out.(*StatusCause)
|
||||
out.Type = in.Type
|
||||
out.Message = in.Message
|
||||
out.Field = in.Field
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_StatusDetails(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*StatusDetails)
|
||||
out := out.(*StatusDetails)
|
||||
out.Name = in.Name
|
||||
out.Group = in.Group
|
||||
out.Kind = in.Kind
|
||||
if in.Causes != nil {
|
||||
in, out := &in.Causes, &out.Causes
|
||||
*out = make([]StatusCause, len(*in))
|
||||
for i := range *in {
|
||||
(*out)[i] = (*in)[i]
|
||||
}
|
||||
} else {
|
||||
out.Causes = nil
|
||||
}
|
||||
out.RetryAfterSeconds = in.RetryAfterSeconds
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Time(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Time)
|
||||
out := out.(*Time)
|
||||
if newVal, err := c.DeepCopy(&in.Time); err != nil {
|
||||
return err
|
||||
} else {
|
||||
out.Time = *newVal.(*time.Time)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_Timestamp(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*Timestamp)
|
||||
out := out.(*Timestamp)
|
||||
out.Seconds = in.Seconds
|
||||
out.Nanos = in.Nanos
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeepCopy_unversioned_TypeMeta(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
{
|
||||
in := in.(*TypeMeta)
|
||||
out := out.(*TypeMeta)
|
||||
out.Kind = in.Kind
|
||||
out.APIVersion = in.APIVersion
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package path
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)
|
||||
var NameMayNotBe = []string{".", ".."}
|
||||
|
||||
// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store)
|
||||
var NameMayNotContain = []string{"/", "%"}
|
||||
|
||||
// IsValidPathSegmentName validates the name can be safely encoded as a path segment
|
||||
func IsValidPathSegmentName(name string) []string {
|
||||
for _, illegalName := range NameMayNotBe {
|
||||
if name == illegalName {
|
||||
return []string{fmt.Sprintf(`may not be '%s'`, illegalName)}
|
||||
}
|
||||
}
|
||||
|
||||
for _, illegalContent := range NameMayNotContain {
|
||||
if strings.Contains(name, illegalContent) {
|
||||
return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment
|
||||
// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid
|
||||
func IsValidPathSegmentPrefix(name string) []string {
|
||||
for _, illegalContent := range NameMayNotContain {
|
||||
if strings.Contains(name, illegalContent) {
|
||||
return []string{fmt.Sprintf(`may not contain '%s'`, illegalContent)}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidatePathSegmentName validates the name can be safely encoded as a path segment
|
||||
func ValidatePathSegmentName(name string, prefix bool) []string {
|
||||
if prefix {
|
||||
return IsValidPathSegmentPrefix(name)
|
||||
} else {
|
||||
return IsValidPathSegmentName(name)
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package announced contains tools for announcing API group factories. This is
|
||||
// distinct from registration (in the 'registered' package) in that it's safe
|
||||
// to announce every possible group linked in, but only groups requested at
|
||||
// runtime should be registered. This package contains both a registry, and
|
||||
// factory code (which was formerly copy-pasta in every install package).
|
||||
package announced
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultGroupFactoryRegistry = make(APIGroupFactoryRegistry)
|
||||
|
||||
// These functions will announce your group or version.
|
||||
AnnounceGroupVersion = DefaultGroupFactoryRegistry.AnnounceGroupVersion
|
||||
AnnounceGroup = DefaultGroupFactoryRegistry.AnnounceGroup
|
||||
)
|
||||
|
||||
// APIGroupFactoryRegistry allows for groups and versions to announce themselves,
|
||||
// which simply makes them available and doesn't take other actions. Later,
|
||||
// users of the registry can select which groups and versions they'd actually
|
||||
// like to register with an APIRegistrationManager.
|
||||
//
|
||||
// (Right now APIRegistrationManager has separate 'registration' and 'enabled'
|
||||
// concepts-- APIGroupFactory is going to take over the former function;
|
||||
// they will overlap untill the refactoring is finished.)
|
||||
//
|
||||
// The key is the group name. After initialization, this should be treated as
|
||||
// read-only. It is implemented as a map from group name to group factory, and
|
||||
// it is safe to use this knowledge to manually pick out groups to register
|
||||
// (e.g., for testing).
|
||||
type APIGroupFactoryRegistry map[string]*GroupMetaFactory
|
||||
|
||||
func (gar APIGroupFactoryRegistry) group(groupName string) *GroupMetaFactory {
|
||||
gmf, ok := gar[groupName]
|
||||
if !ok {
|
||||
gmf = &GroupMetaFactory{VersionArgs: map[string]*GroupVersionFactoryArgs{}}
|
||||
gar[groupName] = gmf
|
||||
}
|
||||
return gmf
|
||||
}
|
||||
|
||||
// AnnounceGroupVersion adds the particular arguments for this group version to the group factory.
|
||||
func (gar APIGroupFactoryRegistry) AnnounceGroupVersion(gvf *GroupVersionFactoryArgs) error {
|
||||
gmf := gar.group(gvf.GroupName)
|
||||
if _, ok := gmf.VersionArgs[gvf.VersionName]; ok {
|
||||
return fmt.Errorf("version %q in group %q has already been announced", gvf.VersionName, gvf.GroupName)
|
||||
}
|
||||
gmf.VersionArgs[gvf.VersionName] = gvf
|
||||
return nil
|
||||
}
|
||||
|
||||
// AnnounceGroup adds the group-wide arguments to the group factory.
|
||||
func (gar APIGroupFactoryRegistry) AnnounceGroup(args *GroupMetaFactoryArgs) error {
|
||||
gmf := gar.group(args.GroupName)
|
||||
if gmf.GroupArgs != nil {
|
||||
return fmt.Errorf("group %q has already been announced", args.GroupName)
|
||||
}
|
||||
gmf.GroupArgs = args
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAndEnableAll throws every factory at the specified API registration
|
||||
// manager, and lets it decide which to register. (If you want to do this a la
|
||||
// cart, you may look through gar itself-- it's just a map.)
|
||||
func (gar APIGroupFactoryRegistry) RegisterAndEnableAll(m *registered.APIRegistrationManager, scheme *runtime.Scheme) error {
|
||||
for groupName, gmf := range gar {
|
||||
if err := gmf.Register(m); err != nil {
|
||||
return fmt.Errorf("error registering %v: %v", groupName, err)
|
||||
}
|
||||
if err := gmf.Enable(m, scheme); err != nil {
|
||||
return fmt.Errorf("error enabling %v: %v", groupName, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AnnouncePreconstructedFactory announces a factory which you've manually assembled.
|
||||
// You may call this instead of calling AnnounceGroup and AnnounceGroupVersion.
|
||||
func (gar APIGroupFactoryRegistry) AnnouncePreconstructedFactory(gmf *GroupMetaFactory) error {
|
||||
name := gmf.GroupArgs.GroupName
|
||||
if _, exists := gar[name]; exists {
|
||||
return fmt.Errorf("the group %q has already been announced.", name)
|
||||
}
|
||||
gar[name] = gmf
|
||||
return nil
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package announced
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery/registered"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
type SchemeFunc func(*runtime.Scheme) error
|
||||
type VersionToSchemeFunc map[string]SchemeFunc
|
||||
|
||||
// GroupVersionFactoryArgs contains all the per-version parts of a GroupMetaFactory.
|
||||
type GroupVersionFactoryArgs struct {
|
||||
GroupName string
|
||||
VersionName string
|
||||
|
||||
AddToScheme SchemeFunc
|
||||
}
|
||||
|
||||
// GroupMetaFactoryArgs contains the group-level args of a GroupMetaFactory.
|
||||
type GroupMetaFactoryArgs struct {
|
||||
GroupName string
|
||||
VersionPreferenceOrder []string
|
||||
ImportPrefix string
|
||||
|
||||
RootScopedKinds sets.String // nil is allowed
|
||||
IgnoredKinds sets.String // nil is allowed
|
||||
|
||||
// May be nil if there are no internal objects.
|
||||
AddInternalObjectsToScheme SchemeFunc
|
||||
}
|
||||
|
||||
// NewGroupMetaFactory builds the args for you. This is for if you're
|
||||
// constructing a factory all at once and not using the registry.
|
||||
func NewGroupMetaFactory(groupArgs *GroupMetaFactoryArgs, versions VersionToSchemeFunc) *GroupMetaFactory {
|
||||
gmf := &GroupMetaFactory{
|
||||
GroupArgs: groupArgs,
|
||||
VersionArgs: map[string]*GroupVersionFactoryArgs{},
|
||||
}
|
||||
for v, f := range versions {
|
||||
gmf.VersionArgs[v] = &GroupVersionFactoryArgs{
|
||||
GroupName: groupArgs.GroupName,
|
||||
VersionName: v,
|
||||
AddToScheme: f,
|
||||
}
|
||||
}
|
||||
return gmf
|
||||
}
|
||||
|
||||
// Announce adds this Group factory to the global factory registry. It should
|
||||
// only be called if you constructed the GroupMetaFactory yourself via
|
||||
// NewGroupMetadFactory.
|
||||
// Note that this will panic on an error, since it's expected that you'll be
|
||||
// calling this at initialization time and any error is a result of a
|
||||
// programmer importing the wrong set of packages. If this assumption doesn't
|
||||
// work for you, just call DefaultGroupFactoryRegistry.AnnouncePreconstructedFactory
|
||||
// yourself.
|
||||
func (gmf *GroupMetaFactory) Announce() *GroupMetaFactory {
|
||||
if err := DefaultGroupFactoryRegistry.AnnouncePreconstructedFactory(gmf); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gmf
|
||||
}
|
||||
|
||||
// GroupMetaFactory has the logic for actually assembling and registering a group.
|
||||
//
|
||||
// There are two ways of obtaining one of these.
|
||||
// 1. You can announce your group and versions separately, and then let the
|
||||
// GroupFactoryRegistry assemble this object for you. (This allows group and
|
||||
// versions to be imported separately, without referencing each other, to
|
||||
// keep import trees small.)
|
||||
// 2. You can call NewGroupMetaFactory(), which is mostly a drop-in replacement
|
||||
// for the old, bad way of doing things. You can then call .Announce() to
|
||||
// announce your constructed factory to any code that would like to do
|
||||
// things the new, better way.
|
||||
//
|
||||
// Note that GroupMetaFactory actually does construct GroupMeta objects, but
|
||||
// currently it does so in a way that's very entangled with an
|
||||
// APIRegistrationManager. It's a TODO item to cleanly separate that interface.
|
||||
type GroupMetaFactory struct {
|
||||
GroupArgs *GroupMetaFactoryArgs
|
||||
// map of version name to version factory
|
||||
VersionArgs map[string]*GroupVersionFactoryArgs
|
||||
|
||||
// assembled by Register()
|
||||
prioritizedVersionList []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
// Register constructs the finalized prioritized version list and sanity checks
|
||||
// the announced group & versions. Then it calls register.
|
||||
func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager) error {
|
||||
if gmf.GroupArgs == nil {
|
||||
return fmt.Errorf("partially announced groups are not allowed, only got versions: %#v", gmf.VersionArgs)
|
||||
}
|
||||
if len(gmf.VersionArgs) == 0 {
|
||||
return fmt.Errorf("group %v announced but no versions announced", gmf.GroupArgs.GroupName)
|
||||
}
|
||||
|
||||
pvSet := sets.NewString(gmf.GroupArgs.VersionPreferenceOrder...)
|
||||
if pvSet.Len() != len(gmf.GroupArgs.VersionPreferenceOrder) {
|
||||
return fmt.Errorf("preference order for group %v has duplicates: %v", gmf.GroupArgs.GroupName, gmf.GroupArgs.VersionPreferenceOrder)
|
||||
}
|
||||
prioritizedVersions := []unversioned.GroupVersion{}
|
||||
for _, v := range gmf.GroupArgs.VersionPreferenceOrder {
|
||||
prioritizedVersions = append(
|
||||
prioritizedVersions,
|
||||
unversioned.GroupVersion{
|
||||
Group: gmf.GroupArgs.GroupName,
|
||||
Version: v,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Go through versions that weren't explicitly prioritized.
|
||||
unprioritizedVersions := []unversioned.GroupVersion{}
|
||||
for _, v := range gmf.VersionArgs {
|
||||
if v.GroupName != gmf.GroupArgs.GroupName {
|
||||
return fmt.Errorf("found %v/%v in group %v?", v.GroupName, v.VersionName, gmf.GroupArgs.GroupName)
|
||||
}
|
||||
if pvSet.Has(v.VersionName) {
|
||||
pvSet.Delete(v.VersionName)
|
||||
continue
|
||||
}
|
||||
unprioritizedVersions = append(unprioritizedVersions, unversioned.GroupVersion{Group: v.GroupName, Version: v.VersionName})
|
||||
}
|
||||
if len(unprioritizedVersions) > 1 {
|
||||
glog.Warningf("group %v has multiple unprioritized versions: %#v. They will have an arbitrary preference order!", gmf.GroupArgs.GroupName, unprioritizedVersions)
|
||||
}
|
||||
if pvSet.Len() != 0 {
|
||||
return fmt.Errorf("group %v has versions in the priority list that were never announced: %s", gmf.GroupArgs.GroupName, pvSet)
|
||||
}
|
||||
prioritizedVersions = append(prioritizedVersions, unprioritizedVersions...)
|
||||
m.RegisterVersions(prioritizedVersions)
|
||||
gmf.prioritizedVersionList = prioritizedVersions
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gmf *GroupMetaFactory) newRESTMapper(scheme *runtime.Scheme, externalVersions []unversioned.GroupVersion, groupMeta *apimachinery.GroupMeta) meta.RESTMapper {
|
||||
// the list of kinds that are scoped at the root of the api hierarchy
|
||||
// if a kind is not enumerated here, it is assumed to have a namespace scope
|
||||
rootScoped := sets.NewString()
|
||||
if gmf.GroupArgs.RootScopedKinds != nil {
|
||||
rootScoped = gmf.GroupArgs.RootScopedKinds
|
||||
}
|
||||
ignoredKinds := sets.NewString()
|
||||
if gmf.GroupArgs.IgnoredKinds != nil {
|
||||
ignoredKinds = gmf.GroupArgs.IgnoredKinds
|
||||
}
|
||||
|
||||
return api.NewDefaultRESTMapperFromScheme(
|
||||
externalVersions,
|
||||
groupMeta.InterfacesFor,
|
||||
gmf.GroupArgs.ImportPrefix,
|
||||
ignoredKinds,
|
||||
rootScoped,
|
||||
scheme,
|
||||
)
|
||||
}
|
||||
|
||||
// Enable enables group versions that are allowed, adds methods to the scheme, etc.
|
||||
func (gmf *GroupMetaFactory) Enable(m *registered.APIRegistrationManager, scheme *runtime.Scheme) error {
|
||||
externalVersions := []unversioned.GroupVersion{}
|
||||
for _, v := range gmf.prioritizedVersionList {
|
||||
if !m.IsAllowedVersion(v) {
|
||||
continue
|
||||
}
|
||||
externalVersions = append(externalVersions, v)
|
||||
if err := m.EnableVersions(v); err != nil {
|
||||
return err
|
||||
}
|
||||
gmf.VersionArgs[v.Version].AddToScheme(scheme)
|
||||
}
|
||||
if len(externalVersions) == 0 {
|
||||
glog.V(4).Infof("No version is registered for group %v", gmf.GroupArgs.GroupName)
|
||||
return nil
|
||||
}
|
||||
|
||||
if gmf.GroupArgs.AddInternalObjectsToScheme != nil {
|
||||
gmf.GroupArgs.AddInternalObjectsToScheme(scheme)
|
||||
}
|
||||
|
||||
preferredExternalVersion := externalVersions[0]
|
||||
accessor := meta.NewAccessor()
|
||||
|
||||
groupMeta := &apimachinery.GroupMeta{
|
||||
GroupVersion: preferredExternalVersion,
|
||||
GroupVersions: externalVersions,
|
||||
SelfLinker: runtime.SelfLinker(accessor),
|
||||
}
|
||||
for _, v := range externalVersions {
|
||||
gvf := gmf.VersionArgs[v.Version]
|
||||
if err := groupMeta.AddVersionInterfaces(
|
||||
unversioned.GroupVersion{Group: gvf.GroupName, Version: gvf.VersionName},
|
||||
&meta.VersionInterfaces{
|
||||
ObjectConvertor: scheme,
|
||||
MetadataAccessor: accessor,
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
groupMeta.InterfacesFor = groupMeta.DefaultInterfacesFor
|
||||
groupMeta.RESTMapper = gmf.newRESTMapper(scheme, externalVersions, groupMeta)
|
||||
|
||||
if err := m.RegisterGroup(*groupMeta); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAndEnable is provided only to allow this code to get added in multiple steps.
|
||||
// It's really bad that this is called in init() methods, but supporting this
|
||||
// temporarily lets us do the change incrementally.
|
||||
func (gmf *GroupMetaFactory) RegisterAndEnable() error {
|
||||
if err := gmf.Register(registered.DefaultAPIRegistrationManager); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gmf.Enable(registered.DefaultAPIRegistrationManager, api.Scheme); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package to keep track of API Versions that can be registered and are enabled in api.Scheme.
|
||||
package registered
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/apimachinery"
|
||||
"k8s.io/client-go/1.5/pkg/util/sets"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultAPIRegistrationManager = NewOrDie(os.Getenv("KUBE_API_VERSIONS"))
|
||||
)
|
||||
|
||||
// APIRegistrationManager provides the concept of what API groups are enabled.
|
||||
//
|
||||
// TODO: currently, it also provides a "registered" concept. But it's wrong to
|
||||
// have both concepts in the same object. Therefore the "announced" package is
|
||||
// going to take over the registered concept. After all the install packages
|
||||
// are switched to using the announce package instead of this package, then we
|
||||
// can combine the registered/enabled concepts in this object. Simplifying this
|
||||
// isn't easy right now because there are so many callers of this package.
|
||||
type APIRegistrationManager struct {
|
||||
// registeredGroupVersions stores all API group versions for which RegisterGroup is called.
|
||||
registeredVersions map[unversioned.GroupVersion]struct{}
|
||||
|
||||
// thirdPartyGroupVersions are API versions which are dynamically
|
||||
// registered (and unregistered) via API calls to the apiserver
|
||||
thirdPartyGroupVersions []unversioned.GroupVersion
|
||||
|
||||
// enabledVersions represents all enabled API versions. It should be a
|
||||
// subset of registeredVersions. Please call EnableVersions() to add
|
||||
// enabled versions.
|
||||
enabledVersions map[unversioned.GroupVersion]struct{}
|
||||
|
||||
// map of group meta for all groups.
|
||||
groupMetaMap map[string]*apimachinery.GroupMeta
|
||||
|
||||
// envRequestedVersions represents the versions requested via the
|
||||
// KUBE_API_VERSIONS environment variable. The install package of each group
|
||||
// checks this list before add their versions to the latest package and
|
||||
// Scheme. This list is small and order matters, so represent as a slice
|
||||
envRequestedVersions []unversioned.GroupVersion
|
||||
}
|
||||
|
||||
// NewAPIRegistrationManager constructs a new manager. The argument ought to be
|
||||
// the value of the KUBE_API_VERSIONS env var, or a value of this which you
|
||||
// wish to test.
|
||||
func NewAPIRegistrationManager(kubeAPIVersions string) (*APIRegistrationManager, error) {
|
||||
m := &APIRegistrationManager{
|
||||
registeredVersions: map[unversioned.GroupVersion]struct{}{},
|
||||
thirdPartyGroupVersions: []unversioned.GroupVersion{},
|
||||
enabledVersions: map[unversioned.GroupVersion]struct{}{},
|
||||
groupMetaMap: map[string]*apimachinery.GroupMeta{},
|
||||
envRequestedVersions: []unversioned.GroupVersion{},
|
||||
}
|
||||
|
||||
if len(kubeAPIVersions) != 0 {
|
||||
for _, version := range strings.Split(kubeAPIVersions, ",") {
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid api version: %s in KUBE_API_VERSIONS: %s.",
|
||||
version, kubeAPIVersions)
|
||||
}
|
||||
m.envRequestedVersions = append(m.envRequestedVersions, gv)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func NewOrDie(kubeAPIVersions string) *APIRegistrationManager {
|
||||
m, err := NewAPIRegistrationManager(kubeAPIVersions)
|
||||
if err != nil {
|
||||
glog.Fatalf("Could not construct version manager: %v (KUBE_API_VERSIONS=%q)", err, kubeAPIVersions)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// People are calling global functions. Let them continue to do that (for now).
|
||||
var (
|
||||
ValidateEnvRequestedVersions = DefaultAPIRegistrationManager.ValidateEnvRequestedVersions
|
||||
AllPreferredGroupVersions = DefaultAPIRegistrationManager.AllPreferredGroupVersions
|
||||
RESTMapper = DefaultAPIRegistrationManager.RESTMapper
|
||||
GroupOrDie = DefaultAPIRegistrationManager.GroupOrDie
|
||||
AddThirdPartyAPIGroupVersions = DefaultAPIRegistrationManager.AddThirdPartyAPIGroupVersions
|
||||
IsThirdPartyAPIGroupVersion = DefaultAPIRegistrationManager.IsThirdPartyAPIGroupVersion
|
||||
RegisteredGroupVersions = DefaultAPIRegistrationManager.RegisteredGroupVersions
|
||||
IsRegisteredVersion = DefaultAPIRegistrationManager.IsRegisteredVersion
|
||||
IsRegistered = DefaultAPIRegistrationManager.IsRegistered
|
||||
Group = DefaultAPIRegistrationManager.Group
|
||||
EnabledVersionsForGroup = DefaultAPIRegistrationManager.EnabledVersionsForGroup
|
||||
EnabledVersions = DefaultAPIRegistrationManager.EnabledVersions
|
||||
IsEnabledVersion = DefaultAPIRegistrationManager.IsEnabledVersion
|
||||
IsAllowedVersion = DefaultAPIRegistrationManager.IsAllowedVersion
|
||||
EnableVersions = DefaultAPIRegistrationManager.EnableVersions
|
||||
RegisterGroup = DefaultAPIRegistrationManager.RegisterGroup
|
||||
RegisterVersions = DefaultAPIRegistrationManager.RegisterVersions
|
||||
InterfacesFor = DefaultAPIRegistrationManager.InterfacesFor
|
||||
)
|
||||
|
||||
// RegisterVersions adds the given group versions to the list of registered group versions.
|
||||
func (m *APIRegistrationManager) RegisterVersions(availableVersions []unversioned.GroupVersion) {
|
||||
for _, v := range availableVersions {
|
||||
m.registeredVersions[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterGroup adds the given group to the list of registered groups.
|
||||
func (m *APIRegistrationManager) RegisterGroup(groupMeta apimachinery.GroupMeta) error {
|
||||
groupName := groupMeta.GroupVersion.Group
|
||||
if _, found := m.groupMetaMap[groupName]; found {
|
||||
return fmt.Errorf("group %v is already registered", m.groupMetaMap)
|
||||
}
|
||||
m.groupMetaMap[groupName] = &groupMeta
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnableVersions adds the versions for the given group to the list of enabled versions.
|
||||
// Note that the caller should call RegisterGroup before calling this method.
|
||||
// The caller of this function is responsible to add the versions to scheme and RESTMapper.
|
||||
func (m *APIRegistrationManager) EnableVersions(versions ...unversioned.GroupVersion) error {
|
||||
var unregisteredVersions []unversioned.GroupVersion
|
||||
for _, v := range versions {
|
||||
if _, found := m.registeredVersions[v]; !found {
|
||||
unregisteredVersions = append(unregisteredVersions, v)
|
||||
}
|
||||
m.enabledVersions[v] = struct{}{}
|
||||
}
|
||||
if len(unregisteredVersions) != 0 {
|
||||
return fmt.Errorf("Please register versions before enabling them: %v", unregisteredVersions)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsAllowedVersion returns if the version is allowed by the KUBE_API_VERSIONS
|
||||
// environment variable. If the environment variable is empty, then it always
|
||||
// returns true.
|
||||
func (m *APIRegistrationManager) IsAllowedVersion(v unversioned.GroupVersion) bool {
|
||||
if len(m.envRequestedVersions) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, envGV := range m.envRequestedVersions {
|
||||
if v == envGV {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsEnabledVersion returns if a version is enabled.
|
||||
func (m *APIRegistrationManager) IsEnabledVersion(v unversioned.GroupVersion) bool {
|
||||
_, found := m.enabledVersions[v]
|
||||
return found
|
||||
}
|
||||
|
||||
// EnabledVersions returns all enabled versions. Groups are randomly ordered, but versions within groups
|
||||
// are priority order from best to worst
|
||||
func (m *APIRegistrationManager) EnabledVersions() []unversioned.GroupVersion {
|
||||
ret := []unversioned.GroupVersion{}
|
||||
for _, groupMeta := range m.groupMetaMap {
|
||||
for _, version := range groupMeta.GroupVersions {
|
||||
if m.IsEnabledVersion(version) {
|
||||
ret = append(ret, version)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// EnabledVersionsForGroup returns all enabled versions for a group in order of best to worst
|
||||
func (m *APIRegistrationManager) EnabledVersionsForGroup(group string) []unversioned.GroupVersion {
|
||||
groupMeta, ok := m.groupMetaMap[group]
|
||||
if !ok {
|
||||
return []unversioned.GroupVersion{}
|
||||
}
|
||||
|
||||
ret := []unversioned.GroupVersion{}
|
||||
for _, version := range groupMeta.GroupVersions {
|
||||
if m.IsEnabledVersion(version) {
|
||||
ret = append(ret, version)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Group returns the metadata of a group if the group is registered, otherwise
|
||||
// an error is returned.
|
||||
func (m *APIRegistrationManager) Group(group string) (*apimachinery.GroupMeta, error) {
|
||||
groupMeta, found := m.groupMetaMap[group]
|
||||
if !found {
|
||||
return nil, fmt.Errorf("group %v has not been registered", group)
|
||||
}
|
||||
groupMetaCopy := *groupMeta
|
||||
return &groupMetaCopy, nil
|
||||
}
|
||||
|
||||
// IsRegistered takes a string and determines if it's one of the registered groups
|
||||
func (m *APIRegistrationManager) IsRegistered(group string) bool {
|
||||
_, found := m.groupMetaMap[group]
|
||||
return found
|
||||
}
|
||||
|
||||
// IsRegisteredVersion returns if a version is registered.
|
||||
func (m *APIRegistrationManager) IsRegisteredVersion(v unversioned.GroupVersion) bool {
|
||||
_, found := m.registeredVersions[v]
|
||||
return found
|
||||
}
|
||||
|
||||
// RegisteredGroupVersions returns all registered group versions.
|
||||
func (m *APIRegistrationManager) RegisteredGroupVersions() []unversioned.GroupVersion {
|
||||
ret := []unversioned.GroupVersion{}
|
||||
for groupVersion := range m.registeredVersions {
|
||||
ret = append(ret, groupVersion)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// IsThirdPartyAPIGroupVersion returns true if the api version is a user-registered group/version.
|
||||
func (m *APIRegistrationManager) IsThirdPartyAPIGroupVersion(gv unversioned.GroupVersion) bool {
|
||||
for ix := range m.thirdPartyGroupVersions {
|
||||
if m.thirdPartyGroupVersions[ix] == gv {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddThirdPartyAPIGroupVersions sets the list of third party versions,
|
||||
// registers them in the API machinery and enables them.
|
||||
// Skips GroupVersions that are already registered.
|
||||
// Returns the list of GroupVersions that were skipped.
|
||||
func (m *APIRegistrationManager) AddThirdPartyAPIGroupVersions(gvs ...unversioned.GroupVersion) []unversioned.GroupVersion {
|
||||
filteredGVs := []unversioned.GroupVersion{}
|
||||
skippedGVs := []unversioned.GroupVersion{}
|
||||
for ix := range gvs {
|
||||
if !m.IsRegisteredVersion(gvs[ix]) {
|
||||
filteredGVs = append(filteredGVs, gvs[ix])
|
||||
} else {
|
||||
glog.V(3).Infof("Skipping %s, because its already registered", gvs[ix].String())
|
||||
skippedGVs = append(skippedGVs, gvs[ix])
|
||||
}
|
||||
}
|
||||
if len(filteredGVs) == 0 {
|
||||
return skippedGVs
|
||||
}
|
||||
m.RegisterVersions(filteredGVs)
|
||||
m.EnableVersions(filteredGVs...)
|
||||
m.thirdPartyGroupVersions = append(m.thirdPartyGroupVersions, filteredGVs...)
|
||||
|
||||
return skippedGVs
|
||||
}
|
||||
|
||||
// InterfacesFor is a union meta.VersionInterfacesFunc func for all registered types
|
||||
func (m *APIRegistrationManager) InterfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
groupMeta, err := m.Group(version.Group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return groupMeta.InterfacesFor(version)
|
||||
}
|
||||
|
||||
// TODO: This is an expedient function, because we don't check if a Group is
|
||||
// supported throughout the code base. We will abandon this function and
|
||||
// checking the error returned by the Group() function.
|
||||
func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMeta {
|
||||
groupMeta, found := m.groupMetaMap[group]
|
||||
if !found {
|
||||
if group == "" {
|
||||
panic("The legacy v1 API is not registered.")
|
||||
} else {
|
||||
panic(fmt.Sprintf("Group %s is not registered.", group))
|
||||
}
|
||||
}
|
||||
groupMetaCopy := *groupMeta
|
||||
return &groupMetaCopy
|
||||
}
|
||||
|
||||
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
|
||||
// 1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR
|
||||
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
|
||||
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
|
||||
// all other groups alphabetical.
|
||||
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper {
|
||||
unionMapper := meta.MultiRESTMapper{}
|
||||
unionedGroups := sets.NewString()
|
||||
for enabledVersion := range m.enabledVersions {
|
||||
if !unionedGroups.Has(enabledVersion.Group) {
|
||||
unionedGroups.Insert(enabledVersion.Group)
|
||||
groupMeta := m.groupMetaMap[enabledVersion.Group]
|
||||
unionMapper = append(unionMapper, groupMeta.RESTMapper)
|
||||
}
|
||||
}
|
||||
|
||||
if len(versionPatterns) != 0 {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
for _, versionPriority := range versionPatterns {
|
||||
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
|
||||
}
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
if len(m.envRequestedVersions) != 0 {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
|
||||
for _, versionPriority := range m.envRequestedVersions {
|
||||
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
|
||||
}
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
prioritizedGroups := []string{"", "extensions", "metrics"}
|
||||
resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)
|
||||
|
||||
prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
|
||||
remainingGroups := sets.String{}
|
||||
for enabledVersion := range m.enabledVersions {
|
||||
if !prioritizedGroupsSet.Has(enabledVersion.Group) {
|
||||
remainingGroups.Insert(enabledVersion.Group)
|
||||
}
|
||||
}
|
||||
|
||||
remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
|
||||
resourcePriority = append(resourcePriority, remainingResourcePriority...)
|
||||
kindPriority = append(kindPriority, remainingKindPriority...)
|
||||
|
||||
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
|
||||
}
|
||||
|
||||
// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
|
||||
// then any non-preferred version of the group second.
|
||||
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]unversioned.GroupVersionResource, []unversioned.GroupVersionKind) {
|
||||
resourcePriority := []unversioned.GroupVersionResource{}
|
||||
kindPriority := []unversioned.GroupVersionKind{}
|
||||
|
||||
for _, group := range groups {
|
||||
availableVersions := m.EnabledVersionsForGroup(group)
|
||||
if len(availableVersions) > 0 {
|
||||
resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
|
||||
kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
|
||||
}
|
||||
}
|
||||
for _, group := range groups {
|
||||
resourcePriority = append(resourcePriority, unversioned.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
|
||||
kindPriority = append(kindPriority, unversioned.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
|
||||
}
|
||||
|
||||
return resourcePriority, kindPriority
|
||||
}
|
||||
|
||||
// AllPreferredGroupVersions returns the preferred versions of all registered
|
||||
// groups in the form of "group1/version1,group2/version2,..."
|
||||
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
|
||||
if len(m.groupMetaMap) == 0 {
|
||||
return ""
|
||||
}
|
||||
var defaults []string
|
||||
for _, groupMeta := range m.groupMetaMap {
|
||||
defaults = append(defaults, groupMeta.GroupVersion.String())
|
||||
}
|
||||
sort.Strings(defaults)
|
||||
return strings.Join(defaults, ",")
|
||||
}
|
||||
|
||||
// ValidateEnvRequestedVersions returns a list of versions that are requested in
|
||||
// the KUBE_API_VERSIONS environment variable, but not enabled.
|
||||
func (m *APIRegistrationManager) ValidateEnvRequestedVersions() []unversioned.GroupVersion {
|
||||
var missingVersions []unversioned.GroupVersion
|
||||
for _, v := range m.envRequestedVersions {
|
||||
if _, found := m.enabledVersions[v]; !found {
|
||||
missingVersions = append(missingVersions, v)
|
||||
}
|
||||
}
|
||||
return missingVersions
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package apimachinery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/1.5/pkg/api/meta"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
"k8s.io/client-go/1.5/pkg/runtime"
|
||||
)
|
||||
|
||||
// GroupMeta stores the metadata of a group.
|
||||
type GroupMeta struct {
|
||||
// GroupVersion represents the preferred version of the group.
|
||||
GroupVersion unversioned.GroupVersion
|
||||
|
||||
// GroupVersions is Group + all versions in that group.
|
||||
GroupVersions []unversioned.GroupVersion
|
||||
|
||||
// Codec is the default codec for serializing output that should use
|
||||
// the preferred version. Use this Codec when writing to
|
||||
// disk, a data store that is not dynamically versioned, or in tests.
|
||||
// This codec can decode any object that the schema is aware of.
|
||||
Codec runtime.Codec
|
||||
|
||||
// SelfLinker can set or get the SelfLink field of all API types.
|
||||
// TODO: when versioning changes, make this part of each API definition.
|
||||
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
|
||||
// to go through the InterfacesFor method below.
|
||||
SelfLinker runtime.SelfLinker
|
||||
|
||||
// RESTMapper provides the default mapping between REST paths and the objects declared in api.Scheme and all known
|
||||
// versions.
|
||||
RESTMapper meta.RESTMapper
|
||||
|
||||
// InterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
// string, or an error if the version is not known.
|
||||
// TODO: make this stop being a func pointer and always use the default
|
||||
// function provided below once every place that populates this field has been changed.
|
||||
InterfacesFor func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error)
|
||||
|
||||
// InterfacesByVersion stores the per-version interfaces.
|
||||
InterfacesByVersion map[unversioned.GroupVersion]*meta.VersionInterfaces
|
||||
}
|
||||
|
||||
// DefaultInterfacesFor returns the default Codec and ResourceVersioner for a given version
|
||||
// string, or an error if the version is not known.
|
||||
// TODO: Remove the "Default" prefix.
|
||||
func (gm *GroupMeta) DefaultInterfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
if v, ok := gm.InterfacesByVersion[version]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, gm.GroupVersions)
|
||||
}
|
||||
|
||||
// AddVersionInterfaces adds the given version to the group. Only call during
|
||||
// init, after that GroupMeta objects should be immutable. Not thread safe.
|
||||
// (If you use this, be sure to set .InterfacesFor = .DefaultInterfacesFor)
|
||||
// TODO: remove the "Interfaces" suffix and make this also maintain the
|
||||
// .GroupVersions member.
|
||||
func (gm *GroupMeta) AddVersionInterfaces(version unversioned.GroupVersion, interfaces *meta.VersionInterfaces) error {
|
||||
if e, a := gm.GroupVersion.Group, version.Group; a != e {
|
||||
return fmt.Errorf("got a version in group %v, but am in group %v", a, e)
|
||||
}
|
||||
if gm.InterfacesByVersion == nil {
|
||||
gm.InterfacesByVersion = make(map[unversioned.GroupVersion]*meta.VersionInterfaces)
|
||||
}
|
||||
gm.InterfacesByVersion[version] = interfaces
|
||||
|
||||
// TODO: refactor to make the below error not possible, this function
|
||||
// should *set* GroupVersions rather than depend on it.
|
||||
for _, v := range gm.GroupVersions {
|
||||
if v == version {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("added a version interface without the corresponding version %v being in the list %#v", version, gm.GroupVersions)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package apps
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/1.5/pkg/api"
|
||||
"k8s.io/client-go/1.5/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// +genclient=true
|
||||
|
||||
// PetSet represents a set of pods with consistent identities.
|
||||
// Identities are defined as:
|
||||
// - Network: A single stable DNS and hostname.
|
||||
// - Storage: As many VolumeClaims as requested.
|
||||
// The PetSet guarantees that a given network identity will always
|
||||
// map to the same storage identity. PetSet is currently in alpha and
|
||||
// and subject to change without notice.
|
||||
type PetSet struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired identities of pets in this set.
|
||||
Spec PetSetSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current status of Pets in this PetSet. This data
|
||||
// may be out of date by some window of time.
|
||||
Status PetSetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// A PetSetSpec is the specification of a PetSet.
|
||||
type PetSetSpec struct {
|
||||
// Replicas is the desired number of replicas of the given Template.
|
||||
// These are replicas in the sense that they are instantiations of the
|
||||
// same Template, but individual replicas also have a consistent identity.
|
||||
// If unspecified, defaults to 1.
|
||||
// TODO: Consider a rename of this field.
|
||||
Replicas int `json:"replicas,omitempty"`
|
||||
|
||||
// Selector is a label query over pods that should match the replica count.
|
||||
// If empty, defaulted to labels on the pod template.
|
||||
// More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md#label-selectors
|
||||
Selector *unversioned.LabelSelector `json:"selector,omitempty"`
|
||||
|
||||
// Template is the object that describes the pod that will be created if
|
||||
// insufficient replicas are detected. Each pod stamped out by the PetSet
|
||||
// will fulfill this Template, but have a unique identity from the rest
|
||||
// of the PetSet.
|
||||
Template api.PodTemplateSpec `json:"template"`
|
||||
|
||||
// VolumeClaimTemplates is a list of claims that pets are allowed to reference.
|
||||
// The PetSet controller is responsible for mapping network identities to
|
||||
// claims in a way that maintains the identity of a pet. Every claim in
|
||||
// this list must have at least one matching (by name) volumeMount in one
|
||||
// container in the template. A claim in this list takes precedence over
|
||||
// any volumes in the template, with the same name.
|
||||
// TODO: Define the behavior if a claim already exists with the same name.
|
||||
VolumeClaimTemplates []api.PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"`
|
||||
|
||||
// ServiceName is the name of the service that governs this PetSet.
|
||||
// This service must exist before the PetSet, and is responsible for
|
||||
// the network identity of the set. Pets get DNS/hostnames that follow the
|
||||
// pattern: pet-specific-string.serviceName.default.svc.cluster.local
|
||||
// where "pet-specific-string" is managed by the PetSet controller.
|
||||
ServiceName string `json:"serviceName"`
|
||||
}
|
||||
|
||||
// PetSetStatus represents the current state of a PetSet.
|
||||
type PetSetStatus struct {
|
||||
// most recent generation observed by this autoscaler.
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||
|
||||
// Replicas is the number of actual replicas.
|
||||
Replicas int `json:"replicas"`
|
||||
}
|
||||
|
||||
// PetSetList is a collection of PetSets.
|
||||
type PetSetList struct {
|
||||
unversioned.TypeMeta `json:",inline"`
|
||||
unversioned.ListMeta `json:"metadata,omitempty"`
|
||||
Items []PetSet `json:"items"`
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user