diff --git a/README.md b/README.md index 61a47587..66c1032a 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,40 @@ func main() { } ``` +## In Cluster Usage + +To use this tool inside the cluster running as a CronJob and sending the results to a Slack Webhook as raw text(has characters limits of 4000) or to a Slack channel by uploading a file(recommended), you can use the following commands: + +```sh +# Send to a Slack webhook as raw text +helm upgrade -i kor \ + --namespace kor \ + --create-namespace \ + --set cronJob.slackWebhookUrl= \ + ./charts/kor +``` + +```sh +# Send to a Slack channel by uploading a file +helm upgrade -i kor \ + --namespace kor \ + --create-namespace \ + --set cronJob.slackChannel= \ + --set cronJob.slackToken= \ + ./charts/kor +``` + +It's set to run every Monday at 1 a.m. by default. You can change the schedule by setting the `cronJob.schedule` value. + +```sh +helm upgrade -i kor \ + --namespace kor \ + --create-namespace \ + --set cronJob.slackChannel= \ + --set cronJob.slackToken= \ + --set cronJob.schedule="0 1 * * 1" \ + ./charts/kor +``` ## Contributing diff --git a/charts/kor/.helmignore b/charts/kor/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/kor/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/kor/Chart.yaml b/charts/kor/Chart.yaml new file mode 100644 index 00000000..60eed70d --- /dev/null +++ b/charts/kor/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: kor +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.2.2" diff --git a/charts/kor/README.md b/charts/kor/README.md new file mode 100644 index 00000000..6962e68c --- /dev/null +++ b/charts/kor/README.md @@ -0,0 +1,30 @@ +# kor + +![Version: 0.1.0](https://img.shields.io/badge/Version-0.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.2.2](https://img.shields.io/badge/AppVersion-0.2.2-informational?style=flat-square) + +A Helm chart to deploy Kor as into a Kubernetes cluster. + +## Values + +| Key | Type | Default | Description | +| ---------------------------------- | ------ | ------------------- | ----------- | +| cronJob.enabled | bool | `true` | | +| cronJob.failedJobsHistoryLimit | int | `2` | | +| cronJob.image.repository | string | `"yonahdissen/kor"` | | +| cronJob.image.tag | string | `"latest"` | | +| cronJob.command | string | `"kor all"` | | +| cronJob.name | string | `"kor"` | | +| cronJob.restartPolicy | string | `"OnFailure"` | | +| cronJob.schedule | string | `"0 1 * * 1"` | | +| cronJob.slackAuthToken | string | `""` | | +| cronJob.slackChannel | string | `""` | | +| cronJob.slackWebhookUrl | string | `""` | | +| cronJob.successfulJobsHistoryLimit | int | `3` | | +| namespace | string | `"kor"` | | +| serviceAccount.annotations | object | `{}` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | + +--- + +Autogenerated from chart metadata using [helm-docs v1.8.1](https://github.com/norwoodj/helm-docs/releases/v1.8.1) diff --git a/charts/kor/templates/_helpers.tpl b/charts/kor/templates/_helpers.tpl new file mode 100644 index 00000000..5106eec9 --- /dev/null +++ b/charts/kor/templates/_helpers.tpl @@ -0,0 +1,73 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "kor.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kor.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kor.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kor.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kor.labels" -}} +helm.sh/chart: {{ include "kor.chart" . }} +{{ include "kor.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kor.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kor.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kor.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "kor.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/kor/templates/cronjob.yaml b/charts/kor/templates/cronjob.yaml new file mode 100644 index 00000000..0a0100ef --- /dev/null +++ b/charts/kor/templates/cronjob.yaml @@ -0,0 +1,39 @@ +{{- if .Values.cronJob.enabled -}} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ .Release.Name }} + labels: + app: {{ .Release.Name }} +spec: + schedule: {{ .Values.cronJob.schedule }} + jobTemplate: + spec: + template: + metadata: + name: {{ .Release.Name }} + spec: + serviceAccountName: {{ include "kor.serviceAccountName" . }} + containers: + - name: {{ .Release.Name }}-container + image: {{ .Values.cronJob.image.repository }}:{{ .Values.cronJob.image.tag }} + command: ["/bin/sh", "-c"] + {{- if .Values.cronJob.slackWebhookUrl }} + args: ["{{ .Values.cronJob.command }} --slack-webhook-url {{ .Values.cronJob.slackWebhookUrl }}"] + {{- else if and .Values.cronJob.slackChannel .Values.cronJob.slackAuthToken }} + args: ["{{ .Values.cronJob.command }} --slack-channel {{ .Values.cronJob.slackChannel }} --slack-auth-token {{ .Values.cronJob.slackAuthToken }}"] + {{- else }} + args: ["{{ .Values.cronJob.command }}"] + {{- end }} + {{- if .Values.cronJob.env }} + env: + {{- toYaml .Values.cronJob.env | nindent 12 }} + {{- end }} + restartPolicy: {{ .Values.cronJob.restartPolicy }} + {{- if .Values.cronJob.successfulJobsHistoryLimit }} + successfulJobsHistoryLimit: {{ .Values.cronJob.successfulJobsHistoryLimit }} + {{- end }} + {{- if .Values.cronJob.failedJobsHistoryLimit }} + failedJobsHistoryLimit: {{ .Values.cronJob.failedJobsHistoryLimit }} + {{- end }} +{{- end }} diff --git a/charts/kor/templates/role.yaml b/charts/kor/templates/role.yaml new file mode 100644 index 00000000..6883e5bb --- /dev/null +++ b/charts/kor/templates/role.yaml @@ -0,0 +1,58 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "kor.serviceAccountName" . }}-read-resources-role +rules: + - apiGroups: ["*"] + resources: + - pods + - configmaps + - namespaces + - secrets + - services + - serviceaccounts + - deployments + - statefulsets + - roles + - rolebindings + - clusterroles + - clusterrolebindings + - horizontalpodautoscalers + - persistentvolumeclaims + - ingresses + - poddisruptionbudgets + - endpoints + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "kor.serviceAccountName" . }}-read-resources-clusterrole +rules: + - apiGroups: ["*"] + resources: + - pods + - configmaps + - namespaces + - secrets + - services + - serviceaccounts + - deployments + - statefulsets + - roles + - rolebindings + - clusterroles + - clusterrolebindings + - horizontalpodautoscalers + - persistentvolumeclaims + - ingresses + - poddisruptionbudgets + - endpoints + verbs: + - get + - list + - watch diff --git a/charts/kor/templates/rolebinding.yaml b/charts/kor/templates/rolebinding.yaml new file mode 100644 index 00000000..d39855ba --- /dev/null +++ b/charts/kor/templates/rolebinding.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "kor.serviceAccountName" . }}-read-resources-role-binding +subjects: + - kind: ServiceAccount + name: {{ include "kor.serviceAccountName" . }} +roleRef: + kind: Role + name: {{ include "kor.serviceAccountName" . }}-read-resources-role + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "kor.serviceAccountName" . }}-read-resources-clusterrolebinding +subjects: + - kind: ServiceAccount + name: {{ include "kor.serviceAccountName" . }} + namespace: {{ include "kor.namespace" . }} +roleRef: + kind: ClusterRole + name: {{ include "kor.serviceAccountName" . }}-read-resources-clusterrole + apiGroup: rbac.authorization.k8s.io diff --git a/charts/kor/templates/serviceaccount.yaml b/charts/kor/templates/serviceaccount.yaml new file mode 100644 index 00000000..d629a05b --- /dev/null +++ b/charts/kor/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "kor.serviceAccountName" . }} + labels: + {{- include "kor.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/kor/values.yaml b/charts/kor/values.yaml new file mode 100644 index 00000000..d3077b22 --- /dev/null +++ b/charts/kor/values.yaml @@ -0,0 +1,24 @@ +cronJob: + enabled: true + name: kor + schedule: "0 1 * * 1" + image: + repository: yonahdissen/kor + tag: latest + # e.g. kor configmap --include-namespace default,other-ns + command: kor all + slackWebhookUrl: "" + slackChannel: "" + slackAuthToken: "" + restartPolicy: OnFailure + successfulJobsHistoryLimit: 3 + failedJobsHistoryLimit: 2 + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: ""