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

graphql: destinations: add dest as a field on OnCallNotificationRule #3659

Merged
merged 4 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
353 changes: 241 additions & 112 deletions graphql2/generated.go

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions graphql2/graph/destinations.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ extend type Query {
# It does not guarantee that the value is valid for the destination type, only
# that it is valid for the field (i.e., syntax/formatting).
destinationFieldValidate(input: DestinationFieldValidateInput!): Boolean! @experimental(flagName: "dest-types")
destinationFieldSearch(input: DestinationFieldSearchInput!): FieldValueConnection!
destinationFieldValueName(input: DestinationFieldValidateInput!): String!
destinationFieldSearch(input: DestinationFieldSearchInput!): FieldValueConnection! @experimental(flagName: "dest-types")
destinationFieldValueName(input: DestinationFieldValidateInput!): String! @experimental(flagName: "dest-types")

# destinationDisplayInfo returns the display information for a destination.
destinationDisplayInfo(input: DestinationInput!): DestinationDisplayInfo! @experimental(flagName: "dest-types")
Expand Down Expand Up @@ -43,8 +43,7 @@ input DestinationFieldSearchInput {
type Destination {
type: DestinationType!
values: [FieldValuePair!]!
typeInfo: DestinationTypeInfo!
display: DestinationDisplayInfo!
displayInfo: DestinationDisplayInfo! @goField(forceResolver: true)
}

# DestinationDisplayInfo provides information for displaying a destination.
Expand Down
86 changes: 86 additions & 0 deletions graphql2/graphqlapp/compat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package graphqlapp

import (
"context"
"fmt"
"net/url"
"strings"

"github.com/google/uuid"
"github.com/target/goalert/graphql2"
"github.com/target/goalert/notificationchannel"
)

// CompatNCToDest converts a notification channel to a destination.
func (a *App) CompatNCToDest(ctx context.Context, ncID uuid.UUID) (*graphql2.Destination, error) {
nc, err := a.FindOneNC(ctx, ncID)
if err != nil {
return nil, err
}

switch nc.Type {
case notificationchannel.TypeSlackChan:
ch, err := a.SlackStore.Channel(ctx, nc.Value)
if err != nil {
return nil, err
}

return &graphql2.Destination{
Type: destSlackChan,
Values: []graphql2.FieldValuePair{
{
FieldID: fieldSlackChanID,
Value: nc.Value,
Label: ch.Name,
},
},
}, nil
case notificationchannel.TypeSlackUG:
ugID, chanID, ok := strings.Cut(nc.Value, ":")
if !ok {
return nil, fmt.Errorf("invalid slack usergroup pair: %s", nc.Value)
}
ug, err := a.SlackStore.UserGroup(ctx, ugID)
if err != nil {
return nil, err
}
ch, err := a.SlackStore.Channel(ctx, chanID)
if err != nil {
return nil, err
}

return &graphql2.Destination{
Type: destSlackUG,
Values: []graphql2.FieldValuePair{
{
FieldID: fieldSlackUGID,
Value: ugID,
Label: ug.Handle,
},
{
FieldID: fieldSlackChanID,
Value: chanID,
Label: ch.Name,
},
},
}, nil
case notificationchannel.TypeWebhook:
u, err := url.Parse(nc.Value)
if err != nil {
return nil, err
}

return &graphql2.Destination{
Type: destWebhook,
Values: []graphql2.FieldValuePair{
{
FieldID: fieldWebhookURL,
Value: nc.Value,
Label: u.Hostname(),
},
},
}, nil
default:
return nil, fmt.Errorf("unsupported notification channel type: %s", nc.Type)
}
}
20 changes: 20 additions & 0 deletions graphql2/graphqlapp/destinationdisplayinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,26 @@ import (
"github.com/target/goalert/validation"
)

type (
Destination App
)

func (a *App) Destination() graphql2.DestinationResolver { return (*Destination)(a) }

// DisplayInfo will return the display information for a destination by mapping to Query.DestinationDisplayInfo.
func (a *Destination) DisplayInfo(ctx context.Context, obj *graphql2.Destination) (*graphql2.DestinationDisplayInfo, error) {
if obj.DisplayInfo != nil {
return obj.DisplayInfo, nil
}

values := make([]graphql2.FieldValueInput, len(obj.Values))
for i, v := range obj.Values {
values[i] = graphql2.FieldValueInput{FieldID: v.FieldID, Value: v.Value}
}

return (*Query)(a).DestinationDisplayInfo(ctx, graphql2.DestinationInput{Type: obj.Type, Values: values})
}

func (a *Query) DestinationDisplayInfo(ctx context.Context, dest graphql2.DestinationInput) (*graphql2.DestinationDisplayInfo, error) {
app := (*App)(a)
cfg := config.FromContext(ctx)
Expand Down
4 changes: 4 additions & 0 deletions graphql2/graphqlapp/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func (a *App) OnCallNotificationRule() graphql2.OnCallNotificationRuleResolver {
return (*OnCallNotificationRule)(a)
}

func (a *OnCallNotificationRule) Dest(ctx context.Context, raw *schedule.OnCallNotificationRule) (*graphql2.Destination, error) {
return (*App)(a).CompatNCToDest(ctx, raw.ChannelID)
}

func (a *OnCallNotificationRule) Target(ctx context.Context, raw *schedule.OnCallNotificationRule) (*assignment.RawTarget, error) {
ch, err := (*App)(a).FindOneNC(ctx, raw.ChannelID)
if err != nil {
Expand Down
7 changes: 3 additions & 4 deletions graphql2/models_gen.go

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

1 change: 1 addition & 0 deletions graphql2/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ input OnCallNotificationRuleInput {
type OnCallNotificationRule {
id: ID!
target: Target!
dest: Destination! @experimental(flagName: "dest-types")
time: ClockTime
weekdayFilter: WeekdayFilter
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,8 @@ export interface DebugSendSMSInput {
}

export interface Destination {
display: DestinationDisplayInfo
displayInfo: DestinationDisplayInfo
type: DestinationType
typeInfo: DestinationTypeInfo
values: FieldValuePair[]
}

Expand Down Expand Up @@ -662,6 +661,7 @@ export interface NotificationState {
export type NotificationStatus = 'ERROR' | 'OK' | 'WARN'

export interface OnCallNotificationRule {
dest: Destination
id: string
target: Target
time?: null | ClockTime
Expand Down
Loading