Skip to content

Commit

Permalink
feat(destinations): add custom header auth and secureUrl to destinati…
Browse files Browse the repository at this point in the history
…ons (#1122)

Co-authored-by: pranav-new-relic <[email protected]>
  • Loading branch information
nzur-newrelic and pranav-new-relic authored Apr 19, 2024
1 parent 1e6c60d commit 7c6b35f
Show file tree
Hide file tree
Showing 5 changed files with 405 additions and 13 deletions.
6 changes: 6 additions & 0 deletions .tutone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1032,10 +1032,16 @@ packages:
- name: AiNotificationsDestination
- name: AiNotificationsCredentialsInput
field_type_override: "*AiNotificationsCredentialsInput"
- name: AiNotificationsSecureURLInput
field_type_override: "*AiNotificationsSecureURLInput"
- name: AiNotificationsSecureURLUpdate
field_type_override: "*AiNotificationsSecureURLUpdate"
- name: AiNotificationsAuth
field_type_override: "ai.AiNotificationsAuth"
- name: AiNotificationsError
field_type_override: "ai.AiNotificationsError"
- name: AiNotificationsCustomHeadersAuthInput
field_type_override: "*AiNotificationsCustomHeadersAuthInput"
- name: ID
field_type_override: string
skip_type_create: true
Expand Down
76 changes: 76 additions & 0 deletions pkg/ai/types_ai.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ type AiNotificationsTokenAuth struct {
Prefix string `json:"prefix"`
}

func (x AiNotificationsTokenAuth) GetCustomHeaders() []AiNotificationsCustomHeaders {
return nil
}

func (x AiNotificationsTokenAuth) GetAccessTokenURL() string {
return ""
}
Expand Down Expand Up @@ -268,6 +272,10 @@ type AiNotificationsBasicAuth struct {
User string `json:"user"`
}

func (x AiNotificationsBasicAuth) GetCustomHeaders() []AiNotificationsCustomHeaders {
return nil
}

// GetAuthType returns a pointer to the value of AuthType from AiNotificationsBasicAuth
func (x AiNotificationsBasicAuth) GetAuthType() AiNotificationsAuthType {
return x.AuthType
Expand Down Expand Up @@ -390,6 +398,8 @@ type AiNotificationsAuth struct {
Password SecureValue `json:"password,omitempty"`
// Basic auth user
User string `json:"user,omitempty"`
// Custom headers
CustomHeaders []AiNotificationsCustomHeaders `json:"customHeaders,omitempty"`
}

func (x *AiNotificationsAuth) ImplementsAiNotificationsAuth() {}
Expand All @@ -405,8 +415,64 @@ type AiNotificationsAuthInterface interface {
GetRefreshInterval() int
GetRefreshable() bool
GetScope() string
GetCustomHeaders() []AiNotificationsCustomHeaders
}

// AiNotificationsCustomHeaders - Custom headers
type AiNotificationsCustomHeaders struct {
Key string `json:"key"`
}

// AiNotificationsCustomHeadersAuth - Custom headers based authentication
type AiNotificationsCustomHeadersAuth struct {
// Authentication Type - CustomHeaders
AuthType AiNotificationsAuthType `json:"authType"`
// Custom headers
CustomHeaders []AiNotificationsCustomHeaders `json:"customHeaders"`
}

func (x AiNotificationsCustomHeadersAuth) GetUser() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetPrefix() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetAccessTokenURL() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetAuthorizationURL() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetClientId() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetRefreshInterval() int {
return 0
}

func (x AiNotificationsCustomHeadersAuth) GetRefreshable() bool {
return false
}

func (x AiNotificationsCustomHeadersAuth) GetScope() string {
return ""
}

func (x AiNotificationsCustomHeadersAuth) GetAuthType() AiNotificationsAuthType {
return x.AuthType
}

func (x AiNotificationsCustomHeadersAuth) GetCustomHeaders() []AiNotificationsCustomHeaders {
return x.CustomHeaders
}

func (x AiNotificationsCustomHeadersAuth) ImplementsAiNotificationsAuth() {}

// UnmarshalAiNotificationsAuthInterface unmarshals the interface into the correct type
// based on __typename provided by GraphQL
func UnmarshalAiNotificationsAuthInterface(b []byte) (*AiNotificationsAuthInterface, error) {
Expand Down Expand Up @@ -451,6 +517,16 @@ func UnmarshalAiNotificationsAuthInterface(b []byte) (*AiNotificationsAuthInterf

var xxx AiNotificationsAuthInterface = &interfaceType

return &xxx, nil
case "AiNotificationsCustomHeadersAuth":
var interfaceType AiNotificationsCustomHeadersAuth
err = json.Unmarshal(b, &interfaceType)
if err != nil {
return nil, err
}

var xxx AiNotificationsAuthInterface = &interfaceType

return &xxx, nil
}
} else {
Expand Down
29 changes: 28 additions & 1 deletion pkg/notifications/notifications_api.go

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

176 changes: 176 additions & 0 deletions pkg/notifications/notifications_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,182 @@ func TestNotificationMutationDestination_FilterByName(t *testing.T) {
require.NotNil(t, deleteResult)
}

func TestNotificationMutationDestination_CustomHeaderAuth(t *testing.T) {
t.Parallel()

n := newIntegrationTestClient(t)

accountID, err := mock.GetTestAccountID()
if err != nil {
t.Skipf("%s", err)
}

// Create a destination to work with in this test
testIntegrationDestinationNameRandStr := mock.RandSeq(5)
destination := AiNotificationsDestinationInput{}
destination.Type = AiNotificationsDestinationTypeTypes.WEBHOOK
destination.Properties = []AiNotificationsPropertyInput{
{
Key: "url",
Value: "https://webhook.site/94193c01-4a81-4782-8f1b-554d5230395b",
Label: "",
DisplayValue: "",
},
}
destination.Auth = &AiNotificationsCredentialsInput{
Type: AiNotificationsAuthTypeTypes.CUSTOM_HEADERS,
CustomHeaders: &AiNotificationsCustomHeadersAuthInput{
[]AiNotificationsCustomHeaderInput{
{Key: "key1", Value: "value1"},
{Key: "key2", Value: "value2"},
{Key: "key3", Value: "value3"},
},
},
}
destination.Name = fmt.Sprintf("test-notifications-destination-%s", testIntegrationDestinationNameRandStr)

// Test: Create
createResult, err := n.AiNotificationsCreateDestination(accountID, destination)
require.NoError(t, err)
require.NotNil(t, createResult)
require.NotEmpty(t, createResult.Destination.Auth)
require.Equal(t, ai.AiNotificationsAuthType("CUSTOM_HEADERS"), createResult.Destination.Auth.AuthType)
require.Equal(t, 3, len(createResult.Destination.Auth.CustomHeaders))
require.Equal(t, "key1", createResult.Destination.Auth.CustomHeaders[0].Key)
require.Equal(t, "key2", createResult.Destination.Auth.CustomHeaders[1].Key)
require.Equal(t, "key3", createResult.Destination.Auth.CustomHeaders[2].Key)

// Test: Get Destination by id
filters := ai.AiNotificationsDestinationFilter{
ID: createResult.Destination.ID,
}
sorter := AiNotificationsDestinationSorter{}
getDestinationResult, err := n.GetDestinations(accountID, "", filters, sorter)
require.NoError(t, err)
require.NotNil(t, getDestinationResult)
assert.Equal(t, 1, getDestinationResult.TotalCount)
require.NotEmpty(t, getDestinationResult.Entities[0].GUID)
require.Equal(t, ai.AiNotificationsAuthType("CUSTOM_HEADERS"), getDestinationResult.Entities[0].Auth.AuthType)
require.Equal(t, 3, len(getDestinationResult.Entities[0].Auth.CustomHeaders))
require.Equal(t, "key1", getDestinationResult.Entities[0].Auth.CustomHeaders[0].Key)
require.Equal(t, "key2", getDestinationResult.Entities[0].Auth.CustomHeaders[1].Key)
require.Equal(t, "key3", getDestinationResult.Entities[0].Auth.CustomHeaders[2].Key)

// Test: Update Destination
updateDestination := AiNotificationsDestinationUpdate{}
updateDestination.Active = false
updateDestination.Properties = []AiNotificationsPropertyInput{
{
Key: "url",
Value: "https://webhook.site/94193c01-4a81-4782-8f1b-554d5230395b",
Label: "",
DisplayValue: "",
},
}
updateDestination.Auth = &AiNotificationsCredentialsInput{
Type: AiNotificationsAuthTypeTypes.CUSTOM_HEADERS,
CustomHeaders: &AiNotificationsCustomHeadersAuthInput{
[]AiNotificationsCustomHeaderInput{
{Key: "key1", Value: "value1"},
{Key: "key4", Value: "value4"},
},
},
}
updateDestination.Name = fmt.Sprintf("test-notifications-update-destination-%s", testIntegrationDestinationNameRandStr)

updateDestinationResult, err := n.AiNotificationsUpdateDestination(accountID, updateDestination, createResult.Destination.ID)
require.NoError(t, err)
require.NotNil(t, updateDestinationResult)
require.Equal(t, ai.AiNotificationsAuthType("CUSTOM_HEADERS"), updateDestinationResult.Destination.Auth.AuthType)
require.Equal(t, 2, len(updateDestinationResult.Destination.Auth.CustomHeaders))
require.Equal(t, "key1", updateDestinationResult.Destination.Auth.CustomHeaders[0].Key)
require.Equal(t, "key4", updateDestinationResult.Destination.Auth.CustomHeaders[1].Key)

// Test: Delete
deleteResult, err := n.AiNotificationsDeleteDestination(accountID, createResult.Destination.ID)
require.NoError(t, err)
require.NotNil(t, deleteResult)
}

func TestNotificationMutationDestination_secureUrl(t *testing.T) {
t.Parallel()

n := newIntegrationTestClient(t)

accountID, err := mock.GetTestAccountID()
if err != nil {
t.Skipf("%s", err)
}

// Create a destination to work with in this test
testIntegrationDestinationNameRandStr := mock.RandSeq(5)
destination := AiNotificationsDestinationInput{}
destination.Type = AiNotificationsDestinationTypeTypes.WEBHOOK
destination.Properties = []AiNotificationsPropertyInput{}
destination.SecureURL = &AiNotificationsSecureURLInput{
Prefix: "https://webhook.site",
SecureSuffix: "/94193c01-4a81-4782-8f1b-554d5230395b",
}
destination.Auth = &AiNotificationsCredentialsInput{
Type: AiNotificationsAuthTypeTypes.TOKEN,
Token: AiNotificationsTokenAuthInput{
Token: "Token",
Prefix: "Bearer",
},
}
destination.Name = fmt.Sprintf("test-notifications-destination-%s", testIntegrationDestinationNameRandStr)

// Test: Create
createResult, err := n.AiNotificationsCreateDestination(accountID, destination)
require.NoError(t, err)
require.NotNil(t, createResult)
require.NotNil(t, createResult.Destination.SecureURL)
require.Equal(t, createResult.Destination.SecureURL.Prefix, "https://webhook.site")
require.NotEmpty(t, createResult.Destination.Auth)
require.Equal(t, ai.AiNotificationsAuthType("TOKEN"), createResult.Destination.Auth.AuthType)

// Test: Get Destination by id
filters := ai.AiNotificationsDestinationFilter{
ID: createResult.Destination.ID,
}
sorter := AiNotificationsDestinationSorter{}
getDestinationResult, err := n.GetDestinations(accountID, "", filters, sorter)
require.NoError(t, err)
require.NotNil(t, getDestinationResult)
assert.Equal(t, 1, getDestinationResult.TotalCount)
require.NotEmpty(t, getDestinationResult.Entities[0].GUID)
require.NotNil(t, getDestinationResult.Entities[0].SecureURL)
require.Equal(t, getDestinationResult.Entities[0].SecureURL.Prefix, "https://webhook.site")

// Test: Update Destination
updateDestination := AiNotificationsDestinationUpdate{}
updateDestination.Active = false
updateDestination.Properties = []AiNotificationsPropertyInput{}
updateDestination.SecureURL = &AiNotificationsSecureURLUpdate{
Prefix: "https://webhook2.site",
SecureSuffix: "/59bb0d7a-1708-481a-a178-9161416f8ba6",
}
updateDestination.Auth = &AiNotificationsCredentialsInput{
Type: AiNotificationsAuthTypeTypes.TOKEN,
Token: AiNotificationsTokenAuthInput{
Token: "TokenUpdate",
Prefix: "BearerUpdate",
},
}
updateDestination.Name = fmt.Sprintf("test-notifications-update-destination-%s", testIntegrationDestinationNameRandStr)

updateDestinationResult, err := n.AiNotificationsUpdateDestination(accountID, updateDestination, createResult.Destination.ID)
require.NoError(t, err)
require.NotNil(t, updateDestinationResult)
require.NotNil(t, updateDestinationResult.Destination.SecureURL)
require.Equal(t, updateDestinationResult.Destination.SecureURL.Prefix, "https://webhook2.site")

// Test: Delete
deleteResult, err := n.AiNotificationsDeleteDestination(accountID, createResult.Destination.ID)
require.NoError(t, err)
require.NotNil(t, deleteResult)
}

func TestNotificationMutationChannel(t *testing.T) {
t.Parallel()

Expand Down
Loading

0 comments on commit 7c6b35f

Please sign in to comment.