Skip to content

Commit

Permalink
Merge pull request #2 from stakater/rollback-upgrade-deployment
Browse files Browse the repository at this point in the history
[STK-322] Rollback upgrade deployment
  • Loading branch information
waseem-h authored Jul 26, 2018
2 parents 067f09b + dd2b3de commit 0b0679b
Show file tree
Hide file tree
Showing 23 changed files with 2,087 additions and 238 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ release
out/
_gopath/
.DS_Store
.vscode
vendor
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.1
0.0.1
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/groovy
@Library('github.com/stakater/fabric8-pipeline-library@v2.4.0')
@Library('github.com/stakater/fabric8-pipeline-library@v2.5.1')

def dummy

Expand Down
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

## WHY NAME RELOADER

In english language, Reloader is a thing/tool that can reload certain stuff. So refereig to that meaning relaoder can reload
In english language, Reloader is a thing/tool that can reload certain stuff. So referring to that meaning reloader can reload

## Problem

We would like to watch if some change happens in `ConfigMap` and `Secret` objects and then perform certain upgrade on relavent `Deployment`, `Deamonset` and `Statefulset`
We would like to watch if some change happens in `ConfigMap` and `Secret` objects and then perform certain upgrade on relevant `Deployment`, `Deamonset` and `Statefulset`

## Solution

Expand All @@ -21,10 +21,20 @@ For a `Deployment` called `foo` have a `ConfigMap` called `foo`. Then add this a
```yaml
metadata:
annotations:
reloader.stakater.com/update-on-change: "foo"
configmap.reloader.stakater.com/reload: "foo"
```
Then, providing `Reloader` is running, whenever you edit the `ConfigMap` called `foo` the Reloader will update the `Deployment` by adding the environment variable:
OR
For a `Deployment` called `foo` have a `Secret` called `foo`. Then add this annotation to your `Deployment`

```yaml
metadata:
annotations:
secret.reloader.stakater.com/reload: "foo"
```

Then, providing `Reloader` is running, whenever you edit the `ConfigMap` or `Secret` called `foo` the Reloader will update the `Deployment` by adding the environment variable:

```
STAKATER_FOO_REVISION=${reloaderRevision}
Expand Down
13 changes: 13 additions & 0 deletions deployments/kubernetes/chart/reloader/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ rules:
- list
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
Expand Down
13 changes: 13 additions & 0 deletions deployments/kubernetes/manifests/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ rules:
- list
- get
- watch
- apiGroups:
- ""
- "extensions"
- "apps"
resources:
- deployments
- daemonsets
- statefulsets
verbs:
- list
- get
- update
- patch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
Expand Down
32 changes: 28 additions & 4 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions internal/pkg/callbacks/rolling_upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package callbacks

import (
"github.com/sirupsen/logrus"
"github.com/stakater/Reloader/internal/pkg/util"
apps_v1beta1 "k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

//ItemsFunc is a generic function to return a specific resource array in given namespace
type ItemsFunc func(kubernetes.Interface, string) []interface{}

//ContainersFunc is a generic func to return containers
type ContainersFunc func(interface{}) []v1.Container

//UpdateFunc performs the resource update
type UpdateFunc func(kubernetes.Interface, string, interface{}) error

//RollingUpgradeFuncs contains generic functions to perform rolling upgrade
type RollingUpgradeFuncs struct {
ItemsFunc ItemsFunc
ContainersFunc ContainersFunc
UpdateFunc UpdateFunc
ResourceType string
}

// GetDeploymentItems returns the deployments in given namespace
func GetDeploymentItems(client kubernetes.Interface, namespace string) []interface{} {
deployments, err := client.ExtensionsV1beta1().Deployments(namespace).List(meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list deployments %v", err)
}
return util.InterfaceSlice(deployments.Items)
}

// GetDaemonSetItems returns the daemonSet in given namespace
func GetDaemonSetItems(client kubernetes.Interface, namespace string) []interface{} {
daemonSets, err := client.ExtensionsV1beta1().DaemonSets(namespace).List(meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list daemonSets %v", err)
}
return util.InterfaceSlice(daemonSets.Items)
}

// GetStatefulSetItems returns the statefulSet in given namespace
func GetStatefulSetItems(client kubernetes.Interface, namespace string) []interface{} {
statefulSets, err := client.AppsV1beta1().StatefulSets(namespace).List(meta_v1.ListOptions{})
if err != nil {
logrus.Errorf("Failed to list statefulSets %v", err)
}
return util.InterfaceSlice(statefulSets.Items)
}

// GetDeploymentContainers returns the containers of given deployment
func GetDeploymentContainers(item interface{}) []v1.Container {
return item.(v1beta1.Deployment).Spec.Template.Spec.Containers
}

// GetDaemonSetContainers returns the containers of given daemonset
func GetDaemonSetContainers(item interface{}) []v1.Container {
return item.(v1beta1.DaemonSet).Spec.Template.Spec.Containers
}

// GetStatefulsetContainers returns the containers of given statefulSet
func GetStatefulsetContainers(item interface{}) []v1.Container {
return item.(apps_v1beta1.StatefulSet).Spec.Template.Spec.Containers
}

// UpdateDeployment performs rolling upgrade on deployment
func UpdateDeployment(client kubernetes.Interface, namespace string, resource interface{}) error {
deployment := resource.(v1beta1.Deployment)
_, err := client.ExtensionsV1beta1().Deployments(namespace).Update(&deployment)
return err
}

// UpdateDaemonSet performs rolling upgrade on daemonSet
func UpdateDaemonSet(client kubernetes.Interface, namespace string, resource interface{}) error {
daemonSet := resource.(v1beta1.DaemonSet)
_, err := client.ExtensionsV1beta1().DaemonSets(namespace).Update(&daemonSet)
return err
}

// UpdateStatefulset performs rolling upgrade on statefulSet
func UpdateStatefulset(client kubernetes.Interface, namespace string, resource interface{}) error {
statefulSet := resource.(apps_v1beta1.StatefulSet)
_, err := client.AppsV1beta1().StatefulSets(namespace).Update(&statefulSet)
return err
}
8 changes: 8 additions & 0 deletions internal/pkg/constants/annotations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package constants

const (
// ConfigmapUpdateOnChangeAnnotation is an annotation to detect changes in configmaps
ConfigmapUpdateOnChangeAnnotation = "configmap.reloader.stakater.com/reload"
// SecretUpdateOnChangeAnnotation is an annotation to detect changes in secrets
SecretUpdateOnChangeAnnotation = "secret.reloader.stakater.com/reload"
)
10 changes: 10 additions & 0 deletions internal/pkg/constants/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package constants

const (
// ConfigmapEnvVarPostfix is a postfix for configmap envVar
ConfigmapEnvVarPostfix = "_CONFIGMAP"
// SecretEnvVarPostfix is a postfix for secret envVar
SecretEnvVarPostfix = "_SECRET"
// EnvVarPrefix is a Prefix for environment variable
EnvVarPrefix = "STAKATER_"
)
8 changes: 3 additions & 5 deletions internal/pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/stakater/Reloader/pkg/kube"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/runtime"
errorHandler "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
Expand Down Expand Up @@ -65,15 +64,14 @@ func (c *Controller) Update(old interface{}, new interface{}) {

// Delete function to add an object to the queue in case of deleting a resource
func (c *Controller) Delete(old interface{}) {
// TODO Added this function for future usecase
logrus.Infof("Deleted resource has been detected but no further implementation found to take action")
logrus.Infof("Resource deletion has been detected but no further implementation found to take action")
}

//Run function for controller which handles the queue
func (c *Controller) Run(threadiness int, stopCh chan struct{}) {

logrus.Infof("Starting Controller")
defer errorHandler.HandleCrash()
defer runtime.HandleCrash()

// Let the workers stop when we are done
defer c.queue.ShutDown()
Expand All @@ -82,7 +80,7 @@ func (c *Controller) Run(threadiness int, stopCh chan struct{}) {

// Wait for all involved caches to be synced, before processing items from the queue is started
if !cache.WaitForCacheSync(stopCh, c.informer.HasSynced) {
errorHandler.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
return
}

Expand Down
Loading

0 comments on commit 0b0679b

Please sign in to comment.