diff --git a/.gitignore b/.gitignore index 5657f6e..aff4fa1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -vendor \ No newline at end of file +vendor +kubano diff --git a/README.md b/README.md index 3f14560..13327b4 100644 --- a/README.md +++ b/README.md @@ -8,25 +8,28 @@ Add the following [build step](https://docs.drone.io/user-guide/pipeline/steps/) #### drone.yaml partial example ```yml -- name: +- name: Deploy app image: danielgormly/kubano settings: - template: deployment.yaml + template: path/to/deployment.yaml # within repo + ca: # BASE64 encoded string of the K8s CA cert + Endpoint: 10.0.0.24 # K8s master node address + Token: # Service account token to a service account that can manage deployments + Namespace: custom # Custom namespace. (Optional, defaults to `default`) + custom: string # Available to be referenced in template rendering as PLUGIN_CUSTOM + master_alias: production # Custom setting example. Available as PLUGIN_MASTER_ALIAS ``` -#### Settings -- **template**: path to deployment file from repo root e.g. `deploy/deployment.yaml`, etc - ## deployment templates -Deployment config files are first interpreted by raymond ([handlebarsjs](http://handlebarsjs.com/) equivalent). Use `{{variable}}` to add interpolated expressions e.g. +Deployment config files are first interpreted by raymond ([handlebarsjs](http://handlebarsjs.com/) equivalent). You can use all available Use `{{VARIABLE}}` to add interpolated expressions e.g. #### deployment.yaml partial example ```yaml spec: containers: - name: nginx - image: 10.0.0.24:443/danielgormly:{{git-repo}}.{{git-branch}} + image: 10.0.0.24:443/danielgormly:{{DRONE_BRANCH}} ``` #### Development diff --git a/kubano b/kubano deleted file mode 100755 index a41184e..0000000 Binary files a/kubano and /dev/null differ diff --git a/kube.go b/kube.go new file mode 100644 index 0000000..5172248 --- /dev/null +++ b/kube.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/base64" + "log" + + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/clientcmd" +) + +// CreateKubeClient -- Creates KubeClient +func (p Plugin) CreateKubeClient() (*kubernetes.Clientset, error) { + ca, err := base64.StdEncoding.DecodeString(p.KubeConfig.Ca) + config := clientcmdapi.NewConfig() + config.Clusters["drone"] = &clientcmdapi.Cluster{ + Server: p.Config.Server, + CertificateAuthorityData: ca, + } + config.AuthInfos["drone"] = &clientcmdapi.AuthInfo{ + Token: p.Config.Token, + } + config.Contexts["drone"] = &clientcmdapi.Context{ + Cluster: "drone", + AuthInfo: "drone", + } + //config.Clusters["drone"].CertificateAuthorityData = ca + config.CurrentContext = "drone" + clientBuilder := clientcmd.NewNonInteractiveClientConfig(*config, "drone", &clientcmd.ConfigOverrides{}, nil) + actualCfg, err := clientBuilder.ClientConfig() + if err != nil { + log.Fatal(err) + } + return kubernetes.NewForConfig(actualCfg) +} diff --git a/plugin.go b/plugin.go index c3dd042..9c7b927 100644 --- a/plugin.go +++ b/plugin.go @@ -11,19 +11,21 @@ import ( ) type ( + // KubeConfig -- Contains connection settings for Kube client KubeConfig struct { Ca string Endpoint string Token string Namespace string - Template string } + // Plugin -- Contains config for plugin Plugin struct { Template string KubeConfig KubeConfig } ) +// Exec -- Runs plugin func (p Plugin) Exec() error { if p.KubeConfig.Endpoint == "" { log.Fatal("PLUGIN_ENDPOINT is not defined") @@ -40,20 +42,7 @@ func (p Plugin) Exec() error { if p.Template == "" { log.Fatal("PLUGIN_TEMPLATE, or template must be defined") } - // // connect to Kubernetes - // clientset, err := p.createKubeClient() - // if err != nil { - // log.Fatal(err.Error()) - // } - - raw, err := ioutil.ReadFile(p.Template) - if err != nil { - log.Print("Error reading template file:") - return err - } - - source := string(raw) - + // Make map of environment variables set by Drone ctx := make(map[string]string) droneEnv := os.Environ() for _, value := range droneEnv { @@ -63,16 +52,21 @@ func (p Plugin) Exec() error { ctx[matches[1]] = matches[2] } } - - // parse template - tpl, err := raymond.Parse(source) + // Grab template from filesystem + raw, err := ioutil.ReadFile(p.Template) + if err != nil { + log.Print("Error reading template file:") + return err + } + // Parse template + result, err := raymond.Render(string(raw), ctx) if err != nil { panic(err) } - - result, err := tpl.Exec(ctx) + // connect to Kubernetes + clientset, err := p.createKubeClient() if err != nil { - panic(err) + log.Fatal(err.Error()) } fmt.Print(result) diff --git a/test.sh b/test.sh index 9ffc2e8..5185c70 100755 --- a/test.sh +++ b/test.sh @@ -6,7 +6,7 @@ export PLUGIN_CA=test export PLUGIN_TOKEN=test export PLUGIN_ENDPOINT=test export PLUGIN_NAMESPACE=test -export PLUGIN_TEMPLATE=test/deployment.yaml +export PLUGIN_TEMPLATE=test/deployment.template.yaml export PLUGIN_NAME=api go build diff --git a/test/deployment.yaml b/test/deployment.template.yaml similarity index 100% rename from test/deployment.yaml rename to test/deployment.template.yaml