Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to configure webhook message content with a template file #253

Merged
merged 5 commits into from
Sep 17, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/helm/aws-node-termination-handler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ Parameter | Description | Default
`webhookProxy` | Uses the specified HTTP(S) proxy for sending webhooks | ``
`webhookHeaders` | Replaces the default webhook headers. | `{"Content-type":"application/json"}`
`webhookTemplate` | Replaces the default webhook message template. | `{"text":"[NTH][Instance Interruption] EventID: {{ .EventID }} - Kind: {{ .Kind }} - Description: {{ .Description }} - State: {{ .State }} - Start Time: {{ .StartTime }}"}`
`webhookTemplateConfigMapName` | Pass Webhook template file as configmap | None
`webhookTemplateConfigMapKey` | Name of the template file stored in the configmap| None
`dryRun` | If true, only log if a node would be drained | `false`
`enableScheduledEventDraining` | [EXPERIMENTAL] If true, drain nodes before the maintenance window starts for an EC2 instance scheduled event | `false`
`enableSpotInterruptionDraining` | If false, do not drain nodes when the spot interruption termination notice is received | `true`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ spec:
- name: "uptime"
hostPath:
path: {{ .Values.procUptimeFile | default "/proc/uptime" | quote }}
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
- name: "webhookTemplate"
configMap:
name: {{ .Values.webhookTemplateConfigMapName }}
{{- end }}
priorityClassName: {{ .Values.priorityClassName | quote }}
affinity:
nodeAffinity:
Expand Down Expand Up @@ -85,6 +90,10 @@ spec:
- name: "uptime"
mountPath: {{ .Values.procUptimeFile | default "/proc/uptime" | quote }}
readOnly: true
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
- name: "webhookTemplate"
mountPath: "/config/"
{{- end }}
env:
- name: NODE_NAME
valueFrom:
Expand Down Expand Up @@ -125,6 +134,10 @@ spec:
{{- end }}
- name: WEBHOOK_HEADERS
value: {{ .Values.webhookHeaders | quote }}
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
- name: WEBHOOK_TEMPLATE_FILE
value: {{ print "/config/" .Values.webhookTemplateConfigMapKey | quote }}
{{- end }}
- name: WEBHOOK_TEMPLATE
value: {{ .Values.webhookTemplate | quote }}
- name: DRY_RUN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ spec:
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
volumes:
- name: "webhookTemplate"
configMap:
name: {{ .Values.webhookTemplateConfigMapName }}
{{- end }}
priorityClassName: {{ .Values.priorityClassName | quote }}
affinity:
nodeAffinity:
Expand All @@ -64,6 +70,11 @@ spec:
- name: {{ include "aws-node-termination-handler.name" . }}
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
volumeMounts:
- name: "webhookTemplate"
mountPath: "/config/"
{{- end }}
env:
- name: NODE_NAME
valueFrom:
Expand Down Expand Up @@ -97,6 +108,10 @@ spec:
value: {{ .Values.webhookURL | quote }}
- name: WEBHOOK_HEADERS
value: {{ .Values.webhookHeaders | quote }}
{{- if and .Values.webhookTemplateConfigMapName .Values.webhookTemplateConfigMapKey }}
- name: WEBHOOK_TEMPLATE_FILE
value: {{ print "/config/" .Values.webhookTemplateConfigMapKey | quote }}
{{- end }}
- name: WEBHOOK_TEMPLATE
value: {{ .Values.webhookTemplate | quote }}
- name: DRY_RUN
Expand Down
7 changes: 7 additions & 0 deletions config/helm/aws-node-termination-handler/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ webhookProxy: ""
# webhookHeaders if specified, replaces the default webhook headers.
webhookHeaders: ""

# webhook template file will be fetched from given config map name
# if specified, replaces the default webhook message with the content of the template file
webhookTemplateConfigMapName: ""

# template file name stored in configmap
webhookTemplateConfigMapKey: ""

# webhookTemplate if specified, replaces the default webhook message template.
webhookTemplate: ""

Expand Down
3 changes: 3 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
webhookHeadersConfigKey = "WEBHOOK_HEADERS"
webhookHeadersDefault = `{"Content-type":"application/json"}`
webhookTemplateConfigKey = "WEBHOOK_TEMPLATE"
webhookTemplateFileConfigKey = "WEBHOOK_TEMPLATE_FILE"
webhookTemplateDefault = `{"text":"[NTH][Instance Interruption] EventID: {{ .EventID }} - Kind: {{ .Kind }} - Description: {{ .Description }} - Start Time: {{ .StartTime }}"}`
enableScheduledEventDrainingConfigKey = "ENABLE_SCHEDULED_EVENT_DRAINING"
enableScheduledEventDrainingDefault = false
Expand Down Expand Up @@ -79,6 +80,7 @@ type Config struct {
WebhookURL string
WebhookHeaders string
WebhookTemplate string
WebhookTemplateFile string
WebhookProxy string
EnableScheduledEventDraining bool
EnableSpotInterruptionDraining bool
Expand Down Expand Up @@ -116,6 +118,7 @@ func ParseCliArgs() (config Config, err error) {
flag.StringVar(&config.WebhookProxy, "webhook-proxy", getEnv(webhookProxyConfigKey, webhookProxyDefault), "If specified, uses the HTTP(S) proxy to send webhooks. Example: --webhook-url='tcp://<ip-or-dns-to-proxy>:<port>'")
flag.StringVar(&config.WebhookHeaders, "webhook-headers", getEnv(webhookHeadersConfigKey, webhookHeadersDefault), "If specified, replaces the default webhook headers.")
flag.StringVar(&config.WebhookTemplate, "webhook-template", getEnv(webhookTemplateConfigKey, webhookTemplateDefault), "If specified, replaces the default webhook message template.")
flag.StringVar(&config.WebhookTemplateFile, "webhook-template-file", getEnv(webhookTemplateFileConfigKey, ""), "If specified, replaces the default webhook message template with content from template file.")
flag.BoolVar(&config.EnableScheduledEventDraining, "enable-scheduled-event-draining", getBoolEnv(enableScheduledEventDrainingConfigKey, enableScheduledEventDrainingDefault), "[EXPERIMENTAL] If true, drain nodes before the maintenance window starts for an EC2 instance scheduled event")
flag.BoolVar(&config.EnableSpotInterruptionDraining, "enable-spot-interruption-draining", getBoolEnv(enableSpotInterruptionDrainingConfigKey, enableSpotInterruptionDrainingDefault), "If false, do not drain nodes when the spot interruption termination notice is received")
flag.IntVar(&config.MetadataTries, "metadata-tries", getIntEnv(metadataTriesConfigKey, metadataTriesDefault), "The number of times to try requesting metadata. If you would like 2 retries, set metadata-tries to 3.")
Expand Down
16 changes: 15 additions & 1 deletion pkg/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"text/template"
Expand All @@ -35,8 +36,21 @@ type combinedDrainData struct {

// Post makes a http post to send drain event data to webhook url
func Post(additionalInfo ec2metadata.NodeMetadata, event *monitor.InterruptionEvent, nthconfig config.Config) {
var webhookTemplateContent string

if nthconfig.WebhookTemplateFile != "" {
content, err := ioutil.ReadFile(nthconfig.WebhookTemplateFile)
if err != nil {
log.Log().Msgf("Webhook Error: Could not read template file %s - %s", nthconfig.WebhookTemplateFile, err)
return
}
webhookTemplateContent = string(content)
log.Log().Msgf("Template file content - %s", webhookTemplateContent)
bwagner5 marked this conversation as resolved.
Show resolved Hide resolved
} else {
webhookTemplateContent = nthconfig.WebhookTemplate
}

webhookTemplate, err := template.New("message").Parse(nthconfig.WebhookTemplate)
webhookTemplate, err := template.New("message").Parse(webhookTemplateContent)
if err != nil {
log.Log().Msgf("Webhook Error: Template parsing failed - %s", err)
return
Expand Down