diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8041c47d..fda2e400 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,6 +109,8 @@ jobs: NEW_RELIC_LICENSE_KEY: ${{ secrets.NEW_RELIC_LICENSE_KEY }} NEW_RELIC_REGION: ${{ secrets.NEW_RELIC_REGION }} INTEGRATION_TESTING_AWS_ARN: ${{ secrets.INTEGRATION_TESTING_AWS_ARN }} + INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID: ${{ secrets.INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID}} + INTEGRATION_TESTING_NEW_RELIC_AUTHENTICATION_DOMAIN_ID: ${{ secrets.INTEGRATION_TESTING_NEW_RELIC_AUTHENTICATION_DOMAIN_ID}} - name: Report integration test coverage via Codecov uses: codecov/codecov-action@v3 diff --git a/.tutone.yml b/.tutone.yml index d97ce865..0daf9348 100644 --- a/.tutone.yml +++ b/.tutone.yml @@ -1404,6 +1404,209 @@ packages: - name: DateTime field_type_override: nrtime.DateTime skip_type_create: true + + - name: authorizationmanagement + path: pkg/authorizationmanagement + import_path: github.com/newrelic/newrelic-client-go/v2/pkg/authorizationmanagement + generators: + - typegen + - nerdgraphclient + imports: + - github.com/newrelic/newrelic-client-go/v2/pkg/accounts + - github.com/newrelic/newrelic-client-go/v2/pkg/common + - github.com/newrelic/newrelic-client-go/v2/pkg/nrtime + - github.com/newrelic/newrelic-client-go/v2/pkg/users + queries: + - path: ["actor", "organization", "authorizationManagement"] + endpoints: + - name: roles + max_query_field_depth: 4 + mutations: + - name: authorizationManagementGrantAccess + max_query_field_depth: 3 + - name: authorizationManagementRevokeAccess + max_query_field_depth: 3 + types: + - name: ID + field_type_override: string + skip_type_create: true + - name: DateTime + field_type_override: nrtime.DateTime + skip_type_create: true + + - name: organization + path: pkg/organization + import_path: github.com/newrelic/newrelic-client-go/v2/pkg/organization + generators: + - typegen + - nerdgraphclient + imports: + - github.com/newrelic/newrelic-client-go/v2/pkg/accounts + - github.com/newrelic/newrelic-client-go/v2/pkg/common + - github.com/newrelic/newrelic-client-go/v2/pkg/nrtime + - github.com/newrelic/newrelic-client-go/v2/pkg/users + queries: [] + mutations: + - name: organizationCreate + max_query_field_depth: 2 + - name: organizationUpdate + max_query_field_depth: 2 +# - name: organizationCreateSharedAccount +# max_query_field_depth: 2 +# - name: organizationRevokeSharedAccount +# max_query_field_depth: 2 +# - name: organizationUpdateSharedAccount +# max_query_field_depth: 2 + types: + - name: OrganizationNewManagedAccountInput + field_type_override: "*OrganizationNewManagedAccountInput" + - name: OrganizationSharedAccountInput + field_type_override: "*OrganizationSharedAccountInput" + - name: ID + field_type_override: string + skip_type_create: true + - name: DateTime + field_type_override: nrtime.DateTime + skip_type_create: true + + - name: customeradministration + path: pkg/customeradministration + import_path: github.com/newrelic/newrelic-client-go/v2/pkg/customeradministration + generators: + - typegen + - nerdgraphclient + imports: + - github.com/newrelic/newrelic-client-go/v2/pkg/accounts + - github.com/newrelic/newrelic-client-go/v2/pkg/common + - github.com/newrelic/newrelic-client-go/v2/pkg/nrtime + - github.com/newrelic/newrelic-client-go/v2/pkg/users + queries: + - path: ["customerAdministration"] + endpoints: + - name: accountShares + max_query_field_depth: 4 + - name: accounts + max_query_field_depth: 4 + - name: authenticationDomains + max_query_field_depth: 4 + - name: consumption + max_query_field_depth: 4 + - name: contracts + max_query_field_depth: 4 + - name: grants + max_query_field_depth: 4 + - name: groups + max_query_field_depth: 4 + - name: jobs + max_query_field_depth: 4 + - name: organizations + max_query_field_depth: 4 + - name: permissions + max_query_field_depth: 4 + - name: roles + max_query_field_depth: 4 + - name: user + max_query_field_depth: 4 + - name: users + max_query_field_depth: 4 + - path: ["customerAdministration", "jobs"] + endpoints: + - name: organizationCreateAsyncResults + max_query_field_depth: 4 + types: + - name: OrganizationAccountShareFilterInput + - name: OrganizationAccountShareSortInput + - name: OrganizationAccountFilterInput + - name: OrganizationAccountSortInput + - name: OrganizationAuthenticationDomainFilterInput + - name: OrganizationAuthenticationDomainSortInput + - name: OrganizationCustomerContractFilterInput + - name: MultiTenantAuthorizationGrantFilterInputExpression + - name: MultiTenantAuthorizationGrantSortInput + - name: MultiTenantIdentityGroupFilterInput + - name: MultiTenantIdentityGroupSortInput + - name: OrganizationCustomerOrganizationFilterInput + - name: MultiTenantAuthorizationPermissionFilter + - name: MultiTenantAuthorizationRoleFilterInputExpression + - name: MultiTenantAuthorizationRoleSortInput + - name: MultiTenantIdentityUserFilterInput + - name: MultiTenantIdentityUserSortInput + # overrides associated with types starting with MultiTenantIdentityGroupFilterInput + # which is used in the 'groups' endpoint in customerAdministration + - name: MultiTenantIdentityAllowsCapabilityInput + field_type_override: "*MultiTenantIdentityAllowsCapabilityInput" + - name: MultiTenantIdentityAuthenticationDomainIdInput + field_type_override: "*MultiTenantIdentityAuthenticationDomainIdInput" + - name: MultiTenantIdentityGroupIdInput + field_type_override: "*MultiTenantIdentityGroupIdInput" + - name: MultiTenantIdentityGroupMemberIdInput + field_type_override: "*MultiTenantIdentityGroupMemberIdInput" + - name: MultiTenantIdentityGroupNameInput + field_type_override: "*MultiTenantIdentityGroupNameInput" + - name: MultiTenantIdentityOrganizationIdInput + field_type_override: "*MultiTenantIdentityOrganizationIdInput" + # overrides associated with types starting with MultiTenantIdentityUserFilterInput + # which is used in the 'users' endpoint in customerAdministration + - name: MultiTenantIdentityUserEmailInput + field_type_override: "*MultiTenantIdentityUserEmailInput" + - name: MultiTenantIdentityEmailVerificationStateInput + field_type_override: "*MultiTenantIdentityEmailVerificationStateInput" + - name: MultiTenantIdentityUserIdInput + field_type_override: "*MultiTenantIdentityUserIdInput" + - name: MultiTenantIdentityUserGroupIdInput + field_type_override: "*MultiTenantIdentityUserGroupIdInput" + - name: MultiTenantIdentityUserNameInput + field_type_override: "*MultiTenantIdentityUserNameInput" + - name: MultiTenantIdentityPendingUpgradeRequestInput + field_type_override: "*MultiTenantIdentityPendingUpgradeRequestInput" + # overrides associated with types starting with MultiTenantAuthorizationRoleFilterInputExpression + # which is used in the 'roles' endpoint in customerAdministration + - name: MultiTenantAuthorizationRoleGroupIdInputFilter + field_type_override: "*MultiTenantAuthorizationRoleGroupIdInputFilter" + - name: MultiTenantAuthorizationRoleIdInputFilter + field_type_override: "*MultiTenantAuthorizationRoleIdInputFilter" + - name: MultiTenantAuthorizationRoleNameInputFilter + field_type_override: "*MultiTenantAuthorizationRoleNameInputFilter" + - name: MultiTenantAuthorizationRoleOrganizationIdInputFilter + field_type_override: "*MultiTenantAuthorizationRoleOrganizationIdInputFilter" + - name: MultiTenantAuthorizationRoleScopeInputFilter + field_type_override: "*MultiTenantAuthorizationRoleScopeInputFilter" + - name: MultiTenantAuthorizationRoleTypeInputFilter + field_type_override: "*MultiTenantAuthorizationRoleTypeInputFilter" + ##### + # overrides associated with types starting with MultiTenantAuthorizationGrantFilterInputExpression{ + # which is used in the 'grants' endpoint in customerAdministration + - name: MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter" + - name: MultiTenantAuthorizationGrantGroupIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantGroupIdInputFilter" + - name: MultiTenantAuthorizationGrantIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantIdInputFilter" + - name: MultiTenantAuthorizationGrantOrganizationIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantOrganizationIdInputFilter" + - name: MultiTenantAuthorizationGrantRoleIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantRoleIdInputFilter" + - name: MultiTenantAuthorizationGrantScopeIdInputFilter + field_type_override: "*MultiTenantAuthorizationGrantScopeIdInputFilter" + - name: MultiTenantAuthorizationGrantScopeTypeInputFilter + field_type_override: "*MultiTenantAuthorizationGrantScopeTypeInputFilter" + ###### + # overrides associated with types starting with OrganizationOrganizationCreateAsyncResultFilterInput + # which is used in the 'organizationCreateAsyncResults' endpoint in customerAdministration > jobs + - name: OrganizationOrganizationCreateJobCustomerIdInput + field_type_override: "*OrganizationOrganizationCreateJobCustomerIdInput" + - name: OrganizationOrganizationCreateJobIdInput + field_type_override: "*OrganizationOrganizationCreateJobIdInput" + - name: OrganizationOrganizationCreateJobStatusInput + field_type_override: "*OrganizationOrganizationCreateJobStatusInput" + + - name: ID + field_type_override: string + skip_type_create: true + - name: DateTime + field_type_override: nrtime.DateTime + skip_type_create: true + generators: - name: typegen fileName: "types.go" diff --git a/newrelic/newrelic.go b/newrelic/newrelic.go index 3dc6b265..2e489cc5 100644 --- a/newrelic/newrelic.go +++ b/newrelic/newrelic.go @@ -10,9 +10,11 @@ import ( "github.com/newrelic/newrelic-client-go/v2/pkg/alerts" "github.com/newrelic/newrelic-client-go/v2/pkg/apiaccess" "github.com/newrelic/newrelic-client-go/v2/pkg/apm" + "github.com/newrelic/newrelic-client-go/v2/pkg/authorizationmanagement" "github.com/newrelic/newrelic-client-go/v2/pkg/changetracking" "github.com/newrelic/newrelic-client-go/v2/pkg/cloud" "github.com/newrelic/newrelic-client-go/v2/pkg/config" + "github.com/newrelic/newrelic-client-go/v2/pkg/customeradministration" "github.com/newrelic/newrelic-client-go/v2/pkg/dashboards" "github.com/newrelic/newrelic-client-go/v2/pkg/edge" "github.com/newrelic/newrelic-client-go/v2/pkg/entities" @@ -27,6 +29,7 @@ import ( "github.com/newrelic/newrelic-client-go/v2/pkg/notifications" "github.com/newrelic/newrelic-client-go/v2/pkg/nrdb" "github.com/newrelic/newrelic-client-go/v2/pkg/nrqldroprules" + "github.com/newrelic/newrelic-client-go/v2/pkg/organization" "github.com/newrelic/newrelic-client-go/v2/pkg/plugins" "github.com/newrelic/newrelic-client-go/v2/pkg/servicelevel" "github.com/newrelic/newrelic-client-go/v2/pkg/synthetics" @@ -37,33 +40,36 @@ import ( // NewRelic is a collection of New Relic APIs. type NewRelic struct { - AccountManagement accountmanagement.Accountmanagement - AgentApplications agentapplications.AgentApplications - Accounts accounts.Accounts - Alerts alerts.Alerts - APIAccess apiaccess.APIAccess - APM apm.APM - ChangeTracking changetracking.Changetracking - Cloud cloud.Cloud - Dashboards dashboards.Dashboards - Edge edge.Edge - Entities entities.Entities - Events events.Events - EventsToMetrics eventstometrics.EventsToMetrics - InstallEvents installevents.Installevents - Logs logs.Logs - Logconfigurations logconfigurations.Logconfigurations - NerdGraph nerdgraph.NerdGraph - NerdStorage nerdstorage.NerdStorage - Notifications notifications.Notifications - Nrdb nrdb.Nrdb - Nrqldroprules nrqldroprules.Nrqldroprules - Plugins plugins.Plugins - ServiceLevel servicelevel.Servicelevel - Synthetics synthetics.Synthetics - UserManagement usermanagement.Usermanagement - Workflows workflows.Workflows - Workloads workloads.Workloads + AccountManagement accountmanagement.Accountmanagement + AgentApplications agentapplications.AgentApplications + Accounts accounts.Accounts + Alerts alerts.Alerts + APIAccess apiaccess.APIAccess + APM apm.APM + AuthorizationManagement authorizationmanagement.Authorizationmanagement + ChangeTracking changetracking.Changetracking + Cloud cloud.Cloud + CustomerAdministration customeradministration.Customeradministration + Dashboards dashboards.Dashboards + Edge edge.Edge + Entities entities.Entities + Events events.Events + EventsToMetrics eventstometrics.EventsToMetrics + InstallEvents installevents.Installevents + Logs logs.Logs + Logconfigurations logconfigurations.Logconfigurations + NerdGraph nerdgraph.NerdGraph + NerdStorage nerdstorage.NerdStorage + Notifications notifications.Notifications + Nrdb nrdb.Nrdb + Nrqldroprules nrqldroprules.Nrqldroprules + Organization organization.Organization + Plugins plugins.Plugins + ServiceLevel servicelevel.Servicelevel + Synthetics synthetics.Synthetics + UserManagement usermanagement.Usermanagement + Workflows workflows.Workflows + Workloads workloads.Workloads config config.Config } @@ -80,33 +86,36 @@ func New(opts ...ConfigOption) (*NewRelic, error) { nr := &NewRelic{ config: cfg, - AccountManagement: accountmanagement.New(cfg), - AgentApplications: agentapplications.New(cfg), - Accounts: accounts.New(cfg), - Alerts: alerts.New(cfg), - APIAccess: apiaccess.New(cfg), - APM: apm.New(cfg), - ChangeTracking: changetracking.New(cfg), - Cloud: cloud.New(cfg), - Dashboards: dashboards.New(cfg), - Edge: edge.New(cfg), - Entities: entities.New(cfg), - Events: events.New(cfg), - EventsToMetrics: eventstometrics.New(cfg), - InstallEvents: installevents.New(cfg), - Logs: logs.New(cfg), - Logconfigurations: logconfigurations.New(cfg), - NerdGraph: nerdgraph.New(cfg), - NerdStorage: nerdstorage.New(cfg), - Notifications: notifications.New(cfg), - Nrdb: nrdb.New(cfg), - Nrqldroprules: nrqldroprules.New(cfg), - Plugins: plugins.New(cfg), - ServiceLevel: servicelevel.New(cfg), - Synthetics: synthetics.New(cfg), - UserManagement: usermanagement.New(cfg), - Workflows: workflows.New(cfg), - Workloads: workloads.New(cfg), + AccountManagement: accountmanagement.New(cfg), + AgentApplications: agentapplications.New(cfg), + Accounts: accounts.New(cfg), + Alerts: alerts.New(cfg), + APIAccess: apiaccess.New(cfg), + APM: apm.New(cfg), + AuthorizationManagement: authorizationmanagement.New(cfg), + ChangeTracking: changetracking.New(cfg), + Cloud: cloud.New(cfg), + CustomerAdministration: customeradministration.New(cfg), + Dashboards: dashboards.New(cfg), + Edge: edge.New(cfg), + Entities: entities.New(cfg), + Events: events.New(cfg), + EventsToMetrics: eventstometrics.New(cfg), + InstallEvents: installevents.New(cfg), + Logs: logs.New(cfg), + Logconfigurations: logconfigurations.New(cfg), + NerdGraph: nerdgraph.New(cfg), + NerdStorage: nerdstorage.New(cfg), + Notifications: notifications.New(cfg), + Nrdb: nrdb.New(cfg), + Nrqldroprules: nrqldroprules.New(cfg), + Organization: organization.New(cfg), + Plugins: plugins.New(cfg), + ServiceLevel: servicelevel.New(cfg), + Synthetics: synthetics.New(cfg), + UserManagement: usermanagement.New(cfg), + Workflows: workflows.New(cfg), + Workloads: workloads.New(cfg), } return nr, nil diff --git a/pkg/authorizationmanagement/authorizationmanagement.go b/pkg/authorizationmanagement/authorizationmanagement.go new file mode 100644 index 00000000..b8a07ed0 --- /dev/null +++ b/pkg/authorizationmanagement/authorizationmanagement.go @@ -0,0 +1,24 @@ +package authorizationmanagement + +import ( + "github.com/newrelic/newrelic-client-go/v2/internal/http" + "github.com/newrelic/newrelic-client-go/v2/pkg/config" + "github.com/newrelic/newrelic-client-go/v2/pkg/logging" +) + +type Authorizationmanagement struct { + client http.Client + logger logging.Logger + config config.Config +} + +func New(config config.Config) Authorizationmanagement { + client := http.NewClient(config) + + pkg := Authorizationmanagement{ + client: client, + logger: config.GetLogger(), + config: config, + } + return pkg +} diff --git a/pkg/authorizationmanagement/authorizationmanagement_api.go b/pkg/authorizationmanagement/authorizationmanagement_api.go new file mode 100644 index 00000000..2197d7f9 --- /dev/null +++ b/pkg/authorizationmanagement/authorizationmanagement_api.go @@ -0,0 +1,147 @@ +// Code generated by tutone: DO NOT EDIT +package authorizationmanagement + +import "context" + +// Grant access for a group +func (a *Authorizationmanagement) AuthorizationManagementGrantAccess( + grantAccessOptions AuthorizationManagementGrantAccess, +) (*AuthorizationManagementGrantAccessPayload, error) { + return a.AuthorizationManagementGrantAccessWithContext(context.Background(), + grantAccessOptions, + ) +} + +// Grant access for a group +func (a *Authorizationmanagement) AuthorizationManagementGrantAccessWithContext( + ctx context.Context, + grantAccessOptions AuthorizationManagementGrantAccess, +) (*AuthorizationManagementGrantAccessPayload, error) { + + resp := AuthorizationManagementGrantAccessQueryResponse{} + vars := map[string]interface{}{ + "grantAccessOptions": grantAccessOptions, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, AuthorizationManagementGrantAccessMutation, vars, &resp); err != nil { + return nil, err + } + + return &resp.AuthorizationManagementGrantAccessPayload, nil +} + +type AuthorizationManagementGrantAccessQueryResponse struct { + AuthorizationManagementGrantAccessPayload AuthorizationManagementGrantAccessPayload `json:"AuthorizationManagementGrantAccess"` +} + +const AuthorizationManagementGrantAccessMutation = `mutation( + $grantAccessOptions: AuthorizationManagementGrantAccess, +) { authorizationManagementGrantAccess( + grantAccessOptions: $grantAccessOptions, +) { + roles { + accountId + displayName + groupId + id + name + organizationId + roleId + type + } +} }` + +// Revoke access for a group +func (a *Authorizationmanagement) AuthorizationManagementRevokeAccess( + revokeAccessOptions AuthorizationManagementRevokeAccess, +) (*AuthorizationManagementRevokeAccessPayload, error) { + return a.AuthorizationManagementRevokeAccessWithContext(context.Background(), + revokeAccessOptions, + ) +} + +// Revoke access for a group +func (a *Authorizationmanagement) AuthorizationManagementRevokeAccessWithContext( + ctx context.Context, + revokeAccessOptions AuthorizationManagementRevokeAccess, +) (*AuthorizationManagementRevokeAccessPayload, error) { + + resp := AuthorizationManagementRevokeAccessQueryResponse{} + vars := map[string]interface{}{ + "revokeAccessOptions": revokeAccessOptions, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, AuthorizationManagementRevokeAccessMutation, vars, &resp); err != nil { + return nil, err + } + + return &resp.AuthorizationManagementRevokeAccessPayload, nil +} + +type AuthorizationManagementRevokeAccessQueryResponse struct { + AuthorizationManagementRevokeAccessPayload AuthorizationManagementRevokeAccessPayload `json:"AuthorizationManagementRevokeAccess"` +} + +const AuthorizationManagementRevokeAccessMutation = `mutation( + $revokeAccessOptions: AuthorizationManagementRevokeAccess, +) { authorizationManagementRevokeAccess( + revokeAccessOptions: $revokeAccessOptions, +) { + roles { + accountId + displayName + groupId + id + name + organizationId + roleId + type + } +} }` + +// list of roles +func (a *Authorizationmanagement) GetRoles( + cursor string, + iD []string, +) (*AuthorizationManagementRoleSearch, error) { + return a.GetRolesWithContext(context.Background(), + cursor, + iD, + ) +} + +// list of roles +func (a *Authorizationmanagement) GetRolesWithContext( + ctx context.Context, + cursor string, + iD []string, +) (*AuthorizationManagementRoleSearch, error) { + + resp := rolesResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "id": iD, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getRolesQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.Actor.Organization.AuthorizationManagement.Roles, nil +} + +const getRolesQuery = `query( + $id: [ID!], +) { actor { organization { authorizationManagement { roles( + id: $id, +) { + nextCursor + roles { + displayName + id + name + scope + type + } + totalCount +} } } } }` diff --git a/pkg/authorizationmanagement/authorizationmanagement_integration_test.go b/pkg/authorizationmanagement/authorizationmanagement_integration_test.go new file mode 100644 index 00000000..c1c8c572 --- /dev/null +++ b/pkg/authorizationmanagement/authorizationmanagement_integration_test.go @@ -0,0 +1,244 @@ +package authorizationmanagement + +import ( + "regexp" + "strconv" + "testing" + + "github.com/stretchr/testify/require" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" +) + +func TestIntegration_GrantAccess_InvalidGroupError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + _, err = client.AuthorizationManagementGrantAccess( + AuthorizationManagementGrantAccess{ + GroupId: mockGroupId, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mockAccountId, + RoleId: mockRoleId, + }, + }, + }, + ) + + require.Error(t, err) + require.Regexp(t, regexp.MustCompile(invalidGroupErrorRegularExpression), err.Error()) +} + +func TestIntegration_GrantAccess_AccountRole_InvalidAccountIDAndRoleID(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + userManagementClient := newIntegrationTestClientUserManagement(t) + + createdGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + false, + "", + ) + + require.NotNil(t, createdGroupID) + require.NoError(t, err) + + _, err = client.AuthorizationManagementGrantAccess( + AuthorizationManagementGrantAccess{ + GroupId: createdGroupID, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mockAccountId, + RoleId: mockRoleId, + }, + }, + }, + ) + + require.Error(t, err) + require.Regexp(t, regexp.MustCompile(invalidAccountIdAndRoleIdErrorRegularExpression), err.Error()) + + deletedGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + true, + createdGroupID, + ) + + require.NoError(t, err) + require.NotNil(t, deletedGroupID) +} + +func TestIntegration_GrantAccess_AccountRole_InvalidAccountID(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + userManagementClient := newIntegrationTestClientUserManagement(t) + + createdGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + false, + "", + ) + + require.NotNil(t, createdGroupID) + require.NoError(t, err) + + _, err = client.AuthorizationManagementGrantAccess( + AuthorizationManagementGrantAccess{ + GroupId: createdGroupID, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mockAccountId, + RoleId: roleId, + }, + }, + }, + ) + + require.Error(t, err) + require.Regexp(t, regexp.MustCompile(invalidAccountIdErrorRegularExpression), err.Error()) + + deletedGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + true, + createdGroupID, + ) + + require.NoError(t, err) + require.NotNil(t, deletedGroupID) +} + +func TestIntegration_GrantAccess_AccountRole_Success(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + userManagementClient := newIntegrationTestClientUserManagement(t) + + createdGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + false, + "", + ) + + require.NotNil(t, createdGroupID) + require.NoError(t, err) + + grantAccessResponse, err := client.AuthorizationManagementGrantAccess( + AuthorizationManagementGrantAccess{ + GroupId: createdGroupID, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mock.IntegrationTestAccountID, + RoleId: roleId, + }, + }, + }, + ) + + require.NoError(t, err) + foundRole := false + for _, v := range grantAccessResponse.Roles { + if strconv.Itoa(v.RoleId) == roleId && v.AccountID == mock.IntegrationTestAccountID { + foundRole = true + } + } + + require.Equal(t, foundRole, true) + + revokeAccessResponse, err := client.AuthorizationManagementRevokeAccess( + AuthorizationManagementRevokeAccess{ + GroupId: createdGroupID, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mock.IntegrationTestAccountID, + RoleId: roleId, + }, + }, + }, + ) + + require.NoError(t, err) + + // the following condition is actually supposed to be the block of code commented below + // however, the API is currently returning a list of existent roles in the response of this + // mutation, which is why the response is empty after the only role linked to the group + // is removed. Hence, the condition to have an empty list of roles has been added below until this is fixed in the API. + require.Equal(t, revokeAccessResponse.Roles, []AuthorizationManagementGrantedRole{}) + + //foundRevokedRole := false + //for _, v := range revokeAccessResponse.Roles { + // if strconv.Itoa(v.RoleId) == roleId && v.AccountID == mock.IntegrationTestAccountID { + // foundRevokedRole = true + // } + //} + // + //require.Equal(t, foundRevokedRole, true) + + deletedGroupID, err := UserManagementCreateDeleteTestGroupUtility( + userManagementClient, + true, + createdGroupID, + ) + + require.NoError(t, err) + require.NotNil(t, deletedGroupID) +} + +func TestIntegration_RevokeAccess_InvalidGroupError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + _, err = client.AuthorizationManagementRevokeAccess( + AuthorizationManagementRevokeAccess{ + GroupId: mockGroupId, + AccountAccessGrants: []AuthorizationManagementAccountAccessGrant{ + { + AccountID: mockAccountId, + RoleId: mockRoleId, + }, + }, + }, + ) + + require.Error(t, err) + require.Regexp(t, regexp.MustCompile(invalidGroupErrorRegularExpression), err.Error()) +} + +func TestIntegration_GetRoles(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + getRolesResponse, err := client.GetRoles("", []string{roleId}) + require.NoError(t, err) + require.Greater(t, len(getRolesResponse.Roles), 0) +} + +// TODO: +// we still need to add the authorizationManagement > authenticationDomains endpoint and then add +// an integration test - work in progress, to be taken up with the access management feature diff --git a/pkg/authorizationmanagement/authorizationmanagement_test.go b/pkg/authorizationmanagement/authorizationmanagement_test.go new file mode 100644 index 00000000..d7202b0e --- /dev/null +++ b/pkg/authorizationmanagement/authorizationmanagement_test.go @@ -0,0 +1,80 @@ +package authorizationmanagement + +import ( + "fmt" + "testing" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" + "github.com/newrelic/newrelic-client-go/v2/pkg/usermanagement" +) + +func newIntegrationTestClient(t *testing.T) Authorizationmanagement { + tc := mock.NewIntegrationTestConfig(t) + return New(tc) +} + +func newIntegrationTestClientUserManagement(t *testing.T) usermanagement.Usermanagement { + tc := mock.NewIntegrationTestConfig(t) + return usermanagement.New(tc) +} + +var ( + authenticationDomainId = "84cb286a-8eb0-4478-b469-cdf2ccfef553" + + // do not add more than nine 9s here + mockAccountId = 999999999 + mockGroupId = "fake-group-id" + mockRoleId = "fake-role-id" + + roleId = "38236" + + invalidGroupErrorRegularExpression = `An error occurred resolving this field` + invalidAccountIdAndRoleIdErrorRegularExpression = `error granting access` + invalidAccountIdErrorRegularExpression = `Validation failed: granted_on entity .* do not belong to the same organization` +) + +func UserManagementCreateDeleteTestGroupUtility( + userManagementClient usermanagement.Usermanagement, + delete bool, + groupId string, +) (string, error) { + if !delete { + groupCreateResponse, err := userManagementClient.UserManagementCreateGroup( + usermanagement.UserManagementCreateGroup{ + AuthenticationDomainId: authenticationDomainId, + DisplayName: fmt.Sprintf("mock-group-created-for-account-role-grant-%s", mock.RandSeq(5)), + }, + ) + + if err != nil { + return "", err + } + + return groupCreateResponse.Group.ID, nil + + } else { + if groupId == "" { + return "", fmt.Errorf("iud of the group to be deleted has not been specified") + } + groupDeleteResponse, err := userManagementClient.UserManagementDeleteGroup( + usermanagement.UserManagementDeleteGroup{ + ID: groupId, + }, + ) + + if err != nil { + return "", err + } + + return groupDeleteResponse.Group.ID, nil + } +} + +// TODO: Add unit tests in the authorizationmanagement package + +//func newMockResponse(t *testing.T, mockJSONResponse string, statusCode int) Authorizationmanagement { +// ts := mock.NewMockServer(t, mockJSONResponse, statusCode) +// tc := mock.NewTestConfig(t, ts) +// +// return New(tc) +//} diff --git a/pkg/authorizationmanagement/types.go b/pkg/authorizationmanagement/types.go new file mode 100644 index 00000000..731309e5 --- /dev/null +++ b/pkg/authorizationmanagement/types.go @@ -0,0 +1,163 @@ +// Code generated by tutone: DO NOT EDIT +package authorizationmanagement + +// Actor - The `Actor` object contains fields that are scoped to the API user's access level. +type Actor struct { + // The `organization` field is the entry point into data that is scoped to the user's organization. + Organization Organization `json:"organization,omitempty"` +} + +// AuthorizationManagementAccountAccessGrant - The Account and Role a Group should have access to +type AuthorizationManagementAccountAccessGrant struct { + // The Account ID the Role will grant access to + AccountID int `json:"accountId"` + // The Role ID that will define the access + RoleId string `json:"roleId"` +} + +// AuthorizationManagementGrantAccess - The input object representing the access to grant for the group +type AuthorizationManagementGrantAccess struct { + // The Role and the Account the Target Group should have access to + AccountAccessGrants []AuthorizationManagementAccountAccessGrant `json:"accountAccessGrants,omitempty"` + // The Role and the Group the Target Group should have access to + GroupAccessGrants []AuthorizationManagementGroupAccessGrant `json:"groupAccessGrants,omitempty"` + // The Group ID that will have access granted + GroupId string `json:"groupId"` + // The Role and the Organization the Target Group should have access to + OrganizationAccessGrants []AuthorizationManagementOrganizationAccessGrant `json:"organizationAccessGrants,omitempty"` +} + +// AuthorizationManagementGrantAccessPayload - Autogenerated return type of GrantAccess +type AuthorizationManagementGrantAccessPayload struct { + // the roles that were granted to this group + Roles []AuthorizationManagementGrantedRole `json:"roles"` +} + +// AuthorizationManagementGrantedRole - A Granted Role represents the access given to a group. +type AuthorizationManagementGrantedRole struct { + // the account that this role grants access to + AccountID int `json:"accountId,omitempty"` + // the name of the object + DisplayName string `json:"displayName,omitempty"` + // the group that this role grants access to + GroupId string `json:"groupId,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // the organization this role grants access to + OrganizationId string `json:"organizationId,omitempty"` + // the role that defines this access + RoleId int `json:"roleId"` + // the type of the role + Type string `json:"type"` +} + +// AuthorizationManagementGrantedRoleSearch - container for roles enabling cursor based pagination +type AuthorizationManagementGrantedRoleSearch struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the roles granted to this group + Roles []AuthorizationManagementGrantedRole `json:"roles"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// AuthorizationManagementGroupAccessGrant - The Group and Role another Group should have access to +type AuthorizationManagementGroupAccessGrant struct { + // The Group ID the Role will grant access to + GroupId string `json:"groupId"` + // The Role ID that will define the access + RoleId string `json:"roleId"` +} + +// AuthorizationManagementOrganizationAccessGrant - The Organization Role a Group should have access to +type AuthorizationManagementOrganizationAccessGrant struct { + // The Role ID that will define the Organization access + RoleId string `json:"roleId"` +} + +type AuthorizationManagementOrganizationStitchedFields struct { + // list of roles + Roles AuthorizationManagementRoleSearch `json:"roles,omitempty"` +} + +// AuthorizationManagementRevokeAccess - The input object representing the access to revoke for the group +type AuthorizationManagementRevokeAccess struct { + // The Role and the Account the Target Group should no longer have access to + AccountAccessGrants []AuthorizationManagementAccountAccessGrant `json:"accountAccessGrants,omitempty"` + // The Role and the Group the Target Group should no longer have access to + GroupAccessGrants []AuthorizationManagementGroupAccessGrant `json:"groupAccessGrants,omitempty"` + // The Group ID that will have access revoked + GroupId string `json:"groupId"` + // The Role and the Organization the Target Group should no longer have access to + OrganizationAccessGrants []AuthorizationManagementOrganizationAccessGrant `json:"organizationAccessGrants,omitempty"` +} + +// AuthorizationManagementRevokeAccessPayload - Autogenerated return type of RevokeAccess +type AuthorizationManagementRevokeAccessPayload struct { + // the roles that were revoked from this group + Roles []AuthorizationManagementGrantedRole `json:"roles"` +} + +// AuthorizationManagementRole - a role grants access on an account or organization to groups of users +type AuthorizationManagementRole struct { + // the name of the object + DisplayName string `json:"displayName,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // the scope of the role + Scope string `json:"scope"` + // the type of the role + Type string `json:"type"` +} + +// AuthorizationManagementRoleSearch - container for roles enabling cursor based pagination +type AuthorizationManagementRoleSearch struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // control the access granted to groups + Roles []AuthorizationManagementRole `json:"roles"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// MultiTenantAuthorizationRole - Describes a role within the system +type MultiTenantAuthorizationRole struct { + // a value that uniquely identifies this object + ID int `json:"id"` + // the name of the object + Name string `json:"name"` + // The scope the role applies to + Scope string `json:"scope"` + // The type of role + Type string `json:"type"` +} + +// MultiTenantAuthorizationRoleCollection - An iterable collection of roles +type MultiTenantAuthorizationRoleCollection struct { + // collection of roles + Items []MultiTenantAuthorizationRole `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// Organization - The `Organization` object provides basic data about an organization. +type Organization struct { + // This field provides access to AuthorizationManagement data. + AuthorizationManagement AuthorizationManagementOrganizationStitchedFields `json:"authorizationManagement,omitempty"` + // The customer id for the organization. + CustomerId string `json:"customerId,omitempty"` + // The name of the organization. + Name string `json:"name,omitempty"` + // The telemetry id for the organization + TelemetryId string `json:"telemetryId,omitempty"` +} + +type rolesResponse struct { + Actor Actor `json:"actor"` +} diff --git a/pkg/customeradministration/customeradministration.go b/pkg/customeradministration/customeradministration.go new file mode 100644 index 00000000..30ff7d9d --- /dev/null +++ b/pkg/customeradministration/customeradministration.go @@ -0,0 +1,24 @@ +package customeradministration + +import ( + "github.com/newrelic/newrelic-client-go/v2/internal/http" + "github.com/newrelic/newrelic-client-go/v2/pkg/config" + "github.com/newrelic/newrelic-client-go/v2/pkg/logging" +) + +type Customeradministration struct { + client http.Client + logger logging.Logger + config config.Config +} + +func New(config config.Config) Customeradministration { + client := http.NewClient(config) + + pkg := Customeradministration{ + client: client, + logger: config.GetLogger(), + config: config, + } + return pkg +} diff --git a/pkg/customeradministration/customeradministration_api.go b/pkg/customeradministration/customeradministration_api.go new file mode 100644 index 00000000..9e0195f5 --- /dev/null +++ b/pkg/customeradministration/customeradministration_api.go @@ -0,0 +1,687 @@ +// Code generated by tutone: DO NOT EDIT +package customeradministration + +import "context" + +// Accessible account shares +func (a *Customeradministration) GetAccountShares( + cursor string, + filter OrganizationAccountShareFilterInput, + sort []OrganizationAccountShareSortInput, +) (*OrganizationAccountShareCollection, error) { + return a.GetAccountSharesWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// Accessible account shares +func (a *Customeradministration) GetAccountSharesWithContext( + ctx context.Context, + cursor string, + filter OrganizationAccountShareFilterInput, + sort []OrganizationAccountShareSortInput, +) (*OrganizationAccountShareCollection, error) { + + resp := accountSharesResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getAccountSharesQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.AccountShares, nil +} + +const getAccountSharesQuery = `query( + $filter: OrganizationAccountShareFilterInput!, + $sort: [OrganizationAccountShareSortInput!], +) { customerAdministration { accountShares( + filter: $filter, + sort: $sort, +) { + items { + accountId + id + limitingRole { + id + } + name + source { + id + name + } + target { + id + name + } + } + nextCursor +} } }` + +// accounts +func (a *Customeradministration) GetAccounts( + cursor string, + filter OrganizationAccountFilterInput, + sort []OrganizationAccountSortInput, +) (*OrganizationAccountCollection, error) { + return a.GetAccountsWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// accounts +func (a *Customeradministration) GetAccountsWithContext( + ctx context.Context, + cursor string, + filter OrganizationAccountFilterInput, + sort []OrganizationAccountSortInput, +) (*OrganizationAccountCollection, error) { + + resp := accountsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getAccountsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Accounts, nil +} + +const getAccountsQuery = `query( + $filter: OrganizationAccountFilterInput!, + $sort: [OrganizationAccountSortInput!], +) { customerAdministration { accounts( + filter: $filter, + sort: $sort, +) { + items { + id + name + regionCode + status + } + nextCursor + totalCount +} } }` + +// Authentication domains +func (a *Customeradministration) GetAuthenticationDomains( + cursor string, + filter OrganizationAuthenticationDomainFilterInput, + sort []OrganizationAuthenticationDomainSortInput, +) (*OrganizationAuthenticationDomainCollection, error) { + return a.GetAuthenticationDomainsWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// Authentication domains +func (a *Customeradministration) GetAuthenticationDomainsWithContext( + ctx context.Context, + cursor string, + filter OrganizationAuthenticationDomainFilterInput, + sort []OrganizationAuthenticationDomainSortInput, +) (*OrganizationAuthenticationDomainCollection, error) { + + resp := authenticationDomainsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getAuthenticationDomainsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.AuthenticationDomains, nil +} + +const getAuthenticationDomainsQuery = `query( + $filter: OrganizationAuthenticationDomainFilterInput!, + $sort: [OrganizationAuthenticationDomainSortInput!], +) { customerAdministration { authenticationDomains( + filter: $filter, + sort: $sort, +) { + items { + authenticationType + id + name + organizationId + provisioningType + } + nextCursor +} } }` + +// The `consumption` field is the entry point into a customer's consumption data that is scoped to the ID of the customer. +func (a *Customeradministration) GetConsumption( + customerId string, +) (*Consumption, error) { + return a.GetConsumptionWithContext(context.Background(), + customerId, + ) +} + +// The `consumption` field is the entry point into a customer's consumption data that is scoped to the ID of the customer. +func (a *Customeradministration) GetConsumptionWithContext( + ctx context.Context, + customerId string, +) (*Consumption, error) { + + resp := consumptionResponse{} + vars := map[string]interface{}{ + "customerId": customerId, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getConsumptionQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Consumption, nil +} + +const getConsumptionQuery = `query( + $customerId: ID!, +) { customerAdministration { consumption( + customerId: $customerId, +) { + customerId +} } }` + +// Accessible contracts +func (a *Customeradministration) GetContracts( + cursor string, + filter OrganizationCustomerContractFilterInput, +) (*OrganizationCustomerContractWrapper, error) { + return a.GetContractsWithContext(context.Background(), + cursor, + filter, + ) +} + +// Accessible contracts +func (a *Customeradministration) GetContractsWithContext( + ctx context.Context, + cursor string, + filter OrganizationCustomerContractFilterInput, +) (*OrganizationCustomerContractWrapper, error) { + + resp := contractsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getContractsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Contracts, nil +} + +const getContractsQuery = `query { customerAdministration { contracts { + items { + billingStructure + customerId + id + organizationGroups { + items { + id + name + } + nextCursor + } + telemetryId + } + nextCursor +} } }` + +// list of grants +func (a *Customeradministration) GetGrants( + cursor string, + filter MultiTenantAuthorizationGrantFilterInputExpression, + sort []MultiTenantAuthorizationGrantSortInput, +) (*MultiTenantAuthorizationGrantCollection, error) { + return a.GetGrantsWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// list of grants +func (a *Customeradministration) GetGrantsWithContext( + ctx context.Context, + cursor string, + filter MultiTenantAuthorizationGrantFilterInputExpression, + sort []MultiTenantAuthorizationGrantSortInput, +) (*MultiTenantAuthorizationGrantCollection, error) { + + resp := grantsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getGrantsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Grants, nil +} + +const getGrantsQuery = `query( + $filter: MultiTenantAuthorizationGrantFilterInputExpression!, + $sort: [MultiTenantAuthorizationGrantSortInput!], +) { customerAdministration { grants( + filter: $filter, + sort: $sort, +) { + items { + group { + id + } + id + role { + id + name + } + scope { + id + type + } + } + nextCursor +} } }` + +// Named sets of New Relic users within an authentication domain +func (a *Customeradministration) GetGroups( + cursor string, + filter MultiTenantIdentityGroupFilterInput, + sort []MultiTenantIdentityGroupSortInput, +) (*MultiTenantIdentityGroupCollection, error) { + return a.GetGroupsWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// Named sets of New Relic users within an authentication domain +func (a *Customeradministration) GetGroupsWithContext( + ctx context.Context, + cursor string, + filter MultiTenantIdentityGroupFilterInput, + sort []MultiTenantIdentityGroupSortInput, +) (*MultiTenantIdentityGroupCollection, error) { + + resp := groupsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getGroupsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Groups, nil +} + +const getGroupsQuery = `query( + $filter: MultiTenantIdentityGroupFilterInput!, + $sort: [MultiTenantIdentityGroupSortInput!], +) { customerAdministration { groups( + filter: $filter, + sort: $sort, +) { + items { + authenticationDomainId + id + name + users { + items { + email + id + name + timeZone + } + nextCursor + totalCount + } + } + nextCursor + totalCount +} } }` + +// This provides access to fields you can use to check the status of asynchronous jobs related to customer administration. +func (a *Customeradministration) GetJobs() (*CustomerAdministrationJobs, error) { + return a.GetJobsWithContext(context.Background()) +} + +// This provides access to fields you can use to check the status of asynchronous jobs related to customer administration. +func (a *Customeradministration) GetJobsWithContext( + ctx context.Context, +) (*CustomerAdministrationJobs, error) { + + resp := jobsResponse{} + vars := map[string]interface{}{} + + if err := a.client.NerdGraphQueryWithContext(ctx, getJobsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Jobs, nil +} + +const getJobsQuery = `query { customerAdministration { jobs { + +} } }` + +// Organization Create job results +func (a *Customeradministration) GetOrganizationCreateAsyncResults( + cursor string, + filter OrganizationOrganizationCreateAsyncResultFilterInput, +) (*OrganizationOrganizationCreateAsyncResultCollection, error) { + return a.GetOrganizationCreateAsyncResultsWithContext(context.Background(), + cursor, + filter, + ) +} + +// Organization Create job results +func (a *Customeradministration) GetOrganizationCreateAsyncResultsWithContext( + ctx context.Context, + cursor string, + filter OrganizationOrganizationCreateAsyncResultFilterInput, +) (*OrganizationOrganizationCreateAsyncResultCollection, error) { + + resp := organizationCreateAsyncResultsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getOrganizationCreateAsyncResultsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Jobs.OrganizationCreateAsyncResults, nil +} + +const getOrganizationCreateAsyncResultsQuery = `query( + $filter: OrganizationOrganizationCreateAsyncResultFilterInput!, +) { customerAdministration { jobs { organizationCreateAsyncResults( + filter: $filter, +) { + items { + customer { + customerId + } + job { + createdUtc + errorMessage + finishedUtc + id + status + } + organization { + id + name + } + } + nextCursor +} } } }` + +// Accessible organizations +func (a *Customeradministration) GetOrganizations( + cursor string, + filter OrganizationCustomerOrganizationFilterInput, +) (*OrganizationCustomerOrganizationWrapper, error) { + return a.GetOrganizationsWithContext(context.Background(), + cursor, + filter, + ) +} + +// Accessible organizations +func (a *Customeradministration) GetOrganizationsWithContext( + ctx context.Context, + cursor string, + filter OrganizationCustomerOrganizationFilterInput, +) (*OrganizationCustomerOrganizationWrapper, error) { + + resp := organizationsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getOrganizationsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Organizations, nil +} + +const getOrganizationsQuery = `query { customerAdministration { organizations { + items { + contractId + customerId + id + name + } + nextCursor +} } }` + +// list of permissions +func (a *Customeradministration) GetPermissions( + cursor string, + filter MultiTenantAuthorizationPermissionFilter, +) (*MultiTenantAuthorizationPermissionCollection, error) { + return a.GetPermissionsWithContext(context.Background(), + cursor, + filter, + ) +} + +// list of permissions +func (a *Customeradministration) GetPermissionsWithContext( + ctx context.Context, + cursor string, + filter MultiTenantAuthorizationPermissionFilter, +) (*MultiTenantAuthorizationPermissionCollection, error) { + + resp := permissionsResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getPermissionsQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Permissions, nil +} + +const getPermissionsQuery = `query { customerAdministration { permissions { + items { + category + feature + id + name + product + } + nextCursor +} } }` + +// list of roles +func (a *Customeradministration) GetRoles( + cursor string, + filter MultiTenantAuthorizationRoleFilterInputExpression, + sort []MultiTenantAuthorizationRoleSortInput, +) (*MultiTenantAuthorizationRoleCollection, error) { + return a.GetRolesWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// list of roles +func (a *Customeradministration) GetRolesWithContext( + ctx context.Context, + cursor string, + filter MultiTenantAuthorizationRoleFilterInputExpression, + sort []MultiTenantAuthorizationRoleSortInput, +) (*MultiTenantAuthorizationRoleCollection, error) { + + resp := rolesResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getRolesQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Roles, nil +} + +const getRolesQuery = `query( + $filter: MultiTenantAuthorizationRoleFilterInputExpression!, + $sort: [MultiTenantAuthorizationRoleSortInput!], +) { customerAdministration { roles( + filter: $filter, + sort: $sort, +) { + items { + id + name + scope + type + } + nextCursor + totalCount +} } }` + +// The authenticated `User` who made this request. +func (a *Customeradministration) GetUser() (*User, error) { + return a.GetUserWithContext(context.Background()) +} + +// The authenticated `User` who made this request. +func (a *Customeradministration) GetUserWithContext( + ctx context.Context, +) (*User, error) { + + resp := userResponse{} + vars := map[string]interface{}{} + + if err := a.client.NerdGraphQueryWithContext(ctx, getUserQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.User, nil +} + +const getUserQuery = `query { customerAdministration { user { + email + id + name +} } }` + +// A collection of New Relic users +func (a *Customeradministration) GetUsers( + cursor string, + filter MultiTenantIdentityUserFilterInput, + sort []MultiTenantIdentityUserSortInput, +) (*MultiTenantIdentityUserCollection, error) { + return a.GetUsersWithContext(context.Background(), + cursor, + filter, + sort, + ) +} + +// A collection of New Relic users +func (a *Customeradministration) GetUsersWithContext( + ctx context.Context, + cursor string, + filter MultiTenantIdentityUserFilterInput, + sort []MultiTenantIdentityUserSortInput, +) (*MultiTenantIdentityUserCollection, error) { + + resp := usersResponse{} + vars := map[string]interface{}{ + "cursor": cursor, + "filter": filter, + "sort": sort, + } + + if err := a.client.NerdGraphQueryWithContext(ctx, getUsersQuery, vars, &resp); err != nil { + return nil, err + } + + return &resp.CustomerAdministration.Users, nil +} + +const getUsersQuery = `query( + $filter: MultiTenantIdentityUserFilterInput!, + $sort: [MultiTenantIdentityUserSortInput!], +) { customerAdministration { users( + filter: $filter, + sort: $sort, +) { + items { + authenticationDomainId + email + emailVerificationState + groups { + items { + id + name + } + nextCursor + totalCount + } + id + lastActive + name + pendingUpgradeRequest { + id + message + requestedUserType { + id + name + } + } + timeZone + type { + id + name + } + } + nextCursor + totalCount +} } }` diff --git a/pkg/customeradministration/customeradministration_integration_test.go b/pkg/customeradministration/customeradministration_integration_test.go new file mode 100644 index 00000000..254d5884 --- /dev/null +++ b/pkg/customeradministration/customeradministration_integration_test.go @@ -0,0 +1,270 @@ +package customeradministration + +import ( + "regexp" + "strconv" + "testing" + + "github.com/stretchr/testify/require" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" +) + +func TestIntegrationCustomerAdministration_GetAccountShares(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + _, err = client.GetAccountShares( + "", + OrganizationAccountShareFilterInput{ + AccountID: OrganizationAccountIdInput{Eq: mock.IntegrationTestAccountID}, + TargetId: OrganizationTargetIdInput{}, + }, + []OrganizationAccountShareSortInput{}, + ) + require.NoError(t, err) +} + +func TestIntegrationCustomerAdministration_GetAccounts(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getAccountsResponse, err := client.GetAccounts( + "", + OrganizationAccountFilterInput{ + ID: OrganizationAccountIdFilterInput{Eq: mock.IntegrationTestAccountID}, + Name: OrganizationAccountNameFilterInput{}, + OrganizationId: OrganizationAccountOrganizationIdFilterInput{organizationId}, + SharingMode: OrganizationAccountSharingModeFilterInput{}, + Status: OrganizationAccountStatusFilterInput{}, + }, + []OrganizationAccountSortInput{}, + ) + require.NoError(t, err) + require.Equal(t, getAccountsResponse.Items[0].ID, mock.IntegrationTestAccountID) +} + +func TestIntegrationCustomerAdministration_GetAuthenticationDomains(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + _, err = client.GetAuthenticationDomains("", + OrganizationAuthenticationDomainFilterInput{ + Name: OrganizationNameInput{Eq: authenticationDomainName}, + OrganizationId: OrganizationOrganizationIdInput{Eq: organizationId}, + }, + []OrganizationAuthenticationDomainSortInput{}, + ) + require.NoError(t, err) + +} + +func TestIntegrationCustomerAdministration_GetUser(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getUserResponse, err := client.GetUser() + require.NoError(t, err) + require.NotNil(t, getUserResponse.ID) +} + +func TestIntegrationCustomerAdministration_GetUsers(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if authenticationDomainId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_AUTHENTICATION_DOMAIN_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getUsersResponse, err := client.GetUsers( + "", + MultiTenantIdentityUserFilterInput{ + // Authentication Domain ID is required in this filter + AuthenticationDomainId: &MultiTenantIdentityAuthenticationDomainIdInput{Eq: authenticationDomainId}, + }, + []MultiTenantIdentityUserSortInput{}, + ) + + require.NoError(t, err) + require.Greater(t, getUsersResponse.TotalCount, 0) +} + +// This is currently throwing an unauthorized error, need to check - skipping the test until then +func TestIntegrationCustomerAdministration_GetOrganizations_UnauthorizedError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + _, err = client.GetOrganizations( + "", + OrganizationCustomerOrganizationFilterInput{ + ID: OrganizationOrganizationIdInputFilter{ + organizationId, + }, + }, + ) + + require.Regexp(t, regexp.MustCompile("Unauthorized"), err.Error()) +} + +func TestIntegrationCustomerAdministration_GetGroups(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getAccountsResponse, err := client.GetGroups( + "", + MultiTenantIdentityGroupFilterInput{ + AuthenticationDomainId: &MultiTenantIdentityAuthenticationDomainIdInput{Eq: authenticationDomainId}, + OrganizationId: &MultiTenantIdentityOrganizationIdInput{organizationId}, + }, + []MultiTenantIdentityGroupSortInput{}, + ) + + require.NoError(t, err) + require.Greater(t, getAccountsResponse.TotalCount, 0) +} + +func TestIntegrationCustomerAdministration_GetRoles(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getRolesResponse, err := client.GetRoles( + "", + MultiTenantAuthorizationRoleFilterInputExpression{ + Name: &MultiTenantAuthorizationRoleNameInputFilter{ + Eq: roleName, + }, + OrganizationId: &MultiTenantAuthorizationRoleOrganizationIdInputFilter{ + Eq: organizationId, + }, + }, + []MultiTenantAuthorizationRoleSortInput{}, + ) + + require.NoError(t, err) + require.Greater(t, getRolesResponse.TotalCount, 0) +} + +func TestIntegrationCustomerAdministration_GetPermissions(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + getPermissionsResponse, err := client.GetPermissions("", + MultiTenantAuthorizationPermissionFilter{ + RoleId: MultiTenantAuthorizationPermissionFilterRoleIdInput{ + Eq: roleId, + }, + }, + ) + + require.NoError(t, err) + require.Greater(t, len(getPermissionsResponse.Items), 0) + require.NotNil(t, getPermissionsResponse.Items[0].Name) +} + +func TestIntegrationCustomerAdministration_GetGrants(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + if authenticationDomainId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_AUTHENTICATION_DOMAIN_ID is missing, or has an empty value") + } + + roleIdAsInt, _ := strconv.Atoi(roleId) + + client := newIntegrationTestClient(t) + getGrantsResponse, err := client.GetGrants("", + MultiTenantAuthorizationGrantFilterInputExpression{ + // don't use "eq" with filters which have "eq" and "in" since "in" don't have omitempty, and are hence, expected + AuthenticationDomainId: &MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter{ + In: []string{ + authenticationDomainId, + }, + }, + OrganizationId: &MultiTenantAuthorizationGrantOrganizationIdInputFilter{ + organizationId, + }, + // don't use "eq" with filters which have "eq" and "in" since "in" don't have omitempty, and are hence, expected + RoleId: &MultiTenantAuthorizationGrantRoleIdInputFilter{ + In: []int{ + roleIdAsInt, + }, + }, + }, + []MultiTenantAuthorizationGrantSortInput{}, + ) + + require.NoError(t, err) + require.Greater(t, len(getGrantsResponse.Items), 0) + require.NotNil(t, getGrantsResponse.Items[0].ID) +} diff --git a/pkg/customeradministration/customeradministration_test.go b/pkg/customeradministration/customeradministration_test.go new file mode 100644 index 00000000..727a0f64 --- /dev/null +++ b/pkg/customeradministration/customeradministration_test.go @@ -0,0 +1,41 @@ +package customeradministration + +import ( + "os" + "strconv" + "testing" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" +) + +func newIntegrationTestClient(t *testing.T) Customeradministration { + tc := mock.NewIntegrationTestConfig(t) + return New(tc) +} + +var ( + organizationId = os.Getenv("INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID") + + authenticationDomainName = "Test-Auth-Domain DO NOT DELETE" + authenticationDomainId = os.Getenv("INTEGRATION_TESTING_NEW_RELIC_AUTHENTICATION_DOMAIN_ID") + + roleName = "Integration Test Role 1 DO NOT DELETE" + roleId = "38236" + + unitTestMockAccountOneId = "9999999" + unitTestMockAccountOneIdAsInt, _ = strconv.Atoi(unitTestMockAccountOneId) + unitTestMockAccountOneName = "customerAdministration getAccounts Unit Test Mock Account 1" + unitTestMockAccountTwoId = "8888888" + unitTestMockAccountTwoIdAsInt, _ = strconv.Atoi(unitTestMockAccountTwoId) + unitTestMockAccountTwoName = "customerAdministration getAccounts Unit Test Mock Account 2" + unitTestMockNextCursor = "=ExXzxTX1XDN0XXX2EXXyXXX" + + unitTestMockOrganizationId = "58a5a9b8-158c-4189-85ea-e08281c58c98" +) + +func newMockResponse(t *testing.T, mockJSONResponse string, statusCode int) Customeradministration { + ts := mock.NewMockServer(t, mockJSONResponse, statusCode) + tc := mock.NewTestConfig(t, ts) + + return New(tc) +} diff --git a/pkg/customeradministration/customeradministration_unit_test.go b/pkg/customeradministration/customeradministration_unit_test.go new file mode 100644 index 00000000..ccfdc8ba --- /dev/null +++ b/pkg/customeradministration/customeradministration_unit_test.go @@ -0,0 +1,77 @@ +package customeradministration + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + testCustomerAdministrationGetAccountsResponseJSON = `{ + "data": { + "customerAdministration": { + "accounts": { + "items": [ + { + "id": ` + unitTestMockAccountOneId + ` + "name": "` + unitTestMockAccountOneName + `", + "regionCode": "us01", + "status": "active" + }, + { + "id": ` + unitTestMockAccountTwoId + `, + "name": "` + unitTestMockAccountTwoName + `", + "regionCode": "us01", + "status": "active" + } + ], + "nextCursor": "` + unitTestMockNextCursor + `", + "totalCount": 2 + } + } + } + }` +) + +func TestUnit_CustomerAdministration_GetAccounts(t *testing.T) { + t.Parallel() + + t.Skipf("Skipping this test as this test needs a fix, based on current API behaviour") + + customeradministration := newMockResponse(t, testCustomerAdministrationGetAccountsResponseJSON, http.StatusOK) + + expected := OrganizationAccountCollection{ + Items: []OrganizationAccount{ + { + ID: unitTestMockAccountOneIdAsInt, + Name: unitTestMockAccountOneName, + RegionCode: "us01", + Status: "active", + }, + { + ID: unitTestMockAccountTwoIdAsInt, + Name: unitTestMockAccountTwoName, + RegionCode: "us01", + Status: "active", + }, + }, + NextCursor: unitTestMockNextCursor, + TotalCount: 2, + } + + actual, err := customeradministration.GetAccounts( + unitTestMockNextCursor, + OrganizationAccountFilterInput{ + Name: OrganizationAccountNameFilterInput{}, + OrganizationId: OrganizationAccountOrganizationIdFilterInput{unitTestMockOrganizationId}, + SharingMode: OrganizationAccountSharingModeFilterInput{}, + Status: OrganizationAccountStatusFilterInput{}, + }, + []OrganizationAccountSortInput{}, + ) + + assert.NoError(t, err) + assert.NotNil(t, actual) + assert.Equal(t, expected, actual) +} diff --git a/pkg/customeradministration/types.go b/pkg/customeradministration/types.go new file mode 100644 index 00000000..51bc4300 --- /dev/null +++ b/pkg/customeradministration/types.go @@ -0,0 +1,2043 @@ +// Code generated by tutone: DO NOT EDIT +package customeradministration + +import ( + "github.com/newrelic/newrelic-client-go/v2/pkg/nrtime" +) + +// DashboardEntityPermissions - Permisions that represent visibility & editability +type DashboardEntityPermissions string + +var DashboardEntityPermissionsTypes = struct { + // Private + PRIVATE DashboardEntityPermissions + // Public read only + PUBLIC_READ_ONLY DashboardEntityPermissions + // Public read & write + PUBLIC_READ_WRITE DashboardEntityPermissions +}{ + // Private + PRIVATE: "PRIVATE", + // Public read only + PUBLIC_READ_ONLY: "PUBLIC_READ_ONLY", + // Public read & write + PUBLIC_READ_WRITE: "PUBLIC_READ_WRITE", +} + +// DashboardPermissions - Permissions that represent visibility & editing. +type DashboardPermissions string + +var DashboardPermissionsTypes = struct { + // Only you can see the dashboard. Everything but the metadata is hidden. + PRIVATE DashboardPermissions + // All users are able to see the dashboard, but only you have full rights to work with the dashboard. Other users can access the dashboard but are not able to edit or delete it, although they can duplicate it. + PUBLIC_READ_ONLY DashboardPermissions + // All users have full rights to the dashboard. + PUBLIC_READ_WRITE DashboardPermissions +}{ + // Only you can see the dashboard. Everything but the metadata is hidden. + PRIVATE: "PRIVATE", + // All users are able to see the dashboard, but only you have full rights to work with the dashboard. Other users can access the dashboard but are not able to edit or delete it, although they can duplicate it. + PUBLIC_READ_ONLY: "PUBLIC_READ_ONLY", + // All users have full rights to the dashboard. + PUBLIC_READ_WRITE: "PUBLIC_READ_WRITE", +} + +// MultiTenantAuthorizationGrantScopeEnum - Provides the types of grant scopes available +type MultiTenantAuthorizationGrantScopeEnum string + +var MultiTenantAuthorizationGrantScopeEnumTypes = struct { + // Grant scoped to an account + ACCOUNT MultiTenantAuthorizationGrantScopeEnum + // Grant scoped to a group + GROUP MultiTenantAuthorizationGrantScopeEnum + // Grant scoped to an organization + ORGANIZATION MultiTenantAuthorizationGrantScopeEnum +}{ + // Grant scoped to an account + ACCOUNT: "ACCOUNT", + // Grant scoped to a group + GROUP: "GROUP", + // Grant scoped to an organization + ORGANIZATION: "ORGANIZATION", +} + +// MultiTenantAuthorizationGrantSortEnum - The possible fields a grant can be sorted on +type MultiTenantAuthorizationGrantSortEnum string + +var MultiTenantAuthorizationGrantSortEnumTypes = struct { + // Id of the grant + ID MultiTenantAuthorizationGrantSortEnum +}{ + // Id of the grant + ID: "ID", +} + +// MultiTenantAuthorizationPermissionCategoryEnum - The kind of access granted by permissions +type MultiTenantAuthorizationPermissionCategoryEnum string + +var MultiTenantAuthorizationPermissionCategoryEnumTypes = struct { + // Delete access + DELETE MultiTenantAuthorizationPermissionCategoryEnum + // Create and update access + MANAGE MultiTenantAuthorizationPermissionCategoryEnum + // Create and update access + MODIFY MultiTenantAuthorizationPermissionCategoryEnum + // Other access + OTHER MultiTenantAuthorizationPermissionCategoryEnum + // View access + READ MultiTenantAuthorizationPermissionCategoryEnum + // View access + VIEW MultiTenantAuthorizationPermissionCategoryEnum +}{ + // Delete access + DELETE: "DELETE", + // Create and update access + MANAGE: "MANAGE", + // Create and update access + MODIFY: "MODIFY", + // Other access + OTHER: "OTHER", + // View access + READ: "READ", + // View access + VIEW: "VIEW", +} + +// MultiTenantAuthorizationRoleScopeEnum - Enumerations of role scopes +type MultiTenantAuthorizationRoleScopeEnum string + +var MultiTenantAuthorizationRoleScopeEnumTypes = struct { + // Account scoped role + ACCOUNT MultiTenantAuthorizationRoleScopeEnum + // Group scoped role + GROUP MultiTenantAuthorizationRoleScopeEnum + // Organization scoped role + ORGANIZATION MultiTenantAuthorizationRoleScopeEnum +}{ + // Account scoped role + ACCOUNT: "ACCOUNT", + // Group scoped role + GROUP: "GROUP", + // Organization scoped role + ORGANIZATION: "ORGANIZATION", +} + +// MultiTenantAuthorizationRoleSortEnum - The list of sortable fields +type MultiTenantAuthorizationRoleSortEnum string + +var MultiTenantAuthorizationRoleSortEnumTypes = struct { + // Id of the role + ID MultiTenantAuthorizationRoleSortEnum + // Name of the role + NAME MultiTenantAuthorizationRoleSortEnum + // Scope of the role + SCOPE MultiTenantAuthorizationRoleSortEnum + // Type of the role + TYPE MultiTenantAuthorizationRoleSortEnum +}{ + // Id of the role + ID: "ID", + // Name of the role + NAME: "NAME", + // Scope of the role + SCOPE: "SCOPE", + // Type of the role + TYPE: "TYPE", +} + +// MultiTenantAuthorizationRoleTypeEnum - Enumerations of role types +type MultiTenantAuthorizationRoleTypeEnum string + +var MultiTenantAuthorizationRoleTypeEnumTypes = struct { + // Custom role + CUSTOM MultiTenantAuthorizationRoleTypeEnum + // Standard role + STANDARD MultiTenantAuthorizationRoleTypeEnum +}{ + // Custom role + CUSTOM: "CUSTOM", + // Standard role + STANDARD: "STANDARD", +} + +// MultiTenantAuthorizationSortDirectionEnum - Provides the directions data can be sorted +type MultiTenantAuthorizationSortDirectionEnum string + +var MultiTenantAuthorizationSortDirectionEnumTypes = struct { + // Sort in ascending order + ASCENDING MultiTenantAuthorizationSortDirectionEnum + // Sort in descending order + DESCENDING MultiTenantAuthorizationSortDirectionEnum +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// MultiTenantIdentityCapability - Provides the types of group capabilities available +type MultiTenantIdentityCapability string + +var MultiTenantIdentityCapabilityTypes = struct { + // The capability to delete a group + DELETE_GROUP MultiTenantIdentityCapability + // The capability to grant membership to a group + GRANT_GROUP_MEMBERSHIP MultiTenantIdentityCapability + // The capability to revoke membership from a group + REVOKE_GROUP_MEMBERSHIP MultiTenantIdentityCapability + // The capability to update a group's display name + UPDATE_GROUP_NAME MultiTenantIdentityCapability +}{ + // The capability to delete a group + DELETE_GROUP: "DELETE_GROUP", + // The capability to grant membership to a group + GRANT_GROUP_MEMBERSHIP: "GRANT_GROUP_MEMBERSHIP", + // The capability to revoke membership from a group + REVOKE_GROUP_MEMBERSHIP: "REVOKE_GROUP_MEMBERSHIP", + // The capability to update a group's display name + UPDATE_GROUP_NAME: "UPDATE_GROUP_NAME", +} + +// MultiTenantIdentityEmailVerificationState - Email verification validates that a user's email address exists and can receive email. One of: "Not Verifiable", "Verified", and "Pending". +type MultiTenantIdentityEmailVerificationState string + +var MultiTenantIdentityEmailVerificationStateTypes = struct { + // The user's email does not require verification. + NOT_VERIFIABLE MultiTenantIdentityEmailVerificationState + // The user's email requires verification and has not been verified. + PENDING MultiTenantIdentityEmailVerificationState + // The user's email requires verification and has been verified. + VERIFIED MultiTenantIdentityEmailVerificationState +}{ + // The user's email does not require verification. + NOT_VERIFIABLE: "NOT_VERIFIABLE", + // The user's email requires verification and has not been verified. + PENDING: "PENDING", + // The user's email requires verification and has been verified. + VERIFIED: "VERIFIED", +} + +// MultiTenantIdentitySortDirection - Available directions for sorting +type MultiTenantIdentitySortDirection string + +var MultiTenantIdentitySortDirectionTypes = struct { + // Sort in ascending order + ASCENDING MultiTenantIdentitySortDirection + // Sort in descending order + DESCENDING MultiTenantIdentitySortDirection +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// MultiTenantIdentitySortKeyEnum - Available keys for sorting groups +type MultiTenantIdentitySortKeyEnum string + +var MultiTenantIdentitySortKeyEnumTypes = struct { + // Authentication domain ID + AUTHENTICATION_DOMAIN_ID MultiTenantIdentitySortKeyEnum + // Group ID + ID MultiTenantIdentitySortKeyEnum + // Group name + NAME MultiTenantIdentitySortKeyEnum +}{ + // Authentication domain ID + AUTHENTICATION_DOMAIN_ID: "AUTHENTICATION_DOMAIN_ID", + // Group ID + ID: "ID", + // Group name + NAME: "NAME", +} + +// MultiTenantIdentityUserSortKey - Available keys for sorting users +type MultiTenantIdentityUserSortKey string + +var MultiTenantIdentityUserSortKeyTypes = struct { + // User email address + EMAIL MultiTenantIdentityUserSortKey + // User id + ID MultiTenantIdentityUserSortKey + // User last active date + LAST_ACTIVE MultiTenantIdentityUserSortKey + // User name + NAME MultiTenantIdentityUserSortKey + // User type + TYPE MultiTenantIdentityUserSortKey +}{ + // User email address + EMAIL: "EMAIL", + // User id + ID: "ID", + // User last active date + LAST_ACTIVE: "LAST_ACTIVE", + // User name + NAME: "NAME", + // User type + TYPE: "TYPE", +} + +// OrganizationAccountShareSortDirectionEnum - Provides the available values of possible directions to sort the result +type OrganizationAccountShareSortDirectionEnum string + +var OrganizationAccountShareSortDirectionEnumTypes = struct { + // Sort in ascending order + ASCENDING OrganizationAccountShareSortDirectionEnum + // Sort in descending order + DESCENDING OrganizationAccountShareSortDirectionEnum +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// OrganizationAccountShareSortKeyEnum - Provides the available values of possible fields that can be sorted +type OrganizationAccountShareSortKeyEnum string + +var OrganizationAccountShareSortKeyEnumTypes = struct { + // Account id + ACCOUNT_ID OrganizationAccountShareSortKeyEnum + // Name of the target organization the account is shared with + TARGET_ORGANIZATION_NAME OrganizationAccountShareSortKeyEnum +}{ + // Account id + ACCOUNT_ID: "ACCOUNT_ID", + // Name of the target organization the account is shared with + TARGET_ORGANIZATION_NAME: "TARGET_ORGANIZATION_NAME", +} + +// OrganizationAccountSortDirectionEnum - Provides the available values of possible directions to sort the result +type OrganizationAccountSortDirectionEnum string + +var OrganizationAccountSortDirectionEnumTypes = struct { + // Sort in ascending order + ASCENDING OrganizationAccountSortDirectionEnum + // Sort in descending order + DESCENDING OrganizationAccountSortDirectionEnum +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// OrganizationAccountSortKeyEnum - Provides the available values of possible fields that can be sorted +type OrganizationAccountSortKeyEnum string + +var OrganizationAccountSortKeyEnumTypes = struct { + // Account ID + ID OrganizationAccountSortKeyEnum + // Account Name + NAME OrganizationAccountSortKeyEnum +}{ + // Account ID + ID: "ID", + // Account Name + NAME: "NAME", +} + +// OrganizationAccountStatus - Provides the types of account statuses available +type OrganizationAccountStatus string + +var OrganizationAccountStatusTypes = struct { + // Accounts that are not in canceled status + ACTIVE OrganizationAccountStatus + // Accounts that have been canceled + CANCELED OrganizationAccountStatus +}{ + // Accounts that are not in canceled status + ACTIVE: "ACTIVE", + // Accounts that have been canceled + CANCELED: "CANCELED", +} + +// OrganizationAuthenticationTypeEnum - Provides the available values for authentication type +type OrganizationAuthenticationTypeEnum string + +var OrganizationAuthenticationTypeEnumTypes = struct { + // Authentication not configured + DISABLED OrganizationAuthenticationTypeEnum + // Heroku Single Sign-On + HEROKU_SSO OrganizationAuthenticationTypeEnum + // Oidc Single Sign-On + OIDC_SSO OrganizationAuthenticationTypeEnum + // Username and password authentication + PASSWORD OrganizationAuthenticationTypeEnum + // SAML Single Sign-On + SAML_SSO OrganizationAuthenticationTypeEnum +}{ + // Authentication not configured + DISABLED: "DISABLED", + // Heroku Single Sign-On + HEROKU_SSO: "HEROKU_SSO", + // Oidc Single Sign-On + OIDC_SSO: "OIDC_SSO", + // Username and password authentication + PASSWORD: "PASSWORD", + // SAML Single Sign-On + SAML_SSO: "SAML_SSO", +} + +// OrganizationBillingStructure - Valid billing structure values +type OrganizationBillingStructure string + +var OrganizationBillingStructureTypes = struct { + // Account Hierarchy + ACCOUNT_HIERARCHY OrganizationBillingStructure + // Customer Contract + CUSTOMER_CONTRACT OrganizationBillingStructure + // Unstructured + UNSTRUCTURED OrganizationBillingStructure +}{ + // Account Hierarchy + ACCOUNT_HIERARCHY: "ACCOUNT_HIERARCHY", + // Customer Contract + CUSTOMER_CONTRACT: "CUSTOMER_CONTRACT", + // Unstructured + UNSTRUCTURED: "UNSTRUCTURED", +} + +// OrganizationOrganizationCreateJobResultStatusEnum - The possible status values for job results +type OrganizationOrganizationCreateJobResultStatusEnum string + +var OrganizationOrganizationCreateJobResultStatusEnumTypes = struct { + // Jobs that have been created but not yet started running + CREATED OrganizationOrganizationCreateJobResultStatusEnum + // Jobs that have failed and stopped running + FAILED OrganizationOrganizationCreateJobResultStatusEnum + // Jobs that are still running + RUNNING OrganizationOrganizationCreateJobResultStatusEnum + // Jobs that completed successfully + SUCCEEDED OrganizationOrganizationCreateJobResultStatusEnum +}{ + // Jobs that have been created but not yet started running + CREATED: "CREATED", + // Jobs that have failed and stopped running + FAILED: "FAILED", + // Jobs that are still running + RUNNING: "RUNNING", + // Jobs that completed successfully + SUCCEEDED: "SUCCEEDED", +} + +// OrganizationOrganizationCreateJobStatusEnum - The list of valid job statuses to search for +type OrganizationOrganizationCreateJobStatusEnum string + +var OrganizationOrganizationCreateJobStatusEnumTypes = struct { + // All jobs regardless of status + ALL OrganizationOrganizationCreateJobStatusEnum + // Jobs that have been created but not yet started running + CREATED OrganizationOrganizationCreateJobStatusEnum + // Jobs that have failed and stopped running + FAILED OrganizationOrganizationCreateJobStatusEnum + // Jobs that are still running + RUNNING OrganizationOrganizationCreateJobStatusEnum + // Jobs that completed successfully + SUCCEEDED OrganizationOrganizationCreateJobStatusEnum +}{ + // All jobs regardless of status + ALL: "ALL", + // Jobs that have been created but not yet started running + CREATED: "CREATED", + // Jobs that have failed and stopped running + FAILED: "FAILED", + // Jobs that are still running + RUNNING: "RUNNING", + // Jobs that completed successfully + SUCCEEDED: "SUCCEEDED", +} + +// OrganizationProvisioningTypeEnum - Provides the available values for provisioning type +type OrganizationProvisioningTypeEnum string + +var OrganizationProvisioningTypeEnumTypes = struct { + // Provisioning not configured + DISABLED OrganizationProvisioningTypeEnum + // Manual provisioning + MANUAL OrganizationProvisioningTypeEnum + // SCIM automated provisioning + SCIM OrganizationProvisioningTypeEnum +}{ + // Provisioning not configured + DISABLED: "DISABLED", + // Manual provisioning + MANUAL: "MANUAL", + // SCIM automated provisioning + SCIM: "SCIM", +} + +// OrganizationSharingMode - Provides the types of sharing modes available +type OrganizationSharingMode string + +var OrganizationSharingModeTypes = struct { + // Accounts that are accessible to this organization + ALL OrganizationSharingMode + // Accounts that are managed by this organization + MANAGED OrganizationSharingMode + // Accounts managed by this organization that are currently shared with other organizations + SHARED_WITH_OTHER_ORGANIZATIONS OrganizationSharingMode + // Accounts that are shared with this organization + SHARED_WITH_THIS_ORGANIZATION OrganizationSharingMode +}{ + // Accounts that are accessible to this organization + ALL: "ALL", + // Accounts that are managed by this organization + MANAGED: "MANAGED", + // Accounts managed by this organization that are currently shared with other organizations + SHARED_WITH_OTHER_ORGANIZATIONS: "SHARED_WITH_OTHER_ORGANIZATIONS", + // Accounts that are shared with this organization + SHARED_WITH_THIS_ORGANIZATION: "SHARED_WITH_THIS_ORGANIZATION", +} + +// OrganizationSortDirectionEnum - Provides the available values of possible directions to sort the result +type OrganizationSortDirectionEnum string + +var OrganizationSortDirectionEnumTypes = struct { + // Sort in ascending order + ASCENDING OrganizationSortDirectionEnum + // Sort in descending order + DESCENDING OrganizationSortDirectionEnum +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// OrganizationSortKeyEnum - Provides the available values of possible fields that can be sorted +type OrganizationSortKeyEnum string + +var OrganizationSortKeyEnumTypes = struct { + // Authentication domain id + ID OrganizationSortKeyEnum + // Authentication domain name + NAME OrganizationSortKeyEnum +}{ + // Authentication domain id + ID: "ID", + // Authentication domain name + NAME: "NAME", +} + +// UserManagementGroupSortKey - Available keys for sorting groups +type UserManagementGroupSortKey string + +var UserManagementGroupSortKeyTypes = struct { + // Sort by display name + DISPLAY_NAME UserManagementGroupSortKey + // Sort by ID + ID UserManagementGroupSortKey +}{ + // Sort by display name + DISPLAY_NAME: "DISPLAY_NAME", + // Sort by ID + ID: "ID", +} + +// UserManagementSortDirection - Available directions for sorting +type UserManagementSortDirection string + +var UserManagementSortDirectionTypes = struct { + // Sort in ascending order + ASCENDING UserManagementSortDirection + // Sort in descending order + DESCENDING UserManagementSortDirection +}{ + // Sort in ascending order + ASCENDING: "ASCENDING", + // Sort in descending order + DESCENDING: "DESCENDING", +} + +// UserManagementTypeEnum - Available values for Type +type UserManagementTypeEnum string + +var UserManagementTypeEnumTypes = struct { + // Basic type + BASIC UserManagementTypeEnum + // Core type + CORE UserManagementTypeEnum + // Full type + FULL_PLATFORM UserManagementTypeEnum +}{ + // Basic type + BASIC: "BASIC", + // Core type + CORE: "CORE", + // Full type + FULL_PLATFORM: "FULL_PLATFORM", +} + +// AccountOutline - The `AccountOutline` object provides basic data about an account. +type AccountOutline struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` + // Returns event types that are currently reporting in the account. + ReportingEventTypes []string `json:"reportingEventTypes,omitempty"` +} + +// AccountReference - The `AccountReference` object provides basic identifying information about the account. +type AccountReference struct { + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +// AuthorizationManagementAuthenticationDomain - An "authentication domain" is a grouping of New Relic users governed by the same user management settings, like how they're provisioned (added and updated), how they're authenticated (logged in), session settings, and how user upgrades are managed. +type AuthorizationManagementAuthenticationDomain struct { + // container for groups enabling cursor based pagination + Groups AuthorizationManagementGroupSearch `json:"groups"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` +} + +// AuthorizationManagementAuthenticationDomainSearch - container for authentication domains enabling cursor based pagination +type AuthorizationManagementAuthenticationDomainSearch struct { + // containers of users and groups + AuthenticationDomains []AuthorizationManagementAuthenticationDomain `json:"authenticationDomains"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// AuthorizationManagementGrantedRole - A Granted Role represents the access given to a group. +type AuthorizationManagementGrantedRole struct { + // the account that this role grants access to + AccountID int `json:"accountId,omitempty"` + // the name of the object + DisplayName string `json:"displayName,omitempty"` + // the group that this role grants access to + GroupId string `json:"groupId,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // the organization this role grants access to + OrganizationId string `json:"organizationId,omitempty"` + // the role that defines this access + RoleId int `json:"roleId"` + // the type of the role + Type string `json:"type"` +} + +// AuthorizationManagementGrantedRoleSearch - container for roles enabling cursor based pagination +type AuthorizationManagementGrantedRoleSearch struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the roles granted to this group + Roles []AuthorizationManagementGrantedRole `json:"roles"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// AuthorizationManagementGroup - For users on our New Relic One user model, a "group" represents a group of users. Putting users in a group allows the managing of permissions for multiple users at the same time. +type AuthorizationManagementGroup struct { + // the name of the object + DisplayName string `json:"displayName"` + // a value that uniquely identifies this object + ID string `json:"id"` + // container for roles enabling cursor based pagination + Roles AuthorizationManagementGrantedRoleSearch `json:"roles"` +} + +// AuthorizationManagementGroupSearch - container for groups enabling cursor based pagination +type AuthorizationManagementGroupSearch struct { + // contains roles granted to users's groups + Groups []AuthorizationManagementGroup `json:"groups"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// AuthorizationManagementRole - a role grants access on an account or organization to groups of users +type AuthorizationManagementRole struct { + // the name of the object + DisplayName string `json:"displayName,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // the scope of the role + Scope string `json:"scope"` + // the type of the role + Type string `json:"type"` +} + +// AuthorizationManagementRoleSearch - container for roles enabling cursor based pagination +type AuthorizationManagementRoleSearch struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // control the access granted to groups + Roles []AuthorizationManagementRole `json:"roles"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +type Consumption struct { + // The `Consumption` object provides consumption data about a user. + CustomerId string `json:"customerId,omitempty"` +} + +// CustomerAdministration - The `CustomerAdministration` object contains fields for managing the configuration that defines the business relationships between New Relic, partners, and customers. +type CustomerAdministration struct { + // Accessible account shares + AccountShares OrganizationAccountShareCollection `json:"accountShares,omitempty"` + // accounts + Accounts OrganizationAccountCollection `json:"accounts,omitempty"` + // Authentication domains + AuthenticationDomains OrganizationAuthenticationDomainCollection `json:"authenticationDomains,omitempty"` + // The `consumption` field is the entry point into a customer's consumption data that is scoped to the ID of the customer. + Consumption Consumption `json:"consumption,omitempty"` + // Accessible contracts + Contracts OrganizationCustomerContractWrapper `json:"contracts,omitempty"` + // list of grants + Grants MultiTenantAuthorizationGrantCollection `json:"grants,omitempty"` + // Named sets of New Relic users within an authentication domain + Groups MultiTenantIdentityGroupCollection `json:"groups,omitempty"` + // This provides access to fields you can use to check the status of asynchronous jobs related to customer administration. + Jobs CustomerAdministrationJobs `json:"jobs,omitempty"` + // Accessible organizations + Organizations OrganizationCustomerOrganizationWrapper `json:"organizations,omitempty"` + // list of permissions + Permissions MultiTenantAuthorizationPermissionCollection `json:"permissions,omitempty"` + // list of roles + Roles MultiTenantAuthorizationRoleCollection `json:"roles,omitempty"` + // The authenticated `User` who made this request. + User User `json:"user,omitempty"` + // A collection of New Relic users + Users MultiTenantIdentityUserCollection `json:"users,omitempty"` +} + +type CustomerAdministrationJobs struct { + // Organization Create job results + OrganizationCreateAsyncResults OrganizationOrganizationCreateAsyncResultCollection `json:"organizationCreateAsyncResults,omitempty"` +} + +// MultiTenantAuthorizationGrant - A grant within the system +type MultiTenantAuthorizationGrant struct { + // The group associated to the grant + Group MultiTenantAuthorizationGrantGroup `json:"group"` + // The id of the grant + ID int `json:"id"` + // The role associated to the grant + Role MultiTenantAuthorizationGrantRole `json:"role"` + // The scope associated to the grant + Scope MultiTenantAuthorizationGrantScope `json:"scope"` +} + +// MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter - Filters grants by authentication domain id +type MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter struct { + // Performs an equals operation + Eq string `json:"eq,omitempty"` + // Performs an in operation + In []string `json:"in"` +} + +// MultiTenantAuthorizationGrantCollection - A list of grants +type MultiTenantAuthorizationGrantCollection struct { + // List of grants + Items []MultiTenantAuthorizationGrant `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// MultiTenantAuthorizationGrantFilterInputExpression - Provides all the available filters on a grant +type MultiTenantAuthorizationGrantFilterInputExpression struct { + // The authentication domain id of the grant + AuthenticationDomainId *MultiTenantAuthorizationGrantAuthenticationDomainIdInputFilter `json:"authenticationDomainId,omitempty"` + // The group id of the grant + GroupId *MultiTenantAuthorizationGrantGroupIdInputFilter `json:"groupId,omitempty"` + // The id of the grant + ID *MultiTenantAuthorizationGrantIdInputFilter `json:"id,omitempty"` + // The organization id the grant belongs to + OrganizationId *MultiTenantAuthorizationGrantOrganizationIdInputFilter `json:"organizationId,omitempty"` + // The role id of the grant + RoleId *MultiTenantAuthorizationGrantRoleIdInputFilter `json:"roleId,omitempty"` + // the scope id of the grant + ScopeId *MultiTenantAuthorizationGrantScopeIdInputFilter `json:"scopeId,omitempty"` + // The scope type of the grant + ScopeType *MultiTenantAuthorizationGrantScopeTypeInputFilter `json:"scopeType,omitempty"` +} + +// MultiTenantAuthorizationGrantGroup - The group associated to the grant +type MultiTenantAuthorizationGrantGroup struct { + // The id of the group + ID string `json:"id"` +} + +// MultiTenantAuthorizationGrantGroupIdInputFilter - Filters on grants group id +type MultiTenantAuthorizationGrantGroupIdInputFilter struct { + // Performs an equals operation + Eq string `json:"eq,omitempty"` + // Performs an in operation + In []string `json:"in"` +} + +// MultiTenantAuthorizationGrantIdInputFilter - Fitlers on grants id +type MultiTenantAuthorizationGrantIdInputFilter struct { + // Performs an equals operation + Eq int `json:"eq"` +} + +// MultiTenantAuthorizationGrantOrganizationIdInputFilter - Filters on the grants organization id +type MultiTenantAuthorizationGrantOrganizationIdInputFilter struct { + // Performs an equals operation + Eq string `json:"eq"` +} + +// MultiTenantAuthorizationGrantRole - The role associated to the grant +type MultiTenantAuthorizationGrantRole struct { + // The id of the role + ID int `json:"id"` + // The name of the role + Name string `json:"name"` +} + +// MultiTenantAuthorizationGrantRoleIdInputFilter - Filters on the grants role id +type MultiTenantAuthorizationGrantRoleIdInputFilter struct { + // Performs an equals operation + Eq int `json:"eq,omitempty"` + // Performs an in operation + In []int `json:"in"` +} + +// MultiTenantAuthorizationGrantScope - The scope associated to the grant +type MultiTenantAuthorizationGrantScope struct { + // The id of the resource in scope + ID string `json:"id"` + // The type of the resource in scope + Type MultiTenantAuthorizationGrantScopeEnum `json:"type"` +} + +// MultiTenantAuthorizationGrantScopeIdInputFilter - Filters on the grants scope id +type MultiTenantAuthorizationGrantScopeIdInputFilter struct { + // Performs an equals operation + Eq string `json:"eq,omitempty"` + // Performs an in operation + In []string `json:"in"` +} + +// MultiTenantAuthorizationGrantScopeTypeInputFilter - Filters on the grants scope type +type MultiTenantAuthorizationGrantScopeTypeInputFilter struct { + // Performs an equals operation + Eq MultiTenantAuthorizationGrantScopeEnum `json:"eq"` +} + +// MultiTenantAuthorizationGrantSortInput - Provides the sorting options for grants +type MultiTenantAuthorizationGrantSortInput struct { + // The direction which the field should be sorted + Direction MultiTenantAuthorizationSortDirectionEnum `json:"direction,omitempty"` + // The field to be sorted + Key MultiTenantAuthorizationGrantSortEnum `json:"key"` +} + +// MultiTenantAuthorizationPermission - An allowed action +type MultiTenantAuthorizationPermission struct { + // The kind of access + Category MultiTenantAuthorizationPermissionCategoryEnum `json:"category,omitempty"` + // The feature the permission controls access to + Feature string `json:"feature,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // Name of the permission if category is OTHER + Name string `json:"name,omitempty"` + // The product the permission controls access to + Product string `json:"product,omitempty"` +} + +// MultiTenantAuthorizationPermissionCollection - A collection of permissions +type MultiTenantAuthorizationPermissionCollection struct { + // collection of permissions + Items []MultiTenantAuthorizationPermission `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// MultiTenantAuthorizationPermissionFilter - Provides all the available filters on permissions +type MultiTenantAuthorizationPermissionFilter struct { + // Filter permissions by role id + RoleId MultiTenantAuthorizationPermissionFilterRoleIdInput `json:"roleId,omitempty"` +} + +// MultiTenantAuthorizationPermissionFilterRoleIdInput - Filter permissions by role id +type MultiTenantAuthorizationPermissionFilterRoleIdInput struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// MultiTenantAuthorizationRole - Describes a role within the system +type MultiTenantAuthorizationRole struct { + // a value that uniquely identifies this object + ID int `json:"id"` + // the name of the object + Name string `json:"name"` + // The scope the role applies to + Scope string `json:"scope"` + // The type of role + Type string `json:"type"` +} + +// MultiTenantAuthorizationRoleCollection - An iterable collection of roles +type MultiTenantAuthorizationRoleCollection struct { + // collection of roles + Items []MultiTenantAuthorizationRole `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// MultiTenantAuthorizationRoleFilterInputExpression - Provides all the available filters on a role +type MultiTenantAuthorizationRoleFilterInputExpression struct { + // The group id the role has been granted to + GroupId *MultiTenantAuthorizationRoleGroupIdInputFilter `json:"groupId,omitempty"` + // The id of the role + ID *MultiTenantAuthorizationRoleIdInputFilter `json:"id,omitempty"` + // The name of the role + Name *MultiTenantAuthorizationRoleNameInputFilter `json:"name,omitempty"` + // The organization id the role belongs to + OrganizationId *MultiTenantAuthorizationRoleOrganizationIdInputFilter `json:"organizationId,omitempty"` + // The scope of the role + Scope *MultiTenantAuthorizationRoleScopeInputFilter `json:"scope,omitempty"` + // The type of the role + Type *MultiTenantAuthorizationRoleTypeInputFilter `json:"type,omitempty"` +} + +// MultiTenantAuthorizationRoleGroupIdInputFilter - Provides all the available filters on the group id +type MultiTenantAuthorizationRoleGroupIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq,omitempty"` + // A list of group IDs + In []string `json:"in"` +} + +// MultiTenantAuthorizationRoleIdInputFilter - Provides all the available filters on the role id +type MultiTenantAuthorizationRoleIdInputFilter struct { + // performs an equals operation + Eq int `json:"eq"` +} + +// MultiTenantAuthorizationRoleNameInputFilter - Provides all the available filters on the role name +type MultiTenantAuthorizationRoleNameInputFilter struct { + // performs a contains operation + Contains string `json:"contains,omitempty"` + // performs an equals operation + Eq string `json:"eq,omitempty"` +} + +// MultiTenantAuthorizationRoleOrganizationIdInputFilter - Provides all the available filters on the organization id +type MultiTenantAuthorizationRoleOrganizationIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// MultiTenantAuthorizationRoleScopeInputFilter - Provides all the available filters on the role scope +type MultiTenantAuthorizationRoleScopeInputFilter struct { + // performs an equals operation + Eq MultiTenantAuthorizationRoleScopeEnum `json:"eq"` +} + +// MultiTenantAuthorizationRoleSortInput - Provides the field and direction the result should be sorted +type MultiTenantAuthorizationRoleSortInput struct { + // The direction the field should be sorted + Direction MultiTenantAuthorizationSortDirectionEnum `json:"direction,omitempty"` + // The field which should be sorted + Key MultiTenantAuthorizationRoleSortEnum `json:"key"` +} + +// MultiTenantAuthorizationRoleTypeInputFilter - Provides all the available filters on the role type +type MultiTenantAuthorizationRoleTypeInputFilter struct { + // performs an equals operation + Eq MultiTenantAuthorizationRoleTypeEnum `json:"eq"` +} + +// MultiTenantIdentityAllowsCapabilityInput - The input object representing parameters for the allowed capability filter +type MultiTenantIdentityAllowsCapabilityInput struct { + // A list of capabilities. If set, groups with atleast one of the given capabilities granted on them for the user will be returned. Otherwise, only groups with read access granted are returned. + In []MultiTenantIdentityCapability `json:"in"` +} + +// MultiTenantIdentityAuthenticationDomainIdInput - The input object representing parameters for the authentication domain ID filter +type MultiTenantIdentityAuthenticationDomainIdInput struct { + // An authentication domain ID + Eq string `json:"eq"` +} + +// MultiTenantIdentityEmailVerificationStateInput - Available filtering types for email verification states +type MultiTenantIdentityEmailVerificationStateInput struct { + // An email verification state + Pending bool `json:"pending"` +} + +// MultiTenantIdentityGroup - For users on our New Relic One user model, a "group" represents a group of users. Putting users in a group allows the managing of permissions for multiple users at the same time. +type MultiTenantIdentityGroup struct { + // The authentication domain the group belongs to + AuthenticationDomainId string `json:"authenticationDomainId"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // Active users belonging to a group + Users MultiTenantIdentityGroupUsers `json:"users,omitempty"` +} + +// MultiTenantIdentityGroupCollection - List of groups representing named sets of New Relic users within an authentication domain +type MultiTenantIdentityGroupCollection struct { + // groups + Items []MultiTenantIdentityGroup `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// MultiTenantIdentityGroupFilterInput - The input object representing the filter parameters for groups +type MultiTenantIdentityGroupFilterInput struct { + // Filter groups by capabilities + AllowsCapability *MultiTenantIdentityAllowsCapabilityInput `json:"allowsCapability,omitempty"` + // Filter groups by authentication domain + AuthenticationDomainId *MultiTenantIdentityAuthenticationDomainIdInput `json:"authenticationDomainId,omitempty"` + // Filter groups by ID + ID *MultiTenantIdentityGroupIdInput `json:"id,omitempty"` + // Filter groups that contain specific members + Members *MultiTenantIdentityGroupMemberIdInput `json:"members,omitempty"` + // Filter groups by display name + Name *MultiTenantIdentityGroupNameInput `json:"name,omitempty"` + // An organization ID to filter groups by + OrganizationId *MultiTenantIdentityOrganizationIdInput `json:"organizationId,omitempty"` +} + +// MultiTenantIdentityGroupIdInput - The input object representing parameters for the ID input filter +type MultiTenantIdentityGroupIdInput struct { + // A group ID + Eq string `json:"eq"` +} + +// MultiTenantIdentityGroupMemberIdInput - The input object representing parameters for the Members filter +type MultiTenantIdentityGroupMemberIdInput struct { + // A list of user IDs. A group will be returned if all listed users are members. + Contains []string `json:"contains"` + // A list of user IDS. A group will be returned if no listed users are members. + Excludes []string `json:"excludes"` +} + +// MultiTenantIdentityGroupNameInput - The input object representing parameters for the name filter +type MultiTenantIdentityGroupNameInput struct { + // Part of a group name + Contains string `json:"contains,omitempty"` + // A group name + Eq string `json:"eq,omitempty"` +} + +// MultiTenantIdentityGroupSortInput - The input object representing the sort parameters for groups +type MultiTenantIdentityGroupSortInput struct { + // Order by which to sort groups + Direction MultiTenantIdentitySortDirection `json:"direction,omitempty"` + // Group attribute to sort on + Key MultiTenantIdentitySortKeyEnum `json:"key,omitempty"` +} + +// MultiTenantIdentityGroupUser - Active user within group +type MultiTenantIdentityGroupUser struct { + // The email of the user. + Email string `json:"email"` + // a value that uniquely identifies this object + ID string `json:"id"` + // The full name of the user. + Name string `json:"name"` + // The configured time zone of the user. + TimeZone string `json:"timeZone,omitempty"` +} + +// MultiTenantIdentityGroupUserFilterInput - The input object representing the filter parameters for user groups +type MultiTenantIdentityGroupUserFilterInput struct { + // Filter users by IDs + ID *MultiTenantIdentityUserIdInput `json:"id,omitempty"` +} + +// MultiTenantIdentityGroupUsers - List of active users belonging to a group +type MultiTenantIdentityGroupUsers struct { + // Active users within group + Items []MultiTenantIdentityGroupUser `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// MultiTenantIdentityOrganizationIdInput - The input object representing parameters for the organization ID filter +type MultiTenantIdentityOrganizationIdInput struct { + // An organization ID + Eq string `json:"eq"` +} + +// MultiTenantIdentityPendingUpgradeRequest - Exists only if a user has a pending upgrade request. +type MultiTenantIdentityPendingUpgradeRequest struct { + // a value that uniquely identifies this object + ID string `json:"id"` + // Requester message, why the user believes they require the upgrade. + Message string `json:"message,omitempty"` + // Requested user type for the user. + RequestedUserType MultiTenantIdentityUserType `json:"requestedUserType,omitempty"` +} + +// MultiTenantIdentityPendingUpgradeRequestInput - Available filtering types for pending upgrade requests +type MultiTenantIdentityPendingUpgradeRequestInput struct { + // Whether a request exists or not + Exists bool `json:"exists"` +} + +// MultiTenantIdentityUser - A New Relic user +type MultiTenantIdentityUser struct { + // The authentication domain the user belongs to. + AuthenticationDomainId string `json:"authenticationDomainId"` + // Email address of the user. + Email string `json:"email,omitempty"` + // One of: "Not Verifiable", "Verified", and "Pending". + // + // Not Verifiable: the user's email does not require verification. + // + // Verified: the user's email requires verification and has been. + // + // Pending: the user's email requires verification and has not been. + EmailVerificationState MultiTenantIdentityEmailVerificationState `json:"emailVerificationState"` + // container for groups enabling cursor based pagination + Groups MultiTenantIdentityUserGroups `json:"groups,omitempty"` + // The user id. + ID string `json:"id"` + // The last active date of the user. + LastActive nrtime.DateTime `json:"lastActive,omitempty"` + // The full name of the user. + Name string `json:"name,omitempty"` + // The pending upgrade request for the user (if any). + PendingUpgradeRequest MultiTenantIdentityPendingUpgradeRequest `json:"pendingUpgradeRequest,omitempty"` + // Time zone of the user in IANA Time Zone database format, also known as the "Olson" time zone database format (for exmaple, "America/Los_Angeles"). + TimeZone string `json:"timeZone,omitempty"` + // A "user type" is what determines the set of New Relic capabilities a user can theoretically access. + Type MultiTenantIdentityUserType `json:"type"` +} + +// MultiTenantIdentityUserCollection - A collection of New Relic users +type MultiTenantIdentityUserCollection struct { + // Users + Items []MultiTenantIdentityUser `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // The total number of users found. + // Note: Not necessarily the same as number of users returned, due to pagination. + TotalCount int `json:"totalCount"` +} + +// MultiTenantIdentityUserEmailInput - Filters by user email address +type MultiTenantIdentityUserEmailInput struct { + // Part of an email address + Contains string `json:"contains,omitempty"` + // An email address + Eq string `json:"eq,omitempty"` +} + +// MultiTenantIdentityUserFilterInput - Filter users +type MultiTenantIdentityUserFilterInput struct { + // Filter users by authentication domain + AuthenticationDomainId *MultiTenantIdentityAuthenticationDomainIdInput `json:"authenticationDomainId,omitempty"` + // Filter users by email address + Email *MultiTenantIdentityUserEmailInput `json:"email,omitempty"` + // Filter users by email verification state + EmailVerificationState *MultiTenantIdentityEmailVerificationStateInput `json:"emailVerificationState,omitempty"` + // Filter users by group id + GroupId *MultiTenantIdentityUserGroupIdInput `json:"groupId,omitempty"` + // Filter users by id + ID *MultiTenantIdentityUserIdInput `json:"id,omitempty"` + // Filter users by name + Name *MultiTenantIdentityUserNameInput `json:"name,omitempty"` + // Filter users by pending upgrade request + PendingUpgradeRequest *MultiTenantIdentityPendingUpgradeRequestInput `json:"pendingUpgradeRequest,omitempty"` +} + +// MultiTenantIdentityUserGroup - A group of users. +type MultiTenantIdentityUserGroup struct { + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` +} + +// MultiTenantIdentityUserGroupIdInput - Filters by group id +type MultiTenantIdentityUserGroupIdInput struct { + // A group id + Eq string `json:"eq,omitempty"` + // A list of group IDs + In []string `json:"in"` + // Filter users not in group + Not MultiTenantIdentityUserNotGroupIdInput `json:"not,omitempty"` +} + +// MultiTenantIdentityUserGroups - List of groups representing named sets of New Relic users within an authentication domain +type MultiTenantIdentityUserGroups struct { + // User groups + Items []MultiTenantIdentityUserGroup `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// MultiTenantIdentityUserIdInput - Filters by user id +type MultiTenantIdentityUserIdInput struct { + // A user id + Eq string `json:"eq,omitempty"` + // A list of user IDs + In []string `json:"in"` +} + +// MultiTenantIdentityUserNameInput - Filters by user name +type MultiTenantIdentityUserNameInput struct { + // Part of a user name + Contains string `json:"contains,omitempty"` + // A user name + Eq string `json:"eq,omitempty"` +} + +// MultiTenantIdentityUserNotGroupIdInput - Filters by group id +type MultiTenantIdentityUserNotGroupIdInput struct { + // A group id + Eq string `json:"eq"` +} + +// MultiTenantIdentityUserSortInput - Sort users +type MultiTenantIdentityUserSortInput struct { + // Direction to sort in + Direction MultiTenantIdentitySortDirection `json:"direction,omitempty"` + // User attribute to sort on + Key MultiTenantIdentityUserSortKey `json:"key,omitempty"` +} + +// MultiTenantIdentityUserType - A "user type" is what determines the set of New Relic capabilities a user can theoretically access. +type MultiTenantIdentityUserType struct { + // The id of the user type. + ID string `json:"id"` + // The name of the user type. + Name string `json:"name"` +} + +// OrganizationAccount - The account type contains the properties of an account +type OrganizationAccount struct { + // The account id + ID int `json:"id"` + // The account name + Name string `json:"name"` + // The account region code + RegionCode string `json:"regionCode"` + // The status + Status string `json:"status"` +} + +// OrganizationAccountCollection - Accounts +type OrganizationAccountCollection struct { + // Accounts + Items []OrganizationAccount `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// OrganizationAccountFilterInput - A filter for Accounts +type OrganizationAccountFilterInput struct { + // Filter by account ID + ID OrganizationAccountIdFilterInput `json:"id,omitempty"` + // Filter by Account Name + Name OrganizationAccountNameFilterInput `json:"name,omitempty"` + // Filter by organization ID + OrganizationId OrganizationAccountOrganizationIdFilterInput `json:"organizationId,omitempty"` + // Filter by Sharing Mode + SharingMode OrganizationAccountSharingModeFilterInput `json:"sharingMode,omitempty"` + // Filter by an account status. By default filters to active accounts. + Status OrganizationAccountStatusFilterInput `json:"status,omitempty"` +} + +// OrganizationAccountIdFilterInput - A filter for an AccountID +type OrganizationAccountIdFilterInput struct { + // An Account ID + Eq int `json:"eq,omitempty"` +} + +// OrganizationAccountIdInput - Provides the operations available on the account id +type OrganizationAccountIdInput struct { + // An account id + Eq int `json:"eq"` +} + +// OrganizationAccountNameFilterInput - A filter for Account name +type OrganizationAccountNameFilterInput struct { + // Search text for an account name + Contains string `json:"contains,omitempty"` +} + +// OrganizationAccountOrganizationIdFilterInput - A filter for OrganizationID +type OrganizationAccountOrganizationIdFilterInput struct { + // An Organization ID + Eq string `json:"eq"` +} + +// OrganizationAccountShare - An account share +type OrganizationAccountShare struct { + // The ID of the account being shared + AccountID int `json:"accountId"` + // The account share ID + ID string `json:"id"` + // The limiting role + LimitingRole OrganizationAccountShareLimitingRoleWrapper `json:"limitingRole"` + // The name of the account share + Name string `json:"name"` + // The organization sending the account share. + Source OrganizationAccountShareOrganizationWrapper `json:"source"` + // The organization receiving the account share. + Target OrganizationAccountShareOrganizationWrapper `json:"target"` +} + +// OrganizationAccountShareCollection - An organization's shared accounts, both given and received. +type OrganizationAccountShareCollection struct { + // An organization's shared accounts, both given and received. + Items []OrganizationAccountShare `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationAccountShareFilterInput - A filter for account shares +type OrganizationAccountShareFilterInput struct { + // Filter by account id + AccountID OrganizationAccountIdInput `json:"accountId,omitempty"` + // Filter by target id + TargetId OrganizationTargetIdInput `json:"targetId,omitempty"` +} + +// OrganizationAccountShareLimitingRoleWrapper - An account share's limiting role +type OrganizationAccountShareLimitingRoleWrapper struct { + // id + ID string `json:"id"` +} + +// OrganizationAccountShareOrganizationWrapper - An account share's source or target organization +type OrganizationAccountShareOrganizationWrapper struct { + // id + ID string `json:"id,omitempty"` + // name + Name string `json:"name,omitempty"` +} + +// OrganizationAccountShareSortInput - Sort key and direction for account shares +type OrganizationAccountShareSortInput struct { + // Direction to sort in + Direction OrganizationAccountShareSortDirectionEnum `json:"direction,omitempty"` + // Account share attribute to sort on + Key OrganizationAccountShareSortKeyEnum `json:"key,omitempty"` +} + +// OrganizationAccountShares - An organization's shared accounts, both given and received. +type OrganizationAccountShares struct { + // An organization's shared accounts, both given and received. + SharedAccounts []OrganizationSharedAccount `json:"sharedAccounts"` +} + +// OrganizationAccountSharingModeFilterInput - A filter for Sharing Mode +type OrganizationAccountSharingModeFilterInput struct { + // A Sharing Mode for the account. + Eq OrganizationSharingMode `json:"eq,omitempty"` +} + +// OrganizationAccountSortInput - Sort key and direction for accounts +type OrganizationAccountSortInput struct { + // Direction to sort in + Direction OrganizationAccountSortDirectionEnum `json:"direction,omitempty"` + // Account share attribute to sort on + Key OrganizationAccountSortKeyEnum `json:"key,omitempty"` +} + +// OrganizationAccountStatusFilterInput - A filter for Account Status +type OrganizationAccountStatusFilterInput struct { + // An account status + Eq OrganizationAccountStatus `json:"eq,omitempty"` +} + +// OrganizationAuthenticationDomain - A grouping of users governed by the same user management settings +type OrganizationAuthenticationDomain struct { + // Method of authenticating users + AuthenticationType OrganizationAuthenticationTypeEnum `json:"authenticationType"` + // The authentication domain id + ID string `json:"id"` + // The authentication domain name + Name string `json:"name"` + // The organization the authentication domain belongs to + OrganizationId string `json:"organizationId"` + // Method of provisioning users + ProvisioningType OrganizationProvisioningTypeEnum `json:"provisioningType"` +} + +// OrganizationAuthenticationDomainCollection - Authentication domains +type OrganizationAuthenticationDomainCollection struct { + // Authentication domains + Items []OrganizationAuthenticationDomain `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationAuthenticationDomainFilterInput - A filter for authentication domains +type OrganizationAuthenticationDomainFilterInput struct { + // Filter authentication domains by id + ID OrganizationIdInput `json:"id,omitempty"` + // Filter authentication domains by name + Name OrganizationNameInput `json:"name,omitempty"` + // Filter authentication domains by organization + OrganizationId OrganizationOrganizationIdInput `json:"organizationId,omitempty"` +} + +// OrganizationAuthenticationDomainSortInput - Sort key and direction for authentication domains +type OrganizationAuthenticationDomainSortInput struct { + // Direction to sort in + Direction OrganizationSortDirectionEnum `json:"direction,omitempty"` + // Authentication domain attribute to sort on + Key OrganizationSortKeyEnum `json:"key,omitempty"` +} + +// OrganizationContractCustomerIdInputFilter - Provides all the available filters on the customer id +type OrganizationContractCustomerIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationContractOrganizationIdInputFilter - Provides all the available filters on the organization id +type OrganizationContractOrganizationIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationCustomerContract - A customer +type OrganizationCustomerContract struct { + // The customer contract''s billing structure + BillingStructure OrganizationBillingStructure `json:"billingStructure,omitempty"` + // The customers id + CustomerId string `json:"customerId"` + // The customer contracts ID + ID string `json:"id"` + // The customer contracts organization groups + OrganizationGroups OrganizationOrganizationGroupWrapper `json:"organizationGroups"` + // The customer contracts''s telemetry id + TelemetryId string `json:"telemetryId,omitempty"` +} + +// OrganizationCustomerContractFilterInput - A filter for customer contracts +type OrganizationCustomerContractFilterInput struct { + // The id of the customer + CustomerId OrganizationContractCustomerIdInputFilter `json:"customerId,omitempty"` + // The id of the organization + OrganizationId OrganizationContractOrganizationIdInputFilter `json:"organizationId,omitempty"` +} + +// OrganizationCustomerContractWrapper - Accessible customers +type OrganizationCustomerContractWrapper struct { + // Accessible customers + Items []OrganizationCustomerContract `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationCustomerOrganization - A customer organization +type OrganizationCustomerOrganization struct { + // The ID of the organization group + ContractId string `json:"contractId,omitempty"` + // The ID of the customer + CustomerId string `json:"customerId,omitempty"` + // The ID of the organization + ID string `json:"id"` + // The name of the organization + Name string `json:"name,omitempty"` +} + +// OrganizationCustomerOrganizationFilterInput - A filter for customer organizations +type OrganizationCustomerOrganizationFilterInput struct { + // The id of the owned account + AccountID OrganizationOrganizationAccountIdInputFilter `json:"accountId,omitempty"` + // The id of the authentication domain + AuthenticationDomainId OrganizationOrganizationAuthenticationDomainIdInputFilter `json:"authenticationDomainId,omitempty"` + // The id of the customer + CustomerId OrganizationOrganizationCustomerIdInputFilter `json:"customerId,omitempty"` + // The id of the organization + ID OrganizationOrganizationIdInputFilter `json:"id,omitempty"` + // The name of the organization + Name OrganizationOrganizationNameInputFilter `json:"name,omitempty"` +} + +// OrganizationCustomerOrganizationWrapper - A customer organization +type OrganizationCustomerOrganizationWrapper struct { + // Accessible customers + Items []OrganizationCustomerOrganization `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationIdInput - Provides the operations available on the id +type OrganizationIdInput struct { + // An authentication domain id + Eq string `json:"eq"` +} + +// OrganizationNameInput - Provides the operations available on the name +type OrganizationNameInput struct { + // Part of an authentication domain name + Contains string `json:"contains,omitempty"` + // An authentication domain name + Eq string `json:"eq,omitempty"` +} + +// OrganizationOrganizationAccountIdInputFilter - Provides all the available filters on the account id +type OrganizationOrganizationAccountIdInputFilter struct { + // performs an equals operation + Eq int `json:"eq"` +} + +// OrganizationOrganizationAuthenticationDomainIdInputFilter - Provides all the available filters on the authentication domain id +type OrganizationOrganizationAuthenticationDomainIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationOrganizationCreateAsyncCustomerResult - An async organization creation result customer +type OrganizationOrganizationCreateAsyncCustomerResult struct { + // The customer ID + CustomerId string `json:"customerId,omitempty"` +} + +// OrganizationOrganizationCreateAsyncJobResult - An async organization creation job result +type OrganizationOrganizationCreateAsyncJobResult struct { + // The date and time the job was created in UTC + CreatedUtc string `json:"createdUtc"` + // The error message in case of job failure + ErrorMessage string `json:"errorMessage,omitempty"` + // The date and time the job was completed in UTC + FinishedUtc string `json:"finishedUtc,omitempty"` + // The id of the job + ID string `json:"id"` + // The status of the job + Status OrganizationOrganizationCreateJobResultStatusEnum `json:"status"` +} + +// OrganizationOrganizationCreateAsyncOrganizationResult - An async organization creation result organization +type OrganizationOrganizationCreateAsyncOrganizationResult struct { + // Organization ID + ID string `json:"id,omitempty"` + // Organization name + Name string `json:"name,omitempty"` +} + +// OrganizationOrganizationCreateAsyncResult - An async organization creation result +type OrganizationOrganizationCreateAsyncResult struct { + // Organization Creation Async Job Customer + Customer OrganizationOrganizationCreateAsyncCustomerResult `json:"customer,omitempty"` + // Organization Creation Async Job Result + Job OrganizationOrganizationCreateAsyncJobResult `json:"job"` + // Organization Creation Async Job Organization + Organization OrganizationOrganizationCreateAsyncOrganizationResult `json:"organization,omitempty"` +} + +// OrganizationOrganizationCreateAsyncResultCollection - Organization create async result collection +type OrganizationOrganizationCreateAsyncResultCollection struct { + // Organization create async results + Items []OrganizationOrganizationCreateAsyncResult `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationOrganizationCreateAsyncResultFilterInput - A filter for organization create job results +type OrganizationOrganizationCreateAsyncResultFilterInput struct { + // Filter organization create job results by customer ID + CustomerId *OrganizationOrganizationCreateJobCustomerIdInput `json:"customerId,omitempty"` + // Filter oganization create job results by id + JobId *OrganizationOrganizationCreateJobIdInput `json:"jobId,omitempty"` + // Filter organization create job results by status + Status *OrganizationOrganizationCreateJobStatusInput `json:"status,omitempty"` +} + +// OrganizationOrganizationCreateJobCustomerIdInput - The customer id search for jobs +type OrganizationOrganizationCreateJobCustomerIdInput struct { + // A customer id to search for jobs in + Eq string `json:"eq"` +} + +// OrganizationOrganizationCreateJobIdInput - The id of the job to retrieve +type OrganizationOrganizationCreateJobIdInput struct { + // An organization create job id + Eq string `json:"eq,omitempty"` + // A set of job ids to search for + In []string `json:"in"` +} + +// OrganizationOrganizationCreateJobStatusInput - The status of the jobs to search for +type OrganizationOrganizationCreateJobStatusInput struct { + // a job status to search for + Eq OrganizationOrganizationCreateJobStatusEnum `json:"eq,omitempty"` + // a set of job statuses to search for + In []OrganizationOrganizationCreateJobStatusEnum `json:"in"` +} + +// OrganizationOrganizationCustomerIdInputFilter - Provides all the available filters on the customer id +type OrganizationOrganizationCustomerIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationOrganizationGroup - A customers organization group +type OrganizationOrganizationGroup struct { + // The ID of the organization group + ID string `json:"id"` + // The name of the organization group + Name string `json:"name"` +} + +// OrganizationOrganizationGroupFilterInput - A filter for organization groups +type OrganizationOrganizationGroupFilterInput struct { + // The id of the organization group + ID OrganizationOrganizationGroupIdInputFilter `json:"id,omitempty"` + // The name of the organization group + Name OrganizationOrganizationGroupNameInputFilter `json:"name,omitempty"` + // The ID of the organization + OrganizationId OrganizationOrganizationGroupOrganizationIdInputFilter `json:"organizationId,omitempty"` +} + +// OrganizationOrganizationGroupIdInputFilter - Provides all the available filters on the organization group id +type OrganizationOrganizationGroupIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationOrganizationGroupNameInputFilter - Provides all the available filters on the organization group name +type OrganizationOrganizationGroupNameInputFilter struct { + // performs a contains operation + Contains string `json:"contains,omitempty"` + // performs an equals operation + Eq string `json:"eq,omitempty"` +} + +// OrganizationOrganizationGroupOrganizationIdInputFilter - Provides all the available filters on the organization group organization id +type OrganizationOrganizationGroupOrganizationIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationOrganizationGroupWrapper - A customers organization groups +type OrganizationOrganizationGroupWrapper struct { + // A customers organization groups + Items []OrganizationOrganizationGroup `json:"items"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` +} + +// OrganizationOrganizationIdInput - Provides the operations available on the organization id +type OrganizationOrganizationIdInput struct { + // An organization id + Eq string `json:"eq"` +} + +// OrganizationOrganizationIdInputFilter - Provides all the available filters on the organization id +type OrganizationOrganizationIdInputFilter struct { + // performs an equals operation + Eq string `json:"eq"` +} + +// OrganizationOrganizationNameInputFilter - Provides all the available filters on the organization name +type OrganizationOrganizationNameInputFilter struct { + // performs a contains operation + Contains string `json:"contains,omitempty"` + // performs an equals operation + Eq string `json:"eq,omitempty"` +} + +// OrganizationSharedAccount - The attributes of an account share. +type OrganizationSharedAccount struct { + // The ID of the account being shared. + AccountID int `json:"accountId"` + // The ID of the account share. + ID string `json:"id"` + // The ID of the limiting role for the account share. + LimitingRoleId int `json:"limitingRoleId"` + // The name of the account share. + Name string `json:"name,omitempty"` + // The ID of the organization sending the account share. + SourceOrganizationId string `json:"sourceOrganizationId"` + // The name of the organization sending the account share. + SourceOrganizationName string `json:"sourceOrganizationName,omitempty"` + // The ID of the organization receiving the account share. + TargetOrganizationId string `json:"targetOrganizationId"` + // The name of the organization receiving the account share. + TargetOrganizationName string `json:"targetOrganizationName,omitempty"` +} + +// OrganizationTargetIdInput - Provides the operations available on the target id +type OrganizationTargetIdInput struct { + // An organization id + Eq string `json:"eq"` +} + +// TimeWindowInput - Represents a time window input. +type TimeWindowInput struct { + // The end time of the time window the number of milliseconds since the Unix epoch. + EndTime EpochMilliseconds `json:"endTime"` + // The start time of the time window the number of milliseconds since the Unix epoch. + StartTime EpochMilliseconds `json:"startTime"` +} + +// User - The `User` object provides general data about the user. +type User struct { + Email string `json:"email,omitempty"` + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +// UserManagementAuthenticationDomain - An "authentication domain" is a grouping of New Relic users governed by the same user management settings, like how they're provisioned (added and updated), how they're authenticated (logged in), session settings, and how user upgrades are managed. +type UserManagementAuthenticationDomain struct { + // container for groups enabling cursor based pagination + Groups UserManagementGroups `json:"groups,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // the name of the object + Name string `json:"name"` + // the method used to provision users in this authentication domain + ProvisioningType string `json:"provisioningType"` + // container for users enabling cursor based pagination + Users UserManagementUsers `json:"users,omitempty"` +} + +// UserManagementAuthenticationDomains - container for authentication domains enabling cursor based pagination +type UserManagementAuthenticationDomains struct { + // container for authentication_domains enabling cursor based pagination + AuthenticationDomains []UserManagementAuthenticationDomain `json:"authenticationDomains"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// UserManagementDisplayNameInput - Available filtering types for group display names +type UserManagementDisplayNameInput struct { + // Part of a display name + Contains string `json:"contains,omitempty"` + // A display name + Eq string `json:"eq,omitempty"` +} + +// UserManagementEmailInput - Available filtering types for email addresses +type UserManagementEmailInput struct { + // Part of a user email + Contains string `json:"contains,omitempty"` + // A user email + Eq string `json:"eq,omitempty"` +} + +// UserManagementEmailVerificationStateInput - Available filtering types for email verification states +type UserManagementEmailVerificationStateInput struct { + // An email verification state + Pending bool `json:"pending"` +} + +// UserManagementGroup - For users on our New Relic One user model, a "group" represents a group of users. Putting users in a group allows the managing of permissions for multiple users at the same time. +type UserManagementGroup struct { + // the name of the object + DisplayName string `json:"displayName"` + // a value that uniquely identifies this object + ID string `json:"id"` + // container for users enabling cursor based pagination + Users UserManagementGroupUsers `json:"users,omitempty"` +} + +// UserManagementGroupFilterInput - The input object representing the filter parameters for groups +type UserManagementGroupFilterInput struct { + // Filter groups by display name + DisplayName UserManagementDisplayNameInput `json:"displayName,omitempty"` + // Filter groups by group ID + ID UserManagementGroupIdInput `json:"id,omitempty"` +} + +// UserManagementGroupIdInput - Available filtering types for group IDs +type UserManagementGroupIdInput struct { + // A group ID + Eq string `json:"eq,omitempty"` + // An array of group IDs + In []string `json:"in"` +} + +// UserManagementGroupSortInput - The input object representing the sort parameters for groups +type UserManagementGroupSortInput struct { + // Sort groups in this direction + Direction UserManagementSortDirection `json:"direction,omitempty"` + // Sort groups by this key + Key UserManagementGroupSortKey `json:"key,omitempty"` +} + +// UserManagementGroupUser - User information returned within Groups +type UserManagementGroupUser struct { + // The email of the user. + Email string `json:"email"` + // a value that uniquely identifies this object + ID string `json:"id"` + // The full name of the user. + Name string `json:"name"` + // The configured time zone of the user. + TimeZone string `json:"timeZone"` +} + +// UserManagementGroupUsers - container for users enabling cursor based pagination +type UserManagementGroupUsers struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` + // container for users enabling cursor based pagination + Users []UserManagementGroupUser `json:"users"` +} + +// UserManagementGroups - container for groups enabling cursor based pagination +type UserManagementGroups struct { + // container for groups enabling cursor based pagination + Groups []UserManagementGroup `json:"groups"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// UserManagementNameInput - Available filtering types for names +type UserManagementNameInput struct { + // Part of a user name + Contains string `json:"contains,omitempty"` + // A user name + Eq string `json:"eq,omitempty"` +} + +// UserManagementPendingUpgradeRequest - Exists only if a user has a pending upgrade request. +type UserManagementPendingUpgradeRequest struct { + // a value that uniquely identifies this object + ID string `json:"id"` + // Requester message, why the user believes they require the upgrade. + Message string `json:"message,omitempty"` + // Requested user type for the user. + RequestedUserType UserManagementUserType `json:"requestedUserType,omitempty"` +} + +// UserManagementPendingUpgradeRequestInput - Available filtering types for pending upgrade requests +type UserManagementPendingUpgradeRequestInput struct { + // Whether a request exists or not + Exists bool `json:"exists"` +} + +// UserManagementTypeInput - Available filtering types for user type +type UserManagementTypeInput struct { + // A user type + Eq UserManagementTypeEnum `json:"eq"` +} + +// UserManagementUser - A user of New Relic scoped to an authentication domain. +type UserManagementUser struct { + // Email address of the user. + Email string `json:"email,omitempty"` + // One of: "Not Verifiable", "Verified", and "Pending". + // + // Not Verifiable: the user's email does not require verification. + // + // Verified: the user's email requires verification and has been. + // + // Pending: the user's email requires verification and has not been. + EmailVerificationState string `json:"emailVerificationState"` + // container for groups enabling cursor based pagination + Groups UserManagementUserGroups `json:"groups,omitempty"` + // a value that uniquely identifies this object + ID string `json:"id"` + // The last active date of the user. + LastActive nrtime.DateTime `json:"lastActive,omitempty"` + // The full name of the user. + Name string `json:"name,omitempty"` + // The pending upgrade request for the user (if any). + PendingUpgradeRequest UserManagementPendingUpgradeRequest `json:"pendingUpgradeRequest,omitempty"` + // Time zone of the user in IANA Time Zone database format, also known as the "Olson" time zone database format (for exmaple, "America/Los_Angeles"). + TimeZone string `json:"timeZone,omitempty"` + // A "user type" is what determines the set of New Relic capabilities a user can theoretically access. + Type UserManagementUserType `json:"type"` +} + +// UserManagementUserFilterInput - The input object representing the filter parameters for users +type UserManagementUserFilterInput struct { + // Filter users by email address + Email UserManagementEmailInput `json:"email,omitempty"` + // Filter users by email verification state + EmailVerificationState UserManagementEmailVerificationStateInput `json:"emailVerificationState,omitempty"` + // Filter users by user ID + ID UserManagementUserIdInput `json:"id,omitempty"` + // Filter users by name + Name UserManagementNameInput `json:"name,omitempty"` + // Filter users by pending upgrade request + PendingUpgradeRequest UserManagementPendingUpgradeRequestInput `json:"pendingUpgradeRequest,omitempty"` + // Filter users by type + Type UserManagementTypeInput `json:"type,omitempty"` +} + +// UserManagementUserGroup - For users on our New Relic One user model, a "group" represents a group of users. Putting users in a group allows the managing of permissions for multiple users at the same time. +type UserManagementUserGroup struct { + // the name of the object + DisplayName string `json:"displayName"` + // a value that uniquely identifies this object + ID string `json:"id"` +} + +// UserManagementUserGroups - container for groups enabling cursor based pagination +type UserManagementUserGroups struct { + // container for groups enabling cursor based pagination + Groups []UserManagementUserGroup `json:"groups"` + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` +} + +// UserManagementUserIdInput - Available filtering types for user IDs +type UserManagementUserIdInput struct { + // A user ID + Eq string `json:"eq,omitempty"` + // An array of user IDs + In []string `json:"in"` +} + +// UserManagementUserType - A "user type" is what determines the set of New Relic capabilities a user can theoretically access. +type UserManagementUserType struct { + // the name of the object + DisplayName string `json:"displayName"` + // a value that uniquely identifies this object + ID string `json:"id"` +} + +// UserManagementUsers - container for users enabling cursor based pagination +type UserManagementUsers struct { + // an opaque cursor to supply with subsequent requests to get the next page of results, null if there are no more pages + NextCursor string `json:"nextCursor,omitempty"` + // the total number of results + TotalCount int `json:"totalCount"` + // container for users enabling cursor based pagination + Users []UserManagementUser `json:"users"` +} + +// UserReference - The `UserReference` object provides basic identifying information about the user. +type UserReference struct { + Email string `json:"email,omitempty"` + Gravatar string `json:"gravatar,omitempty"` + ID int `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +type UsersActorStitchedFields struct { + // Search for users using a custom query. + // If no query is provided, returns all visible users. + // NOTE: this API only supports users in the New Relic One user model. + UserSearch UsersUserSearchResult `json:"userSearch,omitempty"` +} + +// UsersUserSearch - User information returned for UserSearch +type UsersUserSearch struct { + // The email of the user. + Email string `json:"email,omitempty"` + // The full name of the user. + Name string `json:"name,omitempty"` + // The unique identifier of the user. + UserID string `json:"userId,omitempty"` +} + +// UsersUserSearchQuery - Query object for UserSearch. +type UsersUserSearchQuery struct { + // The scope to filter the search response by. + Scope UsersUserSearchScope `json:"scope,omitempty"` +} + +// UsersUserSearchResult - The result object for UserSearch. +type UsersUserSearchResult struct { + // The cursor for the next page. + NextCursor string `json:"nextCursor,omitempty"` + // The total number of users found. + // Note: Not necessarily the same as number of users returned, due to pagination. + TotalCount int `json:"totalCount"` + // Set of all users returned from the query. + Users []UsersUserSearch `json:"users"` +} + +// UsersUserSearchScope - Different scopes that can be used to filter the returned users. +type UsersUserSearchScope struct { + // Filter by string that will partially match a User's `email`. Same as `name` it will partially match and case is ignored. + Email string `json:"email,omitempty"` + // Filter by string that will partially match a User's `name`. So argument `name='Ste'` will match `name='Steve'` and case is ignored so `name='Koester'` would also match. + Name string `json:"name,omitempty"` + // Will match both a User's `email` and `name`. So argument `search='ple'` will match `name='Johnny Appleseed'` and `email='mary@example.com'`. + Search string `json:"search,omitempty"` + // List of 1 or more userIds to filter by. Will only return data for users with ids that match the full ID, no partial matching. (so 2 ids provided will yield at most 2 users) + UserIDs []string `json:"userIds"` +} + +type accountSharesResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type accountsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type authenticationDomainsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type consumptionResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type contractsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type grantsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type groupsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type jobsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type organizationCreateAsyncResultsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type organizationsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type permissionsResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type rolesResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type userResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +type usersResponse struct { + CustomerAdministration CustomerAdministration `json:"customerAdministration"` +} + +// EpochMilliseconds - The `EpochMilliseconds` scalar represents the number of milliseconds since the Unix epoch +type EpochMilliseconds string diff --git a/pkg/organization/organization.go b/pkg/organization/organization.go new file mode 100644 index 00000000..944cf809 --- /dev/null +++ b/pkg/organization/organization.go @@ -0,0 +1,24 @@ +package organization + +import ( + "github.com/newrelic/newrelic-client-go/v2/internal/http" + "github.com/newrelic/newrelic-client-go/v2/pkg/config" + "github.com/newrelic/newrelic-client-go/v2/pkg/logging" +) + +type Organization struct { + client http.Client + logger logging.Logger + config config.Config +} + +func New(config config.Config) Organization { + client := http.NewClient(config) + + pkg := Organization{ + client: client, + logger: config.GetLogger(), + config: config, + } + return pkg +} diff --git a/pkg/organization/organization_api.go b/pkg/organization/organization_api.go new file mode 100644 index 00000000..b756f8d5 --- /dev/null +++ b/pkg/organization/organization_api.go @@ -0,0 +1,123 @@ +// Code generated by tutone: DO NOT EDIT +package organization + +import "context" + +// The new organization to create. +func (a *Organization) OrganizationCreate( + customerId string, + newManagedAccount *OrganizationNewManagedAccountInput, + organization OrganizationCreateOrganizationInput, + sharedAccount *OrganizationSharedAccountInput, +) (*OrganizationCreateOrganizationResponse, error) { + return a.OrganizationCreateWithContext(context.Background(), + customerId, + newManagedAccount, + organization, + sharedAccount, + ) +} + +// The new organization to create. +func (a *Organization) OrganizationCreateWithContext( + ctx context.Context, + customerId string, + newManagedAccount *OrganizationNewManagedAccountInput, + organization OrganizationCreateOrganizationInput, + sharedAccount *OrganizationSharedAccountInput, +) (*OrganizationCreateOrganizationResponse, error) { + + resp := OrganizationCreateQueryResponse{} + vars := map[string]interface{}{ + "newManagedAccount": newManagedAccount, + "organization": organization, + "sharedAccount": sharedAccount, + } + + // Manual change made out of Tutone's scope, to accommodate for having no customerId in the request + // PLEASE DO NOT DELETE the following if-block + if customerId != "" { + vars["customerId"] = customerId + } + + if err := a.client.NerdGraphQueryWithContext(ctx, OrganizationCreateMutation, vars, &resp); err != nil { + return nil, err + } + + return &resp.OrganizationCreateOrganizationResponse, nil +} + +type OrganizationCreateQueryResponse struct { + OrganizationCreateOrganizationResponse OrganizationCreateOrganizationResponse `json:"OrganizationCreate"` +} + +const OrganizationCreateMutation = `mutation( + $customerId: ID, + $newManagedAccount: OrganizationNewManagedAccountInput, + $organization: OrganizationCreateOrganizationInput!, + $sharedAccount: OrganizationSharedAccountInput, +) { organizationCreate( + customerId: $customerId, + newManagedAccount: $newManagedAccount, + organization: $organization, + sharedAccount: $sharedAccount, +) { + jobId +} }` + +// The organization to update +func (a *Organization) OrganizationUpdate( + organization OrganizationUpdateInput, + organizationId string, +) (*OrganizationUpdateResponse, error) { + return a.OrganizationUpdateWithContext(context.Background(), + organization, + organizationId, + ) +} + +// The organization to update +func (a *Organization) OrganizationUpdateWithContext( + ctx context.Context, + organization OrganizationUpdateInput, + organizationId string, +) (*OrganizationUpdateResponse, error) { + + resp := OrganizationUpdateQueryResponse{} + vars := map[string]interface{}{ + "organization": organization, + } + + // Manual change made out of Tutone's scope, to accommodate for having no organizationId in the request + // PLEASE DO NOT DELETE the following if-block + if organizationId != "" { + vars["organizationId"] = organizationId + } + + if err := a.client.NerdGraphQueryWithContext(ctx, OrganizationUpdateMutation, vars, &resp); err != nil { + return nil, err + } + + return &resp.OrganizationUpdateResponse, nil +} + +type OrganizationUpdateQueryResponse struct { + OrganizationUpdateResponse OrganizationUpdateResponse `json:"OrganizationUpdate"` +} + +const OrganizationUpdateMutation = `mutation( + $organization: OrganizationUpdateInput!, + $organizationId: ID, +) { organizationUpdate( + organization: $organization, + organizationId: $organizationId, +) { + errors { + message + type + } + organizationInformation { + id + name + } +} }` diff --git a/pkg/organization/organization_integration_test.go b/pkg/organization/organization_integration_test.go new file mode 100644 index 00000000..451d5687 --- /dev/null +++ b/pkg/organization/organization_integration_test.go @@ -0,0 +1,123 @@ +package organization + +import ( + "fmt" + "regexp" + "testing" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" + "github.com/stretchr/testify/require" +) + +func TestIntegrationOrganizationCreate_CustomerIdNotFoundError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + + _, err = client.OrganizationCreate( + unitTestMockCustomerId, + &OrganizationNewManagedAccountInput{ + Name: "Some Random Managed Account", + RegionCode: OrganizationRegionCodeEnumTypes.US01, + }, + OrganizationCreateOrganizationInput{ + Name: "Some Random Organization", + }, + &OrganizationSharedAccountInput{ + AccountID: 0000, + LimitingRoleId: 0000, + }, + ) + + require.Error(t, err) + require.Regexp(t, regexp.MustCompile(fmt.Sprintf("%s not found.", unitTestMockCustomerId)), err.Error()) +} + +func TestIntegrationOrganizationCreate_AccessDeniedError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + + organizationCreateResponse, err := client.OrganizationCreate( + "", + &OrganizationNewManagedAccountInput{ + Name: "Some Random Managed Account", + RegionCode: OrganizationRegionCodeEnumTypes.US01, + }, + OrganizationCreateOrganizationInput{ + Name: "Some Random Organization", + }, + &OrganizationSharedAccountInput{ + AccountID: 0000, + LimitingRoleId: 0000, + }, + ) + + // expected behaviour + // require.Error(t, err) + // require.Regexp(t, regexp.MustCompile(fmt.Sprintf("%s not found.", unitTestMockCustomerId)), err.Error()) + + // current behaviour + // the API isn't throwing an error, the error is instead, embedded in the response + + require.NoError(t, err) + require.True(t, matchOrganizationUnauthorizedErrorRegex(organizationCreateResponse.JobId)) +} + +func TestIntegrationOrganizationUpdate(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + if organizationId == "" { + t.Errorf("cannot run integration test as the environment variable INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID is missing, or has an empty value") + } + + client := newIntegrationTestClient(t) + + organizationUpdateResponse, _ := client.OrganizationUpdate( + OrganizationUpdateInput{ + Name: organizationNameUpdated, + }, + organizationId, + ) + + require.NotNil(t, organizationUpdateResponse.OrganizationInformation) + require.Equal(t, organizationUpdateResponse.OrganizationInformation.Name, organizationNameUpdated) +} + +func TestIntegrationOrganizationUpdate_AccessDeniedError(t *testing.T) { + t.Parallel() + _, err := mock.GetTestAccountID() + if err != nil { + t.Skipf("%s", err) + } + + client := newIntegrationTestClient(t) + + organizationUpdateResponse, _ := client.OrganizationUpdate( + OrganizationUpdateInput{ + Name: organizationNameUpdated, + }, + unitTestMockOrganizationOneId, + ) + + // expected behaviour + // require.Error(t, err) + + // actual behaviour + // the error thrown is embedded as a field inside the response of the mutation + + require.NotNil(t, organizationUpdateResponse.Errors) + require.True(t, matchOrganizationUnauthorizedErrorRegex(organizationUpdateResponse.Errors[0].Message)) +} diff --git a/pkg/organization/organization_test.go b/pkg/organization/organization_test.go new file mode 100644 index 00000000..b8d5e115 --- /dev/null +++ b/pkg/organization/organization_test.go @@ -0,0 +1,36 @@ +package organization + +import ( + "os" + "regexp" + "testing" + + mock "github.com/newrelic/newrelic-client-go/v2/pkg/testhelpers" +) + +func newIntegrationTestClient(t *testing.T) Organization { + tc := mock.NewIntegrationTestConfig(t) + return New(tc) +} + +func newMockResponse(t *testing.T, mockJSONResponse string, statusCode int) Organization { + ts := mock.NewMockServer(t, mockJSONResponse, statusCode) + tc := mock.NewTestConfig(t, ts) + + return New(tc) +} + +var ( + unitTestMockOrganizationCreateJobId = "bec1a268-53b8-4dc5-8522-37e648fc9d38" + unitTestMockCustomerId = "CC-0000000000" + unitTestMockOrganizationOneName = "Mock Organization One" + unitTestMockOrganizationOneId = "e1fe1ff8-0032-43d5-935f-caf47567a71d" + + organizationNameUpdated = "Virtuoso / OaC Organization" + organizationId = os.Getenv("INTEGRATION_TESTING_NEW_RELIC_ORGANIZATION_ID") +) + +func matchOrganizationUnauthorizedErrorRegex(errorMessage string) bool { + errorFound, _ := regexp.MatchString("You are not authorized to perform this action", errorMessage) + return errorFound +} diff --git a/pkg/organization/organization_unit_test.go b/pkg/organization/organization_unit_test.go new file mode 100644 index 00000000..61ce8a2a --- /dev/null +++ b/pkg/organization/organization_unit_test.go @@ -0,0 +1,78 @@ +package organization + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + testCreateOrganizationResponseJSON = `{ + "data": { + "organizationCreate": { + "jobId": "` + unitTestMockOrganizationCreateJobId + `" + } + } + }` + + testUpdateOrganizationResponseJSON = `{ + "data": { + "organizationUpdate": { + "organizationInformation": { + "id": "` + unitTestMockOrganizationOneId + `", + "name": "` + unitTestMockOrganizationOneName + `" + } + } + } + }` +) + +func TestUnitCreateOrganization(t *testing.T) { + t.Parallel() + + organization := newMockResponse(t, testCreateOrganizationResponseJSON, http.StatusCreated) + + expected := &OrganizationCreateOrganizationResponse{ + JobId: unitTestMockOrganizationCreateJobId, + } + + actual, err := organization.OrganizationCreate( + unitTestMockCustomerId, + &OrganizationNewManagedAccountInput{ + Name: "Test Account", + }, + OrganizationCreateOrganizationInput{ + Name: unitTestMockOrganizationOneName, + }, + &OrganizationSharedAccountInput{}, + ) + + assert.NoError(t, err) + assert.NotNil(t, actual) + assert.Equal(t, expected, actual) +} + +func TestUnitUpdateOrganization(t *testing.T) { + t.Parallel() + + organization := newMockResponse(t, testUpdateOrganizationResponseJSON, http.StatusCreated) + + expected := &OrganizationUpdateResponse{ + OrganizationInformation: OrganizationInformation{ + ID: unitTestMockOrganizationOneId, + Name: unitTestMockOrganizationOneName, + }, + } + + actual, err := organization.OrganizationUpdate( + OrganizationUpdateInput{ + Name: unitTestMockOrganizationOneName, + }, + unitTestMockOrganizationOneId, + ) + + assert.NoError(t, err) + assert.NotNil(t, actual) + assert.Equal(t, expected, actual) +} diff --git a/pkg/organization/types.go b/pkg/organization/types.go new file mode 100644 index 00000000..4231d318 --- /dev/null +++ b/pkg/organization/types.go @@ -0,0 +1,142 @@ +// Code generated by tutone: DO NOT EDIT +package organization + +// OrganizationRegionCodeEnum - Enums for region codes +type OrganizationRegionCodeEnum string + +var OrganizationRegionCodeEnumTypes = struct { + // Region code for EU + EU01 OrganizationRegionCodeEnum + // Region code for US + US01 OrganizationRegionCodeEnum +}{ + // Region code for EU + EU01: "EU01", + // Region code for US + US01: "US01", +} + +// OrganizationUpdateErrorType - An enum specifying the specific types of errors that may be returned. +type OrganizationUpdateErrorType string + +var OrganizationUpdateErrorTypeTypes = struct { + // Returned when the attributes provided for an object are invalid. + INVALID_RECORD OrganizationUpdateErrorType + // Returned when the actor has insufficient capabilties to fulfill the request. + NOT_AUTHORIZED OrganizationUpdateErrorType +}{ + // Returned when the attributes provided for an object are invalid. + INVALID_RECORD: "INVALID_RECORD", + // Returned when the actor has insufficient capabilties to fulfill the request. + NOT_AUTHORIZED: "NOT_AUTHORIZED", +} + +// OrganizationCreateOrganizationInput - Attributes belonging to the organization to create. +type OrganizationCreateOrganizationInput struct { + // The name for the new organization. + Name string `json:"name"` +} + +// OrganizationCreateOrganizationResponse - The object that's returned from successfully creating an organization. +type OrganizationCreateOrganizationResponse struct { + // The job id of the organization creation task; query this job id to get latest state + JobId string `json:"jobId"` +} + +// OrganizationCreateSharedAccountInput - Attributes for creating a shared account. +type OrganizationCreateSharedAccountInput struct { + // The id of the account to be shared + AccountID int `json:"accountId"` + // The id of the limiting role + LimitingRoleId int `json:"limitingRoleId"` + // The name of the shared account + Name string `json:"name,omitempty"` + // The id of the target organization + TargetOrganizationId string `json:"targetOrganizationId"` +} + +// OrganizationCreateSharedAccountResponse - The object that's returned from successfully creating a shared account. +type OrganizationCreateSharedAccountResponse struct { + // The created shared account. + SharedAccount OrganizationSharedAccount `json:"sharedAccount,omitempty"` +} + +// OrganizationError - A user-readable error +type OrganizationError struct { + // A description of the error. + Message string `json:"message"` + // A description of the type of error. + Type OrganizationUpdateErrorType `json:"type"` +} + +// OrganizationInformation - The attributes of an organization. +type OrganizationInformation struct { + // The ID of the organization. + ID string `json:"id"` + // The name of the organization. + Name string `json:"name"` +} + +// OrganizationNewManagedAccountInput - Attributes for creating a new managed account. +type OrganizationNewManagedAccountInput struct { + // The name of the new account to be created. + Name string `json:"name,omitempty"` + // The region-code for the account to be created. + RegionCode OrganizationRegionCodeEnum `json:"regionCode,omitempty"` +} + +// OrganizationSharedAccount - The attributes of an account share. +type OrganizationSharedAccount struct { + // The ID of the account being shared. + AccountID int `json:"accountId"` + // The ID of the account share. + ID string `json:"id"` + // The ID of the limiting role for the account share. + LimitingRoleId int `json:"limitingRoleId"` + // The name of the account share. + Name string `json:"name,omitempty"` + // The ID of the organization sending the account share. + SourceOrganizationId string `json:"sourceOrganizationId"` + // The name of the organization sending the account share. + SourceOrganizationName string `json:"sourceOrganizationName,omitempty"` + // The ID of the organization receiving the account share. + TargetOrganizationId string `json:"targetOrganizationId"` + // The name of the organization receiving the account share. + TargetOrganizationName string `json:"targetOrganizationName,omitempty"` +} + +// OrganizationSharedAccountInput - Attributes for creating an account share. +type OrganizationSharedAccountInput struct { + // The id of the account to share with new organization + AccountID int `json:"accountId"` + // The limiting role id the new organization will be granted on for the shared account + LimitingRoleId int `json:"limitingRoleId,omitempty"` +} + +// OrganizationUpdateInput - Attributes for updating an organization. +type OrganizationUpdateInput struct { + // The new name for the organization. + Name string `json:"name,omitempty"` +} + +// OrganizationUpdateResponse - The return object for an update mutation. +type OrganizationUpdateResponse struct { + // A description of any errors with the mutation. + Errors []OrganizationError `json:"errors"` + // Information about the updated organization. + OrganizationInformation OrganizationInformation `json:"organizationInformation,omitempty"` +} + +// OrganizationUpdateSharedAccountInput - Attributes for updating an account share. +type OrganizationUpdateSharedAccountInput struct { + // The id of the account share to be updated + ID string `json:"id"` + // The id of the limiting role to be updated + LimitingRoleId int `json:"limitingRoleId"` +} + +// OrganizationUpdateSharedAccountResponse - The object that's returned from successfully updating a shared account. +type OrganizationUpdateSharedAccountResponse struct { + // Information about the updated shared account. + SharedAccount OrganizationSharedAccount `json:"sharedAccount,omitempty"` +} diff --git a/pkg/usermanagement/groups_integration_test.go b/pkg/usermanagement/groups_integration_test.go index e729b62b..0f95dfc0 100644 --- a/pkg/usermanagement/groups_integration_test.go +++ b/pkg/usermanagement/groups_integration_test.go @@ -31,6 +31,12 @@ func TestIntegrationCreateGroup(t *testing.T) { require.NoError(t, err) require.NotNil(t, createGroupResponse.Group.ID) + + deleteGroupInput := UserManagementDeleteGroup{ID: createGroupResponse.Group.ID} + deleteGroupResponse, err := client.UserManagementDeleteGroup(deleteGroupInput) + + require.NoError(t, err) + require.NotNil(t, deleteGroupResponse) } func TestIntegrationCreateGroupError(t *testing.T) {