mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Add apply subresource support to client-go's typed client
This commit is contained in:
parent
f137c47770
commit
29423501f0
@ -37,6 +37,7 @@ import (
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
appsv1apply "k8s.io/client-go/applyconfigurations/apps/v1"
|
||||
appsv1autoscaling "k8s.io/client-go/applyconfigurations/autoscaling/v1"
|
||||
coreinformers "k8s.io/client-go/informers/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1"
|
||||
@ -266,6 +267,10 @@ func (c conversionClient) UpdateScale(ctx context.Context, name string, scale *a
|
||||
return nil, errors.New("UpdateScale() is not implemented for conversionClient")
|
||||
}
|
||||
|
||||
func (c conversionClient) ApplyScale(ctx context.Context, name string, scale *appsv1autoscaling.ScaleApplyConfiguration, opts metav1.ApplyOptions) (*autoscalingv1.Scale, error) {
|
||||
return nil, errors.New("ApplyScale() is not implemented for conversionClient")
|
||||
}
|
||||
|
||||
func convertSlice(rcList []*v1.ReplicationController) ([]*apps.ReplicaSet, error) {
|
||||
rsList := make([]*apps.ReplicaSet, 0, len(rcList))
|
||||
for _, rc := range rcList {
|
||||
|
@ -279,6 +279,12 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||
return &applyconfigurationsautoscalingv1.HorizontalPodAutoscalerSpecApplyConfiguration{}
|
||||
case autoscalingv1.SchemeGroupVersion.WithKind("HorizontalPodAutoscalerStatus"):
|
||||
return &applyconfigurationsautoscalingv1.HorizontalPodAutoscalerStatusApplyConfiguration{}
|
||||
case autoscalingv1.SchemeGroupVersion.WithKind("Scale"):
|
||||
return &applyconfigurationsautoscalingv1.ScaleApplyConfiguration{}
|
||||
case autoscalingv1.SchemeGroupVersion.WithKind("ScaleSpec"):
|
||||
return &applyconfigurationsautoscalingv1.ScaleSpecApplyConfiguration{}
|
||||
case autoscalingv1.SchemeGroupVersion.WithKind("ScaleStatus"):
|
||||
return &applyconfigurationsautoscalingv1.ScaleStatusApplyConfiguration{}
|
||||
|
||||
// Group=autoscaling, Version=v2beta1
|
||||
case v2beta1.SchemeGroupVersion.WithKind("ContainerResourceMetricSource"):
|
||||
|
@ -63,11 +63,12 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
pkgTypes := packageTypesForInputDirs(context, arguments.InputDirs, arguments.OutputPackagePath)
|
||||
customArgs := arguments.CustomArgs.(*applygenargs.CustomArgs)
|
||||
initialTypes := customArgs.ExternalApplyConfigurations
|
||||
refs := refGraphForReachableTypes(pkgTypes, initialTypes)
|
||||
refs := refGraphForReachableTypes(context.Universe, pkgTypes, initialTypes)
|
||||
typeModels, err := newTypeModels(customArgs.OpenAPISchemaFilePath, pkgTypes)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed build type models from typeModels %s: %v", customArgs.OpenAPISchemaFilePath, err)
|
||||
}
|
||||
|
||||
groupVersions := make(map[string]clientgentypes.GroupVersions)
|
||||
groupGoNames := make(map[string]string)
|
||||
applyConfigsForGroupVersion := make(map[clientgentypes.GroupVersion][]applyConfig)
|
||||
|
@ -28,7 +28,7 @@ type refGraph map[types.Name]string
|
||||
|
||||
// refGraphForReachableTypes returns a refGraph that contains all reachable types from
|
||||
// the root clientgen types of the provided packages.
|
||||
func refGraphForReachableTypes(pkgTypes map[string]*types.Package, initialTypes map[types.Name]string) refGraph {
|
||||
func refGraphForReachableTypes(universe types.Universe, pkgTypes map[string]*types.Package, initialTypes map[types.Name]string) refGraph {
|
||||
var refs refGraph = initialTypes
|
||||
|
||||
// Include only types that are reachable from the root clientgen types.
|
||||
@ -42,6 +42,20 @@ func refGraphForReachableTypes(pkgTypes map[string]*types.Package, initialTypes
|
||||
if tags.GenerateClient && hasApply {
|
||||
findReachableTypes(t, reachableTypes)
|
||||
}
|
||||
// If any apply extensions have custom inputs, add them.
|
||||
for _, extension := range tags.Extensions {
|
||||
if extension.HasVerb("apply") {
|
||||
if len(extension.InputTypeOverride) > 0 {
|
||||
inputType := *t
|
||||
if name, pkg := extension.Input(); len(pkg) > 0 {
|
||||
inputType = *(universe.Type(types.Name{Package: pkg, Name: name}))
|
||||
} else {
|
||||
inputType.Name.Name = extension.InputTypeOverride
|
||||
}
|
||||
findReachableTypes(&inputType, reachableTypes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for pkg, p := range pkgTypes {
|
||||
|
@ -90,14 +90,20 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
template string
|
||||
args map[string]interface{}
|
||||
}
|
||||
_, typeGVString := util.ParsePathGroupVersion(g.inputPackage)
|
||||
extendedMethods := []extendedInterfaceMethod{}
|
||||
for _, e := range tags.Extensions {
|
||||
if e.HasVerb("apply") && !generateApply {
|
||||
continue
|
||||
}
|
||||
inputType := *t
|
||||
resultType := *t
|
||||
inputGVString := typeGVString
|
||||
// TODO: Extract this to some helper method as this code is copied into
|
||||
// 2 other places.
|
||||
if len(e.InputTypeOverride) > 0 {
|
||||
if name, pkg := e.Input(); len(pkg) > 0 {
|
||||
_, inputGVString = util.ParsePathGroupVersion(pkg)
|
||||
newType := c.Universe.Type(types.Name{Package: pkg, Name: name})
|
||||
inputType = *newType
|
||||
} else {
|
||||
@ -118,7 +124,7 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
} else {
|
||||
updatedVerbtemplate = e.VerbName + "(" + strings.TrimPrefix(defaultVerbTemplates[e.VerbType], strings.Title(e.VerbType)+"(")
|
||||
}
|
||||
extendedMethods = append(extendedMethods, extendedInterfaceMethod{
|
||||
extendedMethod := extendedInterfaceMethod{
|
||||
template: updatedVerbtemplate,
|
||||
args: map[string]interface{}{
|
||||
"type": t,
|
||||
@ -128,9 +134,15 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
"GetOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "GetOptions"}),
|
||||
"ListOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ListOptions"}),
|
||||
"UpdateOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "UpdateOptions"}),
|
||||
"ApplyOptions": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apis/meta/v1", Name: "ApplyOptions"}),
|
||||
"PatchType": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/types", Name: "PatchType"}),
|
||||
"jsonMarshal": c.Universe.Type(types.Name{Package: "encoding/json", Name: "Marshal"}),
|
||||
},
|
||||
})
|
||||
}
|
||||
if e.HasVerb("apply") {
|
||||
extendedMethod.args["inputApplyConfig"] = types.Ref(path.Join(g.applyConfigurationPackage, inputGVString), inputType.Name.Name+"ApplyConfiguration")
|
||||
}
|
||||
extendedMethods = append(extendedMethods, extendedMethod)
|
||||
}
|
||||
m := map[string]interface{}{
|
||||
"type": t,
|
||||
@ -237,14 +249,18 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
if tags.HasVerb("applyStatus") && generateApply {
|
||||
sw.Do(applyStatusTemplate, m)
|
||||
}
|
||||
// TODO: Add subresource support once apply subresources are supported on the server side
|
||||
|
||||
// generate expansion methods
|
||||
for _, e := range tags.Extensions {
|
||||
if e.HasVerb("apply") && !generateApply {
|
||||
continue
|
||||
}
|
||||
inputType := *t
|
||||
resultType := *t
|
||||
inputGVString := typeGVString
|
||||
if len(e.InputTypeOverride) > 0 {
|
||||
if name, pkg := e.Input(); len(pkg) > 0 {
|
||||
_, inputGVString = util.ParsePathGroupVersion(pkg)
|
||||
newType := c.Universe.Type(types.Name{Package: pkg, Name: name})
|
||||
inputType = *newType
|
||||
} else {
|
||||
@ -262,6 +278,9 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
m["inputType"] = &inputType
|
||||
m["resultType"] = &resultType
|
||||
m["subresourcePath"] = e.SubResourcePath
|
||||
if e.HasVerb("apply") {
|
||||
m["inputApplyConfig"] = types.Ref(path.Join(g.applyConfigurationPackage, inputGVString), inputType.Name.Name+"ApplyConfiguration")
|
||||
}
|
||||
|
||||
if e.HasVerb("get") {
|
||||
if e.IsSubresource() {
|
||||
@ -310,9 +329,12 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
||||
sw.Do(adjustTemplate(e.VerbName, e.VerbType, patchTemplate), m)
|
||||
}
|
||||
|
||||
if e.HasVerb("apply") && generateApply {
|
||||
// TODO: Support apply on arbitrary subresource once it is supported by the api-server.
|
||||
sw.Do(adjustTemplate(e.VerbName, e.VerbType, applyTemplate), m)
|
||||
if e.HasVerb("apply") {
|
||||
if e.IsSubresource() {
|
||||
sw.Do(adjustTemplate(e.VerbName, e.VerbType, applySubresourceTemplate), m)
|
||||
} else {
|
||||
sw.Do(adjustTemplate(e.VerbName, e.VerbType, applyTemplate), m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,7 +366,9 @@ func buildSubresourceDefaultVerbTemplates(generateApply bool) map[string]string
|
||||
"update": `Update(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputType|raw$, opts $.UpdateOptions|raw$) (*$.resultType|raw$, error)`,
|
||||
"get": `Get(ctx context.Context, $.type|private$Name string, options $.GetOptions|raw$) (*$.resultType|raw$, error)`,
|
||||
}
|
||||
// TODO: Support apply on arbitrary subresource once it is supported by the api-server.
|
||||
if generateApply {
|
||||
m["apply"] = `Apply(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (*$.resultType|raw$, error)`
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@ -707,3 +731,30 @@ func (c *$.type|privatePlural$) ApplyStatus(ctx context.Context, $.inputType|pri
|
||||
return
|
||||
}
|
||||
`
|
||||
|
||||
var applySubresourceTemplate = `
|
||||
// Apply takes top resource name and the apply declarative configuration for $.subresourcePath$,
|
||||
// applies it and returns the applied $.resultType|private$, and an error, if there is any.
|
||||
func (c *$.type|privatePlural$) Apply(ctx context.Context, $.type|private$Name string, $.inputType|private$ *$.inputApplyConfig|raw$, opts $.ApplyOptions|raw$) (result *$.resultType|raw$, err error) {
|
||||
if $.inputType|private$ == nil {
|
||||
return nil, fmt.Errorf("$.inputType|private$ provided to Apply must not be nil")
|
||||
}
|
||||
patchOpts := opts.ToPatchOptions()
|
||||
data, err := $.jsonMarshal|raw$($.inputType|private$)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = &$.resultType|raw${}
|
||||
err = c.client.Patch($.ApplyPatchType|raw$).
|
||||
$if .namespaced$Namespace(c.ns).$end$
|
||||
Resource("$.type|resource$").
|
||||
Name($.type|private$Name).
|
||||
SubResource("$.subresourcePath$").
|
||||
VersionedParams(&patchOpts, $.schemeParameterCodec|raw$).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
`
|
||||
|
@ -74,6 +74,7 @@ var unsupportedExtensionVerbs = []string{
|
||||
var inputTypeSupportedVerbs = []string{
|
||||
"create",
|
||||
"update",
|
||||
"apply",
|
||||
}
|
||||
|
||||
// resultTypeSupportedVerbs is a list of verb types that supports overriding the
|
||||
@ -84,6 +85,7 @@ var resultTypeSupportedVerbs = []string{
|
||||
"get",
|
||||
"list",
|
||||
"patch",
|
||||
"apply",
|
||||
}
|
||||
|
||||
// Extensions allows to extend the default set of client verbs
|
||||
|
Loading…
Reference in New Issue
Block a user