Commit 54889d58 authored by Antoine Pelisse's avatar Antoine Pelisse

kubectl dry-run: Check for server didn't work on create

We changed the code to verify that the type supports dry-run, but we've only done it for patch, not for create, which means that people can create objects they don't want to create. We can actually simplify the code by moving the check much earlier in the method, which fixes all possible bug like this.
parent 6fc89ae9
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/jonboulle/clockwork" "github.com/jonboulle/clockwork"
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
...@@ -300,6 +299,11 @@ func (o *ApplyOptions) Run() error { ...@@ -300,6 +299,11 @@ func (o *ApplyOptions) Run() error {
openapiSchema = o.OpenAPISchema openapiSchema = o.OpenAPISchema
} }
dryRunVerifier := &DryRunVerifier{
Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(o.DynamicClient)),
OpenAPIGetter: o.DiscoveryClient,
}
// include the uninitialized objects by default if --prune is true // include the uninitialized objects by default if --prune is true
// unless explicitly set --include-uninitialized=false // unless explicitly set --include-uninitialized=false
r := o.Builder. r := o.Builder.
...@@ -361,6 +365,13 @@ func (o *ApplyOptions) Run() error { ...@@ -361,6 +365,13 @@ func (o *ApplyOptions) Run() error {
if !errors.IsNotFound(err) { if !errors.IsNotFound(err) {
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err) return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
} }
// If server-dry-run is requested but the type doesn't support it, fail right away.
if o.ServerDryRun {
if err := dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err
}
}
// Create the resource if it doesn't exist // Create the resource if it doesn't exist
// First, update the annotation used by kubectl apply // First, update the annotation used by kubectl apply
if err := kubectl.CreateApplyAnnotation(info.Object, unstructured.UnstructuredJSONScheme); err != nil { if err := kubectl.CreateApplyAnnotation(info.Object, unstructured.UnstructuredJSONScheme); err != nil {
...@@ -410,17 +421,11 @@ func (o *ApplyOptions) Run() error { ...@@ -410,17 +421,11 @@ func (o *ApplyOptions) Run() error {
fmt.Fprintf(o.ErrOut, warningNoLastAppliedConfigAnnotation, o.cmdBaseName) fmt.Fprintf(o.ErrOut, warningNoLastAppliedConfigAnnotation, o.cmdBaseName)
} }
dryRunVerifier := &DryRunVerifier{
Finder: cmdutil.NewCRDFinder(cmdutil.CRDFromDynamic(o.DynamicClient)),
OpenAPIGetter: o.DiscoveryClient,
}
helper := resource.NewHelper(info.Client, info.Mapping) helper := resource.NewHelper(info.Client, info.Mapping)
patcher := &Patcher{ patcher := &Patcher{
Mapping: info.Mapping, Mapping: info.Mapping,
Helper: helper, Helper: helper,
DynamicClient: o.DynamicClient, DynamicClient: o.DynamicClient,
DryRunVerifier: dryRunVerifier,
Overwrite: o.Overwrite, Overwrite: o.Overwrite,
BackOff: clockwork.NewRealClock(), BackOff: clockwork.NewRealClock(),
Force: o.DeleteOptions.ForceDeletion, Force: o.DeleteOptions.ForceDeletion,
...@@ -684,7 +689,6 @@ type Patcher struct { ...@@ -684,7 +689,6 @@ type Patcher struct {
Mapping *meta.RESTMapping Mapping *meta.RESTMapping
Helper *resource.Helper Helper *resource.Helper
DynamicClient dynamic.Interface DynamicClient dynamic.Interface
DryRunVerifier *DryRunVerifier
Overwrite bool Overwrite bool
BackOff clockwork.Clock BackOff clockwork.Clock
...@@ -738,12 +742,6 @@ func (v *DryRunVerifier) HasSupport(gvk schema.GroupVersionKind) error { ...@@ -738,12 +742,6 @@ func (v *DryRunVerifier) HasSupport(gvk schema.GroupVersionKind) error {
} }
func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) { func (p *Patcher) patchSimple(obj runtime.Object, modified []byte, source, namespace, name string, errOut io.Writer) ([]byte, runtime.Object, error) {
if p.ServerDryRun {
if err := p.DryRunVerifier.HasSupport(p.Mapping.GroupVersionKind); err != nil {
return nil, nil, err
}
}
// Serialize the current configuration of the object from the server. // Serialize the current configuration of the object from the server.
current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) current, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
if err != nil { if err != nil {
......
...@@ -26,7 +26,6 @@ import ( ...@@ -26,7 +26,6 @@ import (
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/jonboulle/clockwork" "github.com/jonboulle/clockwork"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
...@@ -230,7 +229,6 @@ type InfoObject struct { ...@@ -230,7 +229,6 @@ type InfoObject struct {
Info *resource.Info Info *resource.Info
Encoder runtime.Encoder Encoder runtime.Encoder
OpenAPI openapi.Resources OpenAPI openapi.Resources
DryRunVerifier *apply.DryRunVerifier
} }
var _ Object = &InfoObject{} var _ Object = &InfoObject{}
...@@ -262,7 +260,6 @@ func (obj InfoObject) Merged() (runtime.Object, error) { ...@@ -262,7 +260,6 @@ func (obj InfoObject) Merged() (runtime.Object, error) {
// This is using the patcher from apply, to keep the same behavior. // This is using the patcher from apply, to keep the same behavior.
// We plan on replacing this with server-side apply when it becomes available. // We plan on replacing this with server-side apply when it becomes available.
patcher := &apply.Patcher{ patcher := &apply.Patcher{
DryRunVerifier: obj.DryRunVerifier,
Mapping: obj.Info.Mapping, Mapping: obj.Info.Mapping,
Helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping), Helper: resource.NewHelper(obj.Info.Client, obj.Info.Mapping),
Overwrite: true, Overwrite: true,
...@@ -375,6 +372,10 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error { ...@@ -375,6 +372,10 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
return err return err
} }
if err := dryRunVerifier.HasSupport(info.Mapping.GroupVersionKind); err != nil {
return err
}
local := info.Object.DeepCopyObject() local := info.Object.DeepCopyObject()
if err := info.Get(); err != nil { if err := info.Get(); err != nil {
if !errors.IsNotFound(err) { if !errors.IsNotFound(err) {
...@@ -388,7 +389,6 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error { ...@@ -388,7 +389,6 @@ func RunDiff(f cmdutil.Factory, diff *DiffProgram, options *DiffOptions) error {
Info: info, Info: info,
Encoder: scheme.DefaultJSONEncoder(), Encoder: scheme.DefaultJSONEncoder(),
OpenAPI: schema, OpenAPI: schema,
DryRunVerifier: dryRunVerifier,
} }
return differ.Diff(obj, printer) return differ.Diff(obj, printer)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment