Skip to content

Commit

Permalink
Add Cleanup Command
Browse files Browse the repository at this point in the history
  • Loading branch information
dtomcej committed May 7, 2020
1 parent e4df8eb commit 50641c4
Show file tree
Hide file tree
Showing 10 changed files with 367 additions and 20 deletions.
55 changes: 55 additions & 0 deletions cmd/cleanup/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cleanup

import (
"fmt"
"os"

"github.com/containous/maesh/cmd"
"github.com/containous/maesh/pkg/cleanup"
"github.com/containous/maesh/pkg/k8s"
"github.com/containous/traefik/v2/pkg/cli"
"github.com/sirupsen/logrus"
)

// NewCmd builds a new Cleanup command.
func NewCmd(cConfig *cmd.CleanupConfiguration, loaders []cli.ResourceLoader) *cli.Command {
return &cli.Command{
Name: "cleanup",
Description: `Removes Maesh shadow services from a Kubernetes cluster.`,
Configuration: cConfig,
Run: func(_ []string) error {
return cleanupCommand(cConfig)
},
Resources: loaders,
}
}

func cleanupCommand(cConfig *cmd.CleanupConfiguration) error {
log := logrus.New()

log.SetOutput(os.Stdout)

logLevel, err := logrus.ParseLevel(cConfig.LogLevel)
if err != nil {
return err
}

log.SetLevel(logLevel)

log.Debugln("Starting maesh cleanup...")
log.Debugf("Using masterURL: %q", cConfig.MasterURL)
log.Debugf("Using kubeconfig: %q", cConfig.KubeConfig)

clients, err := k8s.NewClient(log, cConfig.MasterURL, cConfig.KubeConfig)
if err != nil {
return fmt.Errorf("error building clients: %w", err)
}

c := cleanup.NewCleanup(log, clients, cConfig.Namespace)

if err := c.CleanShadowServices(); err != nil {
return fmt.Errorf("error encountered during cluster cleanup: %w", err)
}

return nil
}
17 changes: 17 additions & 0 deletions cmd/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,20 @@ func NewProxyConfiguration() *ProxyConfiguration {
},
}
}

// CleanupConfiguration holds the configuration for the cleanup command.
type CleanupConfiguration struct {
KubeConfig string `description:"Path to a kubeconfig. Only required if out-of-cluster." export:"true"`
MasterURL string `description:"The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster." export:"true"`
Namespace string `description:"The namespace that maesh is installed in." export:"true"`
LogLevel string `description:"The log level." export:"true"`
}

// NewCleanupConfiguration creates CleanupConfiguration.
func NewCleanupConfiguration() *CleanupConfiguration {
return &CleanupConfiguration{
KubeConfig: os.Getenv("KUBECONFIG"),
Namespace: "maesh",
LogLevel: "error",
}
}
7 changes: 7 additions & 0 deletions cmd/maesh/maesh.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/containous/maesh/cmd"
"github.com/containous/maesh/cmd/cleanup"
"github.com/containous/maesh/cmd/prepare"
"github.com/containous/maesh/cmd/proxy"
"github.com/containous/maesh/cmd/version"
Expand Down Expand Up @@ -37,6 +38,12 @@ func main() {
os.Exit(1)
}

cConfig := cmd.NewCleanupConfiguration()
if err := cmdMaesh.AddCommand(cleanup.NewCmd(cConfig, loaders)); err != nil {
stdlog.Println(err)
os.Exit(1)
}

if err := cmdMaesh.AddCommand(proxy.NewCmd(loaders)); err != nil {
stdlog.Println(err)
os.Exit(1)
Expand Down
14 changes: 2 additions & 12 deletions helm/chart/maesh/templates/controller/controller-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ spec:
{{- if .Values.acl }}
- "--acl"
{{- end }}
- "--namespace=$(POD_NAMESPACE)"
- "--namespace={{ .Release.Namespace }}"
{{- if .Values.controller.ignoreNamespaces }}
- {{ include "maesh.controllerIgnoreNamespaces" . | quote }}
{{- end }}
Expand All @@ -86,11 +86,6 @@ spec:
{{- if .Values.limits.udp }}
- "--limitUDPPort={{ .Values.limits.udp }}"
{{- end }}
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
resources:
requests:
memory: {{ .Values.controller.resources.request.mem }}
Expand Down Expand Up @@ -121,12 +116,7 @@ spec:
{{- end }}
- "--clusterdomain"
- {{ default "cluster.local" .Values.clusterDomain | quote }}
- "--namespace=$(POD_NAMESPACE)"
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- "--namespace={{ .Release.Namespace }}"
securityContext:
capabilities:
drop:
Expand Down
113 changes: 113 additions & 0 deletions helm/chart/maesh/templates/controller/hooks/cleanup-hook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: maesh-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name | quote}}
chart: {{ include "maesh.chartLabel" . | quote}}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
annotations:
"helm.sh/hook": "post-delete"
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation"

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: maesh-cleanup-role
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name | quote}}
chart: {{ include "maesh.chartLabel" . | quote}}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
annotations:
"helm.sh/hook": "post-delete"
"helm.sh/hook-weight": "10"
"helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation"
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- delete

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: maesh-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name | quote}}
chart: {{ include "maesh.chartLabel" . | quote}}
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
annotations:
"helm.sh/hook": "post-delete"
"helm.sh/hook-weight": "15"
"helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: maesh-cleanup-role
subjects:
- kind: ServiceAccount
name: maesh-cleanup
namespace: {{ .Release.Namespace }}

---
apiVersion: batch/v1
kind: Job
metadata:
name: maesh-cleanup
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name | quote}}
chart: {{ include "maesh.chartLabel" . | quote }}
release: {{ .Release.Name | quote}}
heritage: {{ .Release.Service | quote}}
annotations:
"helm.sh/hook": "post-delete"
"helm.sh/hook-weight": "20"
"helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation"
spec:
backoffLimit: 0
activeDeadlineSeconds: 30
template:
metadata:
labels:
app: {{ .Release.Name | quote}}
component: cleanup
release: {{ .Release.Name | quote}}
spec:
serviceAccountName: maesh-cleanup
restartPolicy: Never
{{- if .Values.image.pullSecret }}
imagePullSecrets:
- name: {{ .Values.image.pullSecret }}
{{- end }}
containers:
- name: maesh-cleanup
image: {{ include "maesh.image" . | quote }}
imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }}
args:
- "cleanup"
{{- if .Values.controller.logLevel }}
- "--logLevel={{ .Values.controller.logLevel }}"
{{- end }}
- "--namespace={{ .Release.Namespace }}"
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
41 changes: 41 additions & 0 deletions pkg/cleanup/cleanup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cleanup

import (
"github.com/containous/maesh/pkg/k8s"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Cleanup holds the clients for the various resource controllers.
type Cleanup struct {
client k8s.Client
log logrus.FieldLogger
namespace string
}

// NewCleanup returns an initialized cleanup object.
func NewCleanup(log logrus.FieldLogger, client k8s.Client, namespace string) *Cleanup {
return &Cleanup{
client: client,
log: log,
namespace: namespace,
}
}

// CleanShadowServices deletes all shadow services from the cluster.
func (c *Cleanup) CleanShadowServices() error {
serviceList, err := c.client.GetKubernetesClient().CoreV1().Services(c.namespace).List(metav1.ListOptions{
LabelSelector: "app=maesh,type=shadow",
})
if err != nil {
return err
}

for _, s := range serviceList.Items {
if err := c.client.GetKubernetesClient().CoreV1().Services(s.Namespace).Delete(s.Name, &metav1.DeleteOptions{}); err != nil {
return err
}
}

return nil
}
53 changes: 53 additions & 0 deletions pkg/cleanup/cleanup_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cleanup

import (
"context"
"os"
"testing"

"github.com/containous/maesh/pkg/k8s"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestCleanup_New(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

clientMock := k8s.NewClientMock(ctx.Done(), "mock.yaml", false)
log := logrus.New()

log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)

cln := NewCleanup(log, clientMock, metav1.NamespaceDefault)
assert.NotNil(t, cln)
}

func TestCleanup_CleanShadowServices(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

clientMock := k8s.NewClientMock(ctx.Done(), "mock.yaml", false)
log := logrus.New()

log.SetOutput(os.Stdout)
log.SetLevel(logrus.DebugLevel)

cln := NewCleanup(log, clientMock, "maesh")
assert.NotNil(t, cln)

err := cln.CleanShadowServices()
assert.NoError(t, err)

sl, err := clientMock.GetKubernetesClient().CoreV1().Services(metav1.NamespaceAll).List(metav1.ListOptions{
LabelSelector: "app=maesh,type=shadow",
})
assert.NoError(t, err)
assert.Len(t, sl.Items, 0)

srv, err := clientMock.GetKubernetesClient().CoreV1().Services(metav1.NamespaceAll).List(metav1.ListOptions{})
assert.NoError(t, err)
assert.Len(t, srv.Items, 2)
}

0 comments on commit 50641c4

Please sign in to comment.