From 1a36fd43acda72c947714433c3968217e2fa3928 Mon Sep 17 00:00:00 2001 From: vagrawal-newrelic Date: Fri, 25 Oct 2024 12:54:11 +0530 Subject: [PATCH] fix(azure link account): Add update capability for all feilds in azure link account fix(azure link account): remove argument override fix(azure link account): add update capability for all fields in azure cloud link account --- .tutone.yml | 6 ++ pkg/cloud/cloud_api.go | 55 ++++++++++++ pkg/cloud/cloud_api_integration_test.go | 16 ++++ pkg/cloud/cloud_api_unit_test.go | 51 +++++++++++ pkg/cloud/types.go | 110 ++++++++++++++++++++++++ 5 files changed, 238 insertions(+) diff --git a/.tutone.yml b/.tutone.yml index 15c697b34..5d989b156 100644 --- a/.tutone.yml +++ b/.tutone.yml @@ -475,6 +475,12 @@ packages: argument_type_overrides: accountId: "Int!" accounts: "[CloudUnlinkAccountsInput!]!" + - name: cloudUpdateAccount + max_query_field_depth: 3 + exclude_fields: + - "integration" + - "integrations" + - "provider" types: # # Types that we should auto-detect are in another package someday diff --git a/pkg/cloud/cloud_api.go b/pkg/cloud/cloud_api.go index 9fa189db2..18ddf543a 100644 --- a/pkg/cloud/cloud_api.go +++ b/pkg/cloud/cloud_api.go @@ -1808,6 +1808,61 @@ const CloudUnlinkAccountMutation = `mutation( } } }` +// Update one or more Cloud Provider accounts to a NewRelic account. Updates each Linked account with the passed parameters. +func (a *Cloud) CloudUpdateAccount( + accountID int, + accounts CloudUpdateCloudAccountsInput, +) (*CloudUpdateAccountPayload, error) { + return a.CloudUpdateAccountWithContext(context.Background(), + accountID, + accounts, + ) +} + +// Update one or more Cloud Provider accounts to a NewRelic account. Updates each Linked account with the passed parameters. +func (a *Cloud) CloudUpdateAccountWithContext( + ctx context.Context, + accountID int, + accounts CloudUpdateCloudAccountsInput, +) (*CloudUpdateAccountPayload, error) { + + resp := CloudUpdateAccountQueryResponse{} + vars := map[string]interface{}{ + "accountId": accountID, + "accounts": accounts, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, CloudUpdateAccountMutation, vars, &resp); err != nil { + return nil, err + } + + return &resp.CloudUpdateAccountPayload, nil +} + +type CloudUpdateAccountQueryResponse struct { + CloudUpdateAccountPayload CloudUpdateAccountPayload `json:"CloudUpdateAccount"` +} + +const CloudUpdateAccountMutation = `mutation( + $accountId: Int!, + $accounts: CloudUpdateCloudAccountsInput!, +) { cloudUpdateAccount( + accountId: $accountId, + accounts: $accounts, +) { + linkedAccounts { + authLabel + createdAt + disabled + externalId + id + metricCollectionMode + name + nrAccountId + updatedAt + } +} }` + // Get one linked provider account. func (a *Cloud) GetLinkedAccount( accountID int, diff --git a/pkg/cloud/cloud_api_integration_test.go b/pkg/cloud/cloud_api_integration_test.go index 0a7ed828b..6c3e27d64 100644 --- a/pkg/cloud/cloud_api_integration_test.go +++ b/pkg/cloud/cloud_api_integration_test.go @@ -329,6 +329,22 @@ func TestCloudAccount_AzureMonitorIntegration(t *testing.T) { require.NoError(t, err) require.NotNil(t, linkResponse) + //integration-test to test Azure link account update mutation + updateResponse, err := client.CloudUpdateAccount(testAccountID, CloudUpdateCloudAccountsInput{ + Azure: []CloudAzureUpdateAccountInput{ + { + Name: "TEST_AZURE_ACCOUNT_UPDATED", + ApplicationID: azureCredentials["INTEGRATION_TESTING_AZURE_APPLICATION_ID"], + ClientSecret: SecureValue(azureCredentials["INTEGRATION_TESTING_AZURE_CLIENT_SECRET_ID"]), + SubscriptionId: azureCredentials["INTEGRATION_TESTING_AZURE_SUBSCRIPTION_ID"], + TenantId: azureCredentials["INTEGRATION_TESTING_AZURE_TENANT_ID"], + LinkedAccountId: linkResponse.LinkedAccounts[0].ID, + }, + }, + }) + require.NoError(t, err) + require.NotNil(t, updateResponse) + require.Equal(t, "TEST_AZURE_ACCOUNT_UPDATED", updateResponse.LinkedAccounts[0].Name) // Get the linked account getResponse, err = client.GetLinkedAccounts("azure") diff --git a/pkg/cloud/cloud_api_unit_test.go b/pkg/cloud/cloud_api_unit_test.go index c130b8a01..8aed06f34 100644 --- a/pkg/cloud/cloud_api_unit_test.go +++ b/pkg/cloud/cloud_api_unit_test.go @@ -63,6 +63,26 @@ var ( }` linkedAccountID = fmt.Sprintf("%06d", rand.Int63n(1e6)) nrAccountID = fmt.Sprintf("%06d", rand.Int63n(1e6)) + + testUpdateAzureLinkAccount = ` +{ + "data": { + "cloudUpdateAccount": { + "linkedAccounts": [ + { + "authLabel": "36840357-ac3e-4273-94f0-eccg108ff0e9", + "disabled": false, + "externalId": "agjs-dha57-687hag-shgafshd-f79hh", + "id": ` + linkedAccountID + `, + "name": "TEST_AZURE_ACCOUNT_UPDATED", + "nrAccountId": ` + nrAccountID + `, + "updatedAt": 1729674748 + } + ] + } + } +} + ` ) // Unit Test to test the creation of an Azure Monitor. @@ -150,3 +170,34 @@ func newMockResponse(t *testing.T, mockJSONResponse string, statusCode int) Clou return New(tc) } + +// unit test to test azure link account update mutation +func TestUnitAzureLinkAccountUpdate(t *testing.T) { + t.Parallel() + azureUpdateAccountResponse := newMockResponse(t, testUpdateAzureLinkAccount, http.StatusOK) + NRAccountIDInt, _ := strconv.Atoi(nrAccountID) + linkedAccountIDInt, _ := strconv.Atoi(linkedAccountID) + disabled := false + + updateAccountInput := CloudUpdateCloudAccountsInput{ + Azure: []CloudAzureUpdateAccountInput{{ + ApplicationID: "36840357-ac3e-4273-94f0-eccg108ff0e9", + ClientSecret: "gdsajysgda676t5ahgsdhafsdga67as", + Disabled: &disabled, + LinkedAccountId: linkedAccountIDInt, + Name: "TEST_AZURE_ACCOUNT-UPDATED", + SubscriptionId: "agjs-dha57-687hag-shgafshd-f79hh", + TenantId: "ajkhsdjkas676hjgasdhjga687yhhj", + }}, + } + + actual, err := azureUpdateAccountResponse.CloudUpdateAccount(NRAccountIDInt, updateAccountInput) + + assert.NoError(t, err) + assert.NotNil(t, actual) + assert.Equal(t, linkedAccountID, strconv.Itoa(actual.LinkedAccounts[0].ID)) + assert.Equal(t, "TEST_AZURE_ACCOUNT_UPDATED", actual.LinkedAccounts[0].Name) + assert.Equal(t, false, actual.LinkedAccounts[0].Disabled) + assert.Equal(t, nrAccountID, strconv.Itoa(actual.LinkedAccounts[0].NrAccountId)) + +} diff --git a/pkg/cloud/types.go b/pkg/cloud/types.go index 2a56b1c15..afd4da063 100644 --- a/pkg/cloud/types.go +++ b/pkg/cloud/types.go @@ -683,6 +683,22 @@ type CloudAwsGovCloudProvider struct { func (x *CloudAwsGovCloudProvider) ImplementsCloudProvider() {} +// CloudAwsGovCloudUpdateAccountInput - Information required to update an AWS GovCloud account to a NewRelic account. +type CloudAwsGovCloudUpdateAccountInput struct { + // The key used to make requests to AWS service APIs + AccessKeyId string `json:"accessKeyId,omitempty"` + // The AWS account id + AwsAccountId string `json:"awsAccountId,omitempty"` + // Disable the linked account. + Disabled bool `json:"disabled,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` + // The secret key used to make requests to AWS service APIs + SecretAccessKey SecureValue `json:"secretAccessKey,omitempty"` +} + // CloudAwsGovcloudDisableIntegrationsInput - List of integrations type CloudAwsGovcloudDisableIntegrationsInput struct { // API Gateway integration @@ -1405,6 +1421,18 @@ type CloudAwsTransitgatewayIntegrationInput struct { MetricsPollingInterval int `json:"metricsPollingInterval,omitempty"` } +// CloudAwsUpdateAccountInput - Information required to update a AWS account to a NewRelic account. +type CloudAwsUpdateAccountInput struct { + // The AWS role ARN (used to fetch data). + Arn string `json:"arn,omitempty"` + // Disable the linked account. + Disabled bool `json:"disabled,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` +} + // CloudAwsWafIntegration - WAF Integration type CloudAwsWafIntegration struct { // Specify each AWS region that includes the resources that you want to monitor. @@ -2749,6 +2777,24 @@ type CloudAzureStorageIntegrationInput struct { ResourceGroups []string `json:"resourceGroups,omitempty"` } +// CloudAzureUpdateAccountInput - Information required to update a Azure account to a NewRelic account. +type CloudAzureUpdateAccountInput struct { + // The Azure account application identifier (used to fetch data). + ApplicationID string `json:"applicationId,omitempty"` + // The Azure account application secret key. + ClientSecret SecureValue `json:"clientSecret,omitempty"` + // Disable the linked account. + Disabled *bool `json:"disabled,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` + // The Azure account subscription identifier. + SubscriptionId string `json:"subscriptionId,omitempty"` + // The Azure account tenant identifier. + TenantId string `json:"tenantId,omitempty"` +} + // CloudAzureVirtualmachineIntegration - Virtual machine scale sets Integration type CloudAzureVirtualmachineIntegration struct { // The object creation date, in epoch (Unix) time @@ -3120,6 +3166,22 @@ func (x *CloudConfigureIntegrationPayload) UnmarshalJSON(b []byte) error { return nil } +// CloudConfluentUpdateAccountInput - Information required to update a Confluent Cloud account to a NewRelic account. +type CloudConfluentUpdateAccountInput struct { + // The Confluent account API key. + APIKey SecureValue `json:"apiKey"` + // The Confluent Cloud account API Secret key. + APISecret SecureValue `json:"apiSecret"` + // Disable the linked account. + Disabled bool `json:"disabled,omitempty"` + // The Confluent Cloud account identifier. + ExternalId string `json:"externalId,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` +} + // CloudDashboardTemplate - A cloud service dashboard template. type CloudDashboardTemplate struct { // The object creation date, in epoch (Unix) time @@ -3713,6 +3775,20 @@ type CloudEmrIntegrationInput struct { TagValue string `json:"tagValue,omitempty"` } +// CloudFossaUpdateAccountInput - Information required to update a Fossa account to a NewRelic account. +type CloudFossaUpdateAccountInput struct { + // The Fossa account application api key(bearer token). + APIKey SecureValue `json:"apiKey"` + // Disable the linked account. + Disabled bool `json:"disabled,omitempty"` + // The Fossa account identifier. + ExternalId string `json:"externalId,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` +} + // CloudGcpAiplatformIntegration - Vertex AI Integration type CloudGcpAiplatformIntegration struct { // The object creation date, in epoch (Unix) time @@ -4733,6 +4809,18 @@ type CloudGcpStorageIntegrationInput struct { MetricsPollingInterval int `json:"metricsPollingInterval,omitempty"` } +// CloudGcpUpdateAccountInput - Information required to update a GCP account to a NewRelic account. +type CloudGcpUpdateAccountInput struct { + // Disable the linked account. + Disabled bool `json:"disabled,omitempty"` + // The linked account identifier. + LinkedAccountId int `json:"linkedAccountId"` + // The linked account new name. + Name string `json:"name,omitempty"` + // The GCP project identifier. + ProjectId string `json:"projectId,omitempty"` +} + // CloudGcpVmsIntegration - Compute Engine Integration type CloudGcpVmsIntegration struct { // The object creation date, in epoch (Unix) time @@ -5780,6 +5868,28 @@ type CloudUnlinkAccountsInput struct { LinkedAccountId int `json:"linkedAccountId"` } +// CloudUpdateAccountPayload - Autogenerated return type of UpdateAccount +type CloudUpdateAccountPayload struct { + // The updated Linked accounts. + LinkedAccounts []CloudLinkedAccount `json:"linkedAccounts"` +} + +// CloudUpdateCloudAccountsInput - Specific Cloud provider information required to update the Cloud provider account to a NewRelic account. +type CloudUpdateCloudAccountsInput struct { + // Aws provider + Aws []CloudAwsUpdateAccountInput `json:"aws,omitempty"` + // AwsGovCloud provider + AwsGovcloud []CloudAwsGovCloudUpdateAccountInput `json:"awsGovcloud,omitempty"` + // Azure provider + Azure []CloudAzureUpdateAccountInput `json:"azure,omitempty"` + // Confluent Cloud provider + Confluent []CloudConfluentUpdateAccountInput `json:"confluent,omitempty"` + // Fossa provider + Fossa []CloudFossaUpdateAccountInput `json:"fossa,omitempty"` + // Gcp provider + Gcp []CloudGcpUpdateAccountInput `json:"gcp,omitempty"` +} + // CloudVpcIntegration - VPC Integration type CloudVpcIntegration struct { // Specify each AWS region that includes the resources that you want to monitor.