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

Add support for fetching sensitive parts of actions from secrets #816

Merged
merged 29 commits into from
Jul 3, 2024
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
99c9486
Set initial TODOs.
fanicia Apr 11, 2023
229d150
Remove clear text apitoken.
fanicia Apr 21, 2023
f2a622f
Start implementing a secretMap.
fanicia Apr 21, 2023
a43fb2c
Non-working commit.
fanicia Apr 21, 2023
bc6ed0b
Almost removed cleartext token.
fanicia Apr 21, 2023
fdf185f
Fix resolveSecrets.
fanicia Apr 21, 2023
494b27a
Fix OpsGenie and HumioActionRepository.
fanicia Apr 21, 2023
e4014b8
Change TODO.
fanicia Apr 21, 2023
b0cee1d
Remove constants.
fanicia Apr 23, 2023
d910434
update examples and crd.
fanicia Apr 23, 2023
ba96107
Include namespace in lookup key.
fanicia Apr 23, 2023
4be716d
Make keyRefs required.
fanicia Apr 23, 2023
69c3a41
Merge branch 'humio:master' into ha-improve-secrets
fanicia Oct 5, 2023
04bd900
Implement non-breaking solution.
fanicia Jan 29, 2024
2663647
Improve secret helpers.
fanicia Jan 30, 2024
efbc8df
Minor improvement.
fanicia Jan 31, 2024
3372f01
Rebase to fix conflicts.
fanicia Jan 31, 2024
872f00e
Merge branch 'master' into HEAD
SaaldjorMike Jun 17, 2024
64817b1
Add secretRef to PagerDutyProperties
RayeEvtuchM1 Apr 19, 2023
50b9347
wip
SaaldjorMike Jun 25, 2024
7c36b9c
wip2
SaaldjorMike Jun 25, 2024
c2094dd
wip3
SaaldjorMike Jun 26, 2024
1fa4c3a
now it may work
SaaldjorMike Jun 26, 2024
2881825
Merge branch 'master' into mike/fanicia/ha-improve-secrets
SaaldjorMike Jun 26, 2024
36a294e
wip
SaaldjorMike Jun 27, 2024
6a9e88b
wip
SaaldjorMike Jun 27, 2024
9bd6937
wip
SaaldjorMike Jun 27, 2024
aa6c982
Update api/v1alpha1/humioaction_types.go
SaaldjorMike Jul 3, 2024
6df6132
make manifests
SaaldjorMike Jul 3, 2024
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
Prev Previous commit
Next Next commit
wip
SaaldjorMike committed Jun 25, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 50b9347a7261dc6af38367205e7a5bc3e972c2e0
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ endif
eval \$$($(GOBIN)/setup-envtest use -p env ${TEST_K8S_VERSION}); \
export USE_CERTMANAGER=false; \
export TEST_USE_EXISTING_CLUSTER=false; \
$(GINKGO) -vv --procs 3 -output-dir=${PWD} --output-interceptor-mode=none -keep-separate-reports --junit-report=test-results-junit.xml --randomize-suites --randomize-all -timeout 10m ./... -covermode=count -coverprofile cover.out \
$(GINKGO) -vv --no-color --procs 3 -output-dir=${PWD} -keep-separate-reports --junit-report=test-results-junit.xml --randomize-suites --randomize-all -timeout 10m ./... -covermode=count -coverprofile cover.out \
"

##@ Build
8 changes: 4 additions & 4 deletions api/v1alpha1/humioaction_secret_helpers.go
Original file line number Diff line number Diff line change
@@ -3,17 +3,17 @@ package v1alpha1
import "fmt"

var haSecrets map[string]string = make(map[string]string)
var haWebhookHeaders map[string]map[string]string = make(map[string]map[string]string) // TODO: or maybe we just add it as a magic annotation?

func GetSecretForHa(hn *HumioAction) (string, bool) {
if secret, found := haSecrets[fmt.Sprintf("%s-%s", hn.Namespace, hn.Name)]; found {
if secret, found := haSecrets[fmt.Sprintf("%s %s", hn.Namespace, hn.Name)]; found {
return secret, true
}
return "", false
}

// Call this to set the secret in the map
func SetSecretForHa(hn *HumioAction, token string) {
key := fmt.Sprintf("%s-%s", hn.Namespace, hn.Name)
value := token
haSecrets[key] = value
key := fmt.Sprintf("%s %s", hn.Namespace, hn.Name)
haSecrets[key] = token
}
35 changes: 21 additions & 14 deletions api/v1alpha1/humioaction_types.go
Original file line number Diff line number Diff line change
@@ -36,10 +36,15 @@ const (
type HumioActionWebhookProperties struct {
BodyTemplate string `json:"bodyTemplate,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
Method string `json:"method,omitempty"`
Url string `json:"url,omitempty"`
IgnoreSSL bool `json:"ignoreSSL,omitempty"`
UseProxy bool `json:"useProxy,omitempty"`
// HeadersSource
// TODO: Can we even use VarSource, or do we need something else that can refer to configmap/secret? Maybe only "kind: Secret" that assumes key,values from Secret object are the header key-value pairs?
// Maybe what we want is to just specify the key directly as plaintext in action while keeping VALUE of header in a secret, then use VarSource for that?
HeadersSource VarSource `json:"headersSource,omitempty"`
Method string `json:"method,omitempty"`
Url string `json:"url,omitempty"`
UrlSource VarSource `json:"urlSource,omitempty"`
IgnoreSSL bool `json:"ignoreSSL,omitempty"`
UseProxy bool `json:"useProxy,omitempty"`
}

// HumioActionEmailProperties defines the desired state of HumioActionEmailProperties
@@ -74,9 +79,10 @@ type HumioActionPagerDutyProperties struct {

// HumioActionSlackProperties defines the desired state of HumioActionSlackProperties
type HumioActionSlackProperties struct {
Fields map[string]string `json:"fields,omitempty"`
Url string `json:"url,omitempty"`
UseProxy bool `json:"useProxy,omitempty"`
Fields map[string]string `json:"fields,omitempty"`
Url string `json:"url,omitempty"`
UrlSource VarSource `json:"urlSource,omitempty"`
UseProxy bool `json:"useProxy,omitempty"`
}

// HumioActionSlackPostMessageProperties defines the desired state of HumioActionSlackPostMessageProperties
@@ -88,15 +94,16 @@ type HumioActionSlackPostMessageProperties struct {
UseProxy bool `json:"useProxy,omitempty"`
}

type VarSource struct {
SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"`
}

// HumioActionVictorOpsProperties defines the desired state of HumioActionVictorOpsProperties
type HumioActionVictorOpsProperties struct {
MessageType string `json:"messageType,omitempty"`
NotifyUrl string `json:"notifyUrl,omitempty"`
UseProxy bool `json:"useProxy,omitempty"`
MessageType string `json:"messageType,omitempty"`
NotifyUrl string `json:"notifyUrl,omitempty"`
NotifyUrlSource VarSource `json:"notifyUrlSource"`
UseProxy bool `json:"useProxy,omitempty"`
}

type VarSource struct {
SecretKeyRef *corev1.SecretKeySelector `json:"secretKeyRef,omitempty"`
}

// HumioActionSpec defines the desired state of HumioAction
4 changes: 3 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 60 additions & 2 deletions charts/humio-operator/crds/core.humio.com_humioactions.yaml
Original file line number Diff line number Diff line change
@@ -156,8 +156,10 @@ spec:
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
@@ -166,6 +168,7 @@ spec:
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
severity:
type: string
@@ -223,6 +226,30 @@ spec:
type: object
url:
type: string
urlSource:
properties:
secretKeyRef:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
useProxy:
type: boolean
type: object
@@ -234,8 +261,34 @@ spec:
type: string
notifyUrl:
type: string
notifyUrlSource:
properties:
secretKeyRef:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
useProxy:
type: boolean
required:
- notifyUrlSource
type: object
viewName:
description: ViewName is the name of the Humio View under which the
@@ -250,12 +303,17 @@ spec:
headers:
additionalProperties:
type: string
description: |-
TODO: Do we want to have a HeadersSource? Not so easy to add, as it is a set of key-value pairs, and haSecrets is of type map[string]string. Maybe we can just automatically append key to GetSecretForHa and SetSecretForHa?
fmt.Sprintf("%s-%s", hn.Namespace, hn.Name, hn.KeySuffix) ? then join those keys with "-"?
type: object
ignoreSSL:
type: boolean
method:
type: string
url:
description: 'TODO: Do we want to have a UrlSource? Easy to add,
similar to UrlSource on Slack action!'
type: string
useProxy:
type: boolean
62 changes: 60 additions & 2 deletions config/crd/bases/core.humio.com_humioactions.yaml
Original file line number Diff line number Diff line change
@@ -156,8 +156,10 @@ spec:
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
@@ -166,6 +168,7 @@ spec:
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
severity:
type: string
@@ -223,6 +226,30 @@ spec:
type: object
url:
type: string
urlSource:
properties:
secretKeyRef:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
useProxy:
type: boolean
type: object
@@ -234,8 +261,34 @@ spec:
type: string
notifyUrl:
type: string
notifyUrlSource:
properties:
secretKeyRef:
description: SecretKeySelector selects a key of a Secret.
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
x-kubernetes-map-type: atomic
type: object
useProxy:
type: boolean
required:
- notifyUrlSource
type: object
viewName:
description: ViewName is the name of the Humio View under which the
@@ -250,12 +303,17 @@ spec:
headers:
additionalProperties:
type: string
description: |-
TODO: Do we want to have a HeadersSource? Not so easy to add, as it is a set of key-value pairs, and haSecrets is of type map[string]string. Maybe we can just automatically append key to GetSecretForHa and SetSecretForHa?
fmt.Sprintf("%s-%s", hn.Namespace, hn.Name, hn.KeySuffix) ? then join those keys with "-"?
type: object
ignoreSSL:
type: boolean
method:
type: string
url:
description: 'TODO: Do we want to have a UrlSource? Easy to add,
similar to UrlSource on Slack action!'
type: string
useProxy:
type: boolean
32 changes: 27 additions & 5 deletions controllers/humioaction_controller.go
Original file line number Diff line number Diff line change
@@ -202,31 +202,53 @@ func (r *HumioActionReconciler) resolveSecrets(ctx context.Context, ha *humiov1a
if ha.Spec.SlackPostMessageProperties != nil {
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.SlackPostMessageProperties.ApiToken, ha.Spec.SlackPostMessageProperties.ApiTokenSource)
if err != nil {
return fmt.Errorf("slackPostMessageProperties.ApiTokenSource.%v", err)
return fmt.Errorf("slackPostMessageProperties.apiTokenSource.%v", err)
}
}

if ha.Spec.SlackProperties != nil {
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.SlackProperties.Url, ha.Spec.SlackProperties.UrlSource)
if err != nil {
return fmt.Errorf("slackProperties.urlSource.%v", err)
}

}

if ha.Spec.OpsGenieProperties != nil {
ha.Spec.OpsGenieProperties.GenieKey, err = r.resolveField(ctx, ha.Namespace, ha.Spec.OpsGenieProperties.GenieKey, ha.Spec.OpsGenieProperties.GenieKeySource)
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.OpsGenieProperties.GenieKey, ha.Spec.OpsGenieProperties.GenieKeySource)
if err != nil {
return fmt.Errorf("opsGenieProperties.ingestTokenSource.%v", err)
return fmt.Errorf("opsGenieProperties.genieKeySource.%v", err)
}
}

if ha.Spec.HumioRepositoryProperties != nil {
ha.Spec.HumioRepositoryProperties.IngestToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.HumioRepositoryProperties.IngestToken, ha.Spec.HumioRepositoryProperties.IngestTokenSource)
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.HumioRepositoryProperties.IngestToken, ha.Spec.HumioRepositoryProperties.IngestTokenSource)
if err != nil {
return fmt.Errorf("humioRepositoryProperties.ingestTokenSource.%v", err)
}
}

if ha.Spec.PagerDutyProperties != nil {
ha.Spec.PagerDutyProperties.RoutingKey, err = r.resolveField(ctx, ha.Namespace, ha.Spec.PagerDutyProperties.RoutingKey, ha.Spec.PagerDutyProperties.RoutingKeySource)
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.PagerDutyProperties.RoutingKey, ha.Spec.PagerDutyProperties.RoutingKeySource)
if err != nil {
return fmt.Errorf("pagerDutyProperties.routingKeySource.%v", err)
}
}

if ha.Spec.VictorOpsProperties != nil {
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.VictorOpsProperties.NotifyUrl, ha.Spec.VictorOpsProperties.NotifyUrlSource)
if err != nil {
return fmt.Errorf("victorOpsProperties.notifyUrlSource.%v", err)
}
}

if ha.Spec.WebhookProperties != nil {
apiToken, err = r.resolveField(ctx, ha.Namespace, ha.Spec.WebhookProperties.Url, ha.Spec.WebhookProperties.UrlSource)
if err != nil {
return fmt.Errorf("victorOpsProperties.notifyUrlSource.%v", err)
}
}

humiov1alpha1.SetSecretForHa(ha, apiToken)

return nil
345 changes: 320 additions & 25 deletions controllers/suite/resources/humioresources_controller_test.go

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions examples/humioaction-webhook.yaml
Original file line number Diff line number Diff line change
@@ -33,3 +33,24 @@ spec:
bodyTemplate: |-
{alert_name} has alerted
click {url} to see the alert
---
apiVersion: core.humio.com/v1alpha1
kind: HumioAction
metadata:
name: humio-web-hook-action-all-secret-external
spec:
externalClusterName: example-humioexternalcluster
name: example-web-hook-action-using-secrets
viewName: humio
webhookProperties:
urlSource:
secretKeyRef:
name: example-humiocluster-webhook-action-url-secret
key: data
headers: # TODO: How do we want this to be? Should this just be the same as env vars?
some: header
some-other: header
method: POST
bodyTemplate: |-
{alert_name} has alerted
click {url} to see the alert
77 changes: 58 additions & 19 deletions pkg/humio/action_transform.go
Original file line number Diff line number Diff line change
@@ -68,25 +68,24 @@ func CRActionFromAPIAction(action *humioapi.Action) (*humiov1alpha1.HumioAction,
}

if !reflect.ValueOf(action.HumioRepoAction).IsZero() {
ha.Spec.HumioRepositoryProperties = &humiov1alpha1.HumioActionRepositoryProperties{
IngestToken: action.HumioRepoAction.IngestToken,
}
ha.Spec.HumioRepositoryProperties = &humiov1alpha1.HumioActionRepositoryProperties{}
humiov1alpha1.SetSecretForHa(ha, action.HumioRepoAction.IngestToken)
}

if !reflect.ValueOf(action.OpsGenieAction).IsZero() {
ha.Spec.OpsGenieProperties = &humiov1alpha1.HumioActionOpsGenieProperties{
ApiUrl: action.OpsGenieAction.ApiUrl,
GenieKey: action.OpsGenieAction.GenieKey,
UseProxy: action.OpsGenieAction.UseProxy,
}
humiov1alpha1.SetSecretForHa(ha, action.OpsGenieAction.GenieKey)
}

if !reflect.ValueOf(action.PagerDutyAction).IsZero() {
ha.Spec.PagerDutyProperties = &humiov1alpha1.HumioActionPagerDutyProperties{
RoutingKey: action.PagerDutyAction.RoutingKey,
Severity: action.PagerDutyAction.Severity,
UseProxy: action.PagerDutyAction.UseProxy,
Severity: action.PagerDutyAction.Severity,
UseProxy: action.PagerDutyAction.UseProxy,
}
humiov1alpha1.SetSecretForHa(ha, action.PagerDutyAction.RoutingKey)
}

if !reflect.ValueOf(action.SlackAction).IsZero() {
@@ -96,9 +95,9 @@ func CRActionFromAPIAction(action *humioapi.Action) (*humiov1alpha1.HumioAction,
}
ha.Spec.SlackProperties = &humiov1alpha1.HumioActionSlackProperties{
Fields: fields,
Url: action.SlackAction.Url,
UseProxy: action.SlackAction.UseProxy,
}
humiov1alpha1.SetSecretForHa(ha, action.SlackAction.Url)
}

if !reflect.ValueOf(action.SlackPostMessageAction).IsZero() {
@@ -117,9 +116,9 @@ func CRActionFromAPIAction(action *humioapi.Action) (*humiov1alpha1.HumioAction,
if !reflect.ValueOf(action.VictorOpsAction).IsZero() {
ha.Spec.VictorOpsProperties = &humiov1alpha1.HumioActionVictorOpsProperties{
MessageType: action.VictorOpsAction.MessageType,
NotifyUrl: action.VictorOpsAction.NotifyUrl,
UseProxy: action.VictorOpsAction.UseProxy,
}
humiov1alpha1.SetSecretForHa(ha, action.VictorOpsAction.NotifyUrl)
}

if !reflect.ValueOf(action.WebhookAction).IsZero() {
@@ -206,14 +205,21 @@ func humioRepoAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
return action, err
}

if hn.Spec.HumioRepositoryProperties.IngestToken == "" {
apiToken, found := humiov1alpha1.GetSecretForHa(hn)

if hn.Spec.HumioRepositoryProperties.IngestToken == "" && !found {
errorList = append(errorList, "property humioRepositoryProperties.ingestToken is required")
}
if len(errorList) > 0 {
return ifErrors(action, ActionTypeHumioRepo, errorList)
}
if hn.Spec.HumioRepositoryProperties.IngestToken != "" {
action.HumioRepoAction.IngestToken = hn.Spec.HumioRepositoryProperties.IngestToken
} else {
action.HumioRepoAction.IngestToken = apiToken
}

action.Type = humioapi.ActionTypeHumioRepo
action.HumioRepoAction.IngestToken = hn.Spec.HumioRepositoryProperties.IngestToken

return action, nil
}
@@ -225,7 +231,9 @@ func opsGenieAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
return action, err
}

if hn.Spec.OpsGenieProperties.GenieKey == "" {
apiToken, found := humiov1alpha1.GetSecretForHa(hn)

if hn.Spec.OpsGenieProperties.GenieKey == "" && !found {
errorList = append(errorList, "property opsGenieProperties.genieKey is required")
}
if hn.Spec.OpsGenieProperties.ApiUrl == "" {
@@ -234,8 +242,13 @@ func opsGenieAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
if len(errorList) > 0 {
return ifErrors(action, ActionTypeOpsGenie, errorList)
}
if hn.Spec.OpsGenieProperties.GenieKey != "" {
action.OpsGenieAction.GenieKey = hn.Spec.OpsGenieProperties.GenieKey
} else {
action.OpsGenieAction.GenieKey = apiToken
}

action.Type = humioapi.ActionTypeOpsGenie
action.OpsGenieAction.GenieKey = hn.Spec.OpsGenieProperties.GenieKey
action.OpsGenieAction.ApiUrl = hn.Spec.OpsGenieProperties.ApiUrl
action.OpsGenieAction.UseProxy = hn.Spec.OpsGenieProperties.UseProxy

@@ -249,8 +262,10 @@ func pagerDutyAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
return action, err
}

apiToken, found := humiov1alpha1.GetSecretForHa(hn)

var severity string
if hn.Spec.PagerDutyProperties.RoutingKey == "" {
if hn.Spec.PagerDutyProperties.RoutingKey == "" && !found {
errorList = append(errorList, "property pagerDutyProperties.routingKey is required")
}
if hn.Spec.PagerDutyProperties.Severity == "" {
@@ -267,8 +282,13 @@ func pagerDutyAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
if len(errorList) > 0 {
return ifErrors(action, ActionTypePagerDuty, errorList)
}
if hn.Spec.PagerDutyProperties.RoutingKey != "" {
action.PagerDutyAction.RoutingKey = hn.Spec.PagerDutyProperties.RoutingKey
} else {
action.PagerDutyAction.RoutingKey = apiToken
}

action.Type = humioapi.ActionTypePagerDuty
action.PagerDutyAction.RoutingKey = hn.Spec.PagerDutyProperties.RoutingKey
action.PagerDutyAction.Severity = severity
action.PagerDutyAction.UseProxy = hn.Spec.PagerDutyProperties.UseProxy

@@ -282,17 +302,26 @@ func slackAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
return action, err
}

slackUrl, found := humiov1alpha1.GetSecretForHa(hn)
if hn.Spec.SlackProperties.Url == "" && !found {
errorList = append(errorList, "property slackProperties.url is required")
}
if hn.Spec.SlackProperties.Fields == nil {
errorList = append(errorList, "property slackProperties.fields is required")
}
if _, err := url.ParseRequestURI(hn.Spec.SlackProperties.Url); err != nil {
if hn.Spec.SlackProperties.Url != "" {
action.SlackAction.Url = hn.Spec.SlackProperties.Url
} else {
action.SlackAction.Url = slackUrl
}
if _, err := url.ParseRequestURI(action.SlackAction.Url); err != nil {
errorList = append(errorList, fmt.Sprintf("invalid url for slackProperties.url: %s", err.Error()))
}
if len(errorList) > 0 {
return ifErrors(action, ActionTypeSlack, errorList)
}

action.Type = humioapi.ActionTypeSlack
action.SlackAction.Url = hn.Spec.SlackProperties.Url
action.SlackAction.UseProxy = hn.Spec.SlackProperties.UseProxy
action.SlackAction.Fields = []humioapi.SlackFieldEntryInput{}
for k, v := range hn.Spec.SlackProperties.Fields {
@@ -356,7 +385,12 @@ func victorOpsAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
return action, err
}

apiToken, found := humiov1alpha1.GetSecretForHa(hn)

var messageType string
if hn.Spec.VictorOpsProperties.NotifyUrl == "" && !found {
errorList = append(errorList, "property victorOpsProperties.notifyUrl is required")
}
if hn.Spec.VictorOpsProperties.MessageType == "" {
errorList = append(errorList, "property victorOpsProperties.messageType is required")
}
@@ -368,15 +402,20 @@ func victorOpsAction(hn *humiov1alpha1.HumioAction) (*humioapi.Action, error) {
hn.Spec.VictorOpsProperties.MessageType, strings.Join(acceptedMessageTypes, ", ")))
}
}
if _, err := url.ParseRequestURI(hn.Spec.VictorOpsProperties.NotifyUrl); err != nil {
if hn.Spec.VictorOpsProperties.NotifyUrl != "" {
action.VictorOpsAction.NotifyUrl = hn.Spec.VictorOpsProperties.NotifyUrl
} else {
action.VictorOpsAction.NotifyUrl = apiToken
}
if _, err := url.ParseRequestURI(action.VictorOpsAction.NotifyUrl); err != nil {
errorList = append(errorList, fmt.Sprintf("invalid url for victorOpsProperties.notifyUrl: %s", err.Error()))
}
if len(errorList) > 0 {
return ifErrors(action, ActionTypeVictorOps, errorList)
}

action.Type = humioapi.ActionTypeVictorOps
action.VictorOpsAction.MessageType = messageType
action.VictorOpsAction.NotifyUrl = hn.Spec.VictorOpsProperties.NotifyUrl
action.VictorOpsAction.UseProxy = hn.Spec.VictorOpsProperties.UseProxy

return action, nil
4 changes: 2 additions & 2 deletions pkg/humio/action_transform_test.go
Original file line number Diff line number Diff line change
@@ -88,7 +88,7 @@ func TestActionCRAsAction(t *testing.T) {
},
nil,
true,
fmt.Sprintf("%s failed due to errors: property slackProperties.fields is required, invalid url for slackProperties.url: parse \"\": empty url", ActionTypeSlack),
fmt.Sprintf("%s failed due to errors: property slackProperties.url is required, property slackProperties.fields is required, invalid url for slackProperties.url: parse \"\": empty url", ActionTypeSlack),
},
{
"missing required slackPostMessageProperties",
@@ -116,7 +116,7 @@ func TestActionCRAsAction(t *testing.T) {
},
nil,
true,
fmt.Sprintf("%s failed due to errors: property victorOpsProperties.messageType is required, invalid url for victorOpsProperties.notifyUrl: parse \"\": empty url", ActionTypeVictorOps),
fmt.Sprintf("%s failed due to errors: property victorOpsProperties.notifyUrl is required, property victorOpsProperties.messageType is required, invalid url for victorOpsProperties.notifyUrl: parse \"\": empty url", ActionTypeVictorOps),
},
{
"missing required webhookProperties",