mirror of
https://github.com/kubernetes/client-go.git
synced 2026-01-15 14:40:37 +00:00
Merge pull request #109443 from kevindelgado/dynamic-apply
Add Apply and ApplyStatus methods to dynamic ResourceInterface Kubernetes-commit: e8ef77514b5e2fe6a7c602f9663c2ef179387ea4
This commit is contained in:
@@ -454,6 +454,51 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// TODO: opts are currently ignored.
|
||||
func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var uncastRet runtime.Object
|
||||
switch {
|
||||
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootPatchAction(c.resource, name, types.ApplyPatchType, outBytes), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewRootPatchSubresourceAction(c.resource, name, types.ApplyPatchType, outBytes, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewPatchAction(c.resource, c.namespace, name, types.ApplyPatchType, outBytes), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||
uncastRet, err = c.client.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(c.resource, c.namespace, name, types.ApplyPatchType, outBytes, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if uncastRet == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := &unstructured.Unstructured{}
|
||||
if err := c.client.scheme.Convert(uncastRet, ret, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, err
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions) (*unstructured.Unstructured, error) {
|
||||
return c.Apply(ctx, name, obj, options, "status")
|
||||
}
|
||||
|
||||
func convertObjectsToUnstructured(s *runtime.Scheme, objs []runtime.Object) ([]runtime.Object, error) {
|
||||
ul := make([]runtime.Object, 0, len(objs))
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ type ResourceInterface interface {
|
||||
List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
|
||||
Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
Apply(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||
ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, options metav1.ApplyOptions) (*unstructured.Unstructured, error)
|
||||
}
|
||||
|
||||
type NamespaceableResourceInterface interface {
|
||||
|
||||
@@ -324,6 +324,48 @@ func (c *dynamicResourceClient) Patch(ctx context.Context, name string, pt types
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) Apply(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||
if len(name) == 0 {
|
||||
return nil, fmt.Errorf("name is required")
|
||||
}
|
||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
managedFields := accessor.GetManagedFields()
|
||||
if len(managedFields) > 0 {
|
||||
return nil, fmt.Errorf(`cannot apply an object with managed fields already set.
|
||||
Use the client-go/applyconfigurations "UnstructructuredExtractor" to obtain the unstructured ApplyConfiguration for the given field manager that you can use/modify here to apply`)
|
||||
}
|
||||
patchOpts := opts.ToPatchOptions()
|
||||
|
||||
result := c.client.client.
|
||||
Patch(types.ApplyPatchType).
|
||||
AbsPath(append(c.makeURLSegments(name), subresources...)...).
|
||||
Body(outBytes).
|
||||
SpecificallyVersionedParams(&patchOpts, dynamicParameterCodec, versionV1).
|
||||
Do(ctx)
|
||||
if err := result.Error(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
retBytes, err := result.Raw()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uncastObj.(*unstructured.Unstructured), nil
|
||||
}
|
||||
func (c *dynamicResourceClient) ApplyStatus(ctx context.Context, name string, obj *unstructured.Unstructured, opts metav1.ApplyOptions) (*unstructured.Unstructured, error) {
|
||||
return c.Apply(ctx, name, obj, opts, "status")
|
||||
}
|
||||
|
||||
func (c *dynamicResourceClient) makeURLSegments(name string) []string {
|
||||
url := []string{}
|
||||
if len(c.resource.Group) == 0 {
|
||||
|
||||
8
go.mod
8
go.mod
@@ -34,8 +34,8 @@ require (
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
||||
google.golang.org/protobuf v1.27.1
|
||||
k8s.io/api v0.0.0-20220504022944-af4f75e1994c
|
||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5
|
||||
k8s.io/api v0.0.0-20220504062940-f2f8c15fc29f
|
||||
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493
|
||||
k8s.io/klog/v2 v2.60.1
|
||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
||||
@@ -44,6 +44,6 @@ require (
|
||||
)
|
||||
|
||||
replace (
|
||||
k8s.io/api => k8s.io/api v0.0.0-20220504022944-af4f75e1994c
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5
|
||||
k8s.io/api => k8s.io/api v0.0.0-20220504062940-f2f8c15fc29f
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493
|
||||
)
|
||||
|
||||
8
go.sum
8
go.sum
@@ -628,10 +628,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.0.0-20220504022944-af4f75e1994c h1:4chKbSSvIxpT/ls7NTHZyE0xnKewL0HSbdaYyesfrmQ=
|
||||
k8s.io/api v0.0.0-20220504022944-af4f75e1994c/go.mod h1:jimmvAe8QfauNx6CM87E20mTsK3CPgiOzVhfaNASkJc=
|
||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5 h1:nG9Zc74nUlkVHMapMJVjlH8hT3z/fBVixlVfrsQgi24=
|
||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
||||
k8s.io/api v0.0.0-20220504062940-f2f8c15fc29f h1:yahIBtSoM2GJrTtmkge28xngCHtPiW3CyhjcrGSojQg=
|
||||
k8s.io/api v0.0.0-20220504062940-f2f8c15fc29f/go.mod h1:Vj1A561tKmF3X1XV1/cGWVWkImJjDjTF6HwinifdHTU=
|
||||
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493 h1:82cE3vib2ZIhoyz153bSAnuxMUdXg1OpLaUM6pzES7M=
|
||||
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
|
||||
Reference in New Issue
Block a user