Skip to content

Commit

Permalink
graphql: destinations: add dest as a field on OnCallNotificationRule (
Browse files Browse the repository at this point in the history
#3659)

* remove unused `typeInfo` and rename `displayInfo`

* add resolver and sched dest field

* update schema
  • Loading branch information
mastercactapus authored Feb 7, 2024
1 parent 5951311 commit d839c36
Show file tree
Hide file tree
Showing 8 changed files with 343 additions and 130 deletions.
349 changes: 229 additions & 120 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
81 changes: 81 additions & 0 deletions graphql2/graphqlapp/compat.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,91 @@
package graphqlapp

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

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

// 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)
}
}

// CompatDestToCMTypeVal converts a graphql2.DestinationInput to a contactmethod.Type and string value
// for the built-in destination types.
func CompatDestToCMTypeVal(d graphql2.DestinationInput) (contactmethod.Type, string) {
Expand Down
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 @@ -343,9 +343,8 @@ export interface DebugSendSMSInput {
}

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

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

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

0 comments on commit d839c36

Please sign in to comment.