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

opsgenie: Add visible_to #3958

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

chlunde
Copy link
Contributor

@chlunde chlunde commented Aug 15, 2024

Add visible_to with the same support for templating and fields as the
existing responders field.

Opsgenie documentation:

Teams and users that the alert will become visible to without sending
any notification. type field is mandatory for each item, where possible
values are team and user. In addition to the type field, either id or
name should be given for teams and either id or username should be given
for users. Please note: that alert will be visible to the teams that are
specified within responders field by default, so there is no need to
re-specify them within visibleTo field. You can refer below for example
values.

The functionality has been tested with unit tests, and with the following
configuration:

  route:
    receiver: og
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 12h
  receivers:
  - name: og
    opsgenie_configs:
    - send_resolved: true
      api_key: ...top secret...
      api_url: https://api.eu.opsgenie.com/
      message: 'Lab message'
      description: 'Static description'
      source: lab
      details:
        foo: bar
      priority: P4
      visible_to:
      - type: user
        username: [email protected]

Fixes #3953

Add visible_to with the same support for templating and fields as the
existing responders field.

Opsgenie documentation:

  Teams and users that the alert will become visible to without sending
  any notification. type field is mandatory for each item, where possible
  values are team and user. In addition to the type field, either id or
  name should be given for teams and either id or username should be given
  for users. Please note: that alert will be visible to the teams that are
  specified within responders field by default, so there is no need to
  re-specify them within visibleTo field. You can refer below for example
  values.

The functionality has been tested with unit tests, and with the following
configuration:

  route:
    receiver: og
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 12h
  receivers:
  - name: og
    opsgenie_configs:
    - send_resolved: true
      api_key: ...top secret...
      api_url: https://api.eu.opsgenie.com/
      message: 'Lab message'
      description: 'Static description'
      source: lab
      details:
        foo: bar
      priority: P4
      visible_to:
      - type: user
        username: [email protected]

Fixes prometheus#3953

Signed-off-by: Carl Henrik Lunde <[email protected]>
return fmt.Errorf("opsGenieConfig visible_to %v has to have at least one of id, username or name specified", v)
}

if strings.Contains(v.Type, "{{") {
Copy link
Contributor

@grobinson-grafana grobinson-grafana Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this check doesn't work. Consider the following example:

this is an invalid template }}

I suppose you could also check for strings.Contains(v.Type, "}}")?

Perhaps it would be better to just remove this if statement and check all VisibleTo's using template.New("").Parse()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to match the behaviour for receivers, this code was introduced by 9ae6113.

In the case of this is an invalid template }} it will not be considered as a valid template, and ender the "else" case below, which will complain that it does not match the regex for valid types.

But you're right, at least I should not have reused opsgenieTypeMatcher, which is ^(team|teams|user|escalation|schedule)$. Fixed in new commit.

docs/configuration.md Show resolved Hide resolved
@@ -638,6 +657,16 @@ type OpsGenieConfigResponder struct {
Type string `yaml:"type,omitempty" json:"type,omitempty"`
}

type OpsGenieConfigVisibleTo struct {
// One of those 3 should be filled.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment doesn't match the behavior in the code. The code allows for at least one to be filled, not at most one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to match the battle tested code for receivers here too. After considering changing the code, I think it is right.

We want to send exactly one of those fields to the OpsGenie API.
We must verify that at least one is set.
We probably should not disallow setting two or three as templates, as after templating, it is likely that exactly one has a value.

Of course, we could add a lot of validation to check that exactly one is set if it is not templates, and allow 1-3 set if they are all templates, but I'm not sure if it is worth the complexity?

#### `<visible_to>`

```yaml
# Exactly one of these fields should be defined.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from the receivers docs, but we could try to be more precise.

Something like:

Exactly one of these fields must have a value after templating. If none of the fields, including type, are set, the array item will be ignored.

Fixed in new commit.

Type: tmpl(v.Type),
}

if visibleTo == (opsGenieCreateMessageVisibleTo{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would someone want to do this? Is it to catch badly written templates that produce no output?

Copy link
Contributor Author

@chlunde chlunde Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is identical to receivers, for consistent user experience.

Seems like this was introduced in 9ddc5f1

There is an explaination in the comment below. Is this OK?

				// Filter out empty responders. This is useful if you want to fill
 				// responders dynamically from alert's common labels.

teams := safeSplit(visibleTo.Name, ",")
for _, team := range teams {
newVisibleTo := opsGenieCreateMessageVisibleTo{
Name: tmpl(team),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why template the name a second time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy and paste from receivers, I did not catch that, thanks! Would you like me to remove the double templating in the code above too? Or have a dedicated PR for that? It does not change the results of the unit tests.

Fixed in new commit.

for _, team := range teams {
newVisibleTo := opsGenieCreateMessageVisibleTo{
Name: tmpl(team),
Type: tmpl("team"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't make sense to me. You could template it back to user after we've checked that it is teams.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should just be Type: "team". Fixed in new commit.

Not sure if I understand the reference to user here?

continue
}

if visibleTo.Type == "teams" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does teams plural come from btw? In the documentation all I can see is team and user?

type field is mandatory for each item, where possible values are team and user

https://docs.opsgenie.com/docs/alert-api#create-alert

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is identical to receivers, for consistent user experience.

Seems like this was introduced in 05490d8

It is an extension in alert manager not covered by the opsgenie API and documentation, but it is described in configuration.md:

# The `teams` type is configured using the `name` field above.
# This field can contain a comma-separated list of team names.
# If the list is empty, no additional visibility will be configured.

Copy link
Contributor Author

@chlunde chlunde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review, sorry for the delay. I added a new commit that addresses some of the code review comments.

But a lot of the comments apply to the existing code, so I would like to get your input again on them before making further changes. Could you mark the ones you think are OK as resolved, and comment on the others?

Type: tmpl(v.Type),
}

if visibleTo == (opsGenieCreateMessageVisibleTo{}) {
Copy link
Contributor Author

@chlunde chlunde Sep 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is identical to receivers, for consistent user experience.

Seems like this was introduced in 9ddc5f1

There is an explaination in the comment below. Is this OK?

				// Filter out empty responders. This is useful if you want to fill
 				// responders dynamically from alert's common labels.

return fmt.Errorf("opsGenieConfig visible_to %v has to have at least one of id, username or name specified", v)
}

if strings.Contains(v.Type, "{{") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to match the behaviour for receivers, this code was introduced by 9ae6113.

In the case of this is an invalid template }} it will not be considered as a valid template, and ender the "else" case below, which will complain that it does not match the regex for valid types.

But you're right, at least I should not have reused opsgenieTypeMatcher, which is ^(team|teams|user|escalation|schedule)$. Fixed in new commit.

@@ -638,6 +657,16 @@ type OpsGenieConfigResponder struct {
Type string `yaml:"type,omitempty" json:"type,omitempty"`
}

type OpsGenieConfigVisibleTo struct {
// One of those 3 should be filled.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to match the battle tested code for receivers here too. After considering changing the code, I think it is right.

We want to send exactly one of those fields to the OpsGenie API.
We must verify that at least one is set.
We probably should not disallow setting two or three as templates, as after templating, it is likely that exactly one has a value.

Of course, we could add a lot of validation to check that exactly one is set if it is not templates, and allow 1-3 set if they are all templates, but I'm not sure if it is worth the complexity?

#### `<visible_to>`

```yaml
# Exactly one of these fields should be defined.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from the receivers docs, but we could try to be more precise.

Something like:

Exactly one of these fields must have a value after templating. If none of the fields, including type, are set, the array item will be ignored.

Fixed in new commit.

continue
}

if visibleTo.Type == "teams" {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is identical to receivers, for consistent user experience.

Seems like this was introduced in 05490d8

It is an extension in alert manager not covered by the opsgenie API and documentation, but it is described in configuration.md:

# The `teams` type is configured using the `name` field above.
# This field can contain a comma-separated list of team names.
# If the list is empty, no additional visibility will be configured.

teams := safeSplit(visibleTo.Name, ",")
for _, team := range teams {
newVisibleTo := opsGenieCreateMessageVisibleTo{
Name: tmpl(team),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy and paste from receivers, I did not catch that, thanks! Would you like me to remove the double templating in the code above too? Or have a dedicated PR for that? It does not change the results of the unit tests.

Fixed in new commit.

for _, team := range teams {
newVisibleTo := opsGenieCreateMessageVisibleTo{
Name: tmpl(team),
Type: tmpl("team"),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should just be Type: "team". Fixed in new commit.

Not sure if I understand the reference to user here?

@chlunde
Copy link
Contributor Author

chlunde commented Oct 8, 2024

@grobinson-grafana Could you take another look? Or should we involve the authors of the original code? Alternatively I could make a stripped down version of the PR but that would make this field behave differently from receivers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Add visibleTo field to OpsGenie integration
2 participants