mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Merge pull request #64111 from juanvallejo/jvallejo/move-more-helpers
Automatic merge from submit-queue. 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>. Move CanBeExposed helper from factory_client_access **Release note**: ```release-note NONE ``` Moves additional helpers from the "factory_client_access". Continues work from https://github.com/kubernetes/kubernetes/pull/63984 and https://github.com/kubernetes/kubernetes/pull/63884 Moves CanBeExposed from factory_client_access. cc @soltysh
This commit is contained in:
commit
b143093a62
@ -27,7 +27,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructuredscheme"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
@ -92,7 +91,7 @@ type ExposeServiceOptions struct {
|
||||
EnforceNamespace bool
|
||||
|
||||
Generators func(string) map[string]kubectl.Generator
|
||||
CanBeExposed func(kind schema.GroupKind) error
|
||||
CanBeExposed polymorphichelpers.CanBeExposedFunc
|
||||
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
|
||||
MapBasedSelectorForObject func(runtime.Object) (string, error)
|
||||
PortsForObject polymorphichelpers.PortsForObjectFunc
|
||||
@ -191,7 +190,7 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
|
||||
|
||||
o.Generators = f.Generators
|
||||
o.Builder = f.NewBuilder()
|
||||
o.CanBeExposed = f.CanBeExposed
|
||||
o.CanBeExposed = polymorphichelpers.CanBeExposedFn
|
||||
o.ClientForMapping = f.ClientForMapping
|
||||
o.MapBasedSelectorForObject = f.MapBasedSelectorForObject
|
||||
o.PortsForObject = polymorphichelpers.PortsForObjectFn
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
@ -41,7 +42,7 @@ type PauseConfig struct {
|
||||
PrintFlags *genericclioptions.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinter, error)
|
||||
|
||||
Pauser func(info *resource.Info) ([]byte, error)
|
||||
Pauser polymorphichelpers.ObjectPauserFunc
|
||||
Infos []*resource.Info
|
||||
|
||||
genericclioptions.IOStreams
|
||||
@ -101,7 +102,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
||||
}
|
||||
|
||||
o.Pauser = f.Pauser
|
||||
o.Pauser = polymorphichelpers.ObjectPauserFn
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
@ -136,7 +137,7 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, args
|
||||
|
||||
func (o PauseConfig) RunPause() error {
|
||||
allErrs := []error{}
|
||||
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), o.Pauser) {
|
||||
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), set.PatchFn(o.Pauser)) {
|
||||
info := patch.Info
|
||||
if patch.Err != nil {
|
||||
resourceString := info.Mapping.Resource.Resource
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
@ -41,7 +42,7 @@ type ResumeConfig struct {
|
||||
PrintFlags *genericclioptions.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinter, error)
|
||||
|
||||
Resumer func(object *resource.Info) ([]byte, error)
|
||||
Resumer polymorphichelpers.ObjectResumerFunc
|
||||
Infos []*resource.Info
|
||||
|
||||
genericclioptions.IOStreams
|
||||
@ -99,7 +100,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
||||
}
|
||||
|
||||
o.Resumer = f.Resumer
|
||||
o.Resumer = polymorphichelpers.ObjectResumerFn
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
@ -140,7 +141,7 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, arg
|
||||
|
||||
func (o ResumeConfig) RunResume() error {
|
||||
allErrs := []error{}
|
||||
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), o.Resumer) {
|
||||
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), set.PatchFn(o.Resumer)) {
|
||||
info := patch.Info
|
||||
|
||||
if patch.Err != nil {
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
|
||||
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
@ -139,7 +140,7 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rollbacker, err := f.Rollbacker(info.ResourceMapping())
|
||||
rollbacker, err := polymorphichelpers.RollbackerFn(f, info.ResourceMapping())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -118,16 +118,16 @@ type Patch struct {
|
||||
Patch []byte
|
||||
}
|
||||
|
||||
// patchFn is a function type that accepts an info object and returns a byte slice.
|
||||
// Implementations of patchFn should update the object and return it encoded.
|
||||
type patchFn func(*resource.Info) ([]byte, error)
|
||||
// PatchFn is a function type that accepts an info object and returns a byte slice.
|
||||
// Implementations of PatchFn should update the object and return it encoded.
|
||||
type PatchFn func(runtime.Object) ([]byte, error)
|
||||
|
||||
// CalculatePatch calls the mutation function on the provided info object, and generates a strategic merge patch for
|
||||
// the changes in the object. Encoder must be able to encode the info into the appropriate destination type.
|
||||
// This function returns whether the mutation function made any change in the original object.
|
||||
func CalculatePatch(patch *Patch, encoder runtime.Encoder, mutateFn patchFn) bool {
|
||||
func CalculatePatch(patch *Patch, encoder runtime.Encoder, mutateFn PatchFn) bool {
|
||||
patch.Before, patch.Err = runtime.Encode(encoder, patch.Info.Object)
|
||||
patch.After, patch.Err = mutateFn(patch.Info)
|
||||
patch.After, patch.Err = mutateFn(patch.Info.Object)
|
||||
if patch.Err != nil {
|
||||
return true
|
||||
}
|
||||
@ -141,7 +141,7 @@ func CalculatePatch(patch *Patch, encoder runtime.Encoder, mutateFn patchFn) boo
|
||||
|
||||
// CalculatePatches calculates patches on each provided info object. If the provided mutateFn
|
||||
// makes no change in an object, the object is not included in the final list of patches.
|
||||
func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn patchFn) []*Patch {
|
||||
func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn PatchFn) []*Patch {
|
||||
var patches []*Patch
|
||||
for _, info := range infos {
|
||||
patch := &Patch{Info: info}
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
@ -323,12 +324,53 @@ func (o *EnvOptions) RunEnv() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
patches := CalculatePatches(infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||
_, err := o.updatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
|
||||
patches := CalculatePatches(infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
|
||||
_, err := o.updatePodSpecForObject(obj, func(spec *v1.PodSpec) error {
|
||||
resolutionErrorsEncountered := false
|
||||
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
|
||||
objName, err := meta.NewAccessor().Name(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gvks, _, err := scheme.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
objKind := obj.GetObjectKind().GroupVersionKind().Kind
|
||||
if len(objKind) == 0 {
|
||||
for _, gvk := range gvks {
|
||||
if len(gvk.Kind) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
|
||||
objKind = gvk.Kind
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(containers) == 0 {
|
||||
fmt.Fprintf(o.ErrOut, "warning: %s/%s does not have any containers matching %q\n", info.Mapping.Resource, info.Name, o.ContainerSelector)
|
||||
if gvks, _, err := scheme.Scheme.ObjectKinds(obj); err == nil {
|
||||
objKind := obj.GetObjectKind().GroupVersionKind().Kind
|
||||
if len(objKind) == 0 {
|
||||
for _, gvk := range gvks {
|
||||
if len(gvk.Kind) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(gvk.Version) == 0 || gvk.Version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
|
||||
objKind = gvk.Kind
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(o.ErrOut, "warning: %s/%s does not have any containers matching %q\n", objKind, objName, o.ContainerSelector)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
for _, c := range containers {
|
||||
@ -343,7 +385,7 @@ func (o *EnvOptions) RunEnv() error {
|
||||
resolveErrors := map[string][]string{}
|
||||
store := envutil.NewResourceStore()
|
||||
|
||||
fmt.Fprintf(o.Out, "# %s %s, container %s\n", info.Mapping.Resource, info.Name, c.Name)
|
||||
fmt.Fprintf(o.Out, "# %s %s, container %s\n", objKind, objName, c.Name)
|
||||
for _, env := range c.Env {
|
||||
// Print the simple value
|
||||
if env.ValueFrom == nil {
|
||||
@ -357,7 +399,7 @@ func (o *EnvOptions) RunEnv() error {
|
||||
continue
|
||||
}
|
||||
|
||||
value, err := envutil.GetEnvVarRefValue(o.clientset, o.namespace, store, env.ValueFrom, info.Object, c)
|
||||
value, err := envutil.GetEnvVarRefValue(o.clientset, o.namespace, store, env.ValueFrom, obj, c)
|
||||
// Print the resolved value
|
||||
if err == nil {
|
||||
fmt.Fprintf(o.Out, "%s=%s\n", env.Name, value)
|
||||
@ -390,7 +432,7 @@ func (o *EnvOptions) RunEnv() error {
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), obj)
|
||||
}
|
||||
return nil, err
|
||||
})
|
||||
|
@ -210,9 +210,9 @@ func (o *SetImageOptions) Validate() error {
|
||||
func (o *SetImageOptions) Run() error {
|
||||
allErrs := []error{}
|
||||
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
|
||||
transformed := false
|
||||
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
|
||||
_, err := o.UpdatePodSpecForObject(obj, func(spec *v1.PodSpec) error {
|
||||
for name, image := range o.ContainerImages {
|
||||
var (
|
||||
containerFound bool
|
||||
@ -255,11 +255,11 @@ func (o *SetImageOptions) Run() error {
|
||||
return nil, nil
|
||||
}
|
||||
// record this change (for rollout history)
|
||||
if err := o.Recorder.Record(info.Object); err != nil {
|
||||
if err := o.Recorder.Record(obj); err != nil {
|
||||
glog.V(4).Infof("error recording current command: %v", err)
|
||||
}
|
||||
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), obj)
|
||||
})
|
||||
|
||||
for _, patch := range patches {
|
||||
|
@ -222,9 +222,9 @@ func (o *SetResourcesOptions) Validate() error {
|
||||
|
||||
func (o *SetResourcesOptions) Run() error {
|
||||
allErrs := []error{}
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
|
||||
transformed := false
|
||||
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
|
||||
_, err := o.UpdatePodSpecForObject(obj, func(spec *v1.PodSpec) error {
|
||||
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
|
||||
if len(containers) != 0 {
|
||||
for i := range containers {
|
||||
@ -255,11 +255,11 @@ func (o *SetResourcesOptions) Run() error {
|
||||
return nil, nil
|
||||
}
|
||||
// record this change (for rollout history)
|
||||
if err := o.Recorder.Record(info.Object); err != nil {
|
||||
if err := o.Recorder.Record(obj); err != nil {
|
||||
glog.V(4).Infof("error recording current command: %v", err)
|
||||
}
|
||||
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), obj)
|
||||
})
|
||||
|
||||
for _, patch := range patches {
|
||||
|
@ -201,7 +201,7 @@ func (o *SetSelectorOptions) RunSelector() error {
|
||||
|
||||
return r.Visit(func(info *resource.Info, err error) error {
|
||||
patch := &Patch{Info: info}
|
||||
CalculatePatch(patch, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||
CalculatePatch(patch, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
|
||||
selectErr := updateSelectorForObject(info.Object, *o.selector)
|
||||
if selectErr != nil {
|
||||
return nil, selectErr
|
||||
|
@ -173,8 +173,8 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
|
||||
// Run creates and applies the patch either locally or calling apiserver.
|
||||
func (o *SetServiceAccountOptions) Run() error {
|
||||
patchErrs := []error{}
|
||||
patchFn := func(info *resource.Info) ([]byte, error) {
|
||||
_, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error {
|
||||
patchFn := func(obj runtime.Object) ([]byte, error) {
|
||||
_, err := o.updatePodSpecForObject(obj, func(podSpec *v1.PodSpec) error {
|
||||
podSpec.ServiceAccountName = o.serviceAccountName
|
||||
return nil
|
||||
})
|
||||
@ -182,11 +182,11 @@ func (o *SetServiceAccountOptions) Run() error {
|
||||
return nil, err
|
||||
}
|
||||
// record this change (for rollout history)
|
||||
if err := o.Recorder.Record(info.Object); err != nil {
|
||||
if err := o.Recorder.Record(obj); err != nil {
|
||||
glog.V(4).Infof("error recording current command: %v", err)
|
||||
}
|
||||
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), obj)
|
||||
}
|
||||
|
||||
patches := CalculatePatches(o.infos, scheme.DefaultJSONEncoder(), patchFn)
|
||||
|
@ -194,7 +194,7 @@ func (o *SubjectOptions) Validate() error {
|
||||
}
|
||||
|
||||
func (o *SubjectOptions) Run(fn updateSubjects) error {
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(obj runtime.Object) ([]byte, error) {
|
||||
subjects := []rbacv1.Subject{}
|
||||
for _, user := range sets.NewString(o.Users...).List() {
|
||||
subject := rbacv1.Subject{
|
||||
@ -227,10 +227,10 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
|
||||
subjects = append(subjects, subject)
|
||||
}
|
||||
|
||||
transformed, err := updateSubjectForObject(info.Object, subjects, fn)
|
||||
transformed, err := updateSubjectForObject(obj, subjects, fn)
|
||||
if transformed && err == nil {
|
||||
// TODO: switch UpdatePodSpecForObject to work on v1.PodSpec
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||
return runtime.Encode(scheme.DefaultJSONEncoder(), obj)
|
||||
}
|
||||
return nil, err
|
||||
})
|
||||
|
@ -16,7 +16,6 @@ go_library(
|
||||
visibility = ["//build/visible_to:pkg_kubectl_cmd_util_CONSUMERS"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
|
@ -86,23 +86,12 @@ type ClientAccessFactory interface {
|
||||
// SuggestedPodTemplateResources returns a list of resource types that declare a pod template
|
||||
SuggestedPodTemplateResources() []schema.GroupResource
|
||||
|
||||
// Pauser marks the object in the info as paused. Currently supported only for Deployments.
|
||||
// Returns the patched object in bytes and any error that occurred during the encoding or
|
||||
// in case the object is already paused.
|
||||
Pauser(info *resource.Info) ([]byte, error)
|
||||
// Resumer resumes a paused object inside the info. Currently supported only for Deployments.
|
||||
// Returns the patched object in bytes and any error that occurred during the encoding or
|
||||
// in case the object is already resumed.
|
||||
Resumer(info *resource.Info) ([]byte, error)
|
||||
|
||||
// Returns the default namespace to use in cases where no
|
||||
// other namespace is specified and whether the namespace was
|
||||
// overridden.
|
||||
DefaultNamespace() (string, bool, error)
|
||||
// Generators returns the generators for the provided command
|
||||
Generators(cmdName string) map[string]kubectl.Generator
|
||||
// Check whether the kind of resources could be exposed
|
||||
CanBeExposed(kind schema.GroupKind) error
|
||||
}
|
||||
|
||||
// ObjectMappingFactory holds the second level of factory methods. These functions depend upon ClientAccessFactory methods.
|
||||
@ -116,9 +105,6 @@ type ObjectMappingFactory interface {
|
||||
// Returns a Describer for displaying the specified RESTMapping type or an error.
|
||||
Describer(mapping *meta.RESTMapping) (printers.Describer, error)
|
||||
|
||||
// Returns a Rollbacker for changing the rollback version of the specified RESTMapping type or an error
|
||||
Rollbacker(mapping *meta.RESTMapping) (kubectl.Rollbacker, error)
|
||||
|
||||
// Returns a schema that can validate objects stored on disk.
|
||||
Validator(validate bool) (validation.Schema, error)
|
||||
// OpenAPISchema returns the schema openapi schema definition
|
||||
|
@ -19,7 +19,6 @@ limitations under the License.
|
||||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
@ -41,7 +40,6 @@ import (
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
@ -182,32 +180,6 @@ func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *ring0Factory) Pauser(info *resource.Info) ([]byte, error) {
|
||||
switch obj := info.Object.(type) {
|
||||
case *extensions.Deployment:
|
||||
if obj.Spec.Paused {
|
||||
return nil, errors.New("is already paused")
|
||||
}
|
||||
obj.Spec.Paused = true
|
||||
return runtime.Encode(InternalVersionJSONEncoder(), info.Object)
|
||||
default:
|
||||
return nil, fmt.Errorf("pausing is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *ring0Factory) Resumer(info *resource.Info) ([]byte, error) {
|
||||
switch obj := info.Object.(type) {
|
||||
case *extensions.Deployment:
|
||||
if !obj.Spec.Paused {
|
||||
return nil, errors.New("is not paused")
|
||||
}
|
||||
obj.Spec.Paused = false
|
||||
return runtime.Encode(InternalVersionJSONEncoder(), info.Object)
|
||||
default:
|
||||
return nil, fmt.Errorf("resuming is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
func (f *ring0Factory) DefaultNamespace() (string, bool, error) {
|
||||
return f.clientGetter.ToRawKubeConfigLoader().Namespace()
|
||||
}
|
||||
@ -422,17 +394,6 @@ func (f *ring0Factory) Generators(cmdName string) map[string]kubectl.Generator {
|
||||
return DefaultGenerators(cmdName)
|
||||
}
|
||||
|
||||
func (f *ring0Factory) CanBeExposed(kind schema.GroupKind) error {
|
||||
switch kind {
|
||||
case api.Kind("ReplicationController"), api.Kind("Service"), api.Kind("Pod"),
|
||||
extensions.Kind("Deployment"), apps.Kind("Deployment"), extensions.Kind("ReplicaSet"), apps.Kind("ReplicaSet"):
|
||||
// nothing to do here
|
||||
default:
|
||||
return fmt.Errorf("cannot expose a %s", kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// this method exists to help us find the points still relying on internal types.
|
||||
func InternalVersionDecoder() runtime.Decoder {
|
||||
return legacyscheme.Codecs.UniversalDecoder()
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"k8s.io/client-go/dynamic"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
openapivalidation "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||
@ -132,14 +131,6 @@ func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RES
|
||||
return printersinternal.GenericDescriberFor(mapping, dynamicClient, eventsClient), nil
|
||||
}
|
||||
|
||||
func (f *ring1Factory) Rollbacker(mapping *meta.RESTMapping) (kubectl.Rollbacker, error) {
|
||||
external, err := f.clientAccessFactory.KubernetesClientSet()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubectl.RollbackerFor(mapping.GroupVersionKind.GroupKind(), external)
|
||||
}
|
||||
|
||||
func (f *ring1Factory) Validator(validate bool) (validation.Schema, error) {
|
||||
if !validate {
|
||||
return validation.NullSchema{}, nil
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
@ -66,33 +65,6 @@ func TestProtocolsForObject(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanBeExposed(t *testing.T) {
|
||||
factory := NewFactory(genericclioptions.NewTestConfigFlags())
|
||||
tests := []struct {
|
||||
kind schema.GroupKind
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
kind: api.Kind("ReplicationController"),
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
kind: api.Kind("Node"),
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := factory.CanBeExposed(test.kind)
|
||||
if test.expectErr && err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakePortsString(t *testing.T) {
|
||||
tests := []struct {
|
||||
ports []api.ServicePort
|
||||
|
@ -5,17 +5,22 @@ go_library(
|
||||
srcs = [
|
||||
"attachablepodforobject.go",
|
||||
"canbeautoscaled.go",
|
||||
"canbeexposed.go",
|
||||
"helpers.go",
|
||||
"historyviewer.go",
|
||||
"interface.go",
|
||||
"logsforobject.go",
|
||||
"objectpauser.go",
|
||||
"objectresumer.go",
|
||||
"portsforobject.go",
|
||||
"rollbacker.go",
|
||||
"statusviewer.go",
|
||||
"updatepodspec.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
@ -36,6 +41,7 @@ go_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/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
@ -48,6 +54,7 @@ go_library(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"canbeexposed_test.go",
|
||||
"helpers_test.go",
|
||||
"logsforobject_test.go",
|
||||
"portsforobject_test.go",
|
||||
|
38
pkg/kubectl/polymorphichelpers/canbeexposed.go
Normal file
38
pkg/kubectl/polymorphichelpers/canbeexposed.go
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
// Check whether the kind of resources could be exposed
|
||||
func canBeExposed(kind schema.GroupKind) error {
|
||||
switch kind {
|
||||
case api.Kind("ReplicationController"), api.Kind("Service"), api.Kind("Pod"),
|
||||
extensions.Kind("Deployment"), apps.Kind("Deployment"), extensions.Kind("ReplicaSet"), apps.Kind("ReplicaSet"):
|
||||
// nothing to do here
|
||||
default:
|
||||
return fmt.Errorf("cannot expose a %s", kind)
|
||||
}
|
||||
return nil
|
||||
}
|
50
pkg/kubectl/polymorphichelpers/canbeexposed_test.go
Normal file
50
pkg/kubectl/polymorphichelpers/canbeexposed_test.go
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestCanBeExposed(t *testing.T) {
|
||||
tests := []struct {
|
||||
kind schema.GroupKind
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
kind: api.Kind("ReplicationController"),
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
kind: api.Kind("Node"),
|
||||
expectErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := canBeExposed(test.kind)
|
||||
if test.expectErr && err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
@ -71,3 +71,31 @@ 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
|
||||
type CanBeExposedFunc func(kind schema.GroupKind) error
|
||||
|
||||
// CanBeExposedFn gives a way to easily override the function for unit testing if needed
|
||||
var CanBeExposedFn CanBeExposedFunc = canBeExposed
|
||||
|
||||
// ObjectPauserFunc is a function type that marks the object in a given info as paused.
|
||||
type ObjectPauserFunc func(runtime.Object) ([]byte, error)
|
||||
|
||||
// ObjectPauserFn gives a way to easily override the function for unit testing if needed.
|
||||
// Returns the patched object in bytes and any error that occurred during the encoding or
|
||||
// in case the object is already paused.
|
||||
var ObjectPauserFn ObjectPauserFunc = defaultObjectPauser
|
||||
|
||||
// ObjectResumerFunc is a function type that marks the object in a given info as resumed.
|
||||
type ObjectResumerFunc func(runtime.Object) ([]byte, error)
|
||||
|
||||
// ObjectResumerFn gives a way to easily override the function for unit testing if needed.
|
||||
// Returns the patched object in bytes and any error that occurred during the encoding or
|
||||
// in case the object is already resumed.
|
||||
var ObjectResumerFn ObjectResumerFunc = defaultObjectResumer
|
||||
|
||||
// RollbackerFunc gives a way to change the rollback version of the specified RESTMapping type
|
||||
type RollbackerFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (kubectl.Rollbacker, error)
|
||||
|
||||
// RollbackerFn gives a way to easily override the function for unit testing if needed
|
||||
var RollbackerFn RollbackerFunc = rollbacker
|
||||
|
46
pkg/kubectl/polymorphichelpers/objectpauser.go
Normal file
46
pkg/kubectl/polymorphichelpers/objectpauser.go
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
// Currently only supports Deployments.
|
||||
func defaultObjectPauser(obj runtime.Object) ([]byte, error) {
|
||||
switch obj := obj.(type) {
|
||||
case *extensions.Deployment:
|
||||
if obj.Spec.Paused {
|
||||
return nil, errors.New("is already paused")
|
||||
}
|
||||
obj.Spec.Paused = true
|
||||
return runtime.Encode(internalVersionJSONEncoder(), obj)
|
||||
default:
|
||||
return nil, fmt.Errorf("pausing is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
func internalVersionJSONEncoder() runtime.Encoder {
|
||||
encoder := legacyscheme.Codecs.LegacyCodec(legacyscheme.Scheme.PrioritizedVersionsAllGroups()...)
|
||||
return unstructured.JSONFallbackEncoder{Encoder: encoder}
|
||||
}
|
38
pkg/kubectl/polymorphichelpers/objectresumer.go
Normal file
38
pkg/kubectl/polymorphichelpers/objectresumer.go
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
|
||||
func defaultObjectResumer(obj runtime.Object) ([]byte, error) {
|
||||
switch obj := obj.(type) {
|
||||
case *extensions.Deployment:
|
||||
if !obj.Spec.Paused {
|
||||
return nil, errors.New("is not paused")
|
||||
}
|
||||
obj.Spec.Paused = false
|
||||
return runtime.Encode(internalVersionJSONEncoder(), obj)
|
||||
default:
|
||||
return nil, fmt.Errorf("resuming is not supported")
|
||||
}
|
||||
}
|
38
pkg/kubectl/polymorphichelpers/rollbacker.go
Normal file
38
pkg/kubectl/polymorphichelpers/rollbacker.go
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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 (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
// Returns a Rollbacker for changing the rollback version of the specified RESTMapping type or an error
|
||||
func rollbacker(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (kubectl.Rollbacker, error) {
|
||||
clientConfig, err := restClientGetter.ToRESTConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
external, err := kubernetes.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return kubectl.RollbackerFor(mapping.GroupVersionKind.GroupKind(), external)
|
||||
}
|
Loading…
Reference in New Issue
Block a user