mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-26 23:17:34 +00:00
Merge pull request #53743 from DirectXMan12/feature/polymorphic-scale-client
Automatic merge from submit-queue (batch tested with PRs 53743, 53564). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Polymorphic Scale Client This PR introduces a polymorphic scale client based on discovery information that's able to scale scalable resources in arbitrary group-versions, as long as they present the scale subresource in their discovery information. Currently, it supports `extensions/v1beta1.Scale` and `autoscaling/v1.Scale`, but supporting other versions of scale if/when we produce them should be fairly trivial. It also updates the HPA to use this client, meaning the HPA will now work on any scalable resource, not just things in the `extensions/v1beta1` API group. **Release note**: ```release-note Introduces a polymorphic scale client, allowing HorizontalPodAutoscalers to properly function on scalable resources in any API group. ``` Unblocks #29698 Unblocks #38756 Unblocks #49504 Fixes #38810 Kubernetes-commit: ca8d97d673426409116a710503d4bc05ca8207a7
This commit is contained in:
commit
accfc9b01e
118
Godeps/Godeps.json
generated
118
Godeps/Godeps.json
generated
@ -476,199 +476,219 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/equality",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing",
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/fuzzer",
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/api/testing/roundtrip",
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/announced",
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apimachinery/registered",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/fuzzer",
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/fields",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/labels",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/selection",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/types",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/httpstream/spdy",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/remotecommand",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/version",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/pkg/watch",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/netutil",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
|
||||
"Rev": "23d8cc3b3bd5f64c22f31374cb62bdc037c9f6a1"
|
||||
"Rev": "2daf8da27592e02bcfc0eae6e9b5045be9c1b9da"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/kube-openapi/pkg/common",
|
||||
|
@ -68,7 +68,44 @@ func (c *FakeDiscovery) ServerPreferredNamespacedResources() ([]*metav1.APIResou
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) {
|
||||
return nil, nil
|
||||
action := testing.ActionImpl{
|
||||
Verb: "get",
|
||||
Resource: schema.GroupVersionResource{Resource: "group"},
|
||||
}
|
||||
c.Invokes(action, nil)
|
||||
|
||||
groups := map[string]*metav1.APIGroup{}
|
||||
|
||||
for _, res := range c.Resources {
|
||||
gv, err := schema.ParseGroupVersion(res.GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
group := groups[gv.Group]
|
||||
if group == nil {
|
||||
group = &metav1.APIGroup{
|
||||
Name: gv.Group,
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: res.GroupVersion,
|
||||
Version: gv.Version,
|
||||
},
|
||||
}
|
||||
groups[gv.Group] = group
|
||||
}
|
||||
|
||||
group.Versions = append(group.Versions, metav1.GroupVersionForDiscovery{
|
||||
GroupVersion: res.GroupVersion,
|
||||
Version: gv.Version,
|
||||
})
|
||||
}
|
||||
|
||||
list := &metav1.APIGroupList{}
|
||||
for _, apiGroup := range groups {
|
||||
list.Groups = append(list.Groups, *apiGroup)
|
||||
}
|
||||
|
||||
return list, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *FakeDiscovery) ServerVersion() (*version.Info, error) {
|
||||
|
@ -10,7 +10,6 @@ go_library(
|
||||
srcs = ["fake.go"],
|
||||
importpath = "k8s.io/client-go/rest/fake",
|
||||
deps = [
|
||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apimachinery/registered"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@ -46,8 +45,7 @@ func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
type RESTClient struct {
|
||||
Client *http.Client
|
||||
NegotiatedSerializer runtime.NegotiatedSerializer
|
||||
GroupName string
|
||||
APIRegistry *registered.APIRegistrationManager
|
||||
GroupVersion schema.GroupVersion
|
||||
VersionedAPIPath string
|
||||
|
||||
Req *http.Request
|
||||
@ -80,7 +78,7 @@ func (c *RESTClient) Verb(verb string) *restclient.Request {
|
||||
}
|
||||
|
||||
func (c *RESTClient) APIVersion() schema.GroupVersion {
|
||||
return c.APIRegistry.GroupOrDie("").GroupVersion
|
||||
return c.GroupVersion
|
||||
}
|
||||
|
||||
func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
@ -89,22 +87,20 @@ func (c *RESTClient) GetRateLimiter() flowcontrol.RateLimiter {
|
||||
|
||||
func (c *RESTClient) request(verb string) *restclient.Request {
|
||||
config := restclient.ContentConfig{
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
// TODO this was hardcoded before, but it doesn't look right
|
||||
GroupVersion: &c.APIRegistry.GroupOrDie("").GroupVersion,
|
||||
ContentType: runtime.ContentTypeJSON,
|
||||
GroupVersion: &c.GroupVersion,
|
||||
NegotiatedSerializer: c.NegotiatedSerializer,
|
||||
}
|
||||
|
||||
ns := c.NegotiatedSerializer
|
||||
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
|
||||
internalVersion := schema.GroupVersion{
|
||||
Group: c.APIRegistry.GroupOrDie(c.GroupName).GroupVersion.Group,
|
||||
Group: c.GroupVersion.Group,
|
||||
Version: runtime.APIVersionInternal,
|
||||
}
|
||||
internalVersion.Version = runtime.APIVersionInternal
|
||||
serializers := restclient.Serializers{
|
||||
// TODO this was hardcoded before, but it doesn't look right
|
||||
Encoder: ns.EncoderForVersion(info.Serializer, c.APIRegistry.GroupOrDie("").GroupVersion),
|
||||
Encoder: ns.EncoderForVersion(info.Serializer, c.GroupVersion),
|
||||
Decoder: ns.DecoderToVersion(info.Serializer, internalVersion),
|
||||
}
|
||||
if info.StreamSerializer != nil {
|
||||
|
@ -56,6 +56,14 @@ func DefaultServerURL(host, apiPath string, groupVersion schema.GroupVersion, de
|
||||
// hostURL.Path should be blank.
|
||||
//
|
||||
// versionedAPIPath, a path relative to baseURL.Path, points to a versioned API base
|
||||
versionedAPIPath := DefaultVersionedAPIPath(apiPath, groupVersion)
|
||||
|
||||
return hostURL, versionedAPIPath, nil
|
||||
}
|
||||
|
||||
// DefaultVersionedAPIPathFor constructs the default path for the given group version, assuming the given
|
||||
// API path, following the standard conventions of the Kubernetes API.
|
||||
func DefaultVersionedAPIPath(apiPath string, groupVersion schema.GroupVersion) string {
|
||||
versionedAPIPath := path.Join("/", apiPath)
|
||||
|
||||
// Add the version to the end of the path
|
||||
@ -64,10 +72,9 @@ func DefaultServerURL(host, apiPath string, groupVersion schema.GroupVersion, de
|
||||
|
||||
} else {
|
||||
versionedAPIPath = path.Join(versionedAPIPath, groupVersion.Version)
|
||||
|
||||
}
|
||||
|
||||
return hostURL, versionedAPIPath, nil
|
||||
return versionedAPIPath
|
||||
}
|
||||
|
||||
// defaultServerUrlFor is shared between IsConfigTransportTLS and RESTClientFor. It
|
||||
|
73
scale/BUILD
Normal file
73
scale/BUILD
Normal file
@ -0,0 +1,73 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"doc.go",
|
||||
"interfaces.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme/autoscalingv1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme/extensionsint:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme/extensionsv1beta1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"client_test.go",
|
||||
"roundtrip_test.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta2:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/testing/roundtrip:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery:go_default_library",
|
||||
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/client-go/scale/fake:all-srcs",
|
||||
"//staging/src/k8s.io/client-go/scale/scheme:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
197
scale/client.go
Normal file
197
scale/client.go
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
autoscaling "k8s.io/api/autoscaling/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/dynamic"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
var scaleConverter = NewScaleConverter()
|
||||
var codecs = serializer.NewCodecFactory(scaleConverter.Scheme())
|
||||
|
||||
// restInterfaceProvider turns a restclient.Config into a restclient.Interface.
|
||||
// It's overridable for the purposes of testing.
|
||||
type restInterfaceProvider func(*restclient.Config) (restclient.Interface, error)
|
||||
|
||||
// scaleClient is an implementation of ScalesGetter
|
||||
// which makes use of a RESTMapper and a generic REST
|
||||
// client to support an discoverable resource.
|
||||
// It behaves somewhat similarly to the dynamic ClientPool,
|
||||
// but is more specifically scoped to Scale.
|
||||
type scaleClient struct {
|
||||
mapper meta.RESTMapper
|
||||
|
||||
apiPathResolverFunc dynamic.APIPathResolverFunc
|
||||
scaleKindResolver ScaleKindResolver
|
||||
clientBase restclient.Interface
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ScalesGetter which resolves kinds
|
||||
// to resources using the given RESTMapper, and API paths using
|
||||
// the given dynamic.APIPathResolverFunc.
|
||||
func NewForConfig(cfg *restclient.Config, mapper meta.RESTMapper, resolver dynamic.APIPathResolverFunc, scaleKindResolver ScaleKindResolver) (ScalesGetter, error) {
|
||||
// so that the RESTClientFor doesn't complain
|
||||
cfg.GroupVersion = &schema.GroupVersion{}
|
||||
|
||||
cfg.NegotiatedSerializer = serializer.DirectCodecFactory{
|
||||
CodecFactory: codecs,
|
||||
}
|
||||
if len(cfg.UserAgent) == 0 {
|
||||
cfg.UserAgent = restclient.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
client, err := restclient.RESTClientFor(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return New(client, mapper, resolver, scaleKindResolver), nil
|
||||
}
|
||||
|
||||
// New creates a new ScalesGetter using the given client to make requests.
|
||||
// The GroupVersion on the client is ignored.
|
||||
func New(baseClient restclient.Interface, mapper meta.RESTMapper, resolver dynamic.APIPathResolverFunc, scaleKindResolver ScaleKindResolver) ScalesGetter {
|
||||
return &scaleClient{
|
||||
mapper: mapper,
|
||||
|
||||
apiPathResolverFunc: resolver,
|
||||
scaleKindResolver: scaleKindResolver,
|
||||
clientBase: baseClient,
|
||||
}
|
||||
}
|
||||
|
||||
// pathAndVersionFor returns the appropriate base path and the associated full GroupVersionResource
|
||||
// for the given GroupResource
|
||||
func (c *scaleClient) pathAndVersionFor(resource schema.GroupResource) (string, schema.GroupVersionResource, error) {
|
||||
gvr, err := c.mapper.ResourceFor(resource.WithVersion(""))
|
||||
if err != nil {
|
||||
return "", gvr, fmt.Errorf("unable to get full preferred group-version-resource for %s: %v", resource.String(), err)
|
||||
}
|
||||
|
||||
groupVer := gvr.GroupVersion()
|
||||
|
||||
// we need to set the API path based on GroupVersion (defaulting to the legacy path if none is set)
|
||||
// TODO: we "cheat" here since the API path really only depends on group ATM, but this should
|
||||
// *probably* take GroupVersionResource and not GroupVersionKind.
|
||||
apiPath := c.apiPathResolverFunc(groupVer.WithKind(""))
|
||||
if apiPath == "" {
|
||||
apiPath = "/api"
|
||||
}
|
||||
|
||||
path := restclient.DefaultVersionedAPIPath(apiPath, groupVer)
|
||||
|
||||
return path, gvr, nil
|
||||
}
|
||||
|
||||
// namespacedScaleClient is an ScaleInterface for fetching
|
||||
// Scales in a given namespace.
|
||||
type namespacedScaleClient struct {
|
||||
client *scaleClient
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (c *scaleClient) Scales(namespace string) ScaleInterface {
|
||||
return &namespacedScaleClient{
|
||||
client: c,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *namespacedScaleClient) Get(resource schema.GroupResource, name string) (*autoscaling.Scale, error) {
|
||||
// Currently, a /scale endpoint can return different scale types.
|
||||
// Until we have support for the alternative API representations proposal,
|
||||
// we need to deal with accepting different API versions.
|
||||
// In practice, this is autoscaling/v1.Scale and extensions/v1beta1.Scale
|
||||
|
||||
path, gvr, err := c.client.pathAndVersionFor(resource)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get client for %s: %v", resource.String(), err)
|
||||
}
|
||||
|
||||
rawObj, err := c.client.clientBase.Get().
|
||||
AbsPath(path).
|
||||
Namespace(c.namespace).
|
||||
Resource(gvr.Resource).
|
||||
Name(name).
|
||||
SubResource("scale").
|
||||
Do().
|
||||
Get()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// convert whatever this is to autoscaling/v1.Scale
|
||||
scaleObj, err := scaleConverter.ConvertToVersion(rawObj, autoscaling.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("received an object from a /scale endpoint which was not convertible to autoscaling Scale: %v", err)
|
||||
}
|
||||
|
||||
return scaleObj.(*autoscaling.Scale), nil
|
||||
}
|
||||
|
||||
func (c *namespacedScaleClient) Update(resource schema.GroupResource, scale *autoscaling.Scale) (*autoscaling.Scale, error) {
|
||||
path, gvr, err := c.client.pathAndVersionFor(resource)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get client for %s: %v", resource.String(), err)
|
||||
}
|
||||
|
||||
// Currently, a /scale endpoint can receive and return different scale types.
|
||||
// Until we hvae support for the alternative API representations proposal,
|
||||
// we need to deal with sending and accepting differnet API versions.
|
||||
|
||||
// figure out what scale we actually need here
|
||||
desiredGVK, err := c.client.scaleKindResolver.ScaleForResource(gvr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not find proper group-version for scale subresource of %s: %v", gvr.String(), err)
|
||||
}
|
||||
|
||||
// convert this to whatever this endpoint wants
|
||||
scaleUpdate, err := scaleConverter.ConvertToVersion(scale, desiredGVK.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not convert scale update to internal Scale: %v", err)
|
||||
}
|
||||
|
||||
rawObj, err := c.client.clientBase.Put().
|
||||
AbsPath(path).
|
||||
Namespace(c.namespace).
|
||||
Resource(gvr.Resource).
|
||||
Name(scale.Name).
|
||||
SubResource("scale").
|
||||
Body(scaleUpdate).
|
||||
Do().
|
||||
Get()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not fetch the scale for %s %s: %v", resource.String(), scale.Name, err)
|
||||
}
|
||||
|
||||
// convert whatever this is back to autoscaling/v1.Scale
|
||||
scaleObj, err := scaleConverter.ConvertToVersion(rawObj, autoscaling.SchemeGroupVersion)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("received an object from a /scale endpoint which was not convertible to autoscaling Scale: %v", err)
|
||||
}
|
||||
|
||||
return scaleObj.(*autoscaling.Scale), err
|
||||
}
|
246
scale/client_test.go
Normal file
246
scale/client_test.go
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
serializer "k8s.io/apimachinery/pkg/runtime/serializer"
|
||||
"k8s.io/client-go/discovery"
|
||||
fakedisco "k8s.io/client-go/discovery/fake"
|
||||
"k8s.io/client-go/dynamic"
|
||||
fakerest "k8s.io/client-go/rest/fake"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
extv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
coretesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func bytesBody(bodyBytes []byte) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyBytes))
|
||||
}
|
||||
|
||||
func defaultHeaders() http.Header {
|
||||
header := http.Header{}
|
||||
header.Set("Content-Type", runtime.ContentTypeJSON)
|
||||
return header
|
||||
}
|
||||
|
||||
func fakeScaleClient(t *testing.T) (ScalesGetter, []schema.GroupResource) {
|
||||
fakeDiscoveryClient := &fakedisco.FakeDiscovery{Fake: &coretesting.Fake{}}
|
||||
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: corev1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod"},
|
||||
{Name: "replicationcontrollers", Namespaced: true, Kind: "ReplicationController"},
|
||||
{Name: "replicationcontrollers/scale", Namespaced: true, Kind: "Scale", Group: "autoscaling", Version: "v1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: extv1beta1.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "replicasets", Namespaced: true, Kind: "ReplicaSet"},
|
||||
{Name: "replicasets/scale", Namespaced: true, Kind: "Scale"},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: appsv1beta2.SchemeGroupVersion.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "deployments", Namespaced: true, Kind: "Deployment"},
|
||||
{Name: "deployments/scale", Namespaced: true, Kind: "Scale", Group: "autoscaling", Version: "v1"},
|
||||
},
|
||||
},
|
||||
// test a resource that doesn't exist anywere to make sure we're not accidentally depending
|
||||
// on a static RESTMapper anywhere.
|
||||
{
|
||||
GroupVersion: "cheese.testing.k8s.io/v27alpha15",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "cheddars", Namespaced: true, Kind: "Cheddar"},
|
||||
{Name: "cheddars/scale", Namespaced: true, Kind: "Scale", Group: "extensions", Version: "v1beta1"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
restMapperRes, err := discovery.GetAPIGroupResources(fakeDiscoveryClient)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while constructing resource list from fake discovery client: %v")
|
||||
}
|
||||
restMapper := discovery.NewRESTMapper(restMapperRes, apimeta.InterfacesForUnstructured)
|
||||
|
||||
autoscalingScale := &autoscalingv1.Scale{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Scale",
|
||||
APIVersion: autoscalingv1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: autoscalingv1.ScaleSpec{Replicas: 10},
|
||||
Status: autoscalingv1.ScaleStatus{
|
||||
Replicas: 10,
|
||||
Selector: "foo=bar",
|
||||
},
|
||||
}
|
||||
extScale := &extv1beta1.Scale{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Scale",
|
||||
APIVersion: extv1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: extv1beta1.ScaleSpec{Replicas: 10},
|
||||
Status: extv1beta1.ScaleStatus{
|
||||
Replicas: 10,
|
||||
TargetSelector: "foo=bar",
|
||||
},
|
||||
}
|
||||
|
||||
resourcePaths := map[string]runtime.Object{
|
||||
"/api/v1/namespaces/default/replicationcontrollers/foo/scale": autoscalingScale,
|
||||
"/apis/extensions/v1beta1/namespaces/default/replicasets/foo/scale": extScale,
|
||||
"/apis/apps/v1beta2/namespaces/default/deployments/foo/scale": autoscalingScale,
|
||||
"/apis/cheese.testing.k8s.io/v27alpha15/namespaces/default/cheddars/foo/scale": extScale,
|
||||
}
|
||||
|
||||
fakeReqHandler := func(req *http.Request) (*http.Response, error) {
|
||||
scale, isScalePath := resourcePaths[req.URL.Path]
|
||||
if !isScalePath {
|
||||
return nil, fmt.Errorf("unexpected request for URL %q with method %q", req.URL.String(), req.Method)
|
||||
}
|
||||
|
||||
switch req.Method {
|
||||
case "GET":
|
||||
res, err := json.Marshal(scale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Response{StatusCode: 200, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
case "PUT":
|
||||
decoder := codecs.UniversalDeserializer()
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newScale, newScaleGVK, err := decoder.Decode(body, nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unexpected request body: %v", err)
|
||||
}
|
||||
if *newScaleGVK != scale.GetObjectKind().GroupVersionKind() {
|
||||
return nil, fmt.Errorf("unexpected scale API version %s (expected %s)", newScaleGVK.String(), scale.GetObjectKind().GroupVersionKind().String())
|
||||
}
|
||||
res, err := json.Marshal(newScale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &http.Response{StatusCode: 200, Header: defaultHeaders(), Body: bytesBody(res)}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected request for URL %q with method %q", req.URL.String(), req.Method)
|
||||
}
|
||||
}
|
||||
|
||||
fakeClient := &fakerest.RESTClient{
|
||||
Client: fakerest.CreateHTTPClient(fakeReqHandler),
|
||||
NegotiatedSerializer: serializer.DirectCodecFactory{
|
||||
CodecFactory: codecs,
|
||||
},
|
||||
GroupVersion: schema.GroupVersion{},
|
||||
VersionedAPIPath: "/not/a/real/path",
|
||||
}
|
||||
|
||||
resolver := NewDiscoveryScaleKindResolver(fakeDiscoveryClient)
|
||||
client := New(fakeClient, restMapper, dynamic.LegacyAPIPathResolverFunc, resolver)
|
||||
|
||||
groupResources := []schema.GroupResource{
|
||||
{Group: corev1.GroupName, Resource: "replicationcontroller"},
|
||||
{Group: extv1beta1.GroupName, Resource: "replicaset"},
|
||||
{Group: appsv1beta2.GroupName, Resource: "deployment"},
|
||||
{Group: "cheese.testing.k8s.io", Resource: "cheddar"},
|
||||
}
|
||||
|
||||
return client, groupResources
|
||||
}
|
||||
|
||||
func TestGetScale(t *testing.T) {
|
||||
scaleClient, groupResources := fakeScaleClient(t)
|
||||
expectedScale := &autoscalingv1.Scale{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Scale",
|
||||
APIVersion: autoscalingv1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: autoscalingv1.ScaleSpec{Replicas: 10},
|
||||
Status: autoscalingv1.ScaleStatus{
|
||||
Replicas: 10,
|
||||
Selector: "foo=bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, groupResource := range groupResources {
|
||||
scale, err := scaleClient.Scales("default").Get(groupResource, "foo")
|
||||
if !assert.NoError(t, err, "should have been able to fetch a scale for %s", groupResource.String()) {
|
||||
continue
|
||||
}
|
||||
assert.NotNil(t, scale, "should have returned a non-nil scale for %s", groupResource.String())
|
||||
|
||||
assert.Equal(t, expectedScale, scale, "should have returned the expected scale for %s", groupResource.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateScale(t *testing.T) {
|
||||
scaleClient, groupResources := fakeScaleClient(t)
|
||||
expectedScale := &autoscalingv1.Scale{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Scale",
|
||||
APIVersion: autoscalingv1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: autoscalingv1.ScaleSpec{Replicas: 10},
|
||||
Status: autoscalingv1.ScaleStatus{
|
||||
Replicas: 10,
|
||||
Selector: "foo=bar",
|
||||
},
|
||||
}
|
||||
|
||||
for _, groupResource := range groupResources {
|
||||
scale, err := scaleClient.Scales("default").Update(groupResource, expectedScale)
|
||||
if !assert.NoError(t, err, "should have been able to fetch a scale for %s", groupResource.String()) {
|
||||
continue
|
||||
}
|
||||
assert.NotNil(t, scale, "should have returned a non-nil scale for %s", groupResource.String())
|
||||
|
||||
assert.Equal(t, expectedScale, scale, "should have returned the expected scale for %s", groupResource.String())
|
||||
}
|
||||
}
|
21
scale/doc.go
Normal file
21
scale/doc.go
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package scale provides a polymorphic scale client capable of fetching
|
||||
// and updating Scale for any resource which implements the `scale` subresource,
|
||||
// as long as that subresource operates on a version of scale convertable to
|
||||
// autoscaling.Scale.
|
||||
package scale
|
28
scale/fake/BUILD
Normal file
28
scale/fake/BUILD
Normal file
@ -0,0 +1,28 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["client.go"],
|
||||
importpath = "k8s.io/client-go/scale/fake",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale:go_default_library",
|
||||
"//vendor/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
67
scale/fake/client.go
Normal file
67
scale/fake/client.go
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package fake provides a fake client interface to arbitrary Kubernetes
|
||||
// APIs that exposes common high level operations and exposes common
|
||||
// metadata.
|
||||
package fake
|
||||
|
||||
import (
|
||||
autoscalingapi "k8s.io/api/autoscaling/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/scale"
|
||||
"k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
// FakeScaleClient provides a fake implementation of scale.ScalesGetter.
|
||||
type FakeScaleClient struct {
|
||||
testing.Fake
|
||||
}
|
||||
|
||||
func (f *FakeScaleClient) Scales(namespace string) scale.ScaleInterface {
|
||||
return &fakeNamespacedScaleClient{
|
||||
namespace: namespace,
|
||||
fake: &f.Fake,
|
||||
}
|
||||
}
|
||||
|
||||
type fakeNamespacedScaleClient struct {
|
||||
namespace string
|
||||
fake *testing.Fake
|
||||
}
|
||||
|
||||
func (f *fakeNamespacedScaleClient) Get(resource schema.GroupResource, name string) (*autoscalingapi.Scale, error) {
|
||||
obj, err := f.fake.
|
||||
Invokes(testing.NewGetSubresourceAction(resource.WithVersion(""), f.namespace, "scale", name), &autoscalingapi.Scale{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*autoscalingapi.Scale), err
|
||||
}
|
||||
|
||||
func (f *fakeNamespacedScaleClient) Update(resource schema.GroupResource, scale *autoscalingapi.Scale) (*autoscalingapi.Scale, error) {
|
||||
obj, err := f.fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(resource.WithVersion(""), f.namespace, "scale", scale), &autoscalingapi.Scale{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj.(*autoscalingapi.Scale), err
|
||||
|
||||
}
|
39
scale/interfaces.go
Normal file
39
scale/interfaces.go
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scale
|
||||
|
||||
import (
|
||||
autoscalingapi "k8s.io/api/autoscaling/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// ScalesGetter can produce a ScaleInterface
|
||||
// for a particular namespace.
|
||||
type ScalesGetter interface {
|
||||
Scales(namespace string) ScaleInterface
|
||||
}
|
||||
|
||||
// ScaleInterface can fetch and update scales for
|
||||
// resources in a particular namespace which implement
|
||||
// the scale subresource.
|
||||
type ScaleInterface interface {
|
||||
// Get fetches the scale of the given scalable resource.
|
||||
Get(resource schema.GroupResource, name string) (*autoscalingapi.Scale, error)
|
||||
|
||||
// Update updates the scale of the the given scalable resource.
|
||||
Update(resource schema.GroupResource, scale *autoscalingapi.Scale) (*autoscalingapi.Scale, error)
|
||||
}
|
34
scale/roundtrip_test.go
Normal file
34
scale/roundtrip_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scale
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/testing/roundtrip"
|
||||
)
|
||||
|
||||
// NB: this can't be in the scheme package, because importing'
|
||||
// scheme/autoscalingv1 from scheme causes a depedency loop from
|
||||
// conversions
|
||||
|
||||
func TestRoundTrip(t *testing.T) {
|
||||
scheme := NewScaleConverter().Scheme()
|
||||
// we don't actually need any custom fuzzer funcs ATM -- the defaults
|
||||
// will do just fine
|
||||
roundtrip.RoundTripTestForScheme(t, scheme, nil)
|
||||
}
|
39
scale/scheme/BUILD
Normal file
39
scale/scheme/BUILD
Normal file
@ -0,0 +1,39 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale/scheme",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//staging/src/k8s.io/client-go/scale/scheme/autoscalingv1:all-srcs",
|
||||
"//staging/src/k8s.io/client-go/scale/scheme/extensionsint:all-srcs",
|
||||
"//staging/src/k8s.io/client-go/scale/scheme/extensionsv1beta1:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
35
scale/scheme/autoscalingv1/BUILD
Normal file
35
scale/scheme/autoscalingv1/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"zz_generated.conversion.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale/scheme/autoscalingv1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
69
scale/scheme/autoscalingv1/conversion.go
Normal file
69
scale/scheme/autoscalingv1/conversion.go
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package autoscalingv1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1_ScaleStatus,
|
||||
Convert_v1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_scheme_ScaleStatus_To_v1_ScaleStatus(in *scheme.ScaleStatus, out *v1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = ""
|
||||
if in.Selector != nil {
|
||||
selector, err := metav1.LabelSelectorAsSelector(in.Selector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
out.Selector = selector.String()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_ScaleStatus_To_scheme_ScaleStatus(in *v1.ScaleStatus, out *scheme.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
if in.Selector != "" {
|
||||
labelSelector, err := metav1.ParseToLabelSelector(in.Selector)
|
||||
if err != nil {
|
||||
out.Selector = nil
|
||||
return fmt.Errorf("failed to parse target selector: %v", err)
|
||||
}
|
||||
out.Selector = labelSelector
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
20
scale/scheme/autoscalingv1/doc.go
Normal file
20
scale/scheme/autoscalingv1/doc.go
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/vendor/k8s.io/client-go/scale/scheme
|
||||
// +k8s:conversion-gen-external-types=../../../../../k8s.io/api/autoscaling/v1
|
||||
|
||||
package autoscalingv1 // import "k8s.io/client-go/scale/scheme/autoscalingv1"
|
45
scale/scheme/autoscalingv1/register.go
Normal file
45
scale/scheme/autoscalingv1/register.go
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package autoscalingv1
|
||||
|
||||
import (
|
||||
autoscalingapiv1 "k8s.io/api/autoscaling/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = autoscalingapiv1.GroupName
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
localSchemeBuilder = &autoscalingapiv1.SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
}
|
109
scale/scheme/autoscalingv1/zz_generated.conversion.go
Normal file
109
scale/scheme/autoscalingv1/zz_generated.conversion.go
Normal file
@ -0,0 +1,109 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
|
||||
package autoscalingv1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/autoscaling/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1_Scale_To_scheme_Scale,
|
||||
Convert_scheme_Scale_To_v1_Scale,
|
||||
Convert_v1_ScaleSpec_To_scheme_ScaleSpec,
|
||||
Convert_scheme_ScaleSpec_To_v1_ScaleSpec,
|
||||
Convert_v1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
Convert_scheme_ScaleStatus_To_v1_ScaleStatus,
|
||||
)
|
||||
}
|
||||
|
||||
func autoConvert_v1_Scale_To_scheme_Scale(in *v1.Scale, out *scheme.Scale, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1_ScaleSpec_To_scheme_ScaleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1_ScaleStatus_To_scheme_ScaleStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_Scale_To_scheme_Scale is an autogenerated conversion function.
|
||||
func Convert_v1_Scale_To_scheme_Scale(in *v1.Scale, out *scheme.Scale, s conversion.Scope) error {
|
||||
return autoConvert_v1_Scale_To_scheme_Scale(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_scheme_Scale_To_v1_Scale(in *scheme.Scale, out *v1.Scale, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_scheme_ScaleSpec_To_v1_ScaleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_scheme_ScaleStatus_To_v1_ScaleStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_scheme_Scale_To_v1_Scale is an autogenerated conversion function.
|
||||
func Convert_scheme_Scale_To_v1_Scale(in *scheme.Scale, out *v1.Scale, s conversion.Scope) error {
|
||||
return autoConvert_scheme_Scale_To_v1_Scale(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ScaleSpec_To_scheme_ScaleSpec(in *v1.ScaleSpec, out *scheme.ScaleSpec, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_ScaleSpec_To_scheme_ScaleSpec is an autogenerated conversion function.
|
||||
func Convert_v1_ScaleSpec_To_scheme_ScaleSpec(in *v1.ScaleSpec, out *scheme.ScaleSpec, s conversion.Scope) error {
|
||||
return autoConvert_v1_ScaleSpec_To_scheme_ScaleSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_scheme_ScaleSpec_To_v1_ScaleSpec(in *scheme.ScaleSpec, out *v1.ScaleSpec, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_scheme_ScaleSpec_To_v1_ScaleSpec is an autogenerated conversion function.
|
||||
func Convert_scheme_ScaleSpec_To_v1_ScaleSpec(in *scheme.ScaleSpec, out *v1.ScaleSpec, s conversion.Scope) error {
|
||||
return autoConvert_scheme_ScaleSpec_To_v1_ScaleSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_ScaleStatus_To_scheme_ScaleStatus(in *v1.ScaleStatus, out *scheme.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
// WARNING: in.Selector requires manual conversion: inconvertible types (string vs *k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector)
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_scheme_ScaleStatus_To_v1_ScaleStatus(in *scheme.ScaleStatus, out *v1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
// WARNING: in.Selector requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector vs string)
|
||||
return nil
|
||||
}
|
22
scale/scheme/doc.go
Normal file
22
scale/scheme/doc.go
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package,register
|
||||
|
||||
// Package scheme contains a runtime.Scheme to be used for serializing
|
||||
// and deserializing different versions of Scale, and for converting
|
||||
// in between them.
|
||||
package scheme
|
31
scale/scheme/extensionsint/BUILD
Normal file
31
scale/scheme/extensionsint/BUILD
Normal file
@ -0,0 +1,31 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale/scheme/extensionsint",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
22
scale/scheme/extensionsint/doc.go
Normal file
22
scale/scheme/extensionsint/doc.go
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package extensionsint contains the necessary scaffolding of the
|
||||
// internal version of extensions as required by conversion logic.
|
||||
// It doesn't have any of its own types -- it's just necessary to
|
||||
// get the expected behavoir out of runtime.Scheme.ConvertToVersion
|
||||
// and associated methods.
|
||||
package extensionsint
|
53
scale/scheme/extensionsint/register.go
Normal file
53
scale/scheme/extensionsint/register.go
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
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 extensionsint
|
||||
|
||||
import (
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
scalescheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = extensionsv1beta1.GroupName
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&scalescheme.Scale{},
|
||||
)
|
||||
return nil
|
||||
}
|
35
scale/scheme/extensionsv1beta1/BUILD
Normal file
35
scale/scheme/extensionsv1beta1/BUILD
Normal file
@ -0,0 +1,35 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"conversion.go",
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"zz_generated.conversion.go",
|
||||
],
|
||||
importpath = "k8s.io/client-go/scale/scheme/extensionsv1beta1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/client-go/scale/scheme:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
87
scale/scheme/extensionsv1beta1/conversion.go
Normal file
87
scale/scheme/extensionsv1beta1/conversion.go
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package extensionsv1beta1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
v1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
// addConversions registers conversions between the internal version
|
||||
// of Scale and supported external versions of Scale.
|
||||
func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err := scheme.AddConversionFuncs(
|
||||
Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus,
|
||||
Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(in *scheme.ScaleStatus, out *v1beta1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
out.Selector = nil
|
||||
out.TargetSelector = ""
|
||||
if in.Selector != nil {
|
||||
if in.Selector.MatchExpressions == nil || len(in.Selector.MatchExpressions) == 0 {
|
||||
out.Selector = in.Selector.MatchLabels
|
||||
}
|
||||
|
||||
selector, err := metav1.LabelSelectorAsSelector(in.Selector)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid label selector: %v", err)
|
||||
}
|
||||
out.TargetSelector = selector.String()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus(in *v1beta1.ScaleStatus, out *scheme.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
|
||||
// Normally when 2 fields map to the same internal value we favor the old field, since
|
||||
// old clients can't be expected to know about new fields but clients that know about the
|
||||
// new field can be expected to know about the old field (though that's not quite true, due
|
||||
// to kubectl apply). However, these fields are readonly, so any non-nil value should work.
|
||||
if in.TargetSelector != "" {
|
||||
labelSelector, err := metav1.ParseToLabelSelector(in.TargetSelector)
|
||||
if err != nil {
|
||||
out.Selector = nil
|
||||
return fmt.Errorf("failed to parse target selector: %v", err)
|
||||
}
|
||||
out.Selector = labelSelector
|
||||
} else if in.Selector != nil {
|
||||
out.Selector = new(metav1.LabelSelector)
|
||||
selector := make(map[string]string)
|
||||
for key, val := range in.Selector {
|
||||
selector[key] = val
|
||||
}
|
||||
out.Selector.MatchLabels = selector
|
||||
} else {
|
||||
out.Selector = nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
20
scale/scheme/extensionsv1beta1/doc.go
Normal file
20
scale/scheme/extensionsv1beta1/doc.go
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:conversion-gen=k8s.io/kubernetes/vendor/k8s.io/client-go/scale/scheme
|
||||
// +k8s:conversion-gen-external-types=../../../../../k8s.io/api/extensions/v1beta1
|
||||
|
||||
package extensionsv1beta1 // import "k8s.io/client-go/scale/scheme/extensionsv1beta1"
|
45
scale/scheme/extensionsv1beta1/register.go
Normal file
45
scale/scheme/extensionsv1beta1/register.go
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package extensionsv1beta1
|
||||
|
||||
import (
|
||||
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = extensionsapiv1beta1.GroupName
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
localSchemeBuilder = &extensionsapiv1beta1.SchemeBuilder
|
||||
AddToScheme = localSchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We only register manually written functions here. The registration of the
|
||||
// generated functions takes place in the generated files. The separation
|
||||
// makes the code compile even when the generated files are missing.
|
||||
localSchemeBuilder.Register(addConversionFuncs)
|
||||
}
|
110
scale/scheme/extensionsv1beta1/zz_generated.conversion.go
Normal file
110
scale/scheme/extensionsv1beta1/zz_generated.conversion.go
Normal file
@ -0,0 +1,110 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
|
||||
package extensionsv1beta1
|
||||
|
||||
import (
|
||||
v1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
scheme "k8s.io/client-go/scale/scheme"
|
||||
)
|
||||
|
||||
func init() {
|
||||
localSchemeBuilder.Register(RegisterConversions)
|
||||
}
|
||||
|
||||
// RegisterConversions adds conversion functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterConversions(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedConversionFuncs(
|
||||
Convert_v1beta1_Scale_To_scheme_Scale,
|
||||
Convert_scheme_Scale_To_v1beta1_Scale,
|
||||
Convert_v1beta1_ScaleSpec_To_scheme_ScaleSpec,
|
||||
Convert_scheme_ScaleSpec_To_v1beta1_ScaleSpec,
|
||||
Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus,
|
||||
Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus,
|
||||
)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_Scale_To_scheme_Scale(in *v1beta1.Scale, out *scheme.Scale, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_v1beta1_ScaleSpec_To_scheme_ScaleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_v1beta1_ScaleStatus_To_scheme_ScaleStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_Scale_To_scheme_Scale is an autogenerated conversion function.
|
||||
func Convert_v1beta1_Scale_To_scheme_Scale(in *v1beta1.Scale, out *scheme.Scale, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_Scale_To_scheme_Scale(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_scheme_Scale_To_v1beta1_Scale(in *scheme.Scale, out *v1beta1.Scale, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_scheme_ScaleSpec_To_v1beta1_ScaleSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := Convert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(&in.Status, &out.Status, s); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_scheme_Scale_To_v1beta1_Scale is an autogenerated conversion function.
|
||||
func Convert_scheme_Scale_To_v1beta1_Scale(in *scheme.Scale, out *v1beta1.Scale, s conversion.Scope) error {
|
||||
return autoConvert_scheme_Scale_To_v1beta1_Scale(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ScaleSpec_To_scheme_ScaleSpec(in *v1beta1.ScaleSpec, out *scheme.ScaleSpec, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_ScaleSpec_To_scheme_ScaleSpec is an autogenerated conversion function.
|
||||
func Convert_v1beta1_ScaleSpec_To_scheme_ScaleSpec(in *v1beta1.ScaleSpec, out *scheme.ScaleSpec, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_ScaleSpec_To_scheme_ScaleSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_scheme_ScaleSpec_To_v1beta1_ScaleSpec(in *scheme.ScaleSpec, out *v1beta1.ScaleSpec, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_scheme_ScaleSpec_To_v1beta1_ScaleSpec is an autogenerated conversion function.
|
||||
func Convert_scheme_ScaleSpec_To_v1beta1_ScaleSpec(in *scheme.ScaleSpec, out *v1beta1.ScaleSpec, s conversion.Scope) error {
|
||||
return autoConvert_scheme_ScaleSpec_To_v1beta1_ScaleSpec(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_ScaleStatus_To_scheme_ScaleStatus(in *v1beta1.ScaleStatus, out *scheme.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
// WARNING: in.Selector requires manual conversion: inconvertible types (map[string]string vs *k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector)
|
||||
// WARNING: in.TargetSelector requires manual conversion: does not exist in peer-type
|
||||
return nil
|
||||
}
|
||||
|
||||
func autoConvert_scheme_ScaleStatus_To_v1beta1_ScaleStatus(in *scheme.ScaleStatus, out *v1beta1.ScaleStatus, s conversion.Scope) error {
|
||||
out.Replicas = in.Replicas
|
||||
// WARNING: in.Selector requires manual conversion: inconvertible types (*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector vs map[string]string)
|
||||
return nil
|
||||
}
|
52
scale/scheme/register.go
Normal file
52
scale/scheme/register.go
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
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 scheme
|
||||
|
||||
import (
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// GroupName is the group name use in this package
|
||||
const GroupName = autoscalingv1.GroupName
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
|
||||
|
||||
// Kind takes an unqualified kind and returns a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Scale{},
|
||||
)
|
||||
return nil
|
||||
}
|
60
scale/scheme/types.go
Normal file
60
scale/scheme/types.go
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// This file contains our own "internal" version of scale that we use for conversions,
|
||||
// since we can't use the main Kubernetes internal versions.
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Scale represents a scaling request for a resource.
|
||||
type Scale struct {
|
||||
metav1.TypeMeta
|
||||
// Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata.
|
||||
// +optional
|
||||
metav1.ObjectMeta
|
||||
|
||||
// defines the behavior of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status.
|
||||
// +optional
|
||||
Spec ScaleSpec
|
||||
|
||||
// current status of the scale. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status. Read-only.
|
||||
// +optional
|
||||
Status ScaleStatus
|
||||
}
|
||||
|
||||
// ScaleSpec describes the attributes of a scale subresource.
|
||||
type ScaleSpec struct {
|
||||
// desired number of instances for the scaled object.
|
||||
// +optional
|
||||
Replicas int32
|
||||
}
|
||||
|
||||
// ScaleStatus represents the current status of a scale subresource.
|
||||
type ScaleStatus struct {
|
||||
// actual number of observed instances of the scaled object.
|
||||
Replicas int32
|
||||
|
||||
// label query over pods that should match the replicas count.
|
||||
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
|
||||
// +optional
|
||||
Selector *metav1.LabelSelector
|
||||
}
|
123
scale/scheme/zz_generated.deepcopy.go
Normal file
123
scale/scheme/zz_generated.deepcopy.go
Normal file
@ -0,0 +1,123 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package scheme
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(RegisterDeepCopies)
|
||||
}
|
||||
|
||||
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
|
||||
// to allow building arbitrary schemes.
|
||||
//
|
||||
// Deprecated: deepcopy registration will go away when static deepcopy is fully implemented.
|
||||
func RegisterDeepCopies(scheme *runtime.Scheme) error {
|
||||
return scheme.AddGeneratedDeepCopyFuncs(
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*Scale).DeepCopyInto(out.(*Scale))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&Scale{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*ScaleSpec).DeepCopyInto(out.(*ScaleSpec))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&ScaleSpec{})},
|
||||
conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
|
||||
in.(*ScaleStatus).DeepCopyInto(out.(*ScaleStatus))
|
||||
return nil
|
||||
}, InType: reflect.TypeOf(&ScaleStatus{})},
|
||||
)
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Scale) DeepCopyInto(out *Scale) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scale.
|
||||
func (in *Scale) DeepCopy() *Scale {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Scale)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Scale) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScaleSpec) DeepCopyInto(out *ScaleSpec) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScaleSpec.
|
||||
func (in *ScaleSpec) DeepCopy() *ScaleSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScaleSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScaleStatus) DeepCopyInto(out *ScaleStatus) {
|
||||
*out = *in
|
||||
if in.Selector != nil {
|
||||
in, out := &in.Selector, &out.Selector
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScaleStatus.
|
||||
func (in *ScaleStatus) DeepCopy() *ScaleStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScaleStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
159
scale/util.go
Normal file
159
scale/util.go
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scale
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/discovery"
|
||||
scalescheme "k8s.io/client-go/scale/scheme"
|
||||
scaleautoscaling "k8s.io/client-go/scale/scheme/autoscalingv1"
|
||||
scaleextint "k8s.io/client-go/scale/scheme/extensionsint"
|
||||
scaleext "k8s.io/client-go/scale/scheme/extensionsv1beta1"
|
||||
)
|
||||
|
||||
// ScaleKindResolver knows about the relationship between
|
||||
// resources and the GroupVersionKind of their scale subresources.
|
||||
type ScaleKindResolver interface {
|
||||
// ScaleForResource returns the GroupVersionKind of the
|
||||
// scale subresource for the given GroupVersionResource.
|
||||
ScaleForResource(resource schema.GroupVersionResource) (scaleVersion schema.GroupVersionKind, err error)
|
||||
}
|
||||
|
||||
// discoveryScaleResolver is a ScaleKindResolver that uses
|
||||
// a DiscoveryInterface to associate resources with their
|
||||
// scale-kinds
|
||||
type discoveryScaleResolver struct {
|
||||
discoveryClient discovery.ServerResourcesInterface
|
||||
}
|
||||
|
||||
func (r *discoveryScaleResolver) ScaleForResource(inputRes schema.GroupVersionResource) (scaleVersion schema.GroupVersionKind, err error) {
|
||||
groupVerResources, err := r.discoveryClient.ServerResourcesForGroupVersion(inputRes.GroupVersion().String())
|
||||
if err != nil {
|
||||
return schema.GroupVersionKind{}, fmt.Errorf("unable to fetch discovery information for %s: %v", inputRes.String(), err)
|
||||
}
|
||||
|
||||
for _, resource := range groupVerResources.APIResources {
|
||||
resourceParts := strings.SplitN(resource.Name, "/", 2)
|
||||
if len(resourceParts) != 2 || resourceParts[0] != inputRes.Resource || resourceParts[1] != "scale" {
|
||||
// skip non-scale resources, or scales for resources that we're not looking for
|
||||
continue
|
||||
}
|
||||
|
||||
scaleGV := inputRes.GroupVersion()
|
||||
if resource.Group != "" && resource.Version != "" {
|
||||
scaleGV = schema.GroupVersion{
|
||||
Group: resource.Group,
|
||||
Version: resource.Version,
|
||||
}
|
||||
}
|
||||
|
||||
return scaleGV.WithKind(resource.Kind), nil
|
||||
}
|
||||
|
||||
return schema.GroupVersionKind{}, fmt.Errorf("could not find scale subresource for %s in discovery information", inputRes.String())
|
||||
}
|
||||
|
||||
// cachedScaleKindResolver is a ScaleKindResolver that caches results
|
||||
// from another ScaleKindResolver, re-fetching on cache misses.
|
||||
type cachedScaleKindResolver struct {
|
||||
base ScaleKindResolver
|
||||
|
||||
cache map[schema.GroupVersionResource]schema.GroupVersionKind
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
func (r *cachedScaleKindResolver) ScaleForResource(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
r.mu.RLock()
|
||||
gvk, isCached := r.cache[resource]
|
||||
r.mu.RUnlock()
|
||||
if isCached {
|
||||
return gvk, nil
|
||||
}
|
||||
|
||||
// we could have multiple fetches of the same resources, but that's probably
|
||||
// better than limiting to only one reader at once (mu.Mutex),
|
||||
// or blocking checks for other resources while we fetch
|
||||
// (mu.Lock before fetch).
|
||||
gvk, err := r.base.ScaleForResource(resource)
|
||||
if err != nil {
|
||||
return schema.GroupVersionKind{}, err
|
||||
}
|
||||
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.cache[resource] = gvk
|
||||
|
||||
return gvk, nil
|
||||
}
|
||||
|
||||
// NewDiscoveryScaleKindResolver creates a new ScaleKindResolver which uses information from the given
|
||||
// disovery client to resolve the correct Scale GroupVersionKind for different resources.
|
||||
func NewDiscoveryScaleKindResolver(client discovery.ServerResourcesInterface) ScaleKindResolver {
|
||||
base := &discoveryScaleResolver{
|
||||
discoveryClient: client,
|
||||
}
|
||||
|
||||
return &cachedScaleKindResolver{
|
||||
base: base,
|
||||
cache: make(map[schema.GroupVersionResource]schema.GroupVersionKind),
|
||||
}
|
||||
}
|
||||
|
||||
// ScaleConverter knows how to convert between external scale versions.
|
||||
type ScaleConverter struct {
|
||||
scheme *runtime.Scheme
|
||||
internalVersioner runtime.GroupVersioner
|
||||
}
|
||||
|
||||
// NewScaleConverter creates a new ScaleConverter for converting between
|
||||
// Scales in autoscaling/v1 and extensions/v1beta1.
|
||||
func NewScaleConverter() *ScaleConverter {
|
||||
scheme := runtime.NewScheme()
|
||||
scaleautoscaling.AddToScheme(scheme)
|
||||
scalescheme.AddToScheme(scheme)
|
||||
scaleext.AddToScheme(scheme)
|
||||
scaleextint.AddToScheme(scheme)
|
||||
|
||||
return &ScaleConverter{
|
||||
scheme: scheme,
|
||||
internalVersioner: runtime.NewMultiGroupVersioner(
|
||||
scalescheme.SchemeGroupVersion,
|
||||
schema.GroupKind{Group: scaleext.GroupName, Kind: "Scale"},
|
||||
schema.GroupKind{Group: scaleautoscaling.GroupName, Kind: "Scale"},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// Scheme returns the scheme used by this scale converter.
|
||||
func (c *ScaleConverter) Scheme() *runtime.Scheme {
|
||||
return c.scheme
|
||||
}
|
||||
|
||||
// ConvertToVersion converts the given *external* input object to the given output *external* output group-version.
|
||||
func (c *ScaleConverter) ConvertToVersion(in runtime.Object, outVersion schema.GroupVersion) (runtime.Object, error) {
|
||||
scaleInt, err := c.scheme.ConvertToVersion(in, c.internalVersioner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.scheme.ConvertToVersion(scaleInt, outVersion)
|
||||
}
|
Loading…
Reference in New Issue
Block a user