From 644432144e13b1faefd1c553be90b3359873d29a Mon Sep 17 00:00:00 2001 From: Jordan Brockopp Date: Tue, 11 Feb 2020 12:06:57 -0600 Subject: [PATCH 1/2] feat: add validate logic for kubernetes flags --- cmd/vela-kubernetes/config.go | 19 ++++++++ cmd/vela-kubernetes/kubernetes.go | 43 ++++++++++++++++++ cmd/vela-kubernetes/kubernetes_test.go | 62 ++++++++++++++++++++++++++ cmd/vela-kubernetes/main.go | 28 +++++++++++- cmd/vela-kubernetes/plugin.go | 11 ++++- cmd/vela-kubernetes/plugin_test.go | 20 ++++++++- 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 cmd/vela-kubernetes/config.go create mode 100644 cmd/vela-kubernetes/kubernetes.go create mode 100644 cmd/vela-kubernetes/kubernetes_test.go diff --git a/cmd/vela-kubernetes/config.go b/cmd/vela-kubernetes/config.go new file mode 100644 index 0000000..93f3dd3 --- /dev/null +++ b/cmd/vela-kubernetes/config.go @@ -0,0 +1,19 @@ +// Copyright (c) 2020 Target Brands, Inc. All rights reserved. +// +// Use of this source code is governed by the LICENSE file in this repository. + +package main + +import "time" + +// Config represents the plugin configuration for Kubernetes config information. +type Config struct { + // Kubernetes files or directories to apply + Files []string + // new container images from files to apply + Images []string + // Kubernetes resources to watch status of + Statuses []string + // total time allowed to watch Kubernetes resources + Timeout time.Duration +} diff --git a/cmd/vela-kubernetes/kubernetes.go b/cmd/vela-kubernetes/kubernetes.go new file mode 100644 index 0000000..230cbf1 --- /dev/null +++ b/cmd/vela-kubernetes/kubernetes.go @@ -0,0 +1,43 @@ +// Copyright (c) 2020 Target Brands, Inc. All rights reserved. +// +// Use of this source code is governed by the LICENSE file in this repository. + +package main + +import ( + "fmt" + + "github.com/sirupsen/logrus" +) + +// Kubernetes represents the plugin configuration for Kubernetes information. +type Kubernetes struct { + // cluster configuration to use for interactions + Config string + // cluster context to use for interactions + Context string + // cluster namespace to use for interactions + Namespace string +} + +// Validate verifies the Kubernetes is properly configured. +func (k *Kubernetes) Validate() error { + logrus.Trace("validating kubernetes configuration") + + // verify config is provided + if len(k.Config) == 0 { + return fmt.Errorf("no kubernetes config provided") + } + + // verify context is provided + if len(k.Context) == 0 { + return fmt.Errorf("no kubernetes context provided") + } + + // verify namespace is provided + if len(k.Namespace) == 0 { + return fmt.Errorf("no kubernetes namespace provided") + } + + return nil +} diff --git a/cmd/vela-kubernetes/kubernetes_test.go b/cmd/vela-kubernetes/kubernetes_test.go new file mode 100644 index 0000000..8d4ded8 --- /dev/null +++ b/cmd/vela-kubernetes/kubernetes_test.go @@ -0,0 +1,62 @@ +// Copyright (c) 2020 Target Brands, Inc. All rights reserved. +// +// Use of this source code is governed by the LICENSE file in this repository. + +package main + +import ( + "testing" +) + +func TestKubernetes_Kubernetes_Validate(t *testing.T) { + // setup types + k := &Kubernetes{ + Config: "config", + Context: "context", + Namespace: "namespace", + } + + err := k.Validate() + if err != nil { + t.Errorf("Validate returned err: %v", err) + } +} + +func TestKubernetes_Kubernetes_Validate_NoConfig(t *testing.T) { + // setup types + k := &Kubernetes{ + Context: "context", + Namespace: "namespace", + } + + err := k.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestKubernetes_Kubernetes_Validate_NoContext(t *testing.T) { + // setup types + k := &Kubernetes{ + Config: "config", + Namespace: "namespace", + } + + err := k.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestKubernetes_Kubernetes_Validate_NoNamespace(t *testing.T) { + // setup types + k := &Kubernetes{ + Config: "config", + Context: "context", + } + + err := k.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} diff --git a/cmd/vela-kubernetes/main.go b/cmd/vela-kubernetes/main.go index 13145c1..687fca0 100644 --- a/cmd/vela-kubernetes/main.go +++ b/cmd/vela-kubernetes/main.go @@ -6,7 +6,6 @@ package main import ( "os" - "time" "github.com/sirupsen/logrus" @@ -46,6 +45,24 @@ func main() { Usage: "set log level - options: (trace|debug|info|warn|error|fatal|panic)", Value: "info", }, + + // Kubernetes Flags + + cli.StringFlag{ + EnvVar: "PARAMETER_CONFIG,KUBE_CONFIG,KUBERNETES_CONFIG", + Name: "kubernetes.config", + Usage: "kubernetes cluster configuration", + }, + cli.StringFlag{ + EnvVar: "PARAMETER_CONTEXT,KUBE_CONTEXT,KUBERNETES_CONTEXT", + Name: "kubernetes.context", + Usage: "kubernetes cluster context to interact with", + }, + cli.StringFlag{ + EnvVar: "PARAMETER_NAMESPACE,KUBE_NAMESPACE,KUBERNETES_NAMESPACE", + Name: "kubernetes.namespace", + Usage: "kubernetes cluster namespace to interact with", + }, } err := app.Run(os.Args) @@ -83,7 +100,14 @@ func run(c *cli.Context) error { }).Info("Vela Kubernetes Plugin") // create the plugin - p := &Plugin{} + p := &Plugin{ + // Kubernetes configuration + Kubernetes: &Kubernetes{ + Config: c.String("kubernetes.config"), + Context: c.String("kubernetes.context"), + Namespace: c.String("kubernetes.namespace"), + }, + } // validate the plugin err := p.Validate() diff --git a/cmd/vela-kubernetes/plugin.go b/cmd/vela-kubernetes/plugin.go index f48038a..6459597 100644 --- a/cmd/vela-kubernetes/plugin.go +++ b/cmd/vela-kubernetes/plugin.go @@ -11,7 +11,10 @@ import ( ) // Plugin represents the configuration loaded for the plugin. -type Plugin struct{} +type Plugin struct { + // kubernetes arguments loaded for the plugin + Kubernetes *Kubernetes +} // Command formats and outputs the command necessary for // kubectl to manage Kubernetes resources. @@ -35,5 +38,11 @@ func (p *Plugin) Exec() error { func (p *Plugin) Validate() error { logrus.Debug("validating plugin configuration") + // validate Kubernetes configuration + err := p.Kubernetes.Validate() + if err != nil { + return err + } + return nil } diff --git a/cmd/vela-kubernetes/plugin_test.go b/cmd/vela-kubernetes/plugin_test.go index 5523108..42c6d31 100644 --- a/cmd/vela-kubernetes/plugin_test.go +++ b/cmd/vela-kubernetes/plugin_test.go @@ -38,10 +38,28 @@ func TestKubernetes_Plugin_Exec(t *testing.T) { func TestKubernetes_Plugin_Validate(t *testing.T) { // setup types - p := &Plugin{} + p := &Plugin{ + Kubernetes: &Kubernetes{ + Config: "config", + Context: "context", + Namespace: "namespace", + }, + } err := p.Validate() if err != nil { t.Errorf("Validate returned err: %v", err) } } + +func TestKubernetes_Plugin_Validate_NoKubernetes(t *testing.T) { + // setup types + p := &Plugin{ + Kubernetes: &Kubernetes{}, + } + + err := p.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} From d04082fcf2bd72651162d428ae710d69c0033b59 Mon Sep 17 00:00:00 2001 From: Jordan Brockopp Date: Tue, 11 Feb 2020 12:16:33 -0600 Subject: [PATCH 2/2] feat: add validate logic for config flags --- cmd/vela-kubernetes/config.go | 34 ++++++++++++- cmd/vela-kubernetes/config_test.go | 81 ++++++++++++++++++++++++++++++ cmd/vela-kubernetes/main.go | 31 ++++++++++++ cmd/vela-kubernetes/plugin.go | 10 +++- cmd/vela-kubernetes/plugin_test.go | 30 +++++++++++ 5 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 cmd/vela-kubernetes/config_test.go diff --git a/cmd/vela-kubernetes/config.go b/cmd/vela-kubernetes/config.go index 93f3dd3..8e775ff 100644 --- a/cmd/vela-kubernetes/config.go +++ b/cmd/vela-kubernetes/config.go @@ -4,7 +4,12 @@ package main -import "time" +import ( + "fmt" + "time" + + "github.com/sirupsen/logrus" +) // Config represents the plugin configuration for Kubernetes config information. type Config struct { @@ -17,3 +22,30 @@ type Config struct { // total time allowed to watch Kubernetes resources Timeout time.Duration } + +// Validate verifies the Config is properly configured. +func (c *Config) Validate() error { + logrus.Trace("validating config configuration") + + // verify files are provided + if len(c.Files) == 0 { + return fmt.Errorf("no config files provided") + } + + // verify images are provided + if len(c.Images) == 0 { + return fmt.Errorf("no config images provided") + } + + // verify statuses are provided + if len(c.Statuses) == 0 { + return fmt.Errorf("no config statuses provided") + } + + // verify timeout is provided + if c.Timeout <= 0 { + return fmt.Errorf("no config timeout provided") + } + + return nil +} diff --git a/cmd/vela-kubernetes/config_test.go b/cmd/vela-kubernetes/config_test.go new file mode 100644 index 0000000..64e0933 --- /dev/null +++ b/cmd/vela-kubernetes/config_test.go @@ -0,0 +1,81 @@ +// Copyright (c) 2020 Target Brands, Inc. All rights reserved. +// +// Use of this source code is governed by the LICENSE file in this repository. + +package main + +import ( + "testing" + "time" +) + +func TestKubernetes_Config_Validate(t *testing.T) { + // setup types + c := &Config{ + Files: []string{"files"}, + Images: []string{"images"}, + Statuses: []string{"statuses"}, + Timeout: 5 * time.Minute, + } + + err := c.Validate() + if err != nil { + t.Errorf("Validate returned err: %v", err) + } +} + +func TestKubernetes_Config_Validate_NoFiles(t *testing.T) { + // setup types + c := &Config{ + Images: []string{"images"}, + Statuses: []string{"statuses"}, + Timeout: 5 * time.Minute, + } + + err := c.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestKubernetes_Config_Validate_NoImages(t *testing.T) { + // setup types + c := &Config{ + Files: []string{"files"}, + Statuses: []string{"statuses"}, + Timeout: 5 * time.Minute, + } + + err := c.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestKubernetes_Config_Validate_NoStatuses(t *testing.T) { + // setup types + c := &Config{ + Files: []string{"files"}, + Images: []string{"images"}, + Timeout: 5 * time.Minute, + } + + err := c.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestKubernetes_Config_Validate_NoTimeout(t *testing.T) { + // setup types + c := &Config{ + Files: []string{"files"}, + Images: []string{"images"}, + Statuses: []string{"statuses"}, + } + + err := c.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} diff --git a/cmd/vela-kubernetes/main.go b/cmd/vela-kubernetes/main.go index 687fca0..fdca984 100644 --- a/cmd/vela-kubernetes/main.go +++ b/cmd/vela-kubernetes/main.go @@ -46,6 +46,30 @@ func main() { Value: "info", }, + // Config Flags + + cli.StringSliceFlag{ + EnvVar: "PARAMETER_FILES,CONFIG_FILES", + Name: "config.files", + Usage: "kubernetes files or directories to interact with", + }, + cli.StringFlag{ + EnvVar: "PARAMETER_IMAGES,CONFIG_IMAGES", + Name: "config.images", + Usage: "container images from files to interact with", + }, + cli.StringSliceFlag{ + EnvVar: "PARAMETER_STATUSES,CONFIG_STATUSES", + Name: "config.statuses", + Usage: "kubernetes resources to watch status on", + }, + cli.DurationFlag{ + EnvVar: "PARAMETER_TIMEOUT,CONFIG_TIMEOUT", + Name: "config.timeout", + Usage: "maximum duration to watch status on kubernetes resources", + Value: 5 * time.Minute, + }, + // Kubernetes Flags cli.StringFlag{ @@ -101,6 +125,13 @@ func run(c *cli.Context) error { // create the plugin p := &Plugin{ + // config configuration + Config: &Config{ + Files: c.StringSlice("config.files"), + Images: c.StringSlice("config.images"), + Statuses: c.StringSlice("config.statuses"), + Timeout: c.Duration("config.timeout"), + }, // Kubernetes configuration Kubernetes: &Kubernetes{ Config: c.String("kubernetes.config"), diff --git a/cmd/vela-kubernetes/plugin.go b/cmd/vela-kubernetes/plugin.go index 6459597..2b3302a 100644 --- a/cmd/vela-kubernetes/plugin.go +++ b/cmd/vela-kubernetes/plugin.go @@ -12,6 +12,8 @@ import ( // Plugin represents the configuration loaded for the plugin. type Plugin struct { + // config arguments loaded for the plugin + Config *Config // kubernetes arguments loaded for the plugin Kubernetes *Kubernetes } @@ -38,8 +40,14 @@ func (p *Plugin) Exec() error { func (p *Plugin) Validate() error { logrus.Debug("validating plugin configuration") + // validate config configuration + err := p.Config.Validate() + if err != nil { + return err + } + // validate Kubernetes configuration - err := p.Kubernetes.Validate() + err = p.Kubernetes.Validate() if err != nil { return err } diff --git a/cmd/vela-kubernetes/plugin_test.go b/cmd/vela-kubernetes/plugin_test.go index 42c6d31..7bed507 100644 --- a/cmd/vela-kubernetes/plugin_test.go +++ b/cmd/vela-kubernetes/plugin_test.go @@ -8,6 +8,7 @@ import ( "os/exec" "reflect" "testing" + "time" ) func TestKubernetes_Plugin_Command(t *testing.T) { @@ -39,6 +40,12 @@ func TestKubernetes_Plugin_Exec(t *testing.T) { func TestKubernetes_Plugin_Validate(t *testing.T) { // setup types p := &Plugin{ + Config: &Config{ + Files: []string{"files"}, + Images: []string{"images"}, + Statuses: []string{"statuses"}, + Timeout: 5 * time.Minute, + }, Kubernetes: &Kubernetes{ Config: "config", Context: "context", @@ -52,9 +59,32 @@ func TestKubernetes_Plugin_Validate(t *testing.T) { } } +func TestKubernetes_Plugin_Validate_NoConfig(t *testing.T) { + // setup types + p := &Plugin{ + Config: &Config{}, + Kubernetes: &Kubernetes{ + Config: "config", + Context: "context", + Namespace: "namespace", + }, + } + + err := p.Validate() + if err == nil { + t.Errorf("Validate should have returned err") + } +} + func TestKubernetes_Plugin_Validate_NoKubernetes(t *testing.T) { // setup types p := &Plugin{ + Config: &Config{ + Files: []string{"files"}, + Images: []string{"images"}, + Statuses: []string{"statuses"}, + Timeout: 5 * time.Minute, + }, Kubernetes: &Kubernetes{}, }