mirror of https://github.com/k3s-io/k3s
Add Custom Resource support to "kubectl autoscale"
Generalize the autoscsale command to simply let the dynamic client check if a scale subresource is registered for the supplied type. This allows using the autoscale command for built in types as well as custom resources.pull/564/head
parent
fdf381098b
commit
c9479990b3
|
@ -10,7 +10,6 @@ go_library(
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
"//pkg/kubectl/generate:go_default_library",
|
"//pkg/kubectl/generate:go_default_library",
|
||||||
"//pkg/kubectl/generate/versioned:go_default_library",
|
"//pkg/kubectl/generate/versioned:go_default_library",
|
||||||
"//pkg/kubectl/polymorphichelpers:go_default_library",
|
|
||||||
"//pkg/kubectl/scheme:go_default_library",
|
"//pkg/kubectl/scheme:go_default_library",
|
||||||
"//pkg/kubectl/util/i18n:go_default_library",
|
"//pkg/kubectl/util/i18n:go_default_library",
|
||||||
"//pkg/kubectl/util/templates:go_default_library",
|
"//pkg/kubectl/util/templates:go_default_library",
|
||||||
|
@ -20,6 +19,7 @@ go_library(
|
||||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/printers:go_default_library",
|
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/printers:go_default_library",
|
||||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
|
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/kubernetes/typed/autoscaling/v1:go_default_library",
|
"//staging/src/k8s.io/client-go/kubernetes/typed/autoscaling/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/scale:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
|
|
|
@ -28,11 +28,11 @@ import (
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions/printers"
|
"k8s.io/cli-runtime/pkg/genericclioptions/printers"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
||||||
autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
|
autoscalingv1client "k8s.io/client-go/kubernetes/typed/autoscaling/v1"
|
||||||
|
"k8s.io/client-go/scale"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/generate"
|
"k8s.io/kubernetes/pkg/kubectl/generate"
|
||||||
generateversioned "k8s.io/kubernetes/pkg/kubectl/generate/versioned"
|
generateversioned "k8s.io/kubernetes/pkg/kubectl/generate/versioned"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/templates"
|
"k8s.io/kubernetes/pkg/kubectl/util/templates"
|
||||||
|
@ -74,10 +74,10 @@ type AutoscaleOptions struct {
|
||||||
namespace string
|
namespace string
|
||||||
dryRun bool
|
dryRun bool
|
||||||
builder *resource.Builder
|
builder *resource.Builder
|
||||||
canBeAutoscaled polymorphichelpers.CanBeAutoscaledFunc
|
|
||||||
generatorFunc func(string, *meta.RESTMapping) (generate.StructuredGenerator, error)
|
generatorFunc func(string, *meta.RESTMapping) (generate.StructuredGenerator, error)
|
||||||
|
|
||||||
HPAClient autoscalingv1client.HorizontalPodAutoscalersGetter
|
HPAClient autoscalingv1client.HorizontalPodAutoscalersGetter
|
||||||
|
scaleKindResolver scale.ScaleKindResolver
|
||||||
|
|
||||||
genericclioptions.IOStreams
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,11 @@ func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
||||||
o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run")
|
o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run")
|
||||||
o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
|
||||||
o.builder = f.NewBuilder()
|
o.builder = f.NewBuilder()
|
||||||
o.canBeAutoscaled = polymorphichelpers.CanBeAutoscaledFn
|
discoveryClient, err := f.ToDiscoveryClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.scaleKindResolver = scale.NewDiscoveryScaleKindResolver(discoveryClient)
|
||||||
o.args = args
|
o.args = args
|
||||||
o.RecordFlags.Complete(cmd)
|
o.RecordFlags.Complete(cmd)
|
||||||
|
|
||||||
|
@ -196,7 +200,7 @@ func (o *AutoscaleOptions) Validate() error {
|
||||||
|
|
||||||
func (o *AutoscaleOptions) Run() error {
|
func (o *AutoscaleOptions) Run() error {
|
||||||
r := o.builder.
|
r := o.builder.
|
||||||
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
Unstructured().
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(o.namespace).DefaultNamespace().
|
NamespaceParam(o.namespace).DefaultNamespace().
|
||||||
FilenameParam(o.enforceNamespace, o.FilenameOptions).
|
FilenameParam(o.enforceNamespace, o.FilenameOptions).
|
||||||
|
@ -214,8 +218,9 @@ func (o *AutoscaleOptions) Run() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping := info.ResourceMapping()
|
mapping := info.ResourceMapping()
|
||||||
if err := o.canBeAutoscaled(mapping.GroupVersionKind.GroupKind()); err != nil {
|
gvr := mapping.GroupVersionKind.GroupVersion().WithResource(mapping.Resource.Resource)
|
||||||
return err
|
if _, err := o.scaleKindResolver.ScaleForResource(gvr); err != nil {
|
||||||
|
return fmt.Errorf("cannot autoscale a %v: %v", mapping.GroupVersionKind.Kind, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
generator, err := o.generatorFunc(info.Name, mapping)
|
generator, err := o.generatorFunc(info.Name, mapping)
|
||||||
|
|
|
@ -4,7 +4,6 @@ go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
"attachablepodforobject.go",
|
"attachablepodforobject.go",
|
||||||
"canbeautoscaled.go",
|
|
||||||
"canbeexposed.go",
|
"canbeexposed.go",
|
||||||
"helpers.go",
|
"helpers.go",
|
||||||
"historyviewer.go",
|
"historyviewer.go",
|
||||||
|
@ -51,7 +50,6 @@ go_library(
|
||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"canbeautoscaled_test.go",
|
|
||||||
"canbeexposed_test.go",
|
"canbeexposed_test.go",
|
||||||
"helpers_test.go",
|
"helpers_test.go",
|
||||||
"logsforobject_test.go",
|
"logsforobject_test.go",
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 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 polymorphichelpers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func canBeAutoscaled(kind schema.GroupKind) error {
|
|
||||||
switch kind {
|
|
||||||
case
|
|
||||||
corev1.SchemeGroupVersion.WithKind("ReplicationController").GroupKind(),
|
|
||||||
appsv1.SchemeGroupVersion.WithKind("Deployment").GroupKind(),
|
|
||||||
appsv1.SchemeGroupVersion.WithKind("ReplicaSet").GroupKind(),
|
|
||||||
appsv1.SchemeGroupVersion.WithKind("StatefulSet").GroupKind(),
|
|
||||||
extensionsv1beta1.SchemeGroupVersion.WithKind("Deployment").GroupKind(),
|
|
||||||
extensionsv1beta1.SchemeGroupVersion.WithKind("ReplicaSet").GroupKind():
|
|
||||||
// nothing to do here
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("cannot autoscale a %v", kind)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2018 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 polymorphichelpers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCanBeAutoscaled(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
kind schema.GroupKind
|
|
||||||
expectErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
kind: corev1.SchemeGroupVersion.WithKind("ReplicationController").GroupKind(),
|
|
||||||
expectErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: appsv1.SchemeGroupVersion.WithKind("Deployment").GroupKind(),
|
|
||||||
expectErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: appsv1.SchemeGroupVersion.WithKind("StatefulSet").GroupKind(),
|
|
||||||
expectErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: extensionsv1beta1.SchemeGroupVersion.WithKind("ReplicaSet").GroupKind(),
|
|
||||||
expectErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: corev1.SchemeGroupVersion.WithKind("Node").GroupKind(),
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: corev1.SchemeGroupVersion.WithKind("Service").GroupKind(),
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: corev1.SchemeGroupVersion.WithKind("Pod").GroupKind(),
|
|
||||||
expectErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
err := canBeAutoscaled(test.kind)
|
|
||||||
if test.expectErr && err == nil {
|
|
||||||
t.Error("unexpected non-error")
|
|
||||||
}
|
|
||||||
if !test.expectErr && err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -79,12 +79,6 @@ type PortsForObjectFunc func(object runtime.Object) ([]string, error)
|
||||||
// PortsForObjectFn gives a way to easily override the function for unit testing if needed
|
// PortsForObjectFn gives a way to easily override the function for unit testing if needed
|
||||||
var PortsForObjectFn PortsForObjectFunc = portsForObject
|
var PortsForObjectFn PortsForObjectFunc = portsForObject
|
||||||
|
|
||||||
// CanBeAutoscaledFunc checks whether the kind of resources could be autoscaled
|
|
||||||
type CanBeAutoscaledFunc func(kind schema.GroupKind) error
|
|
||||||
|
|
||||||
// CanBeAutoscaledFn gives a way to easily override the function for unit testing if needed
|
|
||||||
var CanBeAutoscaledFn CanBeAutoscaledFunc = canBeAutoscaled
|
|
||||||
|
|
||||||
// CanBeExposedFunc is a function type that can tell you whether a given GroupKind is capable of being exposed
|
// CanBeExposedFunc is a function type that can tell you whether a given GroupKind is capable of being exposed
|
||||||
type CanBeExposedFunc func(kind schema.GroupKind) error
|
type CanBeExposedFunc func(kind schema.GroupKind) error
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue