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

feat: add organizationRevokeSharedAccount and accountManagementCancelAccount mutations #1187

6 changes: 4 additions & 2 deletions .tutone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ packages:
max_query_field_depth: 3
- name: accountManagementUpdateAccount
max_query_field_depth: 3
- name: accountManagementCancelAccount
max_query_field_depth: 3

- name: accounts
path: pkg/accounts
Expand Down Expand Up @@ -1242,8 +1244,8 @@ packages:
max_query_field_depth: 2
# - name: organizationCreateSharedAccount
# max_query_field_depth: 2
# - name: organizationRevokeSharedAccount
# max_query_field_depth: 2
- name: organizationRevokeSharedAccount
max_query_field_depth: 2
- name: organizationUpdateSharedAccount
max_query_field_depth: 2
types:
Expand Down
48 changes: 48 additions & 0 deletions pkg/accountmanagement/accountmanagement_api.go

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

73 changes: 73 additions & 0 deletions pkg/accountmanagement/accountmanagement_api_.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Code **NOT** generated by tutone
package accountmanagement

import (
"context"

"github.com/newrelic/newrelic-client-go/v2/pkg/errors"
)

// --------------------------------------------------------------------
// NOTE: (for the maintainers and users of newrelic-client-go)
// --------------------------------------------------------------------
// The function `GetManagedAccountsWithAdditionalArguments`, function `GetManagedAccountsWithAdditionalArgumentsWithContext` and the query `getManagedAccountsWithAdditionalArgumentsQuery` in this file
// are "modified" versions of the function `GetManagedAccounts`, the function `GetManagedAccountsWithContext` and the query `getManagedAccountsQuery` respectively,
// originally defined in accountmanagement_api.go.
//
// These manual modifications had to be written owing to the introduction of a new input (and output) field to the `getManagedAccountsQuery`, "isCanceled", which
// is causing conflicts with the Tutone generated code; see the PR linked to this change for more details on the exact limitations.
//
// Owing to this, in order to facilitate using these functions with the isCanceled attribute, modified versions of the functions and mutations have been added to
// this file. This would also allow us to ensure the older counterparts of these functions defined in accountmanagement_api.go inflict no breaking changes onto upstream
// services, such as the New Relic Terraform Provider. While we shall aim to bring this under Tutone's scope, please use the functions in this file to use the "isCanceled"
// attribute recently added to this query.
//
// TL;DR The functions in this file are NOT Tutone generated; we would eventually need to move functionalities in these duplicated functions into the original ones
// in accountmanagement_api.go .

// Admin-level info about the accounts in an organization.
func (a *Accountmanagement) GetManagedAccountsWithAdditionalArguments(
isCanceled *bool,
) (*[]AccountManagementManagedAccount, error) {
return a.GetManagedAccountsWithAdditionalArgumentsWithContext(context.Background(),
isCanceled,
)
}

// Admin-level info about the accounts in an organization.
func (a *Accountmanagement) GetManagedAccountsWithAdditionalArgumentsWithContext(
ctx context.Context,
isCanceled *bool,
) (*[]AccountManagementManagedAccount, error) {

resp := managedAccountsResponse{}
vars := map[string]interface{}{
"isCanceled": &isCanceled,
}

if err := a.client.NerdGraphQueryWithContext(ctx, getManagedAccountsWithAdditionalArgumentsQuery, vars, &resp); err != nil {
return nil, err
}

if len(resp.Actor.Organization.AccountManagement.ManagedAccounts) == 0 {
return nil, errors.NewNotFound("")
}

return &resp.Actor.Organization.AccountManagement.ManagedAccounts, nil
}

const getManagedAccountsWithAdditionalArgumentsQuery = `query ($isCanceled: Boolean) {
actor {
organization {
accountManagement {
managedAccounts(isCanceled: $isCanceled) {
id
isCanceled
name
regionCode
}
}
}
}
}
`
137 changes: 137 additions & 0 deletions pkg/accountmanagement/accountmanagement_integration_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package accountmanagement

import (
"log"
"testing"
"time"

"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -64,3 +66,138 @@ func TestIntegrationUpdateAccountError(t *testing.T) {
require.Nil(t, actual)
require.NotNil(t, err)
}

func TestIntegrationAccountManagement_CreateUpdateCancelAccount(t *testing.T) {
t.Parallel()
accountManagementClient := newAccountManagementTestClient(t)

// Create Account
name := "client-go-test-account-" + mock.RandSeq(5)
createAccountInput := AccountManagementCreateInput{
Name: name,
RegionCode: "us01",
}
createAccountResponse, err := accountManagementClient.AccountManagementCreateAccount(createAccountInput)

require.Nil(t, err)
require.NotNil(t, createAccountResponse.ManagedAccount.ID)
require.Equal(t, createAccountInput.RegionCode, createAccountResponse.ManagedAccount.RegionCode)
require.Equal(t, createAccountInput.Name, createAccountResponse.ManagedAccount.Name)
time.Sleep(time.Second * 2)

// Update Account
updateAccountInput := AccountManagementUpdateInput{
ID: createAccountResponse.ManagedAccount.ID,
Name: name + "-updated",
}
updateAccountResponse, err := accountManagementClient.AccountManagementUpdateAccount(updateAccountInput)

require.Nil(t, err)
require.NotNil(t, updateAccountResponse.ManagedAccount.ID)
require.Equal(t, updateAccountResponse.ManagedAccount.ID, createAccountResponse.ManagedAccount.ID)
require.Equal(t, updateAccountInput.Name, updateAccountResponse.ManagedAccount.Name)
time.Sleep(time.Second * 3)

// Get Account
getAccountResponse, err := accountManagementClient.GetManagedAccounts()

require.Nil(t, err)
require.NotNil(t, getAccountResponse)
foundAccountInGetResponse := false

for _, account := range *getAccountResponse {
if account.ID == updateAccountResponse.ManagedAccount.ID {
foundAccountInGetResponse = true
break
}
}

require.True(t, foundAccountInGetResponse)

// Cancel Account
cancelAccountResponse, err := accountManagementClient.AccountManagementCancelAccount(createAccountResponse.ManagedAccount.ID)

require.Nil(t, err)
require.NotNil(t, cancelAccountResponse)
time.Sleep(time.Second * 2)

// Get Account to Confirm Account Cancellation based on the value of `isCanceled`
isCancelled := true
getAccountResponse, err = accountManagementClient.GetManagedAccountsWithAdditionalArguments(&isCancelled)

require.Nil(t, err)
require.NotNil(t, getAccountResponse)
foundAccountInGetResponse = false

for _, account := range *getAccountResponse {
if account.ID == updateAccountResponse.ManagedAccount.ID {
foundAccountInGetResponse = true
require.True(t, account.IsCanceled)
break
}
}

require.True(t, foundAccountInGetResponse)

}

func TestIntegrationGetManagedAccounts(t *testing.T) {
t.Parallel()
accountManagementClient := newAccountManagementTestClient(t)

actual, _ := accountManagementClient.GetManagedAccounts()

log.Println(actual)
require.NotNil(t, actual)
require.NotZero(t, len(*actual))
}

func TestIntegrationGetManagedAccountsModified_CanceledAccounts(t *testing.T) {
t.Parallel()
accountManagementClient := newAccountManagementTestClient(t)

cancelled := true
actual, _ := accountManagementClient.GetManagedAccountsWithAdditionalArguments(&cancelled)
log.Println(actual)
require.NotNil(t, actual)
require.NotZero(t, len(*actual))
}

func TestIntegrationGetManagedAccountsModified_NonCanceledAccounts(t *testing.T) {
t.Parallel()
accountManagementClient := newAccountManagementTestClient(t)

cancelled := false
actual, _ := accountManagementClient.GetManagedAccountsWithAdditionalArguments(&cancelled)
log.Println(actual)
require.NotNil(t, actual)
require.NotZero(t, len(*actual))
}

func TestIntegrationGetManagedAccountsModified_AllCancellationStatuses(t *testing.T) {
t.Parallel()
accountManagementClient := newAccountManagementTestClient(t)

actual, _ := accountManagementClient.GetManagedAccountsWithAdditionalArguments(nil)

require.NotNil(t, actual)
require.NotZero(t, len(*actual))

foundCancelledAccount := false
foundUncancelledAccount := false

for _, acct := range *actual {
if foundUncancelledAccount == true && foundCancelledAccount == true {
break
}
if acct.IsCanceled == true {
foundCancelledAccount = true
}
if acct.IsCanceled == false {
foundUncancelledAccount = true
}
}

require.True(t, foundCancelledAccount)
require.True(t, foundUncancelledAccount)
}
27 changes: 27 additions & 0 deletions pkg/accountmanagement/accountmanagement_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ var (
"regionCode": "us01"
}
}
}`
testCancelAccountResponseJSON = `{
"accountManagementCancelAccount": {
"id": 3833407,
"isCanceled": true,
"name": "test sub account",
"regionCode": "us01"
}
}`
)

Expand Down Expand Up @@ -78,3 +86,22 @@ func TestCreateAccount(t *testing.T) {
assert.NotNil(t, actual)
assert.Equal(t, expected, actual)
}

func TestCancelAccount(t *testing.T) {
t.Parallel()
respJSON := fmt.Sprintf(`{ "data":%s }`, testCancelAccountResponseJSON)
accountManagement := newMockResponse(t, respJSON, http.StatusCreated)

expected := &AccountManagementManagedAccount{
Name: "test sub account",
RegionCode: "us01",
ID: 3833407,
IsCanceled: true,
}

actual, err := accountManagement.AccountManagementCancelAccount(3833407)

assert.NoError(t, err)
assert.NotNil(t, actual)
assert.Equal(t, expected, actual)
}
13 changes: 13 additions & 0 deletions pkg/accountmanagement/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ package accountmanagement
type AccountManagementCreateInput struct {
// The name of the account.
Name string `json:"name"`
// The id of the managed organization where the account will be created.
OrganizationId int `json:"organizationId,omitempty"`
// The data center region for the account
RegionCode string `json:"regionCode,omitempty"`
}
Expand All @@ -19,6 +21,8 @@ type AccountManagementCreateResponse struct {
type AccountManagementManagedAccount struct {
// The account ID.
ID int `json:"id"`
// True if account is canceled
IsCanceled bool `json:"isCanceled"`
// The name of the account.
Name string `json:"name"`
// The data center region for the account (US or EU).
Expand Down Expand Up @@ -57,6 +61,8 @@ type Organization struct {
AccountManagement AccountManagementOrganizationStitchedFields `json:"accountManagement,omitempty"`
// The customer id for the organization.
CustomerId string `json:"customerId,omitempty"`
// The ID of the organization.
ID int `json:"id,omitempty"`
// The name of the organization.
Name string `json:"name,omitempty"`
// The telemetry id for the organization
Expand All @@ -66,3 +72,10 @@ type Organization struct {
type managedAccountsResponse struct {
Actor Actor `json:"actor"`
}

// ID - The `ID` scalar type represents a unique identifier, often used to
// refetch an object or as key for a cache. The ID type appears in a JSON
// response as a String; however, it is not intended to be human-readable.
// When expected as an input type, any string (such as `"4"`) or integer
// (such as `4`) input value will be accepted as an ID.
type ID string
Loading
Loading