mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #63803 from deads2k/cli-58-set-versioned
Automatic merge from submit-queue (batch tested with PRs 63272, 63782, 63715, 63811, 63803). 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>. switch to versioned objects only for set Only used versioned types in the `kubectl set` commands. This has long been the goal and we finally make it so here. @liggitt @soltysh as promised in earlier pulls when I asked you to go with it while I unwound the debt. This frees the entire package. ```release-note NONE ```
This commit is contained in:
commit
d2952c0b2e
@ -33,6 +33,7 @@ go_library(
|
|||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/meta: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:go_default_library",
|
||||||
@ -63,9 +64,7 @@ go_test(
|
|||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
|
||||||
"//pkg/api/testapi:go_default_library",
|
"//pkg/api/testapi:go_default_library",
|
||||||
"//pkg/apis/rbac:go_default_library",
|
|
||||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
@ -80,6 +79,7 @@ go_test(
|
|||||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||||
"//vendor/k8s.io/api/core/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/api/extensions/v1beta1:go_default_library",
|
||||||
|
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1: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:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
@ -414,18 +414,17 @@ func (o *EnvOptions) RunEnv() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Local || o.dryRun {
|
if o.Local || o.dryRun {
|
||||||
if err := o.PrintObj(patch.Info.Object, o.Out); err != nil {
|
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, fmt.Errorf("failed to patch env update to pod template: %v\n", err))
|
allErrs = append(allErrs, fmt.Errorf("failed to patch env update to pod template: %v\n", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
info.Refresh(obj, true)
|
|
||||||
|
|
||||||
// make sure arguments to set or replace environment variables are set
|
// make sure arguments to set or replace environment variables are set
|
||||||
// before returning a successful message
|
// before returning a successful message
|
||||||
@ -433,7 +432,7 @@ func (o *EnvOptions) RunEnv() error {
|
|||||||
return fmt.Errorf("at least one environment variable must be provided")
|
return fmt.Errorf("at least one environment variable must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
if err := o.PrintObj(actual, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/serializer"
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
@ -50,10 +49,9 @@ func TestSetEnvLocal(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -66,8 +64,8 @@ func TestSetEnvLocal(t *testing.T) {
|
|||||||
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
||||||
opts := NewEnvOptions(streams)
|
opts := NewEnvOptions(streams)
|
||||||
opts.PrintFlags = &printers.PrintFlags{
|
opts.PrintFlags = &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
}
|
}
|
||||||
opts.FilenameOptions = resource.FilenameOptions{
|
opts.FilenameOptions = resource.FilenameOptions{
|
||||||
@ -93,10 +91,9 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -109,8 +106,8 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
|
|||||||
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
streams, _, buf, bufErr := genericclioptions.NewTestIOStreams()
|
||||||
opts := NewEnvOptions(streams)
|
opts := NewEnvOptions(streams)
|
||||||
opts.PrintFlags = &printers.PrintFlags{
|
opts.PrintFlags = &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
}
|
}
|
||||||
opts.FilenameOptions = resource.FilenameOptions{
|
opts.FilenameOptions = resource.FilenameOptions{
|
||||||
@ -463,17 +460,15 @@ func TestSetEnvRemote(t *testing.T) {
|
|||||||
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
|
tf.ClientConfigVal = &restclient.Config{ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Version: ""}}}
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: groupVersion,
|
GroupVersion: groupVersion,
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
||||||
switch p, m := req.URL.Path, req.Method; {
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
case p == resourcePath && m == http.MethodGet:
|
case p == resourcePath && m == http.MethodGet:
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
case p == resourcePath && m == http.MethodPatch:
|
case p == resourcePath && m == http.MethodPatch:
|
||||||
stream, err := req.GetBody()
|
stream, err := req.GetBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -484,7 +479,7 @@ func TestSetEnvRemote(t *testing.T) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
|
assert.Contains(t, string(bytes), `"value":`+`"`+"prod"+`"`, fmt.Sprintf("env not updated for %#v", input.object))
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
default:
|
default:
|
||||||
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
|
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
|
||||||
return nil, fmt.Errorf("unexpected request")
|
return nil, fmt.Errorf("unexpected request")
|
||||||
@ -497,8 +492,8 @@ func TestSetEnvRemote(t *testing.T) {
|
|||||||
streams := genericclioptions.NewTestIOStreamsDiscard()
|
streams := genericclioptions.NewTestIOStreamsDiscard()
|
||||||
opts := NewEnvOptions(streams)
|
opts := NewEnvOptions(streams)
|
||||||
opts.PrintFlags = &printers.PrintFlags{
|
opts.PrintFlags = &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
}
|
}
|
||||||
opts.Local = false
|
opts.Local = false
|
||||||
|
@ -275,21 +275,20 @@ func (o *SetImageOptions) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Local || o.DryRun {
|
if o.Local || o.DryRun {
|
||||||
if err := o.PrintObj(patch.Info.Object, o.Out); err != nil {
|
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// patch the change
|
// patch the change
|
||||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v\n", err))
|
allErrs = append(allErrs, fmt.Errorf("failed to patch image update to pod template: %v\n", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
info.Refresh(obj, true)
|
|
||||||
|
|
||||||
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
if err := o.PrintObj(actual, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
|
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
@ -51,11 +50,9 @@ func TestImageLocal(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -74,8 +71,8 @@ func TestImageLocal(t *testing.T) {
|
|||||||
|
|
||||||
opts := SetImageOptions{
|
opts := SetImageOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -101,8 +98,8 @@ func TestImageLocal(t *testing.T) {
|
|||||||
|
|
||||||
func TestSetImageValidation(t *testing.T) {
|
func TestSetImageValidation(t *testing.T) {
|
||||||
printFlags := &printers.PrintFlags{
|
printFlags := &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -174,11 +171,9 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -197,8 +192,8 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
|
|||||||
|
|
||||||
opts := SetImageOptions{
|
opts := SetImageOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -554,17 +549,15 @@ func TestSetImageRemote(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
|
|
||||||
ns := serializer.DirectCodecFactory{CodecFactory: scheme.Codecs}
|
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: groupVersion,
|
GroupVersion: groupVersion,
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
||||||
switch p, m := req.URL.Path, req.Method; {
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
case p == resourcePath && m == http.MethodGet:
|
case p == resourcePath && m == http.MethodGet:
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
case p == resourcePath && m == http.MethodPatch:
|
case p == resourcePath && m == http.MethodPatch:
|
||||||
stream, err := req.GetBody()
|
stream, err := req.GetBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -575,7 +568,7 @@ func TestSetImageRemote(t *testing.T) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
|
assert.Contains(t, string(bytes), `"image":`+`"`+"thingy"+`"`, fmt.Sprintf("image not updated for %#v", input.object))
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
default:
|
default:
|
||||||
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
|
t.Errorf("%s: unexpected request: %s %#v\n%#v", "image", req.Method, req.URL, req)
|
||||||
return nil, fmt.Errorf("unexpected request")
|
return nil, fmt.Errorf("unexpected request")
|
||||||
@ -591,8 +584,8 @@ func TestSetImageRemote(t *testing.T) {
|
|||||||
cmd.Flags().Set("output", outputFormat)
|
cmd.Flags().Set("output", outputFormat)
|
||||||
opts := SetImageOptions{
|
opts := SetImageOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar
|
|||||||
|
|
||||||
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||||
builder := f.NewBuilder().
|
builder := f.NewBuilder().
|
||||||
WithScheme(legacyscheme.Scheme).
|
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||||
LocalParam(o.Local).
|
LocalParam(o.Local).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
@ -222,9 +223,8 @@ func (o *SetResourcesOptions) Validate() error {
|
|||||||
|
|
||||||
func (o *SetResourcesOptions) Run() error {
|
func (o *SetResourcesOptions) Run() error {
|
||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||||
transformed := false
|
transformed := false
|
||||||
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
|
|
||||||
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
|
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
|
||||||
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
|
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
|
||||||
if len(containers) != 0 {
|
if len(containers) != 0 {
|
||||||
@ -260,7 +260,7 @@ func (o *SetResourcesOptions) Run() error {
|
|||||||
glog.V(4).Infof("error recording current command: %v", err)
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
|
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, patch := range patches {
|
for _, patch := range patches {
|
||||||
@ -277,20 +277,19 @@ func (o *SetResourcesOptions) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Local || o.DryRun {
|
if o.Local || o.DryRun {
|
||||||
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
|
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, fmt.Errorf("failed to patch limit update to pod template %v\n", err))
|
allErrs = append(allErrs, fmt.Errorf("failed to patch limit update to pod template %v\n", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
info.Refresh(obj, true)
|
|
||||||
|
|
||||||
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
|
if err := o.PrintObj(actual, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,9 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
@ -49,11 +49,10 @@ import (
|
|||||||
func TestResourcesLocal(t *testing.T) {
|
func TestResourcesLocal(t *testing.T) {
|
||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -72,8 +71,8 @@ func TestResourcesLocal(t *testing.T) {
|
|||||||
|
|
||||||
opts := SetResourcesOptions{
|
opts := SetResourcesOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -104,11 +103,10 @@ func TestResourcesLocal(t *testing.T) {
|
|||||||
func TestSetMultiResourcesLimitsLocal(t *testing.T) {
|
func TestSetMultiResourcesLimitsLocal(t *testing.T) {
|
||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -127,8 +125,8 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
|
|||||||
|
|
||||||
opts := SetResourcesOptions{
|
opts := SetResourcesOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -471,17 +469,16 @@ func TestSetResourcesRemote(t *testing.T) {
|
|||||||
testapi.Default = testapi.Groups[input.testAPIGroup]
|
testapi.Default = testapi.Groups[input.testAPIGroup]
|
||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
|
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: groupVersion,
|
GroupVersion: groupVersion,
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
||||||
switch p, m := req.URL.Path, req.Method; {
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
case p == resourcePath && m == http.MethodGet:
|
case p == resourcePath && m == http.MethodGet:
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
case p == resourcePath && m == http.MethodPatch:
|
case p == resourcePath && m == http.MethodPatch:
|
||||||
stream, err := req.GetBody()
|
stream, err := req.GetBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -492,7 +489,7 @@ func TestSetResourcesRemote(t *testing.T) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
assert.Contains(t, string(bytes), "200m", fmt.Sprintf("resources not updated for %#v", input.object))
|
assert.Contains(t, string(bytes), "200m", fmt.Sprintf("resources not updated for %#v", input.object))
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
default:
|
default:
|
||||||
t.Errorf("%s: unexpected request: %s %#v\n%#v", "resources", req.Method, req.URL, req)
|
t.Errorf("%s: unexpected request: %s %#v\n%#v", "resources", req.Method, req.URL, req)
|
||||||
return nil, fmt.Errorf("unexpected request")
|
return nil, fmt.Errorf("unexpected request")
|
||||||
@ -508,8 +505,8 @@ func TestSetResourcesRemote(t *testing.T) {
|
|||||||
cmd.Flags().Set("output", outputFormat)
|
cmd.Flags().Set("output", outputFormat)
|
||||||
opts := SetResourcesOptions{
|
opts := SetResourcesOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
|
|||||||
|
|
||||||
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||||
o.builder = f.NewBuilder().
|
o.builder = f.NewBuilder().
|
||||||
WithScheme(legacyscheme.Scheme).
|
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||||
LocalParam(o.local).
|
LocalParam(o.local).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
@ -201,9 +202,7 @@ func (o *SetSelectorOptions) RunSelector() error {
|
|||||||
|
|
||||||
return r.Visit(func(info *resource.Info, err error) error {
|
return r.Visit(func(info *resource.Info, err error) error {
|
||||||
patch := &Patch{Info: info}
|
patch := &Patch{Info: info}
|
||||||
CalculatePatch(patch, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
CalculatePatch(patch, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||||
versioned := cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
|
|
||||||
patch.Info.Object = versioned
|
|
||||||
selectErr := updateSelectorForObject(info.Object, *o.selector)
|
selectErr := updateSelectorForObject(info.Object, *o.selector)
|
||||||
if selectErr != nil {
|
if selectErr != nil {
|
||||||
return nil, selectErr
|
return nil, selectErr
|
||||||
@ -214,7 +213,7 @@ func (o *SetSelectorOptions) RunSelector() error {
|
|||||||
glog.V(4).Infof("error recording current command: %v", err)
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
|
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||||
})
|
})
|
||||||
|
|
||||||
if patch.Err != nil {
|
if patch.Err != nil {
|
||||||
@ -224,13 +223,12 @@ func (o *SetSelectorOptions) RunSelector() error {
|
|||||||
return o.PrintObj(info.Object, o.Out)
|
return o.PrintObj(info.Object, o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Refresh(patched, true)
|
return o.PrintObj(actual, o.Out)
|
||||||
return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, info.Mapping), o.Out)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,12 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUpdateSelectorForObjectTypes(t *testing.T) {
|
func TestUpdateSelectorForObjectTypes(t *testing.T) {
|
||||||
@ -319,10 +320,9 @@ func TestSelectorTest(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
|
|||||||
resources := args[:len(args)-1]
|
resources := args[:len(args)-1]
|
||||||
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||||
builder := f.NewBuilder().
|
builder := f.NewBuilder().
|
||||||
WithScheme(legacyscheme.Scheme).
|
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||||
LocalParam(o.local).
|
LocalParam(o.local).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
@ -174,7 +175,6 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
|
|||||||
func (o *SetServiceAccountOptions) Run() error {
|
func (o *SetServiceAccountOptions) Run() error {
|
||||||
patchErrs := []error{}
|
patchErrs := []error{}
|
||||||
patchFn := func(info *resource.Info) ([]byte, error) {
|
patchFn := func(info *resource.Info) ([]byte, error) {
|
||||||
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
|
|
||||||
_, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error {
|
_, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error {
|
||||||
podSpec.ServiceAccountName = o.serviceAccountName
|
podSpec.ServiceAccountName = o.serviceAccountName
|
||||||
return nil
|
return nil
|
||||||
@ -187,10 +187,10 @@ func (o *SetServiceAccountOptions) Run() error {
|
|||||||
glog.V(4).Infof("error recording current command: %v", err)
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.Object)
|
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
patches := CalculatePatches(o.infos, cmdutil.InternalVersionJSONEncoder(), patchFn)
|
patches := CalculatePatches(o.infos, scheme.DefaultJSONEncoder(), patchFn)
|
||||||
for _, patch := range patches {
|
for _, patch := range patches {
|
||||||
info := patch.Info
|
info := patch.Info
|
||||||
if patch.Err != nil {
|
if patch.Err != nil {
|
||||||
@ -198,19 +198,18 @@ func (o *SetServiceAccountOptions) Run() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if o.local || o.dryRun {
|
if o.local || o.dryRun {
|
||||||
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
|
if err := o.PrintObj(info.Object, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
patched, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
patchErrs = append(patchErrs, fmt.Errorf("failed to patch ServiceAccountName %v", err))
|
patchErrs = append(patchErrs, fmt.Errorf("failed to patch ServiceAccountName %v", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
info.Refresh(patched, true)
|
|
||||||
|
|
||||||
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
|
if err := o.PrintObj(actual, o.Out); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,9 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
@ -91,8 +91,8 @@ func TestSetServiceAccountLocal(t *testing.T) {
|
|||||||
testapi.Default = testapi.Groups[input.apiGroup]
|
testapi.Default = testapi.Groups[input.apiGroup]
|
||||||
saConfig := SetServiceAccountOptions{
|
saConfig := SetServiceAccountOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -115,10 +115,9 @@ func TestSetServiceAccountMultiLocal(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: schema.GroupVersion{Version: ""},
|
GroupVersion: schema.GroupVersion{Version: ""},
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -135,8 +134,8 @@ func TestSetServiceAccountMultiLocal(t *testing.T) {
|
|||||||
cmd.Flags().Set("local", "true")
|
cmd.Flags().Set("local", "true")
|
||||||
opts := SetServiceAccountOptions{
|
opts := SetServiceAccountOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -342,17 +341,15 @@ func TestSetServiceAccountRemote(t *testing.T) {
|
|||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
|
||||||
codec := scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(groupVersion), scheme.Codecs.UniversalDecoder(groupVersion), groupVersion, groupVersion)
|
|
||||||
ns := legacyscheme.Codecs
|
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.Client = &fake.RESTClient{
|
tf.Client = &fake.RESTClient{
|
||||||
GroupVersion: groupVersion,
|
GroupVersion: groupVersion,
|
||||||
NegotiatedSerializer: ns,
|
NegotiatedSerializer: serializer.DirectCodecFactory{CodecFactory: scheme.Codecs},
|
||||||
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
|
||||||
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
resourcePath := testapi.Default.ResourcePath(input.args[0]+"s", tf.Namespace, input.args[1])
|
||||||
switch p, m := req.URL.Path, req.Method; {
|
switch p, m := req.URL.Path, req.Method; {
|
||||||
case p == resourcePath && m == http.MethodGet:
|
case p == resourcePath && m == http.MethodGet:
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
case p == resourcePath && m == http.MethodPatch:
|
case p == resourcePath && m == http.MethodPatch:
|
||||||
stream, err := req.GetBody()
|
stream, err := req.GetBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -363,7 +360,7 @@ func TestSetServiceAccountRemote(t *testing.T) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
|
assert.Contains(t, string(bytes), `"serviceAccountName":`+`"`+serviceAccount+`"`, fmt.Sprintf("serviceaccount not updated for %#v", input.object))
|
||||||
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(codec, input.object)}, nil
|
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: objBody(input.object)}, nil
|
||||||
default:
|
default:
|
||||||
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
|
t.Errorf("%s: unexpected request: %s %#v\n%#v", "serviceaccount", req.Method, req.URL, req)
|
||||||
return nil, fmt.Errorf("unexpected request")
|
return nil, fmt.Errorf("unexpected request")
|
||||||
@ -379,8 +376,8 @@ func TestSetServiceAccountRemote(t *testing.T) {
|
|||||||
cmd.Flags().Set("output", outputFormat)
|
cmd.Flags().Set("output", outputFormat)
|
||||||
saConfig := SetServiceAccountOptions{
|
saConfig := SetServiceAccountOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -426,8 +423,8 @@ func TestServiceAccountValidation(t *testing.T) {
|
|||||||
|
|
||||||
saConfig := &SetServiceAccountOptions{
|
saConfig := &SetServiceAccountOptions{
|
||||||
PrintFlags: &printers.PrintFlags{
|
PrintFlags: &printers.PrintFlags{
|
||||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(legacyscheme.Scheme),
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(scheme.Scheme),
|
||||||
NamePrintFlags: printers.NewNamePrintFlags("", legacyscheme.Scheme),
|
NamePrintFlags: printers.NewNamePrintFlags("", scheme.Scheme),
|
||||||
|
|
||||||
OutputFormat: &outputFormat,
|
OutputFormat: &outputFormat,
|
||||||
},
|
},
|
||||||
@ -439,8 +436,8 @@ func TestServiceAccountValidation(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func objBody(codec runtime.Codec, obj runtime.Object) io.ReadCloser {
|
func objBody(obj runtime.Object) io.ReadCloser {
|
||||||
return bytesBody([]byte(runtime.EncodeOrDie(codec, obj)))
|
return bytesBody([]byte(runtime.EncodeOrDie(scheme.DefaultJSONEncoder(), obj)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultHeader() http.Header {
|
func defaultHeader() http.Header {
|
||||||
|
@ -20,10 +20,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
@ -34,7 +33,9 @@ import (
|
|||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -52,7 +53,7 @@ var (
|
|||||||
kubectl create rolebinding admin --role=admin --user=admin -o yaml --dry-run | kubectl set subject --local -f - --user=foo -o yaml`)
|
kubectl create rolebinding admin --role=admin --user=admin -o yaml --dry-run | kubectl set subject --local -f - --user=foo -o yaml`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type updateSubjects func(existings []rbac.Subject, targets []rbac.Subject) (bool, []rbac.Subject)
|
type updateSubjects func(existings []rbacv1.Subject, targets []rbacv1.Subject) (bool, []rbacv1.Subject)
|
||||||
|
|
||||||
// SubjectOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
// SubjectOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
// referencing the cmd.Flags
|
// referencing the cmd.Flags
|
||||||
@ -138,7 +139,7 @@ func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||||||
|
|
||||||
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||||
builder := f.NewBuilder().
|
builder := f.NewBuilder().
|
||||||
WithScheme(legacyscheme.Scheme).
|
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
|
||||||
LocalParam(o.Local).
|
LocalParam(o.Local).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(o.namespace).DefaultNamespace().
|
NamespaceParam(o.namespace).DefaultNamespace().
|
||||||
@ -194,10 +195,10 @@ func (o *SubjectOptions) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *SubjectOptions) Run(fn updateSubjects) error {
|
func (o *SubjectOptions) Run(fn updateSubjects) error {
|
||||||
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
patches := CalculatePatches(o.Infos, scheme.DefaultJSONEncoder(), func(info *resource.Info) ([]byte, error) {
|
||||||
subjects := []rbac.Subject{}
|
subjects := []rbacv1.Subject{}
|
||||||
for _, user := range sets.NewString(o.Users...).List() {
|
for _, user := range sets.NewString(o.Users...).List() {
|
||||||
subject := rbac.Subject{
|
subject := rbacv1.Subject{
|
||||||
Kind: rbac.UserKind,
|
Kind: rbac.UserKind,
|
||||||
APIGroup: rbac.GroupName,
|
APIGroup: rbac.GroupName,
|
||||||
Name: user,
|
Name: user,
|
||||||
@ -205,7 +206,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
|
|||||||
subjects = append(subjects, subject)
|
subjects = append(subjects, subject)
|
||||||
}
|
}
|
||||||
for _, group := range sets.NewString(o.Groups...).List() {
|
for _, group := range sets.NewString(o.Groups...).List() {
|
||||||
subject := rbac.Subject{
|
subject := rbacv1.Subject{
|
||||||
Kind: rbac.GroupKind,
|
Kind: rbac.GroupKind,
|
||||||
APIGroup: rbac.GroupName,
|
APIGroup: rbac.GroupName,
|
||||||
Name: group,
|
Name: group,
|
||||||
@ -219,7 +220,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
|
|||||||
if len(namespace) == 0 {
|
if len(namespace) == 0 {
|
||||||
namespace = o.namespace
|
namespace = o.namespace
|
||||||
}
|
}
|
||||||
subject := rbac.Subject{
|
subject := rbacv1.Subject{
|
||||||
Kind: rbac.ServiceAccountKind,
|
Kind: rbac.ServiceAccountKind,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -230,7 +231,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
|
|||||||
transformed, err := updateSubjectForObject(info.Object, subjects, fn)
|
transformed, err := updateSubjectForObject(info.Object, subjects, fn)
|
||||||
if transformed && err == nil {
|
if transformed && err == nil {
|
||||||
// TODO: switch UpdatePodSpecForObject to work on v1.PodSpec
|
// TODO: switch UpdatePodSpecForObject to work on v1.PodSpec
|
||||||
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping))
|
return runtime.Encode(scheme.DefaultJSONEncoder(), info.Object)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
})
|
})
|
||||||
@ -256,26 +257,25 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
actual, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, fmt.Errorf("failed to patch subjects to rolebinding: %v\n", err))
|
allErrs = append(allErrs, fmt.Errorf("failed to patch subjects to rolebinding: %v\n", err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
info.Refresh(obj, true)
|
|
||||||
|
|
||||||
return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
|
return o.PrintObj(actual, o.Out)
|
||||||
}
|
}
|
||||||
return utilerrors.NewAggregate(allErrs)
|
return utilerrors.NewAggregate(allErrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: the obj mutates in the function
|
//Note: the obj mutates in the function
|
||||||
func updateSubjectForObject(obj runtime.Object, subjects []rbac.Subject, fn updateSubjects) (bool, error) {
|
func updateSubjectForObject(obj runtime.Object, subjects []rbacv1.Subject, fn updateSubjects) (bool, error) {
|
||||||
switch t := obj.(type) {
|
switch t := obj.(type) {
|
||||||
case *rbac.RoleBinding:
|
case *rbacv1.RoleBinding:
|
||||||
transformed, result := fn(t.Subjects, subjects)
|
transformed, result := fn(t.Subjects, subjects)
|
||||||
t.Subjects = result
|
t.Subjects = result
|
||||||
return transformed, nil
|
return transformed, nil
|
||||||
case *rbac.ClusterRoleBinding:
|
case *rbacv1.ClusterRoleBinding:
|
||||||
transformed, result := fn(t.Subjects, subjects)
|
transformed, result := fn(t.Subjects, subjects)
|
||||||
t.Subjects = result
|
t.Subjects = result
|
||||||
return transformed, nil
|
return transformed, nil
|
||||||
@ -284,7 +284,7 @@ func updateSubjectForObject(obj runtime.Object, subjects []rbac.Subject, fn upda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addSubjects(existings []rbac.Subject, targets []rbac.Subject) (bool, []rbac.Subject) {
|
func addSubjects(existings []rbacv1.Subject, targets []rbacv1.Subject) (bool, []rbacv1.Subject) {
|
||||||
transformed := false
|
transformed := false
|
||||||
updated := existings
|
updated := existings
|
||||||
for _, item := range targets {
|
for _, item := range targets {
|
||||||
@ -296,7 +296,7 @@ func addSubjects(existings []rbac.Subject, targets []rbac.Subject) (bool, []rbac
|
|||||||
return transformed, updated
|
return transformed, updated
|
||||||
}
|
}
|
||||||
|
|
||||||
func contain(slice []rbac.Subject, item rbac.Subject) bool {
|
func contain(slice []rbacv1.Subject, item rbacv1.Subject) bool {
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if v == item {
|
if v == item {
|
||||||
return true
|
return true
|
||||||
|
@ -20,9 +20,9 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
rbacv1 "k8s.io/api/rbac/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
|
||||||
)
|
)
|
||||||
@ -65,11 +65,11 @@ func TestValidate(t *testing.T) {
|
|||||||
options: &SubjectOptions{
|
options: &SubjectOptions{
|
||||||
Infos: []*resource.Info{
|
Infos: []*resource.Info{
|
||||||
{
|
{
|
||||||
Object: &rbac.ClusterRoleBinding{
|
Object: &rbacv1.ClusterRoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "clusterrolebinding",
|
Name: "clusterrolebinding",
|
||||||
},
|
},
|
||||||
RoleRef: rbac.RoleRef{
|
RoleRef: rbacv1.RoleRef{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "ClusterRole",
|
Kind: "ClusterRole",
|
||||||
Name: "role",
|
Name: "role",
|
||||||
@ -87,12 +87,12 @@ func TestValidate(t *testing.T) {
|
|||||||
options: &SubjectOptions{
|
options: &SubjectOptions{
|
||||||
Infos: []*resource.Info{
|
Infos: []*resource.Info{
|
||||||
{
|
{
|
||||||
Object: &rbac.RoleBinding{
|
Object: &rbacv1.RoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "rolebinding",
|
Name: "rolebinding",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
},
|
},
|
||||||
RoleRef: rbac.RoleRef{
|
RoleRef: rbacv1.RoleRef{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "ClusterRole",
|
Kind: "ClusterRole",
|
||||||
Name: "role",
|
Name: "role",
|
||||||
@ -123,13 +123,13 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
Name string
|
Name string
|
||||||
obj runtime.Object
|
obj runtime.Object
|
||||||
subjects []rbac.Subject
|
subjects []rbacv1.Subject
|
||||||
expected []rbac.Subject
|
expected []rbacv1.Subject
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "invalid object type",
|
Name: "invalid object type",
|
||||||
obj: &rbac.Role{
|
obj: &rbacv1.Role{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "role",
|
Name: "role",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -139,12 +139,12 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "add resource with users in rolebinding",
|
Name: "add resource with users in rolebinding",
|
||||||
obj: &rbac.RoleBinding{
|
obj: &rbacv1.RoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "rolebinding",
|
Name: "rolebinding",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
},
|
},
|
||||||
Subjects: []rbac.Subject{
|
Subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -152,7 +152,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -164,7 +164,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
Name: "b",
|
Name: "b",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -180,12 +180,12 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "add resource with groups in rolebinding",
|
Name: "add resource with groups in rolebinding",
|
||||||
obj: &rbac.RoleBinding{
|
obj: &rbacv1.RoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "rolebinding",
|
Name: "rolebinding",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
},
|
},
|
||||||
Subjects: []rbac.Subject{
|
Subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "Group",
|
Kind: "Group",
|
||||||
@ -193,7 +193,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "Group",
|
Kind: "Group",
|
||||||
@ -205,7 +205,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
Name: "b",
|
Name: "b",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "Group",
|
Kind: "Group",
|
||||||
@ -221,12 +221,12 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "add resource with serviceaccounts in rolebinding",
|
Name: "add resource with serviceaccounts in rolebinding",
|
||||||
obj: &rbac.RoleBinding{
|
obj: &rbacv1.RoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "rolebinding",
|
Name: "rolebinding",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
},
|
},
|
||||||
Subjects: []rbac.Subject{
|
Subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -234,7 +234,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -246,7 +246,7 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
Name: "b",
|
Name: "b",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -262,11 +262,11 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "add resource with serviceaccounts in clusterrolebinding",
|
Name: "add resource with serviceaccounts in clusterrolebinding",
|
||||||
obj: &rbac.ClusterRoleBinding{
|
obj: &rbacv1.ClusterRoleBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "clusterrolebinding",
|
Name: "clusterrolebinding",
|
||||||
},
|
},
|
||||||
Subjects: []rbac.Subject{
|
Subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -279,14 +279,14 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
Name: "a",
|
Name: "a",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -312,11 +312,11 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
want := tt.expected
|
want := tt.expected
|
||||||
var got []rbac.Subject
|
var got []rbacv1.Subject
|
||||||
switch t := tt.obj.(type) {
|
switch t := tt.obj.(type) {
|
||||||
case *rbac.RoleBinding:
|
case *rbacv1.RoleBinding:
|
||||||
got = t.Subjects
|
got = t.Subjects
|
||||||
case *rbac.ClusterRoleBinding:
|
case *rbacv1.ClusterRoleBinding:
|
||||||
got = t.Subjects
|
got = t.Subjects
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(got, want) {
|
if !reflect.DeepEqual(got, want) {
|
||||||
@ -330,14 +330,14 @@ func TestUpdateSubjectForObject(t *testing.T) {
|
|||||||
func TestAddSubject(t *testing.T) {
|
func TestAddSubject(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Name string
|
Name string
|
||||||
existing []rbac.Subject
|
existing []rbacv1.Subject
|
||||||
subjects []rbac.Subject
|
subjects []rbacv1.Subject
|
||||||
expected []rbac.Subject
|
expected []rbacv1.Subject
|
||||||
wantChange bool
|
wantChange bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "add resource with users",
|
Name: "add resource with users",
|
||||||
existing: []rbac.Subject{
|
existing: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -349,14 +349,14 @@ func TestAddSubject(t *testing.T) {
|
|||||||
Name: "b",
|
Name: "b",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
Name: "a",
|
Name: "a",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
APIGroup: "rbac.authorization.k8s.io",
|
APIGroup: "rbac.authorization.k8s.io",
|
||||||
Kind: "User",
|
Kind: "User",
|
||||||
@ -372,7 +372,7 @@ func TestAddSubject(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "add resource with serviceaccounts",
|
Name: "add resource with serviceaccounts",
|
||||||
existing: []rbac.Subject{
|
existing: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -384,14 +384,14 @@ func TestAddSubject(t *testing.T) {
|
|||||||
Name: "b",
|
Name: "b",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
subjects: []rbac.Subject{
|
subjects: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "two",
|
Namespace: "two",
|
||||||
Name: "a",
|
Name: "a",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: []rbac.Subject{
|
expected: []rbacv1.Subject{
|
||||||
{
|
{
|
||||||
Kind: "ServiceAccount",
|
Kind: "ServiceAccount",
|
||||||
Namespace: "one",
|
Namespace: "one",
|
||||||
@ -413,7 +413,7 @@ func TestAddSubject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
changed := false
|
changed := false
|
||||||
got := []rbac.Subject{}
|
got := []rbacv1.Subject{}
|
||||||
if changed, got = addSubjects(tt.existing, tt.subjects); (changed != false) != tt.wantChange {
|
if changed, got = addSubjects(tt.existing, tt.subjects); (changed != false) != tt.wantChange {
|
||||||
t.Errorf("%q. addSubjects() changed = %v, wantChange = %v", tt.Name, changed, tt.wantChange)
|
t.Errorf("%q. addSubjects() changed = %v, wantChange = %v", tt.Name, changed, tt.wantChange)
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ func (f *ring0Factory) UpdatePodSpecForObject(obj runtime.Object, fn func(*v1.Po
|
|||||||
return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec)
|
return true, fn(&t.Spec.JobTemplate.Spec.Template.Spec)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false, fmt.Errorf("the object is not a pod or does not have a pod template")
|
return false, fmt.Errorf("the object is not a pod or does not have a pod template: %T", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user