Skip to content

Commit

Permalink
Add version checking for --dry-run flag (#145)
Browse files Browse the repository at this point in the history
  • Loading branch information
mlclmj committed Apr 7, 2021
1 parent a8b78aa commit 5eb5582
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 1 deletion.
59 changes: 58 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const (
keyPath = "/tmp/gcloud.json"
nsPath = "/tmp/namespace.json"
templateBasePath = "/tmp"

dryRunFlagPre118 = "--dry-run=true"
dryRunFlagDefault = "--dry-run=client"
)

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

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

// Parse and adjust the dry-run flag if needed
var dryRunBuffer bytes.Buffer
dryRunRunner := NewBasicRunner("/", []string{}, &dryRunBuffer, &dryRunBuffer)
if err := setDryRunFlag(dryRunRunner, &dryRunBuffer); err != nil {
return err
}

// Parse variables and secrets
vars, err := parseVars(c)
if err != nil {
Expand Down Expand Up @@ -395,6 +406,52 @@ func parseSkips(c *cli.Context) error {
return nil
}

// setDryRunFlag sets the value of the dry-run flag for the version of kubectl
// that is being used
func setDryRunFlag(runner Runner, output io.Reader) error {
dryRunFlag = dryRunFlagDefault
version, err := getMinorVersion(runner, output)
if err != nil {
return fmt.Errorf("Error determining which kubectl version is running: %v", err)
}
// default is the >= 1.18 flag
if version < 18 {
dryRunFlag = dryRunFlagPre118
}
return nil
}

// getMinorVersion fetches and parses the version from kubectl
func getMinorVersion(runner Runner, output io.Reader) (int64, error) {
runner.Run(kubectlCmd, "version", "--client", "-o=json")
data, err := ioutil.ReadAll(output)
if err != nil {
return 0, fmt.Errorf("Error reading kubectl version: %v", err)
}

var versionOutput struct {
ClientVersion struct {
Minor string
}
}

err = json.Unmarshal(data, &versionOutput)
if err != nil {
return 0, fmt.Errorf("Error reading kubectl version: %v", err)
}

versionString, err := strings.Replace(versionOutput.ClientVersion.Minor, "+", "", 1), nil
if err != nil {
return 0, fmt.Errorf("Error removing extra '+' from version string: %v", err)
}

versionInt, err := strconv.ParseInt(versionString, 10, 64)
if err != nil {
return 0, fmt.Errorf("Couldn't parse minor version from string: %v", err)
}
return versionInt, nil
}

// parseVars parses vars (in JSON) and returns a map
func parseVars(c *cli.Context) (map[string]interface{}, error) {
// Parse variables.
Expand Down Expand Up @@ -758,7 +815,7 @@ func applyArgs(dryrun bool, file string) []string {
}

if dryrun {
args = append(args, "--dry-run=client")
args = append(args, dryRunFlag)
}

args = append(args, "--filename")
Expand Down
160 changes: 160 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,163 @@ func TestTokenParamPrecedence(t *testing.T) {
})
}
}

func TestSetDryRunFlag(t *testing.T) {
tests := []struct {
name string
versionCommandOutput string
explicitVersion string

expectedFlag string
}{
{
name: "default-1.17",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "17+",
"gitVersion": "v1.17.17-dispatcher",
"gitCommit": "a39a896b5018d0c800124a36757433c660fd0880",
"gitTreeState": "clean",
"buildDate": "2021-01-28T21:47:26Z",
"goVersion": "go1.13.9",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "",
expectedFlag: dryRunFlagPre118,
},
{
name: "kubectl-1.15",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "15",
"gitVersion": "v1.15.12",
"gitCommit": "e2a822d9f3c2fdb5c9bfbe64313cf9f657f0a725",
"gitTreeState": "clean",
"buildDate": "2020-05-06T05:17:59Z",
"goVersion": "go1.12.17",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "1.15",
expectedFlag: dryRunFlagPre118,
},
{
name: "kubectl-1.16",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "16",
"gitVersion": "v1.16.15",
"gitCommit": "2adc8d7091e89b6e3ca8d048140618ec89b39369",
"gitTreeState": "clean",
"buildDate": "2020-09-02T11:40:00Z",
"goVersion": "go1.13.15",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "1.16",
expectedFlag: dryRunFlagPre118,
},
{
name: "kubectl-1.17",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "17",
"gitVersion": "v1.17.17",
"gitCommit": "f3abc15296f3a3f54e4ee42e830c61047b13895f",
"gitTreeState": "clean",
"buildDate": "2021-01-13T13:21:12Z",
"goVersion": "go1.13.15",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "1.17",
expectedFlag: dryRunFlagPre118,
},
{
name: "kubectl-1.18",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "18",
"gitVersion": "v1.18.15",
"gitCommit": "73dd5c840662bb066a146d0871216333181f4b64",
"gitTreeState": "clean",
"buildDate": "2021-01-13T13:22:41Z",
"goVersion": "go1.13.15",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "1.18",
expectedFlag: dryRunFlagDefault,
},
{
name: "kubectl-1.19",
versionCommandOutput: `{
"clientVersion": {
"major": "1",
"minor": "19",
"gitVersion": "v1.19.7",
"gitCommit": "1dd5338295409edcfff11505e7bb246f0d325d15",
"gitTreeState": "clean",
"buildDate": "2021-01-13T13:23:52Z",
"goVersion": "go1.15.5",
"compiler": "gc",
"platform": "linux/amd64"
}
}`,
explicitVersion: "1.19",
expectedFlag: dryRunFlagDefault,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
os.Clearenv()

os.Setenv("PLUGIN_KUBECTL_VERSION", test.explicitVersion)

err := (&cli.App{
Flags: getAppFlags(),
Action: func(ctx *cli.Context) error {
// setup

// copied from lines 227-230 of main.go
kubectlVersion := ctx.String("kubectl-version")
if kubectlVersion != "" {
kubectlCmd = fmt.Sprintf("%s.%s", kubectlCmdName, kubectlVersion)
}

buf := bytes.NewBufferString(test.versionCommandOutput)
testRunner := new(MockedRunner)
if test.explicitVersion != "" {
testRunner.On("Run", []string{fmt.Sprintf("kubectl.%s", test.explicitVersion), "version", "--client", "-o=json"}).Return(nil)
} else {
testRunner.On("Run", []string{"kubectl", "version", "--client", "-o=json"}).Return(nil)
}

// Run
setDryRunFlag(testRunner, buf)

// Check
if dryRunFlag != test.expectedFlag {
t.Fatalf("expected: %s, got: %s", test.expectedFlag, dryRunFlag)
}
return nil
},
}).Run([]string{"run"})

if err != nil {
t.Fatalf("unepected err: %v", err)
}
})
}
}

0 comments on commit 5eb5582

Please sign in to comment.