diff --git a/cmd/delete.go b/cmd/delete.go index 9da63f41ec3a9ca88af88451387805155dd66cd1..5826c21cc86c57063e146fc4eaae17352d21a9ff 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -41,8 +41,6 @@ var deleteCmd = &cobra.Command{ Short: "Delete Kubernetes resources described in local config", RunE: func(cmd *cobra.Command, args []string) error { flags := cmd.Flags() - boolFalse := false - deletePolicyForeground := metav1.DeletePropagationForeground gracePeriod, err := flags.GetInt64(flagGracePeriod) if err != nil { @@ -64,13 +62,22 @@ var deleteCmd = &cobra.Command{ return err } + version, err := utils.FetchVersion(disco) + if err != nil { + return err + } + sort.Sort(sort.Reverse(utils.DependencyOrder(objs))) - deleteOpts := metav1.DeleteOptions{ + deleteOpts := metav1.DeleteOptions{} + if version.Compare(1, 6) < 0 { // 1.5.x option - OrphanDependents: &boolFalse, + boolFalse := false + deleteOpts.OrphanDependents = &boolFalse + } else { // 1.6.x option (NB: Background is broken) - PropagationPolicy: &deletePolicyForeground, + fg := metav1.DeletePropagationForeground + deleteOpts.PropagationPolicy = &fg } if gracePeriod >= 0 { deleteOpts.GracePeriodSeconds = &gracePeriod diff --git a/utils/meta.go b/utils/meta.go new file mode 100644 index 0000000000000000000000000000000000000000..9d448a44db70697d74d65d4e0382007751cc8ca3 --- /dev/null +++ b/utils/meta.go @@ -0,0 +1,62 @@ +package utils + +import ( + "fmt" + "strconv" + + "k8s.io/apimachinery/pkg/version" + "k8s.io/client-go/discovery" +) + +// ServerVersion captures k8s major.minor version in a parsed form +type ServerVersion struct { + Major int + Minor int +} + +// ParseVersion parses version.Info into a ServerVersion struct +func ParseVersion(v *version.Info) (ret ServerVersion, err error) { + ret.Major, err = strconv.Atoi(v.Major) + if err != nil { + return + } + ret.Minor, err = strconv.Atoi(v.Minor) + if err != nil { + return + } + return +} + +// FetchVersion fetches version information from discovery client, and parses +func FetchVersion(v discovery.ServerVersionInterface) (ret ServerVersion, err error) { + version, err := v.ServerVersion() + if err != nil { + return ServerVersion{}, err + } + return ParseVersion(version) +} + +// Compare returns -1/0/+1 iff v is less than / equal / greater than major.minor +func (v ServerVersion) Compare(major, minor int) int { + a := v.Major + b := major + + if a == b { + a = v.Minor + b = minor + } + + var res int + if a > b { + res = 1 + } else if a == b { + res = 0 + } else { + res = -1 + } + return res +} + +func (v ServerVersion) String() string { + return fmt.Sprintf("%d.%d", v.Major, v.Minor) +} diff --git a/utils/meta_test.go b/utils/meta_test.go new file mode 100644 index 0000000000000000000000000000000000000000..2bcf32e9014fc35e819e224c1a81fa77502a10ca --- /dev/null +++ b/utils/meta_test.go @@ -0,0 +1,65 @@ +package utils + +import ( + "testing" + + "k8s.io/apimachinery/pkg/version" +) + +func TestParseVersion(t *testing.T) { + tests := []struct { + input version.Info + expected ServerVersion + error bool + }{ + { + input: version.Info{Major: "1", Minor: "6"}, + expected: ServerVersion{Major: 1, Minor: 6}, + }, + { + input: version.Info{Major: "1", Minor: "70"}, + expected: ServerVersion{Major: 1, Minor: 70}, + }, + { + input: version.Info{Major: "1", Minor: "6x"}, + error: true, + }, + } + + for _, test := range tests { + v, err := ParseVersion(&test.input) + if test.error { + if err == nil { + t.Errorf("test %s should have failed and did not", test.input) + } + continue + } + if err != nil { + t.Errorf("test %v failed: %v", test.input, err) + continue + } + if v != test.expected { + t.Errorf("Expected %v, got %v", test.expected, v) + } + } +} + +func TestVersionCompare(t *testing.T) { + v := ServerVersion{Major: 2, Minor: 3} + tests := []struct { + major, minor, result int + }{ + {major: 1, minor: 0, result: 1}, + {major: 2, minor: 0, result: 1}, + {major: 2, minor: 2, result: 1}, + {major: 2, minor: 3, result: 0}, + {major: 2, minor: 4, result: -1}, + {major: 3, minor: 0, result: -1}, + } + for _, test := range tests { + res := v.Compare(test.major, test.minor) + if res != test.result { + t.Errorf("%d.%d => Expected %d, got %d", test.major, test.minor, test.result, res) + } + } +}