From baba219ca8df3850f5a7029d6b42445feb3d7d51 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 14 Jun 2019 10:53:03 +1000 Subject: [PATCH] Split into template types, simplified Deployment types (config map wip) --- .env.sample | 3 --- README.md | 8 ++++++-- config-map.go | 13 +++---------- deployment.go | 26 +++++++++----------------- plugin.go | 23 ++++++++++++----------- test.sh => test-config-map.sh | 4 ++++ test-deployment.sh | 10 ++++++++++ test/configmap.template.yaml | 21 --------------------- 8 files changed, 44 insertions(+), 64 deletions(-) rename test.sh => test-config-map.sh (56%) create mode 100755 test-deployment.sh delete mode 100644 test/configmap.template.yaml diff --git a/.env.sample b/.env.sample index 88bc32c..cff4530 100644 --- a/.env.sample +++ b/.env.sample @@ -1,6 +1,3 @@ PLUGIN_SERVER= PLUGIN_CA= PLUGIN_TOKEN= -PLUGIN_TEMPLATE= -PLUGIN_NAME= -PLUGIN_COMMIT= diff --git a/README.md b/README.md index ce0375d..69a6175 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ [![](https://images.microbadger.com/badges/version/danielgormly/drone-plugin-kube.svg)](https://microbadger.com/images/danielgormly/drone-plugin-kube "Get your own version badge on microbadger.com") -A simple Drone plugin for updating Kubernetes deployments. Follows from [vallard/drone-kube](https://github.com/vallard/drone-kube) but with dependency management, up-to-date client-go, docs updated to Drone 1.0.0 syntax, examples and a different structure. This plugin will create a deployment if it doesn't currently exist. +A simple Drone plugin for updating Kubernetes deployments from templates & configMaps from files. Follows from [vallard/drone-kube](https://github.com/vallard/drone-kube) but with dependency management, up-to-date client-go, docs updated to Drone 1.0.0 syntax, examples and a different structure. This plugin will create a deployment if it doesn't currently exist. ## Usage Add the following [build step](https://docs.drone.io/user-guide/pipeline/steps/) to your drone pipeline definition. Currently this plugin only updates deployments, it does not create them. I can add this behaviour or I will accept pull requests to introduce it. -#### drone.yaml partial example +#### drone.yaml deployment example ```yml - name: Deploy app image: danielgormly/drone-plugin-kube @@ -26,6 +26,10 @@ Add the following [build step](https://docs.drone.io/user-guide/pipeline/steps/) Deployment config files are first interpreted by **aymerick/raymond** ([handlebarsjs](http://handlebarsjs.com/) equivalent). You can use all available raymond expressions and anything you put in settings will be made available in your deployment template e.g. `{{namespace}}`. See [example/deployment.template.yaml](/example/deployment.template.yaml) for a complete example. +## Config maps from files + +In this case + #### Adding a service account to Kubernetes that can manage deployments See [example/Role.yaml](example/Role.yaml), [example/ServiceAccount.yaml](example/ServiceAccount.yaml), [example/RoleBinding.yaml](example/RoleBinding.yaml). diff --git a/config-map.go b/config-map.go index cf85cfd..1d1f79f 100644 --- a/config-map.go +++ b/config-map.go @@ -3,18 +3,11 @@ package main import ( appv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" ) -// CreateConfigMapObj -- Construct ConfigMap ready json from YAML definition file -func CreateConfigMapObj(yaml string) *appv1.ConfigMap { +// CreateConfigMap -- Updates given deployment in Kubernetes +func CreateConfigMapFromFile(clientset *kubernetes.Clientset, namespace string, name string) error { configMap := appv1.ConfigMap{} - scheme.Codecs.UniversalDeserializer().Decode([]byte(yaml), nil, &configMap) - return &configMap -} - -// CreateDeployment -- Updates given deployment in Kubernetes -func CreateDeployment(clientset *kubernetes.Clientset, namespace string, deployment *appv1.Deployment) error { - _, err := clientset.AppsV1().Deployments(namespace).Create(deployment) + _, err := clientset.AppsV1().ConfigMap(namespace).Create(configMap) return err } diff --git a/deployment.go b/deployment.go index 1f1550a..a5e1ab8 100644 --- a/deployment.go +++ b/deployment.go @@ -5,25 +5,17 @@ import ( "k8s.io/apimachinery/pkg/api/errors" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" ) -// CreateDeploymentObj -- Construct KubeClient ready json from YAML definition file -func CreateDeploymentObj(yaml string) *appv1.Deployment { - deployment := appv1.Deployment{} - scheme.Codecs.UniversalDeserializer().Decode([]byte(yaml), nil, &deployment) - return &deployment -} - -// UpdateDeployment -- Updates given deployment in Kubernetes -func UpdateDeployment(clientset *kubernetes.Clientset, namespace string, deployment *appv1.Deployment) error { - _, err := clientset.AppsV1().Deployments(namespace).Update(deployment) - return err -} - -// CreateDeployment -- Updates given deployment in Kubernetes -func CreateDeployment(clientset *kubernetes.Clientset, namespace string, deployment *appv1.Deployment) error { - _, err := clientset.AppsV1().Deployments(namespace).Create(deployment) +// CreateOrUpdateDeployment -- Checks if deployment already exists, updates if it does, creates if it doesn't +func CreateOrUpdateDeployment(clientset *kubernetes.Clientset, namespace string, deployment *appv1.Deployment) error { + deploymentExists, err := DeploymentExists(clientset, namespace, deployment.Name) + if deploymentExists { + // log.Printf("📦 Found existing deployment. Updating.\n%s\n", depYaml) + _, err = clientset.AppsV1().Deployments(namespace).Update(deployment) + return err + } + _, err = clientset.AppsV1().Deployments(namespace).Create(deployment) return err } diff --git a/plugin.go b/plugin.go index 06ca278..dbdd479 100644 --- a/plugin.go +++ b/plugin.go @@ -9,6 +9,9 @@ import ( "strings" "github.com/aymerick/raymond" + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes/scheme" ) type ( @@ -62,8 +65,7 @@ func (p Plugin) Exec() error { return err } // Parse template - depYaml, err := raymond.Render(string(raw), ctx) - + templateYaml, err := raymond.Render(string(raw), ctx) if err != nil { return err } @@ -72,14 +74,13 @@ func (p Plugin) Exec() error { if err != nil { return err } - deployment := CreateDeploymentObj(depYaml) - deploymentExists, err := DeploymentExists(clientset, p.KubeConfig.Namespace, deployment.Name) - if deploymentExists { - log.Printf("📦 Found existing deployment. Updating.\n%s\n", depYaml) - err = UpdateDeployment(clientset, p.KubeConfig.Namespace, deployment) - return err + // Decode + kubernetesObject, _, err := scheme.Codecs.UniversalDeserializer().Decode([]byte(templateYaml), nil, nil) + + switch o := kubernetesObject.(type) { + case *appv1.Deployment: + CreateOrUpdateDeployment(clientset, p.KubeConfig.Namespace, o) + case *corev1.ConfigMap: + CreateOrUpdateConfigMap(clientset, p.KubeConfig.Namespace, o) } - log.Printf("📦 Creating new deployment.\n%s\n", depYaml) - err = CreateDeployment(clientset, p.KubeConfig.Namespace, deployment) - return err } diff --git a/test.sh b/test-config-map.sh similarity index 56% rename from test.sh rename to test-config-map.sh index 7acbdff..edbb500 100755 --- a/test.sh +++ b/test-config-map.sh @@ -1,5 +1,9 @@ #!/bin/bash +PLUGIN_TEMPLATE=test/deployment.template.yaml +PLUGIN_NAME=drone-kube-test +PLUGIN_COMMIT=a5b81d0f + go build -o build/kubano export $(cat .env | xargs) && ./build/kubano diff --git a/test-deployment.sh b/test-deployment.sh new file mode 100755 index 0000000..edbb500 --- /dev/null +++ b/test-deployment.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +PLUGIN_TEMPLATE=test/deployment.template.yaml +PLUGIN_NAME=drone-kube-test +PLUGIN_COMMIT=a5b81d0f + +go build -o build/kubano +export $(cat .env | xargs) && ./build/kubano + +# docker run --env-file=.env drone-kubano diff --git a/test/configmap.template.yaml b/test/configmap.template.yaml deleted file mode 100644 index 437cb9e..0000000 --- a/test/configmap.template.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: apps/v1 -kind: ConfigMap -metadata: - name: {{name}} -spec: - selector: - matchLabels: - app: {{name}} - replicas: 1 - template: - metadata: - labels: - app: {{name}} - spec: - containers: - - name: nginx - image: 10.0.0.24:443/test:example.{{commit}} - ports: - - containerPort: 80 - imagePullSecrets: - - name: regcred