diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 7b65a50807e..3f146f18f22 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -645,6 +645,7 @@ function codegen::clients() { --input-base="k8s.io/api" \ --plural-exceptions "${PLURAL_EXCEPTIONS}" \ --apply-configuration-package "${APPLYCONFIG_PKG}" \ + --prefers-protobuf \ $(printf -- " --input %s" "${gv_dirs[@]}") \ "$@" diff --git a/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh b/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh index 7d5770f59cc..93a25e2dc72 100755 --- a/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh +++ b/staging/src/k8s.io/apiextensions-apiserver/hack/update-codegen.sh @@ -52,4 +52,5 @@ kube::codegen::gen_client \ --output-pkg "${THIS_PKG}/pkg/client" \ --versioned-name "clientset" \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ + --prefers-protobuf \ "${SCRIPT_ROOT}/pkg/apis" diff --git a/staging/src/k8s.io/client-go/gentype/type.go b/staging/src/k8s.io/client-go/gentype/type.go index b5be84318da..267f911188f 100644 --- a/staging/src/k8s.io/client-go/gentype/type.go +++ b/staging/src/k8s.io/client-go/gentype/type.go @@ -51,6 +51,8 @@ type Client[T objectWithMeta] struct { namespace string // "" for non-namespaced clients newObject func() T parameterCodec runtime.ParameterCodec + + prefersProtobuf bool } // ClientWithList represents a client with support for lists. @@ -82,26 +84,37 @@ type alsoApplier[T objectWithMeta, C namedObject] struct { client *Client[T] } +type Option[T objectWithMeta] func(*Client[T]) + +func PrefersProtobuf[T objectWithMeta]() Option[T] { + return func(c *Client[T]) { c.prefersProtobuf = true } +} + // NewClient constructs a client, namespaced or not, with no support for lists or apply. // Non-namespaced clients are constructed by passing an empty namespace (""). func NewClient[T objectWithMeta]( resource string, client rest.Interface, parameterCodec runtime.ParameterCodec, namespace string, emptyObjectCreator func() T, + options ...Option[T], ) *Client[T] { - return &Client[T]{ + c := &Client[T]{ resource: resource, client: client, parameterCodec: parameterCodec, namespace: namespace, newObject: emptyObjectCreator, } + for _, option := range options { + option(c) + } + return c } // NewClientWithList constructs a namespaced client with support for lists. func NewClientWithList[T objectWithMeta, L runtime.Object]( resource string, client rest.Interface, parameterCodec runtime.ParameterCodec, namespace string, emptyObjectCreator func() T, - emptyListCreator func() L, + emptyListCreator func() L, options ...Option[T], ) *ClientWithList[T, L] { - typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator) + typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator, options...) return &ClientWithList[T, L]{ typeClient, alsoLister[T, L]{typeClient, emptyListCreator}, @@ -111,8 +124,9 @@ func NewClientWithList[T objectWithMeta, L runtime.Object]( // NewClientWithApply constructs a namespaced client with support for apply declarative configurations. func NewClientWithApply[T objectWithMeta, C namedObject]( resource string, client rest.Interface, parameterCodec runtime.ParameterCodec, namespace string, emptyObjectCreator func() T, + options ...Option[T], ) *ClientWithApply[T, C] { - typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator) + typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator, options...) return &ClientWithApply[T, C]{ typeClient, alsoApplier[T, C]{typeClient}, @@ -122,9 +136,9 @@ func NewClientWithApply[T objectWithMeta, C namedObject]( // NewClientWithListAndApply constructs a client with support for lists and applying declarative configurations. func NewClientWithListAndApply[T objectWithMeta, L runtime.Object, C namedObject]( resource string, client rest.Interface, parameterCodec runtime.ParameterCodec, namespace string, emptyObjectCreator func() T, - emptyListCreator func() L, + emptyListCreator func() L, options ...Option[T], ) *ClientWithListAndApply[T, L, C] { - typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator) + typeClient := NewClient[T](resource, client, parameterCodec, namespace, emptyObjectCreator, options...) return &ClientWithListAndApply[T, L, C]{ typeClient, alsoLister[T, L]{typeClient, emptyListCreator}, @@ -146,6 +160,7 @@ func (c *Client[T]) GetNamespace() string { func (c *Client[T]) Get(ctx context.Context, name string, options metav1.GetOptions) (T, error) { result := c.newObject() err := c.client.Get(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). Name(name). @@ -181,6 +196,7 @@ func (l *alsoLister[T, L]) list(ctx context.Context, opts metav1.ListOptions) (L timeout = time.Duration(*opts.TimeoutSeconds) * time.Second } err := l.client.client.Get(). + UseProtobufAsDefaultIfPreferred(l.client.prefersProtobuf). NamespaceIfScoped(l.client.namespace, l.client.namespace != ""). Resource(l.client.resource). VersionedParams(&opts, l.client.parameterCodec). @@ -198,6 +214,7 @@ func (l *alsoLister[T, L]) watchList(ctx context.Context, opts metav1.ListOption } result = l.newList() err = l.client.client.Get(). + UseProtobufAsDefaultIfPreferred(l.client.prefersProtobuf). NamespaceIfScoped(l.client.namespace, l.client.namespace != ""). Resource(l.client.resource). VersionedParams(&opts, l.client.parameterCodec). @@ -215,6 +232,7 @@ func (c *Client[T]) Watch(ctx context.Context, opts metav1.ListOptions) (watch.I } opts.Watch = true return c.client.Get(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). VersionedParams(&opts, c.parameterCodec). @@ -226,6 +244,7 @@ func (c *Client[T]) Watch(ctx context.Context, opts metav1.ListOptions) (watch.I func (c *Client[T]) Create(ctx context.Context, obj T, opts metav1.CreateOptions) (T, error) { result := c.newObject() err := c.client.Post(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). VersionedParams(&opts, c.parameterCodec). @@ -239,6 +258,7 @@ func (c *Client[T]) Create(ctx context.Context, obj T, opts metav1.CreateOptions func (c *Client[T]) Update(ctx context.Context, obj T, opts metav1.UpdateOptions) (T, error) { result := c.newObject() err := c.client.Put(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). Name(obj.GetName()). @@ -253,6 +273,7 @@ func (c *Client[T]) Update(ctx context.Context, obj T, opts metav1.UpdateOptions func (c *Client[T]) UpdateStatus(ctx context.Context, obj T, opts metav1.UpdateOptions) (T, error) { result := c.newObject() err := c.client.Put(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). Name(obj.GetName()). @@ -267,6 +288,7 @@ func (c *Client[T]) UpdateStatus(ctx context.Context, obj T, opts metav1.UpdateO // Delete takes name of the resource and deletes it. Returns an error if one occurs. func (c *Client[T]) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { return c.client.Delete(). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). Name(name). @@ -282,6 +304,7 @@ func (l *alsoLister[T, L]) DeleteCollection(ctx context.Context, opts metav1.Del timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second } return l.client.client.Delete(). + UseProtobufAsDefaultIfPreferred(l.client.prefersProtobuf). NamespaceIfScoped(l.client.namespace, l.client.namespace != ""). Resource(l.client.resource). VersionedParams(&listOpts, l.client.parameterCodec). @@ -295,6 +318,7 @@ func (l *alsoLister[T, L]) DeleteCollection(ctx context.Context, opts metav1.Del func (c *Client[T]) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (T, error) { result := c.newObject() err := c.client.Patch(pt). + UseProtobufAsDefaultIfPreferred(c.prefersProtobuf). NamespaceIfScoped(c.namespace, c.namespace != ""). Resource(c.resource). Name(name). @@ -321,6 +345,7 @@ func (a *alsoApplier[T, C]) Apply(ctx context.Context, obj C, opts metav1.ApplyO return *new(T), fmt.Errorf("obj.Name must be provided to Apply") } err = a.client.client.Patch(types.ApplyPatchType). + UseProtobufAsDefaultIfPreferred(a.client.prefersProtobuf). NamespaceIfScoped(a.client.namespace, a.client.namespace != ""). Resource(a.client.resource). Name(*obj.GetName()). @@ -348,6 +373,7 @@ func (a *alsoApplier[T, C]) ApplyStatus(ctx context.Context, obj C, opts metav1. result := a.client.newObject() err = a.client.client.Patch(types.ApplyPatchType). + UseProtobufAsDefaultIfPreferred(a.client.prefersProtobuf). NamespaceIfScoped(a.client.namespace, a.client.namespace != ""). Resource(a.client.resource). Name(*obj.GetName()). diff --git a/staging/src/k8s.io/client-go/rest/request.go b/staging/src/k8s.io/client-go/rest/request.go index 91d91ca49be..2f325ecd628 100644 --- a/staging/src/k8s.io/client-go/rest/request.go +++ b/staging/src/k8s.io/client-go/rest/request.go @@ -176,12 +176,7 @@ func NewRequest(c *RESTClient) *Request { contentTypeNotSet: contentTypeNotSet, } - switch { - case len(c.content.AcceptContentTypes) > 0: - r.SetHeader("Accept", c.content.AcceptContentTypes) - case len(c.content.ContentType) > 0: - r.SetHeader("Accept", c.content.ContentType+", */*") - } + r.setAcceptHeader() return r } @@ -195,6 +190,31 @@ func NewRequestWithClient(base *url.URL, versionedAPIPath string, content Client }) } +func (r *Request) UseProtobufAsDefaultIfPreferred(prefersProtobuf bool) *Request { + if prefersProtobuf { + return r.UseProtobufAsDefault() + } + return r +} + +func (r *Request) UseProtobufAsDefault() *Request { + if r.contentTypeNotSet && len(r.contentConfig.AcceptContentTypes) == 0 { + r.contentConfig.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json" + r.contentConfig.ContentType = "application/vnd.kubernetes.protobuf" + r.setAcceptHeader() + } + return r +} + +func (r *Request) setAcceptHeader() { + switch { + case len(r.contentConfig.AcceptContentTypes) > 0: + r.SetHeader("Accept", r.contentConfig.AcceptContentTypes) + case len(r.contentConfig.ContentType) > 0: + r.SetHeader("Accept", r.contentConfig.ContentType+", */*") + } +} + // Verb sets the verb this request will use. func (r *Request) Verb(verb string) *Request { r.verb = verb diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go b/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go index e0914e69d2f..5620fc0c2e0 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/args/args.go @@ -61,6 +61,9 @@ type Args struct { // If non-empty, Apply functions are generated for each type and reference the apply builders. // If empty (""), Apply functions are not generated. ApplyConfigurationPackage string + + // PrefersProtobuf determines if the generated clientset uses protobuf for API requests. + PrefersProtobuf bool } func New() *Args { @@ -99,6 +102,8 @@ func (args *Args) AddFlags(fs *pflag.FlagSet, inputBase string) { "list of comma separated plural exception definitions in Type:PluralizedType form") fs.StringVar(&args.ApplyConfigurationPackage, "apply-configuration-package", args.ApplyConfigurationPackage, "optional package of apply configurations, generated by applyconfiguration-gen, that are required to generate Apply functions for each type in the clientset. By default Apply functions are not generated.") + fs.BoolVar(&args.PrefersProtobuf, "prefers-protobuf", args.PrefersProtobuf, + "when set, client-gen will generate a clientset that uses protobuf for API requests") // support old flags fs.SetNormalizeFunc(mapFlagName("clientset-path", "output-pkg", fs.GetNormalizeFunc())) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go index 1fc21c224b5..c8fa01a8ecd 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/client_generator.go @@ -128,7 +128,7 @@ func DefaultNameSystem() string { return "public" } -func targetForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetDir, clientsetPkg string, groupPkgName string, groupGoName string, apiPath string, inputPkg string, applyBuilderPkg string, boilerplate []byte) generator.Target { +func targetForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clientsetDir, clientsetPkg string, groupPkgName string, groupGoName string, apiPath string, inputPkg string, applyBuilderPkg string, boilerplate []byte, prefersProtobuf bool) generator.Target { subdir := []string{"typed", strings.ToLower(groupPkgName), strings.ToLower(gv.Version.NonEmpty())} gvDir := filepath.Join(clientsetDir, filepath.Join(subdir...)) gvPkg := path.Join(clientsetPkg, path.Join(subdir...)) @@ -160,6 +160,7 @@ func targetForGroup(gv clientgentypes.GroupVersion, typeList []*types.Type, clie group: gv.Group.NonEmpty(), version: gv.Version.String(), groupGoName: groupGoName, + prefersProtobuf: prefersProtobuf, typeToMatch: t, imports: generator.NewImportTrackerForPackage(gvPkg), }) @@ -424,7 +425,7 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target targetForGroup( gv, orderer.OrderTypes(types), clientsetDir, clientsetPkg, group.PackageName, groupGoNames[gv], args.ClientsetAPIPath, - inputPath, args.ApplyConfigurationPackage, boilerplate)) + inputPath, args.ApplyConfigurationPackage, boilerplate, args.PrefersProtobuf)) if args.FakeClient { targetList = append(targetList, fake.TargetForGroup(gv, orderer.OrderTypes(types), clientsetDir, clientsetPkg, group.PackageName, groupGoNames[gv], inputPath, args.ApplyConfigurationPackage, boilerplate)) diff --git a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go index 53e970c05ee..4c63b8f8ebd 100644 --- a/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go +++ b/staging/src/k8s.io/code-generator/cmd/client-gen/generators/generator_for_type.go @@ -41,6 +41,7 @@ type genClientForType struct { group string version string groupGoName string + prefersProtobuf bool typeToMatch *types.Type imports namer.ImportTracker } @@ -161,6 +162,7 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i "subresource": false, "subresourcePath": "", "GroupGoName": g.groupGoName, + "prefersProtobuf": g.prefersProtobuf, "Version": namer.IC(g.version), "CreateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "CreateOptions"}), "DeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "DeleteOptions"}), @@ -483,7 +485,9 @@ var newStruct = []string{ c.RESTClient(), $.schemeParameterCodec|raw$, namespace, - func() *$.resultType|raw$ { return &$.resultType|raw${} }), + func() *$.resultType|raw$ { return &$.resultType|raw${} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -496,7 +500,9 @@ var newStruct = []string{ c.RESTClient(), $.schemeParameterCodec|raw$, namespace, - func() *$.resultType|raw$ { return &$.resultType|raw${} }), + func() *$.resultType|raw$ { return &$.resultType|raw${} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -510,7 +516,9 @@ var newStruct = []string{ $.schemeParameterCodec|raw$, namespace, func() *$.resultType|raw$ { return &$.resultType|raw${} }, - func() *$.resultType|raw$List { return &$.resultType|raw$List{} }), + func() *$.resultType|raw$List { return &$.resultType|raw$List{} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -524,7 +532,9 @@ var newStruct = []string{ $.schemeParameterCodec|raw$, namespace, func() *$.resultType|raw$ { return &$.resultType|raw${} }, - func() *$.resultType|raw$List { return &$.resultType|raw$List{} }), + func() *$.resultType|raw$List { return &$.resultType|raw$List{} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -537,7 +547,9 @@ var newStruct = []string{ c.RESTClient(), $.schemeParameterCodec|raw$, "", - func() *$.resultType|raw$ { return &$.resultType|raw${} }), + func() *$.resultType|raw$ { return &$.resultType|raw${} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -550,7 +562,9 @@ var newStruct = []string{ c.RESTClient(), $.schemeParameterCodec|raw$, "", - func() *$.resultType|raw$ { return &$.resultType|raw${} }), + func() *$.resultType|raw$ { return &$.resultType|raw${} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -564,7 +578,9 @@ var newStruct = []string{ $.schemeParameterCodec|raw$, "", func() *$.resultType|raw$ { return &$.resultType|raw${} }, - func() *$.resultType|raw$List { return &$.resultType|raw$List{} }), + func() *$.resultType|raw$List { return &$.resultType|raw$List{} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -578,7 +594,9 @@ var newStruct = []string{ $.schemeParameterCodec|raw$, "", func() *$.resultType|raw$ { return &$.resultType|raw${} }, - func() *$.resultType|raw$List { return &$.resultType|raw$List{} }), + func() *$.resultType|raw$List { return &$.resultType|raw$List{} }, + $if .prefersProtobuf$gentype.PrefersProtobuf[*$.resultType|raw$](),$end$ + ), } } `, @@ -614,6 +632,7 @@ func (c *$.type|privatePlural$) list(ctx $.context|raw$, opts $.ListOptions|raw$ } result = &$.resultType|raw$List{} err = c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). VersionedParams(&opts, $.schemeParameterCodec|raw$). @@ -633,6 +652,7 @@ func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.type|private$Name } result = &$.resultType|raw$List{} err = c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.type|private$Name). @@ -650,6 +670,7 @@ var getTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name(name). @@ -665,6 +686,7 @@ var getSubresourceTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.type|private$Name string, options $.GetOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.type|private$Name). @@ -680,6 +702,7 @@ var deleteTemplate = ` // $.verb$ takes name of the $.type|private$ and deletes it. Returns an error if one occurs. func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, name string, opts $.DeleteOptions|raw$) error { return c.GetClient().Delete(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name(name). @@ -694,6 +717,7 @@ var createSubresourceTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Post(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.type|private$Name). @@ -711,6 +735,7 @@ var createTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.inputType|private$ *$.inputType|raw$, opts $.CreateOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Post(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). VersionedParams(&opts, $.schemeParameterCodec|raw$). @@ -726,6 +751,7 @@ var updateSubresourceTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Put(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.type|private$Name). @@ -743,6 +769,7 @@ var updateTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Put(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.inputType|private$.Name). @@ -763,6 +790,7 @@ func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, opts $.ListOptions|r } opts.Watch = true return c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ VersionedParams(&opts, $.schemeParameterCodec|raw$). Timeout(timeout). @@ -779,6 +807,7 @@ func (c *$.type|privatePlural$) watchList(ctx $.context|raw$, opts $.ListOptions } result = &$.resultType|raw$List{} err = c.GetClient().Get(). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). VersionedParams(&opts, $.schemeParameterCodec|raw$). @@ -794,6 +823,7 @@ var patchTemplate = ` func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, name string, pt $.PatchType|raw$, data []byte, opts $.PatchOptions|raw$, subresources ...string) (result *$.resultType|raw$, err error) { result = &$.resultType|raw${} err = c.GetClient().Patch(pt). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name(name). @@ -823,6 +853,7 @@ func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.inputType|private$ } result = &$.resultType|raw${} err = c.GetClient().Patch($.ApplyPatchType|raw$). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name(*name). @@ -849,6 +880,7 @@ func (c *$.type|privatePlural$) $.verb$(ctx $.context|raw$, $.type|private$Name result = &$.resultType|raw${} err = c.GetClient().Patch($.ApplyPatchType|raw$). + $if .prefersProtobuf$UseProtobufAsDefault().$end$ $if .namespaced$Namespace(c.GetNamespace()).$end$ Resource("$.type|resource$"). Name($.type|private$Name). diff --git a/staging/src/k8s.io/code-generator/kube_codegen.sh b/staging/src/k8s.io/code-generator/kube_codegen.sh index f57c52caec8..8207da5eddd 100755 --- a/staging/src/k8s.io/code-generator/kube_codegen.sh +++ b/staging/src/k8s.io/code-generator/kube_codegen.sh @@ -433,6 +433,9 @@ function kube::codegen::gen_openapi() { # --plural-exceptions # An optional list of comma separated plural exception definitions in Type:PluralizedType form. # +# --prefers-protobuf +# Enables generation of clientsets that use protobuf for API requests. +# function kube::codegen::gen_client() { local in_dir="" local one_input_api="" @@ -450,6 +453,7 @@ function kube::codegen::gen_client() { local boilerplate="${KUBE_CODEGEN_ROOT}/hack/boilerplate.go.txt" local plural_exceptions="" local v="${KUBE_VERBOSE:-0}" + local prefers_protobuf="false" while [ "$#" -gt 0 ]; do case "$1" in @@ -509,6 +513,10 @@ function kube::codegen::gen_client() { plural_exceptions="$2" shift 2 ;; + "--prefers-protobuf") + prefers_protobuf="true" + shift + ;; *) if [[ "$1" =~ ^-- ]]; then echo "unknown argument: $1" >&2 @@ -625,6 +633,7 @@ function kube::codegen::gen_client() { --apply-configuration-package "${applyconfig_pkg}" \ --input-base "$(cd "${in_dir}" && pwd -P)" `# must be absolute path or Go import path"` \ --plural-exceptions "${plural_exceptions}" \ + --prefers-protobuf="${prefers_protobuf}" \ "${inputs[@]}" if [ "${watchable}" == "true" ]; then diff --git a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh index fcb08291f5c..a58ff7ffad3 100755 --- a/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh +++ b/staging/src/k8s.io/kube-aggregator/hack/update-codegen.sh @@ -51,4 +51,5 @@ kube::codegen::gen_client \ --clientset-name "clientset_generated" \ --versioned-name "clientset" \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ + --prefers-protobuf \ "${SCRIPT_ROOT}/pkg/apis" diff --git a/staging/src/k8s.io/metrics/hack/update-codegen.sh b/staging/src/k8s.io/metrics/hack/update-codegen.sh index 465169dc2bd..23e4e3ee241 100755 --- a/staging/src/k8s.io/metrics/hack/update-codegen.sh +++ b/staging/src/k8s.io/metrics/hack/update-codegen.sh @@ -36,4 +36,5 @@ kube::codegen::gen_client \ --output-dir "${SCRIPT_ROOT}/pkg/client" \ --output-pkg "${THIS_PKG}/pkg/client" \ --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ + --prefers-protobuf \ "${SCRIPT_ROOT}/pkg/apis"