grim/convey

Parents 02f6bf176f35
Children 3f70720d5621
Add kubectl/apply, kubectl/create, and kubectl/delete commands. Fixed #170
--- a/ChangeLog Wed Feb 14 00:28:46 2018 -0600
+++ b/ChangeLog Thu Feb 15 01:27:37 2018 -0600
@@ -15,6 +15,7 @@
* Add copies of all VCS environment variables without their prefix as well as
a VCS environment variable. Fixed #164
* Added a new aws/ecr-login task for logging into AWS ECR. Fixed #161
+ * Added kubectl/apply, kubectl/create, and kubectl/delete tasks. Fixed #170
0.13.1: 20180114
* Write warning, error, and fatal log messages to stderr. Fixed #156
--- a/REFERENCE.md Wed Feb 14 00:28:46 2018 -0600
+++ b/REFERENCE.md Thu Feb 15 01:27:37 2018 -0600
@@ -519,6 +519,72 @@
----
+### kubectl/apply Tasks
+
+An apply task will apply kubernetes manifests to the cluster.
+
+#### Attributes
+
+| Name | Required | Default | Description |
+| ----------| -------- | ---------- | ----------- |
+| context | | | The kubernetes context to use. |
+| files | Yes | | The list of manifest files to apply. |
+| namespace | | | The kubernetes namespace to use. |
+| selector | | | The selector to use. |
+
+#### Example
+
+ apply:
+ type: kubectl/apply
+ files:
+ - manifest.yml
+
+----
+
+### kubectl/create Tasks
+
+A create task will create kubernetes manifests on the cluster.
+
+#### Attributes
+
+| Name | Required | Default | Description |
+| ----------| -------- | ---------- | ----------- |
+| context | | | The kubernetes context to use. |
+| files | Yes | | The list of manifest files to apply. |
+| namespace | | | The kubernetes namespace to use. |
+| selector | | | The selector to use. |
+
+#### Example
+
+ apply:
+ type: kubectl/create
+ files:
+ - manifest.yml
+
+----
+
+### kubectl/delete Tasks
+
+A delete task will delete kubernetes manifests from the cluster.
+
+#### Attributes
+
+| Name | Required | Default | Description |
+| ----------| -------- | ---------- | ----------- |
+| context | | | The kubernetes context to use. |
+| files | Yes | | The list of manifest files to apply. |
+| namespace | | | The kubernetes namespace to use. |
+| selector | | | The selector to use. |
+
+#### Example
+
+ apply:
+ type: kubectl/delete
+ files:
+ - manifest.yml
+
+----
+
## Environment
The environment section defines a list of environment variables to set for the run.
--- a/config/tasks.go Wed Feb 14 00:28:46 2018 -0600
+++ b/config/tasks.go Thu Feb 15 01:27:37 2018 -0600
@@ -20,6 +20,7 @@
"bitbucket.org/rw_grim/convey/aws"
"bitbucket.org/rw_grim/convey/docker"
"bitbucket.org/rw_grim/convey/intrinsic"
+ "bitbucket.org/rw_grim/convey/kubectl"
"bitbucket.org/rw_grim/convey/tasks"
)
@@ -32,18 +33,23 @@
)
func init() {
+ // add the aws tasks
+ for taskName, task := range aws.Tasks {
+ TasksMap["aws/"+taskName] = task
+ }
+
// add the docker tasks
for taskName, task := range docker.Tasks {
TasksMap["docker/"+taskName] = task
}
- // add the aws tasks
- for taskName, task := range aws.Tasks {
- TasksMap["aws/"+taskName] = task
- }
-
// add the intrinsic convey tasks
for taskName, task := range intrinsic.Tasks {
TasksMap["convey/"+taskName] = task
}
+
+ // add the kubectl tasks
+ for taskName, task := range kubectl.Tasks {
+ TasksMap["kubectl/"+taskName] = task
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/apply.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,51 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/state"
+ "bitbucket.org/rw_grim/convey/tasks"
+)
+
+type Apply CRUDCommand
+
+func (a *Apply) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
+ cmd := &CRUDCommand{
+ Context: a.Context,
+ Namespace: a.Namespace,
+ Files: a.Files,
+ Selector: a.Selector,
+ }
+
+ return cmd.Execute(name, "apply", logger, env, st)
+}
+
+// New creates a new kubectl/apply task.
+func (a *Apply) New() tasks.Task {
+ return &Apply{}
+}
+
+// Valid check if the apply task is valid
+func (a *Apply) Valid() error {
+ if len(a.Files) <= 0 {
+ return errNoFiles
+ }
+
+ return nil
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/apply_test.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,32 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/sweet"
+ . "github.com/onsi/gomega"
+)
+
+type applySuite struct{}
+
+func (s *applySuite) TestFilesRequired(t sweet.T) {
+ a := &Apply{}
+ Expect(a.Valid()).To(Not(BeNil()))
+
+ a = &Apply{Files: []string{"foo.yml"}}
+ Expect(a.Valid()).To(BeNil())
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/command.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,78 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// Package intrinsic contains the intrinsic commands
+package kubectl
+
+import (
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/command"
+ "bitbucket.org/rw_grim/convey/environment"
+ "bitbucket.org/rw_grim/convey/state"
+ "bitbucket.org/rw_grim/convey/yaml"
+)
+
+type CRUDCommand struct {
+ Context string `yaml:"context"`
+ Namespace string `yaml:"namespace"`
+ Files yaml.StringOrSlice `yaml:"files"`
+ Selector string `yaml:"selector"`
+}
+
+func (c *CRUDCommand) Execute(name, action string, logger *gomol.LogAdapter, env []string, st *state.State) error {
+ fullEnv := environment.Merge(env, st.GetEnv())
+
+ // if we have a context use it
+ if c.Context != "" {
+ err := useContext(name, c.Context, logger, env, st.PlanTimeout)
+ if err != nil {
+ return err
+ }
+ }
+
+ // now build the apply command line
+ cmd := command.NewGenerator("kubectl", action)
+
+ if c.Namespace != "" {
+ namespace, err := environment.Mapper(c.Namespace, fullEnv)
+ if err != nil {
+ return err
+ }
+
+ cmd.Append("-n", namespace)
+ }
+
+ if c.Selector != "" {
+ selector, err := environment.Mapper(c.Selector, fullEnv)
+ if err != nil {
+ return err
+ }
+
+ cmd.Append("-l", selector)
+ }
+
+ for _, file := range c.Files {
+ realFile, err := environment.Mapper(file, fullEnv)
+ if err != nil {
+ return err
+ }
+
+ cmd.Append("-f", realFile)
+ }
+
+ return command.Run(name, cmd.Command(), st.PlanTimeout)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/context.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,38 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "time"
+
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/command"
+ "bitbucket.org/rw_grim/convey/environment"
+)
+
+// useContext calls `kubectl config use-context` for the given context
+func useContext(name, context string, logger *gomol.LogAdapter, env []string, timeout time.Duration) error {
+ realContext, err := environment.Mapper(context, env)
+ if err != nil {
+ return err
+ }
+
+ cmdv := []string{"kubectl", "config", "use-context", realContext}
+
+ return command.Run(name, cmdv, timeout)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/create.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,51 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/state"
+ "bitbucket.org/rw_grim/convey/tasks"
+)
+
+type Create CRUDCommand
+
+func (c *Create) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
+ cmd := &CRUDCommand{
+ Context: c.Context,
+ Namespace: c.Namespace,
+ Files: c.Files,
+ Selector: c.Selector,
+ }
+
+ return cmd.Execute(name, "create", logger, env, st)
+}
+
+// New creates a new kubectl/create task.
+func (c *Create) New() tasks.Task {
+ return &Create{}
+}
+
+// Valid check if the apply task is valid
+func (c *Create) Valid() error {
+ if len(c.Files) <= 0 {
+ return errNoFiles
+ }
+
+ return nil
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/create_test.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,32 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/sweet"
+ . "github.com/onsi/gomega"
+)
+
+type createSuite struct{}
+
+func (s *createSuite) TestFilesRequired(t sweet.T) {
+ c := &Create{}
+ Expect(c.Valid()).To(Not(BeNil()))
+
+ c = &Create{Files: []string{"foo.yml"}}
+ Expect(c.Valid()).To(BeNil())
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/delete.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,51 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/gomol"
+
+ "bitbucket.org/rw_grim/convey/state"
+ "bitbucket.org/rw_grim/convey/tasks"
+)
+
+type Delete CRUDCommand
+
+func (d *Delete) Execute(name string, logger *gomol.LogAdapter, env []string, st *state.State) error {
+ cmd := &CRUDCommand{
+ Context: d.Context,
+ Namespace: d.Namespace,
+ Files: d.Files,
+ Selector: d.Selector,
+ }
+
+ return cmd.Execute(name, "delete", logger, env, st)
+}
+
+// New creates a new kubectl/create task.
+func (d *Delete) New() tasks.Task {
+ return &Delete{}
+}
+
+// Valid check if the apply task is valid
+func (d *Delete) Valid() error {
+ if len(d.Files) <= 0 {
+ return errNoFiles
+ }
+
+ return nil
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/delete_test.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,32 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "github.com/aphistic/sweet"
+ . "github.com/onsi/gomega"
+)
+
+type deleteSuite struct{}
+
+func (s *deleteSuite) TestFilesRequired(t sweet.T) {
+ d := &Delete{}
+ Expect(d.Valid()).To(Not(BeNil()))
+
+ d = &Delete{Files: []string{"foo.yml"}}
+ Expect(d.Valid()).To(BeNil())
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/errors.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,25 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "errors"
+)
+
+var (
+ errNoFiles = errors.New("no files specified")
+)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/kubectl.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,31 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+// Package intrinsic contains the intrinsic commands
+package kubectl
+
+import (
+ "bitbucket.org/rw_grim/convey/tasks"
+)
+
+var (
+ // Tasks is a map of kubectl tasks.
+ Tasks = map[string]tasks.Task{
+ "apply": &Apply{},
+ "create": &Create{},
+ "delete": &Delete{},
+ }
+)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kubectl/kubectl_test.go Thu Feb 15 01:27:37 2018 -0600
@@ -0,0 +1,37 @@
+// Convey
+// Copyright 2016-2018 Gary Kramlich <grim@reaperworld.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package kubectl
+
+import (
+ "testing"
+
+ "github.com/aphistic/sweet"
+ junit "github.com/aphistic/sweet-junit"
+ . "github.com/onsi/gomega"
+)
+
+func TestMain(m *testing.M) {
+ RegisterFailHandler(sweet.GomegaFail)
+
+ sweet.Run(m, func(s *sweet.S) {
+ s.RegisterPlugin(junit.NewPlugin())
+
+ s.AddSuite(&applySuite{})
+ s.AddSuite(&createSuite{})
+ s.AddSuite(&deleteSuite{})
+ })
+}