Skip to content

Commit 5eb5582

Browse files
authored
Add version checking for --dry-run flag (#145)
1 parent a8b78aa commit 5eb5582

File tree

2 files changed

+218
-1
lines changed

2 files changed

+218
-1
lines changed

main.go

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const (
3838
keyPath = "/tmp/gcloud.json"
3939
nsPath = "/tmp/namespace.json"
4040
templateBasePath = "/tmp"
41+
42+
dryRunFlagPre118 = "--dry-run=true"
43+
dryRunFlagDefault = "--dry-run=client"
4144
)
4245

4346
// default to kubectlCmdName, can be overriden via kubectl-version param
@@ -51,6 +54,7 @@ metadata:
5154
name: %s
5255
`
5356
var invalidNameRegex = regexp.MustCompile(`[^a-z0-9\.\-]+`)
57+
var dryRunFlag = dryRunFlagDefault
5458

5559
func main() {
5660
err := wrapMain()
@@ -225,6 +229,13 @@ func run(c *cli.Context) error {
225229
kubectlCmd = fmt.Sprintf("%s.%s", kubectlCmdName, kubectlVersion)
226230
}
227231

232+
// Parse and adjust the dry-run flag if needed
233+
var dryRunBuffer bytes.Buffer
234+
dryRunRunner := NewBasicRunner("/", []string{}, &dryRunBuffer, &dryRunBuffer)
235+
if err := setDryRunFlag(dryRunRunner, &dryRunBuffer); err != nil {
236+
return err
237+
}
238+
228239
// Parse variables and secrets
229240
vars, err := parseVars(c)
230241
if err != nil {
@@ -395,6 +406,52 @@ func parseSkips(c *cli.Context) error {
395406
return nil
396407
}
397408

409+
// setDryRunFlag sets the value of the dry-run flag for the version of kubectl
410+
// that is being used
411+
func setDryRunFlag(runner Runner, output io.Reader) error {
412+
dryRunFlag = dryRunFlagDefault
413+
version, err := getMinorVersion(runner, output)
414+
if err != nil {
415+
return fmt.Errorf("Error determining which kubectl version is running: %v", err)
416+
}
417+
// default is the >= 1.18 flag
418+
if version < 18 {
419+
dryRunFlag = dryRunFlagPre118
420+
}
421+
return nil
422+
}
423+
424+
// getMinorVersion fetches and parses the version from kubectl
425+
func getMinorVersion(runner Runner, output io.Reader) (int64, error) {
426+
runner.Run(kubectlCmd, "version", "--client", "-o=json")
427+
data, err := ioutil.ReadAll(output)
428+
if err != nil {
429+
return 0, fmt.Errorf("Error reading kubectl version: %v", err)
430+
}
431+
432+
var versionOutput struct {
433+
ClientVersion struct {
434+
Minor string
435+
}
436+
}
437+
438+
err = json.Unmarshal(data, &versionOutput)
439+
if err != nil {
440+
return 0, fmt.Errorf("Error reading kubectl version: %v", err)
441+
}
442+
443+
versionString, err := strings.Replace(versionOutput.ClientVersion.Minor, "+", "", 1), nil
444+
if err != nil {
445+
return 0, fmt.Errorf("Error removing extra '+' from version string: %v", err)
446+
}
447+
448+
versionInt, err := strconv.ParseInt(versionString, 10, 64)
449+
if err != nil {
450+
return 0, fmt.Errorf("Couldn't parse minor version from string: %v", err)
451+
}
452+
return versionInt, nil
453+
}
454+
398455
// parseVars parses vars (in JSON) and returns a map
399456
func parseVars(c *cli.Context) (map[string]interface{}, error) {
400457
// Parse variables.
@@ -758,7 +815,7 @@ func applyArgs(dryrun bool, file string) []string {
758815
}
759816

760817
if dryrun {
761-
args = append(args, "--dry-run=client")
818+
args = append(args, dryRunFlag)
762819
}
763820

764821
args = append(args, "--filename")

main_test.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,3 +678,163 @@ func TestTokenParamPrecedence(t *testing.T) {
678678
})
679679
}
680680
}
681+
682+
func TestSetDryRunFlag(t *testing.T) {
683+
tests := []struct {
684+
name string
685+
versionCommandOutput string
686+
explicitVersion string
687+
688+
expectedFlag string
689+
}{
690+
{
691+
name: "default-1.17",
692+
versionCommandOutput: `{
693+
"clientVersion": {
694+
"major": "1",
695+
"minor": "17+",
696+
"gitVersion": "v1.17.17-dispatcher",
697+
"gitCommit": "a39a896b5018d0c800124a36757433c660fd0880",
698+
"gitTreeState": "clean",
699+
"buildDate": "2021-01-28T21:47:26Z",
700+
"goVersion": "go1.13.9",
701+
"compiler": "gc",
702+
"platform": "linux/amd64"
703+
}
704+
}`,
705+
explicitVersion: "",
706+
expectedFlag: dryRunFlagPre118,
707+
},
708+
{
709+
name: "kubectl-1.15",
710+
versionCommandOutput: `{
711+
"clientVersion": {
712+
"major": "1",
713+
"minor": "15",
714+
"gitVersion": "v1.15.12",
715+
"gitCommit": "e2a822d9f3c2fdb5c9bfbe64313cf9f657f0a725",
716+
"gitTreeState": "clean",
717+
"buildDate": "2020-05-06T05:17:59Z",
718+
"goVersion": "go1.12.17",
719+
"compiler": "gc",
720+
"platform": "linux/amd64"
721+
}
722+
}`,
723+
explicitVersion: "1.15",
724+
expectedFlag: dryRunFlagPre118,
725+
},
726+
{
727+
name: "kubectl-1.16",
728+
versionCommandOutput: `{
729+
"clientVersion": {
730+
"major": "1",
731+
"minor": "16",
732+
"gitVersion": "v1.16.15",
733+
"gitCommit": "2adc8d7091e89b6e3ca8d048140618ec89b39369",
734+
"gitTreeState": "clean",
735+
"buildDate": "2020-09-02T11:40:00Z",
736+
"goVersion": "go1.13.15",
737+
"compiler": "gc",
738+
"platform": "linux/amd64"
739+
}
740+
}`,
741+
explicitVersion: "1.16",
742+
expectedFlag: dryRunFlagPre118,
743+
},
744+
{
745+
name: "kubectl-1.17",
746+
versionCommandOutput: `{
747+
"clientVersion": {
748+
"major": "1",
749+
"minor": "17",
750+
"gitVersion": "v1.17.17",
751+
"gitCommit": "f3abc15296f3a3f54e4ee42e830c61047b13895f",
752+
"gitTreeState": "clean",
753+
"buildDate": "2021-01-13T13:21:12Z",
754+
"goVersion": "go1.13.15",
755+
"compiler": "gc",
756+
"platform": "linux/amd64"
757+
}
758+
}`,
759+
explicitVersion: "1.17",
760+
expectedFlag: dryRunFlagPre118,
761+
},
762+
{
763+
name: "kubectl-1.18",
764+
versionCommandOutput: `{
765+
"clientVersion": {
766+
"major": "1",
767+
"minor": "18",
768+
"gitVersion": "v1.18.15",
769+
"gitCommit": "73dd5c840662bb066a146d0871216333181f4b64",
770+
"gitTreeState": "clean",
771+
"buildDate": "2021-01-13T13:22:41Z",
772+
"goVersion": "go1.13.15",
773+
"compiler": "gc",
774+
"platform": "linux/amd64"
775+
}
776+
}`,
777+
explicitVersion: "1.18",
778+
expectedFlag: dryRunFlagDefault,
779+
},
780+
{
781+
name: "kubectl-1.19",
782+
versionCommandOutput: `{
783+
"clientVersion": {
784+
"major": "1",
785+
"minor": "19",
786+
"gitVersion": "v1.19.7",
787+
"gitCommit": "1dd5338295409edcfff11505e7bb246f0d325d15",
788+
"gitTreeState": "clean",
789+
"buildDate": "2021-01-13T13:23:52Z",
790+
"goVersion": "go1.15.5",
791+
"compiler": "gc",
792+
"platform": "linux/amd64"
793+
}
794+
}`,
795+
explicitVersion: "1.19",
796+
expectedFlag: dryRunFlagDefault,
797+
},
798+
}
799+
for _, test := range tests {
800+
t.Run(test.name, func(t *testing.T) {
801+
os.Clearenv()
802+
803+
os.Setenv("PLUGIN_KUBECTL_VERSION", test.explicitVersion)
804+
805+
err := (&cli.App{
806+
Flags: getAppFlags(),
807+
Action: func(ctx *cli.Context) error {
808+
// setup
809+
810+
// copied from lines 227-230 of main.go
811+
kubectlVersion := ctx.String("kubectl-version")
812+
if kubectlVersion != "" {
813+
kubectlCmd = fmt.Sprintf("%s.%s", kubectlCmdName, kubectlVersion)
814+
}
815+
816+
buf := bytes.NewBufferString(test.versionCommandOutput)
817+
testRunner := new(MockedRunner)
818+
if test.explicitVersion != "" {
819+
testRunner.On("Run", []string{fmt.Sprintf("kubectl.%s", test.explicitVersion), "version", "--client", "-o=json"}).Return(nil)
820+
} else {
821+
testRunner.On("Run", []string{"kubectl", "version", "--client", "-o=json"}).Return(nil)
822+
}
823+
824+
// Run
825+
setDryRunFlag(testRunner, buf)
826+
827+
// Check
828+
if dryRunFlag != test.expectedFlag {
829+
t.Fatalf("expected: %s, got: %s", test.expectedFlag, dryRunFlag)
830+
}
831+
return nil
832+
},
833+
}).Run([]string{"run"})
834+
835+
if err != nil {
836+
t.Fatalf("unepected err: %v", err)
837+
}
838+
})
839+
}
840+
}

0 commit comments

Comments
 (0)