mirror of
https://github.com/danielgormly/drone-plugin-kube.git
synced 2026-06-04 18:23:48 +08:00
Updated readme, added examples, deployment updates added
This commit is contained in:
+4
-3
@@ -1,4 +1,5 @@
|
||||
vendor
|
||||
kubano
|
||||
# Development
|
||||
test*
|
||||
vendor
|
||||
build/kubano
|
||||
test
|
||||
test.sh
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# drone-kubano
|
||||
|
||||
A simple Drone plugin for managing Kubernetes deployments. Follows from `vallard/drone-kube` but with dependency management system, improved docs, examples and restructured code.
|
||||
A simple Drone plugin for managing Kubernetes deployments. Follows from `vallard/drone-kube` but with dependency management, up-to-date , improved docs updated to Drone 1.0.0, examples, restructured code and I will .
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -12,28 +12,24 @@ Add the following [build step](https://docs.drone.io/user-guide/pipeline/steps/)
|
||||
image: danielgormly/kubano
|
||||
settings:
|
||||
template: path/to/deployment.yaml # within repo
|
||||
ca: # BASE64 encoded string of the K8s CA cert
|
||||
Server: 10.0.0.24:6443 # 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
|
||||
ca: LS0tLS1... # BASE64 encoded string of the K8s CA cert
|
||||
server: https://10.0.0.20:6443 # K8s master node address
|
||||
token: ey... # Service account token to a service account that can manage deployments
|
||||
namespace: custom # [Optional] Custom namespace. (Defaults to `default`)
|
||||
custom: string # [Optional] Available to be referenced in template rendering as PLUGIN_CUSTOM
|
||||
master_alias: production # [Optional] Custom setting example. Available as PLUGIN_MASTER_ALIAS
|
||||
```
|
||||
|
||||
## deployment templates
|
||||
|
||||
Deployment config files are first interpreted by **aymerick/raymond** ([handlebarsjs](http://handlebarsjs.com/) equivalent). You can use all available raymond expressions, [DRONE_*](https://docs.drone.io/reference/environ/), PLUGIN_* environment variables. Use `{{VARIABLE}}` to add interpolated expressions e.g.
|
||||
Deployment config files are first interpreted by **aymerick/raymond** ([handlebarsjs](http://handlebarsjs.com/) equivalent). You can use all available raymond expressions, [DRONE_*](https://docs.drone.io/reference/environ/), PLUGIN_* environment variables. Use `{{VARIABLE}}` to add interpolated expressions. See `/example/deployment.template.yaml` for a complete example.
|
||||
|
||||
#### deployment.yaml partial example
|
||||
```yaml
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: 10.0.0.24:443/danielgormly:{{DRONE_BRANCH}}
|
||||
```
|
||||
#### Adding a service account to Kubernetes that can manage deployments
|
||||
See `/example/Role.yaml`, `/example/ServiceAccount.yaml`, `/example/RoleBinding.yaml`.
|
||||
|
||||
#### Development
|
||||
### Development
|
||||
- Kubernetes client not yet supported by dep, so we are using
|
||||
[`brew install glide`](https://github.com/Masterminds/glide).
|
||||
- Update dependencies with brew `glide update --strip-vendor`
|
||||
- [Creating a Drone plugin in Go](https://docs.drone.io/plugins/examples/golang/)
|
||||
- Testing with minikube (OSX: `brew cask install minikube`)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine
|
||||
ADD slack /bin/
|
||||
ADD kubano /bin/
|
||||
RUN apk -Uuv add ca-certificates
|
||||
ENTRYPOINT /bin/slack
|
||||
ENTRYPOINT /bin/kubano
|
||||
@@ -0,0 +1,12 @@
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
namespace: default
|
||||
name: update-deployments
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
@@ -0,0 +1,12 @@
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: drone-ci
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: drone-ci
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: update-deployments
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: drone-ci
|
||||
automountServiceAccountToken: true
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: 10.0.0.24:443/test:{{DRONE_BRANCH}}.{{DRONE_COMMIT_SHA}}
|
||||
image: 10.0.0.24:443/image:{{DRONE_COMMIT_SHA}}
|
||||
ports:
|
||||
- containerPort: 80
|
||||
imagePullSecrets:
|
||||
Generated
+1
-13
@@ -1,5 +1,5 @@
|
||||
hash: 3db3288a056b65e1736f52faf757d1a393b0af3d0ebbe5b63bdeab60b37e1da0
|
||||
updated: 2019-04-01T15:48:47.671231+11:00
|
||||
updated: 2019-04-02T13:06:49.449913+11:00
|
||||
imports:
|
||||
- name: github.com/aymerick/raymond
|
||||
version: b565731e1464263de0bda75f2e45d97b54b60110
|
||||
@@ -54,7 +54,6 @@ imports:
|
||||
version: 0ed95abb35c445290478a5348a7b38bb154135fd
|
||||
subpackages:
|
||||
- context
|
||||
- context/ctxhttp
|
||||
- http2
|
||||
- http2/hpack
|
||||
- idna
|
||||
@@ -120,7 +119,6 @@ imports:
|
||||
- core/v1
|
||||
- events/v1beta1
|
||||
- extensions/v1beta1
|
||||
- imagepolicy/v1alpha1
|
||||
- networking/v1
|
||||
- policy/v1beta1
|
||||
- rbac/v1
|
||||
@@ -143,7 +141,6 @@ imports:
|
||||
- pkg/api/meta
|
||||
- pkg/api/resource
|
||||
- pkg/apis/meta/fuzzer
|
||||
- pkg/apis/meta/internalversion
|
||||
- pkg/apis/meta/v1
|
||||
- pkg/apis/meta/v1/unstructured
|
||||
- pkg/apis/meta/v1beta1
|
||||
@@ -161,30 +158,21 @@ imports:
|
||||
- pkg/runtime/serializer/versioning
|
||||
- pkg/selection
|
||||
- pkg/types
|
||||
- pkg/util/cache
|
||||
- pkg/util/clock
|
||||
- pkg/util/diff
|
||||
- pkg/util/errors
|
||||
- pkg/util/framer
|
||||
- pkg/util/httpstream
|
||||
- pkg/util/httpstream/spdy
|
||||
- pkg/util/intstr
|
||||
- pkg/util/json
|
||||
- pkg/util/mergepatch
|
||||
- pkg/util/naming
|
||||
- pkg/util/net
|
||||
- pkg/util/remotecommand
|
||||
- pkg/util/runtime
|
||||
- pkg/util/sets
|
||||
- pkg/util/strategicpatch
|
||||
- pkg/util/validation
|
||||
- pkg/util/validation/field
|
||||
- pkg/util/wait
|
||||
- pkg/util/yaml
|
||||
- pkg/version
|
||||
- pkg/watch
|
||||
- third_party/forked/golang/json
|
||||
- third_party/forked/golang/netutil
|
||||
- third_party/forked/golang/reflect
|
||||
- name: k8s.io/client-go
|
||||
version: e64494209f554a6723674bd494d69445fb76a1d4
|
||||
|
||||
@@ -1,31 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
appv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/clientcmd/api"
|
||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||
)
|
||||
|
||||
// CreateKubeClient -- Creates KubeClient
|
||||
func (p Plugin) CreateKubeClient() (*kubernetes.Clientset, error) {
|
||||
// ca, err := base64.StdEncoding.DecodeString(p.KubeConfig.Ca)
|
||||
config := api.NewConfig()
|
||||
config.Clusters["default"] = &api.Cluster{
|
||||
config := clientcmdapi.NewConfig()
|
||||
clusterConfig := clientcmdapi.Cluster{
|
||||
Server: p.KubeConfig.Server,
|
||||
// CertificateAuthorityData: ca,
|
||||
InsecureSkipTLSVerify: true,
|
||||
}
|
||||
config.AuthInfos["default"] = &api.AuthInfo{
|
||||
if p.KubeConfig.InsecureSkipTLSVerify == true {
|
||||
clusterConfig.InsecureSkipTLSVerify = true
|
||||
log.Println("InsecureSkipTLSVerify flag set")
|
||||
} else {
|
||||
ca, err := base64.StdEncoding.DecodeString(p.KubeConfig.Ca)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
clusterConfig.CertificateAuthorityData = ca
|
||||
}
|
||||
config.Clusters["default"] = &clusterConfig
|
||||
config.AuthInfos["default"] = &clientcmdapi.AuthInfo{
|
||||
Token: p.KubeConfig.Token,
|
||||
}
|
||||
config.Contexts["default"] = &api.Context{
|
||||
Cluster: "default",
|
||||
AuthInfo: "default",
|
||||
config.Contexts["default"] = &clientcmdapi.Context{
|
||||
Cluster: "default",
|
||||
AuthInfo: "default",
|
||||
Namespace: p.KubeConfig.Namespace,
|
||||
}
|
||||
config.CurrentContext = "default"
|
||||
clientBuilder := clientcmd.NewNonInteractiveClientConfig(*config, "default", &clientcmd.ConfigOverrides{}, nil)
|
||||
@@ -39,14 +49,25 @@ func (p Plugin) CreateKubeClient() (*kubernetes.Clientset, error) {
|
||||
return kubernetes.NewForConfig(actualCfg)
|
||||
}
|
||||
|
||||
// WatchPodCounts -- Example function
|
||||
func WatchPodCounts(clientset *kubernetes.Clientset) {
|
||||
for {
|
||||
pods, err := clientset.Core().Pods("").List(v1.ListOptions{})
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
// ListDeployments -- List deployments in Kubernetes
|
||||
// func ListDeployments(clientset *kubernetes.Clientset, namespace string) {
|
||||
// deployments, err := clientset.AppsV1().Deployments(namespace).List(v1.ListOptions{})
|
||||
// if err != nil {
|
||||
// log.Fatal(err.Error())
|
||||
// }
|
||||
// fmt.Println(deployments.Items)
|
||||
// // return deployments.Items
|
||||
// }
|
||||
|
||||
@@ -9,10 +9,11 @@ func main() {
|
||||
plugin := Plugin{
|
||||
Template: os.Getenv("PLUGIN_TEMPLATE"),
|
||||
KubeConfig: KubeConfig{
|
||||
Token: os.Getenv("PLUGIN_TOKEN"),
|
||||
Server: os.Getenv("PLUGIN_SERVER"),
|
||||
Ca: os.Getenv("PLUGIN_CA"),
|
||||
Namespace: os.Getenv("PLUGIN_NAMESPACE"),
|
||||
Token: os.Getenv("PLUGIN_TOKEN"),
|
||||
Server: os.Getenv("PLUGIN_SERVER"),
|
||||
Ca: os.Getenv("PLUGIN_CA"),
|
||||
Namespace: os.Getenv("PLUGIN_NAMESPACE"),
|
||||
InsecureSkipTLSVerify: os.Getenv("PLUGIN_SKIP_TLS") == "false",
|
||||
},
|
||||
}
|
||||
err := plugin.Exec()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
@@ -13,10 +12,11 @@ import (
|
||||
type (
|
||||
// KubeConfig -- Contains connection settings for Kube client
|
||||
KubeConfig struct {
|
||||
Ca string
|
||||
Server string
|
||||
Token string
|
||||
Namespace string
|
||||
Ca string
|
||||
Server string
|
||||
Token string
|
||||
Namespace string
|
||||
InsecureSkipTLSVerify bool
|
||||
}
|
||||
// Plugin -- Contains config for plugin
|
||||
Plugin struct {
|
||||
@@ -59,17 +59,16 @@ func (p Plugin) Exec() error {
|
||||
return err
|
||||
}
|
||||
// Parse template
|
||||
result, err := raymond.Render(string(raw), ctx)
|
||||
depYaml, err := raymond.Render(string(raw), ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// connect to Kubernetes
|
||||
// Connect to Kubernetes
|
||||
clientset, err := p.CreateKubeClient()
|
||||
WatchPodCounts(clientset)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
fmt.Print(result)
|
||||
|
||||
deployment := CreateDeploymentObj(depYaml)
|
||||
UpdateDeployment(clientset, p.KubeConfig.Namespace, deployment)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user