diff --git a/charts/releasemanager/.helmignore b/charts/releasemanager/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/charts/releasemanager/.helmignore @@ -0,0 +1,21 @@ +# 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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/charts/releasemanager/Chart.yaml b/charts/releasemanager/Chart.yaml new file mode 100644 index 0000000..19d46ef --- /dev/null +++ b/charts/releasemanager/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: Release Manager provides a long-running application that will periodically poll for releases in your cluster. +name: releasemanager +version: 0.3.0 +maintainers: +- name: LogicMonitor + email: techops@logicmonitor.com +icon: https://logicmonitor.github.io/helm-charts/lm_logo.png diff --git a/charts/releasemanager/README.md b/charts/releasemanager/README.md new file mode 100644 index 0000000..f69d537 --- /dev/null +++ b/charts/releasemanager/README.md @@ -0,0 +1,39 @@ +# Release Manager + +This Helm chart installs [Release Manager](https://github.com/logicmonitor/k8s-release-manager). + +```bash +$ helm upgrade + --install \ + --debug \ + --wait \ + --set debug=$DEBUG \ + --set verbose=$VERBOSE \ + --set daemon.pollingInterval=$POLLING_INTERVAL \ + --set backend.type=s3 \ + --set backend.path=$BACKEND_PATH \ + --set s3.bucket=$S3_BUCKET \ + --set s3.region=$S3_REGION \ + --set s3.accessKeyID=$AWS_ACCESS_KEY_ID \ + --set s3.secretAccessKey=$AWS_SECRET_ACCESS_KEY \ + --set s3.sessionToken=$AWS_SESSION_TOKEN \ + releasemanager logicmonitor/releasemanager +``` + +## Values: +- **debug:** Enable debugging output +- **dryRun:** Print planned actions without making any modifications +- **verbose:** Enable verbose output +- **backend.path:** Required. Use this path within the backend for state storage +- **backend.type:** Required: The backend type to use. Valid options are: s3 +- **daemon.pollingInterval:** Specify, in seconds, how frequently the daemon should export the current state (default 30) + +### ingress configuration values +- **ingress.hosts:** A list of hosts to associate with the ingress object. If this is empty, ot ingress will be created + +### s3 backend configuration values +- **s3.bucket:** Required for s3 backend. Use this S3 bucket for backend storage +- **s3.region:** The backend S3 bucket's region +- **s3.accessKeyID:** An AWS Access Key ID for accessing the S3 bucket, otherwise use the default AWS credential provider chain +- **s3.secretAccessKey:** An AWS Secret Access Key for accessing the S3 bucket, otherwise use the default AWS credential provider chain +- **s3.sessionToken:** An AWS STS Session Token for accessing the S3 bucket, otherwise use the default AWS credential provider chain diff --git a/charts/releasemanager/ci/base-sanity.yaml b/charts/releasemanager/ci/base-sanity.yaml new file mode 100644 index 0000000..cdb1f32 --- /dev/null +++ b/charts/releasemanager/ci/base-sanity.yaml @@ -0,0 +1,2 @@ +backend: + path: "/tmp/dummy" \ No newline at end of file diff --git a/charts/releasemanager/templates/NOTES.txt b/charts/releasemanager/templates/NOTES.txt new file mode 100644 index 0000000..082ef69 --- /dev/null +++ b/charts/releasemanager/templates/NOTES.txt @@ -0,0 +1,40 @@ +Release Manager has been installed with the release name '{{ tpl (.Release.Name) .}}' + + This cluster's release state is being stored in +{{- if and .Values.s3 (eq .Values.backend.type "s3") }} + s3://{{ .Values.s3.bucket }}/{{ .Values.backend.path }} +{{- end }} + +{{- if .Values.ingress }} +{{- if .Values.ingress.hosts }} +You can view Release Manager metrics and stored releases by querying: +{{- range $host := .Values.ingress.hosts }} + {{ $host }}/debug/vars + {{ $host }}/releases +{{- end }} +{{- end }} +{{- end }} + +You can import the stored state into another cluster by executing +releasemanager import \ + --path {{ .Values.backend.path }} \ +{{ .Values.backend.type }} \ +{{- if and .Values.s3 (eq .Values.backend.type "s3") }} + --bucket {{ .Values.s3.bucket }} \ +{{- if .Values.s3.region }} + --region {{ .Values.s3.region }} \ +{{- end }} +{{- if .Values.s3.accessKeyID }} + --accessKeyID {{ .Values.s3.accessKeyID }} \ +{{- end }} +{{- if .Values.s3.secretAccessKey }} + --secretAccessKey {{ .Values.s3.secretAccessKey }} \ +{{- end }} +{{- if .Values.s3.sessionToken }} + --sessionToken {{ .Values.s3.sessionToken }} \ +{{- end }} +{{- end }} {{/* s3 backend type if */}} + --new-path "new-cluster" + +IMPORTANT!! Be sure to update --new-path to reflect the backend storage \ +path you want to use for the target cluster's new Release Manager diff --git a/charts/releasemanager/templates/_helpers.tpl b/charts/releasemanager/templates/_helpers.tpl new file mode 100644 index 0000000..580c25c --- /dev/null +++ b/charts/releasemanager/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "releasemanager.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 "releasemanager.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 -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "releasemanager.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/releasemanager/templates/configmap.yaml b/charts/releasemanager/templates/configmap.yaml new file mode 100644 index 0000000..7077089 --- /dev/null +++ b/charts/releasemanager/templates/configmap.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: releasemanager +data: + config.yaml: | + debug: {{ .Values.debug }} + dryRun: {{ .Values.dryRun }} + path: {{ required "A valid .Values.backend.path entry required" .Values.backend.path }} + pollingInterval: {{ .Values.daemon.pollingInterval }} + verbose: {{ .Values.verbose }} +{{- if and .Values.s3 (eq .Values.backend.type "s3") }} + region: {{ required "A valid .Values.s3.region entry required for s3 backend type" .Values.s3.region }} + bucket: {{ required "A valid .Values.s3.bucket entry required for s3 backend type" .Values.s3.bucket }} +{{- end }} diff --git a/charts/releasemanager/templates/deployment.yaml b/charts/releasemanager/templates/deployment.yaml new file mode 100644 index 0000000..d9753d8 --- /dev/null +++ b/charts/releasemanager/templates/deployment.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "releasemanager.fullname" . }} + labels: + app: {{ template "releasemanager.name" . }} + chart: {{ template "releasemanager.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "releasemanager.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "releasemanager.name" . }} + release: {{ .Release.Name }} + spec: + serviceAccountName: releasemanager + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8080 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 30 + timeoutSeconds: 10 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 30 + timeoutSeconds: 15 + args: + - export + - --config + - /etc/releasemanager/config.yaml + - --daemon + - {{ required "A valid .Values.backend.type entry required" .Values.backend.type }} + - --release-name + - {{ tpl (.Release.Name) .}} + env: +{{- if and .Values.s3 (eq .Values.backend.type "s3") }} +{{- if and .Values.s3 .Values.s3.accessKeyID }} + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: releasemanager + key: accessKeyID +{{- end }} +{{- if and .Values.s3 .Values.s3.secretAccessKey }} + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: releasemanager + key: secretAccessKey +{{- end }} +{{- if and .Values.s3 .Values.s3.sessionToken }} + - name: AWS_SESSION_TOKEN + valueFrom: + secretKeyRef: + name: releasemanager + key: sessionToken +{{- end }} +{{- end }} + volumeMounts: + - name: etc-releasemanager + mountPath: "/etc/releasemanager" + readOnly: true + volumes: + - name: etc-releasemanager + projected: + sources: + - configMap: + name: releasemanager + items: + - key: config.yaml + path: config.yaml diff --git a/charts/releasemanager/templates/ingress.yaml b/charts/releasemanager/templates/ingress.yaml new file mode 100644 index 0000000..07c26ff --- /dev/null +++ b/charts/releasemanager/templates/ingress.yaml @@ -0,0 +1,27 @@ +{{- if .Values.ingress }} +{{- if .Values.ingress.hosts }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "releasemanager.name" $ }} +spec: + tls: + - hosts: +{{- range $host := .Values.ingress.hosts }} + - {{ $host }} +{{- end }} + rules: +{{- range $host := .Values.ingress.hosts }} + - host: {{ $host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ template "releasemanager.name" $ }} + port: + number: 8080 +{{- end }} +{{- end }} +{{- end }} diff --git a/charts/releasemanager/templates/rbac.yaml b/charts/releasemanager/templates/rbac.yaml new file mode 100644 index 0000000..19a56e4 --- /dev/null +++ b/charts/releasemanager/templates/rbac.yaml @@ -0,0 +1,33 @@ +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: releasemanager +rules: +- apiGroups: + - "" + resources: + - pods + - secrets + verbs: + - list +- apiGroups: + - "" + resources: + - pods/portforward + verbs: + - create + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: releasemanager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: releasemanager +subjects: +- kind: ServiceAccount + name: releasemanager + namespace: {{ .Release.Namespace }} diff --git a/charts/releasemanager/templates/secret.yaml b/charts/releasemanager/templates/secret.yaml new file mode 100644 index 0000000..9e12fe7 --- /dev/null +++ b/charts/releasemanager/templates/secret.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Secret +metadata: + name: releasemanager +type: Opaque +data: +{{- if and .Values.s3 (eq .Values.backend.type "s3") }} +{{- if and .Values.s3 .Values.s3.accessKeyID }} + accessKeyID: {{ .Values.s3.accessKeyID | b64enc }} +{{- end }} +{{- if and .Values.s3 .Values.s3.secretAccessKey }} + secretAccessKey: {{ .Values.s3.secretAccessKey | b64enc }} +{{- end }} +{{- if and .Values.s3 .Values.s3.sessionToken }} + sessionToken: {{ .Values.s3.sessionToken | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/releasemanager/templates/service.yaml b/charts/releasemanager/templates/service.yaml new file mode 100644 index 0000000..a245eea --- /dev/null +++ b/charts/releasemanager/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "releasemanager.name" . }} + labels: + chart: {{ template "releasemanager.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + type: ClusterIP + selector: + app: {{ template "releasemanager.name" . }} + ports: + - name: app + port: 8080 diff --git a/charts/releasemanager/templates/serviceaccount.yaml b/charts/releasemanager/templates/serviceaccount.yaml new file mode 100644 index 0000000..907ed5c --- /dev/null +++ b/charts/releasemanager/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: releasemanager + namespace: {{ .Release.Namespace }} diff --git a/charts/releasemanager/values.yaml b/charts/releasemanager/values.yaml new file mode 100644 index 0000000..cd4dba2 --- /dev/null +++ b/charts/releasemanager/values.yaml @@ -0,0 +1,78 @@ +# Default values for releasemanager. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: logicmonitor/releasemanager + tag: latest + pullPolicy: IfNotPresent + +## Enable debugging output +## +debug: false + +## Print planned actions without making any modifications +## +dryRun: false + +## Enable verbose output +## +verbose: false + + +## Release Manager daemon configuration options +## +daemon: + ## Specify, in seconds, how frequently the daemon should export the current state (default 30) + ## + pollingInterval: 30 + +## Backend configuration options +## +backend: + ## Required. Use this path within the backend for state storage + ## + path: "" + + ## Required: The backend type to use. Valid options are: s3 + ## + type: s3 + +## ingress configuration options +## +ingress: + ## A list of hosts to associate with the ingress object + ## + hosts: [] + # - host1 + # - host2 + + +## s3 backend configuration options +## +s3: {} + ## Required for s3 backend. Use this S3 bucket for backend storage + ## + # bucket: + + ## The backend S3 bucket's region + ## + # region: us-east-1 + + ## An AWS Access Key ID for accessing the S3 bucket, otherwise use the default AWS credential provider chain + ## + # accessKeyID: + + ## An AWS Secret Access Key for accessing the S3 bucket, otherwise use the default AWS credential provider chain + ## + # secretAccessKey: + + ## An AWS STS Session Token for accessing the S3 bucket, otherwise use the default AWS credential provider chain + ## +# sessionToken: + +nameOverride: "" + +fullnameOverride: ""