func Post()

in pkg/webhook/webhook.go [41:129]


func Post(additionalInfo ec2metadata.NodeMetadata, event *monitor.InterruptionEvent, nthConfig config.Config) {
	var webhookTemplateContent string

	if nthConfig.WebhookTemplateFile != "" {
		content, err := os.ReadFile(nthConfig.WebhookTemplateFile)
		if err != nil {
			log.Err(err).
				Str("webhook_template_file", nthConfig.WebhookTemplateFile).
				Msg("Webhook Error: Could not read template file")
			return
		}
		webhookTemplateContent = string(content)
		log.Debug().Str("webhook_template_content", webhookTemplateContent)
	} else {
		webhookTemplateContent = nthConfig.WebhookTemplate
	}

	webhookTemplate, err := template.New("message").Funcs(sprig.TxtFuncMap()).Parse(webhookTemplateContent)
	if err != nil {
		log.Err(err).Msg("Webhook Error: Template parsing failed")
		return
	}

	// Need to merge the two data sources manually since both have
	// InstanceID and InstanceType fields
	instanceID := additionalInfo.InstanceID
	if event.InstanceID != "" {
		instanceID = event.InstanceID
	}
	instanceType := additionalInfo.InstanceType
	if event.InstanceType != "" {
		instanceType = event.InstanceType
	}
	var combined = combinedDrainData{NodeMetadata: additionalInfo, InterruptionEvent: *event, InstanceID: instanceID, InstanceType: instanceType}

	var byteBuffer bytes.Buffer
	err = webhookTemplate.Execute(&byteBuffer, combined)
	if err != nil {
		log.Err(err).Msg("Webhook Error: Template execution failed")
		return
	}

	request, err := http.NewRequest("POST", nthConfig.WebhookURL, &byteBuffer)
	if err != nil {
		log.Err(err).Msg("Webhook Error: Http NewRequest failed")
		return
	}

	headerMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(nthConfig.WebhookHeaders), &headerMap)
	if err != nil {
		log.Err(err).Msg("Webhook Error: Header Unmarshal failed")
		return
	}
	for key, value := range headerMap {
		request.Header.Set(key, value.(string))
	}

	client := http.Client{
		Timeout: time.Duration(5 * time.Second),
		Transport: &http.Transport{
			IdleConnTimeout: 1 * time.Second,
			Proxy: func(req *http.Request) (*url.URL, error) {
				if nthConfig.WebhookProxy == "" {
					return nil, nil
				}
				proxy, err := url.Parse(nthConfig.WebhookProxy)
				if err != nil {
					return nil, err
				}
				return proxy, nil
			},
		},
	}
	response, err := client.Do(request)
	if err != nil {
		log.Err(err).Msg("Webhook Error: Client Do failed")
		return
	}

	defer response.Body.Close()

	if response.StatusCode < 200 || response.StatusCode > 299 {
		log.Warn().Int("status_code", response.StatusCode).Msg("Webhook Error: Received Non-Successful Status Code")
		return
	}

	log.Info().Msg("Webhook Success: Notification Sent!")
}