From 0fd0ff1fbfab3752edd2694820cb3bbd864e096e Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Mon, 18 Nov 2024 15:46:32 +0100 Subject: [PATCH 1/7] feat(translations): Add File provider implementation --- .../src/providers/base.provider.ts | 11 +++-------- .../src/providers/file.provider.ts | 18 ++++++++++++++++++ packages/translations/src/providers/index.ts | 4 ++++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 packages/translations/src/providers/file.provider.ts diff --git a/packages/translations/src/providers/base.provider.ts b/packages/translations/src/providers/base.provider.ts index 31306822..2a0130e2 100644 --- a/packages/translations/src/providers/base.provider.ts +++ b/packages/translations/src/providers/base.provider.ts @@ -125,14 +125,9 @@ export default abstract class BaseProvider { await translator.translateAll(this) } - public abstract getTranslations( - language: string - ): Promise<{ [key: string]: string }> - - public abstract uploadTranslations( - language: string, - translations: { [key: string]: string } - ): Promise + public abstract getTranslations(language: string): Promise<{ [key: string]: string }> + + public abstract uploadTranslations(language: string, translations: { [key: string]: string }): Promise public getSourceTerms() { if (!existsSync(this.sourceFile)) { diff --git a/packages/translations/src/providers/file.provider.ts b/packages/translations/src/providers/file.provider.ts new file mode 100644 index 00000000..f3c5bbf1 --- /dev/null +++ b/packages/translations/src/providers/file.provider.ts @@ -0,0 +1,18 @@ +import { BaseConfigFile } from '../utils/config-file' +import BaseProvider from './base.provider' + +export default class File extends BaseProvider { + + public async getTranslations(language: string): Promise<{ [key: string]: string }> { + return {} + } + + public async uploadTranslations(language: string, translations: { [key: string]: string }): Promise { + return true + } + + protected assureRequirementsExists(): Promise { + return Promise.resolve(undefined) + } + +} diff --git a/packages/translations/src/providers/index.ts b/packages/translations/src/providers/index.ts index 1a5df8a1..e5850960 100644 --- a/packages/translations/src/providers/index.ts +++ b/packages/translations/src/providers/index.ts @@ -3,6 +3,7 @@ import { ExecutorContext, logger } from '@nx/devkit' import type { BaseConfigFile } from '../utils/config-file' import BaseProvider from './base.provider' +import File from './file.provider' import PoeditorProvider, { PoeditorConfig } from './poeditor.provider' import SimpleLocalize, { SimpleLocalizeConfig } from './simplelocalize.provider' import TraduoraProvider, { TraduoraConfig } from './traduora.provider' @@ -26,6 +27,9 @@ export const getProvider = async ( case 'simplelocalize': return new SimpleLocalize(context, configFile as SimpleLocalizeConfig) + case 'file': + return new File(context, configFile as SimpleLocalizeConfig) + default: logger.warn(`"${provider}" is not an valid provider!`) From f5be3abf2df54c1b7ded52af8c56e2b6a4fdff4a Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Mon, 18 Nov 2024 15:46:43 +0100 Subject: [PATCH 2/7] fix(translations): Handle error status codes and improve language splitting --- .../src/executors/translate/translate.impl.ts | 2 +- .../src/translators/deepl.translator.ts | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/packages/translations/src/executors/translate/translate.impl.ts b/packages/translations/src/executors/translate/translate.impl.ts index 8b5798bc..e452292a 100644 --- a/packages/translations/src/executors/translate/translate.impl.ts +++ b/packages/translations/src/executors/translate/translate.impl.ts @@ -32,7 +32,7 @@ export async function translateExtractor( success: true } } catch (err) { - logger.error('Error pushing source file') + logger.error('Error translating files') logger.error(err.message || err) } diff --git a/packages/translations/src/translators/deepl.translator.ts b/packages/translations/src/translators/deepl.translator.ts index 844e2257..659ef44c 100644 --- a/packages/translations/src/translators/deepl.translator.ts +++ b/packages/translations/src/translators/deepl.translator.ts @@ -153,34 +153,42 @@ export default class DeeplTranslator { .replace(/}/g, '') .replace(/''/g, '')}`, - `target_lang=${toLocale.split('_').shift()}`, - `source_lang=${this.config.defaultLanguage}`, + `target_lang=${toLocale.split('_').shift().split('-').shift()}`, + `source_lang=${this.config.defaultLanguage.split('_').shift().split('-').shift()}`, 'preserve_formatting=1', 'tag_handling=xml', 'ignore_tags=deepSkip', this.config?.translatorOptions?.formality && - this.formalitySupportedLangs.includes(toLocale) && - `formality=${this.config.translatorOptions.formality}` + this.formalitySupportedLangs.includes(toLocale) && + `formality=${this.config.translatorOptions.formality}` ].filter(Boolean) - const { - status, - data: { translations } - } = await axios.get(url.join('&')) + const { status, data } = await axios.get(url.join('&'),{ + validateStatus: () => true + }) if (status === 429) { logger.warn('To many requests, wait and retry') + } else if (status === 456) { throw new Error('Rate limit!') + + } else if (status === 400) { + translatedMessages.push({ + key: message.key, + value: 'Error translating!' + }) + + continue } translatedMessages.push({ key: message.key, - value: translations[0].text + value: data.translations[0].text .replace(//g, '{') .replace(/<\/deepSkip>/g, '}') - .replace(//g, "''") + .replace(//g, '\'\'') }) } From d69630d034ff311a65eefe1b4f151bfd7c01e52e Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Mon, 18 Nov 2024 15:56:19 +0100 Subject: [PATCH 3/7] refactor(translations): Add JSON file reading to File provider --- .../translations/src/providers/file.provider.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/translations/src/providers/file.provider.ts b/packages/translations/src/providers/file.provider.ts index f3c5bbf1..44fb00fe 100644 --- a/packages/translations/src/providers/file.provider.ts +++ b/packages/translations/src/providers/file.provider.ts @@ -1,10 +1,25 @@ +import { readJsonFile } from '@nx/devkit' +import { existsSync } from 'fs' +import { join } from 'path' + +import { injectProjectRoot } from '../utils' import { BaseConfigFile } from '../utils/config-file' import BaseProvider from './base.provider' export default class File extends BaseProvider { public async getTranslations(language: string): Promise<{ [key: string]: string }> { - return {} + const fileLocation = injectProjectRoot( + join(this.config.outputDirectory, `${language}.json`), + this.config.projectRoot, + this.context.root + ) + + if (!existsSync(fileLocation)) { + return {} + } + + return readJsonFile(fileLocation) } public async uploadTranslations(language: string, translations: { [key: string]: string }): Promise { From 56a7d21688cc4b2fa8456e5aef6cca8e601381cd Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Sat, 23 Nov 2024 15:30:03 +0100 Subject: [PATCH 4/7] feat(pulumi): Added all of IAM roles for GCP services BREAKING CHANGE: Some names changed as this was automatically generated --- packages/pulumi/gcp/iam-roles.ts | 2584 +++++++++++++++++++++++++++--- 1 file changed, 2389 insertions(+), 195 deletions(-) diff --git a/packages/pulumi/gcp/iam-roles.ts b/packages/pulumi/gcp/iam-roles.ts index 89a86d2f..228710a7 100644 --- a/packages/pulumi/gcp/iam-roles.ts +++ b/packages/pulumi/gcp/iam-roles.ts @@ -1,197 +1,2391 @@ export const iamRoles = { - cloudSql: { - // Connects to CloudSQL databases - client: 'roles/cloudsql.client', - // Administers CloudSQL instances - admin: 'roles/cloudsql.admin', - // Provides read-only access to CloudSQL instances - viewer: 'roles/cloudsql.viewer', - // Creates and manages CloudSQL instances - creator: 'roles/cloudsql.instanceUser', - // Full access to CloudSQL backups - backupAdmin: 'roles/cloudsql.backupAdmin' - }, - pubSub: { - // Publishes messages to PubSub - publisher: 'roles/pubsub.publisher', - // Administers PubSub resources - admin: 'roles/pubsub.admin', - // Editor PubSub resource - editor: 'roles/pubsub.editor', - // Consumes PubSub messages - subscriber: 'roles/pubsub.subscriber', - // Provides read-only access to PubSub topics and subscriptions - viewer: 'roles/pubsub.viewer', - // Creates and manages PubSub topics - topicAdmin: 'roles/pubsub.topicAdmin' - }, - storage: { - // Administers Storage resources - admin: 'roles/storage.admin', - // Provides read/write access to Storage objects - objectAdmin: 'roles/storage.objectAdmin', - // Provides read-only access to Storage objects and list them - objectViewer: 'roles/storage.objectViewer', - objectCreator: 'roles/storage.objectCreator', - // Provides read/write access to Storage buckets - bucketAdmin: 'roles/storage.bucketAdmin', - // Provides specific permissions to Storage bucket metadata - bucketMetadataAdmin: 'roles/storage.bucketMetadataAdmin', - // Provides legacy role for read-only access to Storage objects - legacyObjectReader: 'roles/storage.legacyObjectReader', - // Provides legacy role for managing objects - legacyObjectOwner: 'roles/storage.legacyObjectOwner', - // Provides legacy role for reading Storage buckets - legacyBucketReader: 'roles/storage.legacyBucketReader', - // Provides legacy role for writing Storage buckets - legacyBucketWriter: 'roles/storage.legacyBucketWriter' - }, - bigQuery: { - // Administers BigQuery resources - admin: 'roles/bigquery.admin', - // Provides read/write access to BigQuery data - dataEditor: 'roles/bigquery.dataEditor', - // Provides read-only access to BigQuery data - dataViewer: 'roles/bigquery.dataViewer', - // Provides read/write access to BigQuery datasets - datasetEditor: 'roles/bigquery.datasetEditor', - // Provides read-only access to BigQuery datasets - datasetViewer: 'roles/bigquery.datasetViewer', - // General user role for BigQuery - user: 'roles/bigquery.user', - // Creates and manages BigQuery jobs - jobUser: 'roles/bigquery.jobUser' - }, - computeEngine: { - // Administers Compute Engine resources - admin: 'roles/compute.admin', - // Provides read-only access to Compute Engine resources - viewer: 'roles/compute.viewer', - // Provides access to instance admin operations - instanceAdmin: 'roles/compute.instanceAdmin.v1', - // Provides access to snapshot resources - snapshotAdmin: 'roles/compute.snapshotAdmin', - // Provides read/write access to instance network configurations - networkAdmin: 'roles/compute.networkAdmin', - // Manages security aspects of Compute Engine - securityAdmin: 'roles/compute.securityAdmin' - }, - functions: { - // Administers Cloud Functions - admin: 'roles/cloudfunctions.admin', - // Invokes deployed Cloud Functions - invoker: 'roles/cloudfunctions.invoker', - // Provides read-only access to Cloud Functions - viewer: 'roles/cloudfunctions.viewer', - // Develops and manages Cloud Functions - developer: 'roles/cloudfunctions.developer' - }, - iam: { - // Administers IAM policies - admin: 'roles/iam.admin', - // Provides read-only access to IAM policies - viewer: 'roles/iam.viewer', - // Manages service accounts - serviceAccountManager: 'roles/iam.serviceAccountAdmin', - // Manages service account keys - serviceAccountKeyAdmin: 'roles/iam.serviceAccountKeyAdmin', - // Manages IAM roles - roleAdmin: 'roles/iam.roleAdmin', - // Reviews IAM security settings - securityReviewer: 'roles/iam.securityReviewer', - // Manages organization-wide roles - organizationRoleAdmin: 'roles/iam.organizationRoleAdmin', - // Allows workload identity to be used with Kubernetes - workloadIdentityUser: 'roles/iam.workloadIdentityUser' - }, - profiler: { - // Administers Cloud Profiler resources - admin: 'roles/cloudprofiler.admin', - // Provides read-only access to Cloud Profiler data - viewer: 'roles/cloudprofiler.viewer', - // Collects profiling data - agent: 'roles/cloudprofiler.agent' - }, - tracer: { - // Administers Cloud Trace resources - admin: 'roles/cloudtrace.admin', - // Provides read-only access to Cloud Trace data - viewer: 'roles/cloudtrace.viewer', - // Collects trace data - agent: 'roles/cloudtrace.agent' - }, - cloudRun: { - // Administers Cloud Run services - admin: 'roles/run.admin', - // Invokes Cloud Run services - invoker: 'roles/run.invoker', - // Provides read-only access to Cloud Run services - viewer: 'roles/run.viewer', - // Develops and manages Cloud Run services - developer: 'roles/run.developer' - }, - cloudTasks: { - // Administers Cloud Tasks resources - admin: 'roles/cloudtasks.admin', - // Enqueues tasks into Cloud Tasks - enqueuer: 'roles/cloudtasks.enqueuer', - // Provides read-only access to Cloud Tasks resources - viewer: 'roles/cloudtasks.viewer', - // Develops and manages Cloud Tasks resources - developer: 'roles/cloudtasks.developer' - }, - monitoring: { - // Administers monitoring configurations - admin: 'roles/monitoring.admin', - // Edits monitoring configurations - editor: 'roles/monitoring.editor', - // Provides read-only access to monitoring data - viewer: 'roles/monitoring.viewer', - // Writes metrics to monitoring - metricWriter: 'roles/monitoring.metricWriter' - }, - logging: { - // Administers logging configurations - admin: 'roles/logging.admin', - // Writes logging configurations - configWriter: 'roles/logging.configWriter', - // Writes logs - logWriter: 'roles/logging.logWriter', - // Reads logging data - viewer: 'roles/logging.viewer' - }, - networkServices: { - // Administers network services - admin: 'roles/networkservices.admin', - // Provides read-only access to network services - viewer: 'roles/networkservices.viewer', - // Manages network service configurations - serviceManager: 'roles/networkservices.servicemanager' - }, - dns: { - // Administers Cloud DNS resources - admin: 'roles/dns.admin', - // Edits Cloud DNS resources - editor: 'roles/dns.editor', - // Provides read-only access to Cloud DNS resources - viewer: 'roles/dns.viewer' - }, - secretManager: { - // Administers Secret Manager resources - admin: 'roles/secretmanager.admin', - // Accesses secret data in Secret Manager - secretAccessor: 'roles/secretmanager.secretAccessor', - // Provides read-only access to Secret Manager - viewer: 'roles/secretmanager.viewer' - }, - spanner: { - // Administers Cloud Spanner instances and databases - admin: 'roles/spanner.admin', - // Grants read/write access to Cloud Spanner databases - databaseAdmin: 'roles/spanner.databaseAdmin', - // Grants read-only access to Cloud Spanner databases - databaseReader: 'roles/spanner.databaseReader', - // Provides read-only access to Cloud Spanner instance configs - viewer: 'roles/spanner.viewer' + "accessapproval": { + "approver": "roles/accessapproval.approver", + "configEditor": "roles/accessapproval.configEditor", + "invalidator": "roles/accessapproval.invalidator", + "viewer": "roles/accessapproval.viewer" + }, + "accesscontextmanager": { + "gcpAccessAdmin": "roles/accesscontextmanager.gcpAccessAdmin", + "gcpAccessReader": "roles/accesscontextmanager.gcpAccessReader", + "policyAdmin": "roles/accesscontextmanager.policyAdmin", + "policyEditor": "roles/accesscontextmanager.policyEditor", + "policyReader": "roles/accesscontextmanager.policyReader", + "vpcScTroubleshooterViewer": "roles/accesscontextmanager.vpcScTroubleshooterViewer" + }, + "actions": { + "Admin": "roles/actions.Admin", + "Viewer": "roles/actions.Viewer" + }, + "advisorynotifications": { + "admin": "roles/advisorynotifications.admin", + "viewer": "roles/advisorynotifications.viewer" + }, + "aiplatform": { + "admin": "roles/aiplatform.admin", + "batchPredictionServiceAgent": "roles/aiplatform.batchPredictionServiceAgent", + "colabEnterpriseAdmin": "roles/aiplatform.colabEnterpriseAdmin", + "colabEnterpriseUser": "roles/aiplatform.colabEnterpriseUser", + "colabServiceAgent": "roles/aiplatform.colabServiceAgent", + "customCodeServiceAgent": "roles/aiplatform.customCodeServiceAgent", + "entityTypeOwner": "roles/aiplatform.entityTypeOwner", + "expressAdmin": "roles/aiplatform.expressAdmin", + "expressUser": "roles/aiplatform.expressUser", + "extensionCustomCodeServiceAgent": "roles/aiplatform.extensionCustomCodeServiceAgent", + "extensionServiceAgent": "roles/aiplatform.extensionServiceAgent", + "featurestoreAdmin": "roles/aiplatform.featurestoreAdmin", + "featurestoreDataViewer": "roles/aiplatform.featurestoreDataViewer", + "featurestoreDataWriter": "roles/aiplatform.featurestoreDataWriter", + "featurestoreInstanceCreator": "roles/aiplatform.featurestoreInstanceCreator", + "featurestoreResourceViewer": "roles/aiplatform.featurestoreResourceViewer", + "featurestoreUser": "roles/aiplatform.featurestoreUser", + "migrator": "roles/aiplatform.migrator", + "modelMonitoringServiceAgent": "roles/aiplatform.modelMonitoringServiceAgent", + "notebookExecutorUser": "roles/aiplatform.notebookExecutorUser", + "notebookRuntimeAdmin": "roles/aiplatform.notebookRuntimeAdmin", + "notebookRuntimeUser": "roles/aiplatform.notebookRuntimeUser", + "notebookServiceAgent": "roles/aiplatform.notebookServiceAgent", + "onlinePredictionServiceAgent": "roles/aiplatform.onlinePredictionServiceAgent", + "ragServiceAgent": "roles/aiplatform.ragServiceAgent", + "rapidevalServiceAgent": "roles/aiplatform.rapidevalServiceAgent", + "reasoningEngineServiceAgent": "roles/aiplatform.reasoningEngineServiceAgent", + "serviceAgent": "roles/aiplatform.serviceAgent", + "tensorboardWebAppUser": "roles/aiplatform.tensorboardWebAppUser", + "tuningServiceAgent": "roles/aiplatform.tuningServiceAgent", + "user": "roles/aiplatform.user", + "viewer": "roles/aiplatform.viewer" + }, + "alloydb": { + "admin": "roles/alloydb.admin", + "client": "roles/alloydb.client", + "databaseUser": "roles/alloydb.databaseUser", + "serviceAgent": "roles/alloydb.serviceAgent", + "viewer": "roles/alloydb.viewer" + }, + "analyticshub": { + "admin": "roles/analyticshub.admin", + "listingAdmin": "roles/analyticshub.listingAdmin", + "publisher": "roles/analyticshub.publisher", + "subscriber": "roles/analyticshub.subscriber", + "subscriptionOwner": "roles/analyticshub.subscriptionOwner", + "viewer": "roles/analyticshub.viewer" + }, + "androidmanagement": { + "user": "roles/androidmanagement.user" + }, + "anthos": { + "serviceAgent": "roles/anthos.serviceAgent" + }, + "anthosaudit": { + "serviceAgent": "roles/anthosaudit.serviceAgent" + }, + "anthosconfigmanagement": { + "serviceAgent": "roles/anthosconfigmanagement.serviceAgent" + }, + "anthosidentityservice": { + "serviceAgent": "roles/anthosidentityservice.serviceAgent" + }, + "anthospolicycontroller": { + "serviceAgent": "roles/anthospolicycontroller.serviceAgent" + }, + "anthosservicemesh": { + "serviceAgent": "roles/anthosservicemesh.serviceAgent" + }, + "anthossupport": { + "serviceAgent": "roles/anthossupport.serviceAgent" + }, + "apigateway": { + "admin": "roles/apigateway.admin", + "serviceAgent": "roles/apigateway.serviceAgent", + "viewer": "roles/apigateway.viewer" + }, + "apigateway_management": { + "serviceAgent": "roles/apigateway_management.serviceAgent" + }, + "apigee": { + "admin": "roles/apigee.admin", + "analyticsAgent": "roles/apigee.analyticsAgent", + "analyticsEditor": "roles/apigee.analyticsEditor", + "analyticsViewer": "roles/apigee.analyticsViewer", + "apiAdminV2": "roles/apigee.apiAdminV2", + "apiReaderV2": "roles/apigee.apiReaderV2", + "deploymentInvoker": "roles/apigee.deploymentInvoker", + "developerAdmin": "roles/apigee.developerAdmin", + "environmentAdmin": "roles/apigee.environmentAdmin", + "monetizationAdmin": "roles/apigee.monetizationAdmin", + "portalAdmin": "roles/apigee.portalAdmin", + "readOnlyAdmin": "roles/apigee.readOnlyAdmin", + "runtimeAgent": "roles/apigee.runtimeAgent", + "securityAdmin": "roles/apigee.securityAdmin", + "securityViewer": "roles/apigee.securityViewer", + "serviceAgent": "roles/apigee.serviceAgent", + "synchronizerManager": "roles/apigee.synchronizerManager" + }, + "apigeeconnect": { + "Admin": "roles/apigeeconnect.Admin", + "Agent": "roles/apigeeconnect.Agent" + }, + "apigeeregistry": { + "admin": "roles/apigeeregistry.admin", + "editor": "roles/apigeeregistry.editor", + "viewer": "roles/apigeeregistry.viewer", + "worker": "roles/apigeeregistry.worker" + }, + "apihub": { + "admin": "roles/apihub.admin", + "attributeAdmin": "roles/apihub.attributeAdmin", + "editor": "roles/apihub.editor", + "pluginAdmin": "roles/apihub.pluginAdmin", + "provisioningAdmin": "roles/apihub.provisioningAdmin", + "runtimeProjectServiceAgent": "roles/apihub.runtimeProjectServiceAgent", + "viewer": "roles/apihub.viewer" + }, + "apim": { + "admin": "roles/apim.admin", + "apiDiscoveryServiceAgent": "roles/apim.apiDiscoveryServiceAgent", + "viewer": "roles/apim.viewer" + }, + "appdevelopmentexperience": { + "serviceAgent": "roles/appdevelopmentexperience.serviceAgent" + }, + "appengine": { + "appAdmin": "roles/appengine.appAdmin", + "appCreator": "roles/appengine.appCreator", + "appViewer": "roles/appengine.appViewer", + "codeViewer": "roles/appengine.codeViewer", + "debugger": "roles/appengine.debugger", + "deployer": "roles/appengine.deployer", + "memcacheDataAdmin": "roles/appengine.memcacheDataAdmin", + "serviceAdmin": "roles/appengine.serviceAdmin", + "serviceAgent": "roles/appengine.serviceAgent" + }, + "appengineflex": { + "serviceAgent": "roles/appengineflex.serviceAgent" + }, + "apphub": { + "admin": "roles/apphub.admin", + "editor": "roles/apphub.editor", + "viewer": "roles/apphub.viewer" + }, + "applianceactivation": { + "approver": "roles/applianceactivation.approver", + "client": "roles/applianceactivation.client", + "troubleshooter": "roles/applianceactivation.troubleshooter" + }, + "artifactregistry": { + "admin": "roles/artifactregistry.admin", + "containerRegistryMigrationAdmin": "roles/artifactregistry.containerRegistryMigrationAdmin", + "createOnPushRepoAdmin": "roles/artifactregistry.createOnPushRepoAdmin", + "createOnPushWriter": "roles/artifactregistry.createOnPushWriter", + "reader": "roles/artifactregistry.reader", + "repoAdmin": "roles/artifactregistry.repoAdmin", + "serviceAgent": "roles/artifactregistry.serviceAgent", + "writer": "roles/artifactregistry.writer" + }, + "assuredoss": { + "admin": "roles/assuredoss.admin", + "projectAdmin": "roles/assuredoss.projectAdmin", + "reader": "roles/assuredoss.reader", + "user": "roles/assuredoss.user" + }, + "assuredworkloads": { + "admin": "roles/assuredworkloads.admin", + "editor": "roles/assuredworkloads.editor", + "monitoringServiceAgent": "roles/assuredworkloads.monitoringServiceAgent", + "reader": "roles/assuredworkloads.reader", + "serviceAgent": "roles/assuredworkloads.serviceAgent" + }, + "auditmanager": { + "admin": "roles/auditmanager.admin", + "auditor": "roles/auditmanager.auditor", + "serviceAgent": "roles/auditmanager.serviceAgent" + }, + "automl": { + "admin": "roles/automl.admin", + "editor": "roles/automl.editor", + "predictor": "roles/automl.predictor", + "serviceAgent": "roles/automl.serviceAgent", + "viewer": "roles/automl.viewer" + }, + "automlrecommendations": { + "admin": "roles/automlrecommendations.admin", + "adminViewer": "roles/automlrecommendations.adminViewer", + "editor": "roles/automlrecommendations.editor", + "serviceAgent": "roles/automlrecommendations.serviceAgent", + "viewer": "roles/automlrecommendations.viewer" + }, + "autoscaling": { + "metricsWriter": "roles/autoscaling.metricsWriter", + "recommendationsReader": "roles/autoscaling.recommendationsReader", + "sitesAdmin": "roles/autoscaling.sitesAdmin", + "stateWriter": "roles/autoscaling.stateWriter" + }, + "axt": { + "admin": "roles/axt.admin" + }, + "backupdr": { + "admin": "roles/backupdr.admin", + "backupUser": "roles/backupdr.backupUser", + "backupvaultAccessor": "roles/backupdr.backupvaultAccessor", + "backupvaultAdmin": "roles/backupdr.backupvaultAdmin", + "backupvaultLister": "roles/backupdr.backupvaultLister", + "backupvaultViewer": "roles/backupdr.backupvaultViewer", + "cloudStorageOperator": "roles/backupdr.cloudStorageOperator", + "computeEngineOperator": "roles/backupdr.computeEngineOperator", + "managementServerAccessor": "roles/backupdr.managementServerAccessor", + "mountUser": "roles/backupdr.mountUser", + "restoreUser": "roles/backupdr.restoreUser", + "serviceAgent": "roles/backupdr.serviceAgent", + "user": "roles/backupdr.user", + "userv2": "roles/backupdr.userv2", + "viewer": "roles/backupdr.viewer" + }, + "baremetalsolution": { + "admin": "roles/baremetalsolution.admin", + "editor": "roles/baremetalsolution.editor", + "instancesadmin": "roles/baremetalsolution.instancesadmin", + "instancesviewer": "roles/baremetalsolution.instancesviewer", + "lunsadmin": "roles/baremetalsolution.lunsadmin", + "lunsviewer": "roles/baremetalsolution.lunsviewer", + "maintenanceeventsadmin": "roles/baremetalsolution.maintenanceeventsadmin", + "maintenanceeventseditor": "roles/baremetalsolution.maintenanceeventseditor", + "maintenanceeventsviewer": "roles/baremetalsolution.maintenanceeventsviewer", + "networksadmin": "roles/baremetalsolution.networksadmin", + "nfssharesadmin": "roles/baremetalsolution.nfssharesadmin", + "nfsshareseditor": "roles/baremetalsolution.nfsshareseditor", + "nfssharesviewer": "roles/baremetalsolution.nfssharesviewer", + "osimagesviewer": "roles/baremetalsolution.osimagesviewer", + "procurementsadmin": "roles/baremetalsolution.procurementsadmin", + "procurementseditor": "roles/baremetalsolution.procurementseditor", + "procurementsviewer": "roles/baremetalsolution.procurementsviewer", + "serviceAgent": "roles/baremetalsolution.serviceAgent", + "storageadmin": "roles/baremetalsolution.storageadmin", + "viewer": "roles/baremetalsolution.viewer", + "volumesadmin": "roles/baremetalsolution.volumesadmin", + "volumeseditor": "roles/baremetalsolution.volumeseditor", + "volumesnapshotsadmin": "roles/baremetalsolution.volumesnapshotsadmin", + "volumesnapshotseditor": "roles/baremetalsolution.volumesnapshotseditor", + "volumesnapshotsviewer": "roles/baremetalsolution.volumesnapshotsviewer", + "volumessviewer": "roles/baremetalsolution.volumessviewer" + }, + "batch": { + "admin": "roles/batch.admin", + "agentReporter": "roles/batch.agentReporter", + "jobsEditor": "roles/batch.jobsEditor", + "jobsViewer": "roles/batch.jobsViewer", + "resourceAllowancesEditor": "roles/batch.resourceAllowancesEditor", + "resourceAllowancesViewer": "roles/batch.resourceAllowancesViewer", + "serviceAgent": "roles/batch.serviceAgent" + }, + "beyondcorp": { + "admin": "roles/beyondcorp.admin", + "clientConnectorAdmin": "roles/beyondcorp.clientConnectorAdmin", + "clientConnectorServiceUser": "roles/beyondcorp.clientConnectorServiceUser", + "clientConnectorViewer": "roles/beyondcorp.clientConnectorViewer", + "partnerServiceDelegateAdmin": "roles/beyondcorp.partnerServiceDelegateAdmin", + "partnerServiceDelegateViewer": "roles/beyondcorp.partnerServiceDelegateViewer", + "subscriptionAdmin": "roles/beyondcorp.subscriptionAdmin", + "subscriptionViewer": "roles/beyondcorp.subscriptionViewer", + "viewer": "roles/beyondcorp.viewer" + }, + "biglake": { + "admin": "roles/biglake.admin", + "viewer": "roles/biglake.viewer" + }, + "bigquery": { + "admin": "roles/bigquery.admin", + "connectionAdmin": "roles/bigquery.connectionAdmin", + "connectionUser": "roles/bigquery.connectionUser", + "dataEditor": "roles/bigquery.dataEditor", + "dataOwner": "roles/bigquery.dataOwner", + "dataViewer": "roles/bigquery.dataViewer", + "filteredDataViewer": "roles/bigquery.filteredDataViewer", + "jobUser": "roles/bigquery.jobUser", + "metadataViewer": "roles/bigquery.metadataViewer", + "readSessionUser": "roles/bigquery.readSessionUser", + "resourceAdmin": "roles/bigquery.resourceAdmin", + "resourceEditor": "roles/bigquery.resourceEditor", + "resourceViewer": "roles/bigquery.resourceViewer", + "studioAdmin": "roles/bigquery.studioAdmin", + "studioUser": "roles/bigquery.studioUser", + "user": "roles/bigquery.user" + }, + "bigqueryconnection": { + "serviceAgent": "roles/bigqueryconnection.serviceAgent" + }, + "bigquerycontinuousquery": { + "serviceAgent": "roles/bigquerycontinuousquery.serviceAgent" + }, + "bigquerydatapolicy": { + "admin": "roles/bigquerydatapolicy.admin", + "maskedReader": "roles/bigquerydatapolicy.maskedReader", + "rawDataReader": "roles/bigquerydatapolicy.rawDataReader", + "viewer": "roles/bigquerydatapolicy.viewer" + }, + "bigquerydatatransfer": { + "serviceAgent": "roles/bigquerydatatransfer.serviceAgent" + }, + "bigquerymigration": { + "editor": "roles/bigquerymigration.editor", + "orchestrator": "roles/bigquerymigration.orchestrator", + "translationUser": "roles/bigquerymigration.translationUser", + "viewer": "roles/bigquerymigration.viewer", + "worker": "roles/bigquerymigration.worker" + }, + "bigqueryomni": { + "serviceAgent": "roles/bigqueryomni.serviceAgent" + }, + "bigqueryspark": { + "serviceAgent": "roles/bigqueryspark.serviceAgent" + }, + "bigtable": { + "admin": "roles/bigtable.admin", + "reader": "roles/bigtable.reader", + "user": "roles/bigtable.user", + "viewer": "roles/bigtable.viewer" + }, + "billing": { + "admin": "roles/billing.admin", + "carbonViewer": "roles/billing.carbonViewer", + "costsManager": "roles/billing.costsManager", + "creator": "roles/billing.creator", + "projectManager": "roles/billing.projectManager", + "user": "roles/billing.user", + "viewer": "roles/billing.viewer" + }, + "binaryauthorization": { + "attestorsAdmin": "roles/binaryauthorization.attestorsAdmin", + "attestorsEditor": "roles/binaryauthorization.attestorsEditor", + "attestorsVerifier": "roles/binaryauthorization.attestorsVerifier", + "attestorsViewer": "roles/binaryauthorization.attestorsViewer", + "policyAdmin": "roles/binaryauthorization.policyAdmin", + "policyEditor": "roles/binaryauthorization.policyEditor", + "policyEvaluator": "roles/binaryauthorization.policyEvaluator", + "policyViewer": "roles/binaryauthorization.policyViewer", + "serviceAgent": "roles/binaryauthorization.serviceAgent" + }, + "blockchainnodeengine": { + "admin": "roles/blockchainnodeengine.admin", + "serviceAgent": "roles/blockchainnodeengine.serviceAgent", + "viewer": "roles/blockchainnodeengine.viewer" + }, + "blockchainvalidatormanager": { + "admin": "roles/blockchainvalidatormanager.admin", + "viewer": "roles/blockchainvalidatormanager.viewer" + }, + "browser": { + "": "roles/browser" + }, + "capacityplanner": { + "viewer": "roles/capacityplanner.viewer" + }, + "carestudio": { + "viewer": "roles/carestudio.viewer" + }, + "certificatemanager": { + "editor": "roles/certificatemanager.editor", + "owner": "roles/certificatemanager.owner", + "serviceAgent": "roles/certificatemanager.serviceAgent", + "viewer": "roles/certificatemanager.viewer" + }, + "chat": { + "owner": "roles/chat.owner", + "reader": "roles/chat.reader" + }, + "chronicle": { + "admin": "roles/chronicle.admin", + "editor": "roles/chronicle.editor", + "globalDataAccess": "roles/chronicle.globalDataAccess", + "limitedViewer": "roles/chronicle.limitedViewer", + "restrictedDataAccess": "roles/chronicle.restrictedDataAccess", + "restrictedDataAccessViewer": "roles/chronicle.restrictedDataAccessViewer", + "serviceAgent": "roles/chronicle.serviceAgent", + "soarAdmin": "roles/chronicle.soarAdmin", + "soarServiceAgent": "roles/chronicle.soarServiceAgent", + "soarThreatManager": "roles/chronicle.soarThreatManager", + "soarVulnerabilityManager": "roles/chronicle.soarVulnerabilityManager", + "viewer": "roles/chronicle.viewer" + }, + "chroniclesm": { + "admin": "roles/chroniclesm.admin", + "viewer": "roles/chroniclesm.viewer" + }, + "ciem": { + "serviceAgent": "roles/ciem.serviceAgent" + }, + "cloud": { + "locationReader": "roles/cloud.locationReader" + }, + "cloudaicompanion": { + "codeRepositoryIndexesAdmin": "roles/cloudaicompanion.codeRepositoryIndexesAdmin", + "codeRepositoryIndexesViewer": "roles/cloudaicompanion.codeRepositoryIndexesViewer", + "repositoryGroupsUser": "roles/cloudaicompanion.repositoryGroupsUser", + "serviceAgent": "roles/cloudaicompanion.serviceAgent", + "user": "roles/cloudaicompanion.user" + }, + "cloudasset": { + "effectivePolicyServiceAgent": "roles/cloudasset.effectivePolicyServiceAgent", + "owner": "roles/cloudasset.owner", + "serviceAgent": "roles/cloudasset.serviceAgent", + "viewer": "roles/cloudasset.viewer" + }, + "cloudbuild": { + "builds.approver": "roles/cloudbuild.builds.approver", + "builds.builder": "roles/cloudbuild.builds.builder", + "builds.editor": "roles/cloudbuild.builds.editor", + "builds.viewer": "roles/cloudbuild.builds.viewer", + "connectionAdmin": "roles/cloudbuild.connectionAdmin", + "connectionViewer": "roles/cloudbuild.connectionViewer", + "integrationsEditor": "roles/cloudbuild.integrationsEditor", + "integrationsOwner": "roles/cloudbuild.integrationsOwner", + "integrationsViewer": "roles/cloudbuild.integrationsViewer", + "loggingServiceAgent": "roles/cloudbuild.loggingServiceAgent", + "readTokenAccessor": "roles/cloudbuild.readTokenAccessor", + "serviceAgent": "roles/cloudbuild.serviceAgent", + "tokenAccessor": "roles/cloudbuild.tokenAccessor", + "workerPoolEditor": "roles/cloudbuild.workerPoolEditor", + "workerPoolOwner": "roles/cloudbuild.workerPoolOwner", + "workerPoolUser": "roles/cloudbuild.workerPoolUser", + "workerPoolViewer": "roles/cloudbuild.workerPoolViewer" + }, + "cloudconfig": { + "admin": "roles/cloudconfig.admin", + "serviceAgent": "roles/cloudconfig.serviceAgent", + "viewer": "roles/cloudconfig.viewer" + }, + "cloudcontrolspartner": { + "accessApprovalServiceAgent": "roles/cloudcontrolspartner.accessApprovalServiceAgent", + "admin": "roles/cloudcontrolspartner.admin", + "editor": "roles/cloudcontrolspartner.editor", + "ekmServiceAgent": "roles/cloudcontrolspartner.ekmServiceAgent", + "inspectabilityReader": "roles/cloudcontrolspartner.inspectabilityReader", + "monitoringReader": "roles/cloudcontrolspartner.monitoringReader", + "monitoringServiceAgent": "roles/cloudcontrolspartner.monitoringServiceAgent", + "reader": "roles/cloudcontrolspartner.reader", + "supportCaseServiceAgent": "roles/cloudcontrolspartner.supportCaseServiceAgent" + }, + "clouddebugger": { + "agent": "roles/clouddebugger.agent", + "user": "roles/clouddebugger.user" + }, + "clouddeploy": { + "admin": "roles/clouddeploy.admin", + "approver": "roles/clouddeploy.approver", + "customTargetTypeAdmin": "roles/clouddeploy.customTargetTypeAdmin", + "developer": "roles/clouddeploy.developer", + "jobRunner": "roles/clouddeploy.jobRunner", + "operator": "roles/clouddeploy.operator", + "policyAdmin": "roles/clouddeploy.policyAdmin", + "policyOverrider": "roles/clouddeploy.policyOverrider", + "releaser": "roles/clouddeploy.releaser", + "serviceAgent": "roles/clouddeploy.serviceAgent", + "viewer": "roles/clouddeploy.viewer" + }, + "clouddeploymentmanager": { + "serviceAgent": "roles/clouddeploymentmanager.serviceAgent" + }, + "cloudfunctions": { + "admin": "roles/cloudfunctions.admin", + "developer": "roles/cloudfunctions.developer", + "invoker": "roles/cloudfunctions.invoker", + "serviceAgent": "roles/cloudfunctions.serviceAgent", + "viewer": "roles/cloudfunctions.viewer" + }, + "cloudiot": { + "serviceAgent": "roles/cloudiot.serviceAgent" + }, + "cloudjobdiscovery": { + "admin": "roles/cloudjobdiscovery.admin", + "jobsEditor": "roles/cloudjobdiscovery.jobsEditor", + "jobsViewer": "roles/cloudjobdiscovery.jobsViewer", + "profilesEditor": "roles/cloudjobdiscovery.profilesEditor", + "profilesViewer": "roles/cloudjobdiscovery.profilesViewer" + }, + "cloudkms": { + "admin": "roles/cloudkms.admin", + "autokeyAdmin": "roles/cloudkms.autokeyAdmin", + "autokeyUser": "roles/cloudkms.autokeyUser", + "cryptoKeyDecrypter": "roles/cloudkms.cryptoKeyDecrypter", + "cryptoKeyDecrypterViaDelegation": "roles/cloudkms.cryptoKeyDecrypterViaDelegation", + "cryptoKeyEncrypter": "roles/cloudkms.cryptoKeyEncrypter", + "cryptoKeyEncrypterDecrypter": "roles/cloudkms.cryptoKeyEncrypterDecrypter", + "cryptoKeyEncrypterDecrypterViaDelegation": "roles/cloudkms.cryptoKeyEncrypterDecrypterViaDelegation", + "cryptoKeyEncrypterViaDelegation": "roles/cloudkms.cryptoKeyEncrypterViaDelegation", + "cryptoOperator": "roles/cloudkms.cryptoOperator", + "ekmConnectionsAdmin": "roles/cloudkms.ekmConnectionsAdmin", + "expertRawAesCbc": "roles/cloudkms.expertRawAesCbc", + "expertRawAesCtr": "roles/cloudkms.expertRawAesCtr", + "expertRawPKCS1": "roles/cloudkms.expertRawPKCS1", + "importer": "roles/cloudkms.importer", + "orgServiceAgent": "roles/cloudkms.orgServiceAgent", + "protectedResourcesViewer": "roles/cloudkms.protectedResourcesViewer", + "publicKeyViewer": "roles/cloudkms.publicKeyViewer", + "serviceAgent": "roles/cloudkms.serviceAgent", + "signer": "roles/cloudkms.signer", + "signerVerifier": "roles/cloudkms.signerVerifier", + "verifier": "roles/cloudkms.verifier", + "viewer": "roles/cloudkms.viewer" + }, + "cloudkmskacls": { + "serviceAgent": "roles/cloudkmskacls.serviceAgent" + }, + "cloudmigration": { + "inframanager": "roles/cloudmigration.inframanager", + "storageaccess": "roles/cloudmigration.storageaccess", + "velostrataconnect": "roles/cloudmigration.velostrataconnect" + }, + "cloudoptimization": { + "admin": "roles/cloudoptimization.admin", + "editor": "roles/cloudoptimization.editor", + "serviceAgent": "roles/cloudoptimization.serviceAgent", + "viewer": "roles/cloudoptimization.viewer" + }, + "cloudprivatecatalog": { + "consumer": "roles/cloudprivatecatalog.consumer" + }, + "cloudprivatecatalogproducer": { + "admin": "roles/cloudprivatecatalogproducer.admin", + "manager": "roles/cloudprivatecatalogproducer.manager", + "orgAdmin": "roles/cloudprivatecatalogproducer.orgAdmin" + }, + "cloudprofiler": { + "agent": "roles/cloudprofiler.agent", + "user": "roles/cloudprofiler.user" + }, + "cloudquotas": { + "admin": "roles/cloudquotas.admin", + "viewer": "roles/cloudquotas.viewer" + }, + "cloudscheduler": { + "admin": "roles/cloudscheduler.admin", + "jobRunner": "roles/cloudscheduler.jobRunner", + "serviceAgent": "roles/cloudscheduler.serviceAgent", + "viewer": "roles/cloudscheduler.viewer" + }, + "cloudsecurityscanner": { + "editor": "roles/cloudsecurityscanner.editor", + "runner": "roles/cloudsecurityscanner.runner", + "viewer": "roles/cloudsecurityscanner.viewer" + }, + "cloudsql": { + "admin": "roles/cloudsql.admin", + "client": "roles/cloudsql.client", + "editor": "roles/cloudsql.editor", + "instanceUser": "roles/cloudsql.instanceUser", + "schemaViewer": "roles/cloudsql.schemaViewer", + "serviceAgent": "roles/cloudsql.serviceAgent", + "studioUser": "roles/cloudsql.studioUser", + "viewer": "roles/cloudsql.viewer" + }, + "cloudsupport": { + "admin": "roles/cloudsupport.admin", + "techSupportEditor": "roles/cloudsupport.techSupportEditor", + "techSupportViewer": "roles/cloudsupport.techSupportViewer", + "viewer": "roles/cloudsupport.viewer" + }, + "cloudtasks": { + "admin": "roles/cloudtasks.admin", + "enqueuer": "roles/cloudtasks.enqueuer", + "queueAdmin": "roles/cloudtasks.queueAdmin", + "serviceAgent": "roles/cloudtasks.serviceAgent", + "taskDeleter": "roles/cloudtasks.taskDeleter", + "taskRunner": "roles/cloudtasks.taskRunner", + "viewer": "roles/cloudtasks.viewer" + }, + "cloudtestservice": { + "directAccessAdmin": "roles/cloudtestservice.directAccessAdmin", + "directAccessViewer": "roles/cloudtestservice.directAccessViewer", + "testAdmin": "roles/cloudtestservice.testAdmin", + "testViewer": "roles/cloudtestservice.testViewer" + }, + "cloudtpu": { + "serviceAgent": "roles/cloudtpu.serviceAgent" + }, + "cloudtrace": { + "admin": "roles/cloudtrace.admin", + "agent": "roles/cloudtrace.agent", + "user": "roles/cloudtrace.user" + }, + "cloudtranslate": { + "admin": "roles/cloudtranslate.admin", + "editor": "roles/cloudtranslate.editor", + "serviceAgent": "roles/cloudtranslate.serviceAgent", + "user": "roles/cloudtranslate.user", + "viewer": "roles/cloudtranslate.viewer" + }, + "commerceagreementpublishing": { + "admin": "roles/commerceagreementpublishing.admin", + "viewer": "roles/commerceagreementpublishing.viewer" + }, + "commercebusinessenablement": { + "admin": "roles/commercebusinessenablement.admin", + "paymentConfigAdmin": "roles/commercebusinessenablement.paymentConfigAdmin", + "paymentConfigViewer": "roles/commercebusinessenablement.paymentConfigViewer", + "rebatesAdmin": "roles/commercebusinessenablement.rebatesAdmin", + "rebatesViewer": "roles/commercebusinessenablement.rebatesViewer", + "resellerDiscountAdmin": "roles/commercebusinessenablement.resellerDiscountAdmin", + "resellerDiscountViewer": "roles/commercebusinessenablement.resellerDiscountViewer", + "viewer": "roles/commercebusinessenablement.viewer" + }, + "commerceoffercatalog": { + "offersViewer": "roles/commerceoffercatalog.offersViewer" + }, + "commerceorggovernance": { + "admin": "roles/commerceorggovernance.admin", + "user": "roles/commerceorggovernance.user", + "viewer": "roles/commerceorggovernance.viewer" + }, + "commercepricemanagement": { + "eventsViewer": "roles/commercepricemanagement.eventsViewer", + "privateOffersAdmin": "roles/commercepricemanagement.privateOffersAdmin", + "viewer": "roles/commercepricemanagement.viewer" + }, + "commerceproducer": { + "admin": "roles/commerceproducer.admin", + "viewer": "roles/commerceproducer.viewer" + }, + "compliancescanning": { + "serviceAgent": "roles/compliancescanning.serviceAgent" + }, + "composer": { + "ServiceAgentV2Ext": "roles/composer.ServiceAgentV2Ext", + "admin": "roles/composer.admin", + "environmentAndStorageObjectAdmin": "roles/composer.environmentAndStorageObjectAdmin", + "environmentAndStorageObjectUser": "roles/composer.environmentAndStorageObjectUser", + "environmentAndStorageObjectViewer": "roles/composer.environmentAndStorageObjectViewer", + "serviceAgent": "roles/composer.serviceAgent", + "sharedVpcAgent": "roles/composer.sharedVpcAgent", + "user": "roles/composer.user", + "worker": "roles/composer.worker" + }, + "compute": { + "admin": "roles/compute.admin", + "futureReservationAdmin": "roles/compute.futureReservationAdmin", + "futureReservationUser": "roles/compute.futureReservationUser", + "futureReservationViewer": "roles/compute.futureReservationViewer", + "imageUser": "roles/compute.imageUser", + "instanceAdmin": "roles/compute.instanceAdmin", + "instanceAdmin.v1": "roles/compute.instanceAdmin.v1", + "instanceGroupManagerServiceAgent": "roles/compute.instanceGroupManagerServiceAgent", + "loadBalancerAdmin": "roles/compute.loadBalancerAdmin", + "loadBalancerServiceUser": "roles/compute.loadBalancerServiceUser", + "networkAdmin": "roles/compute.networkAdmin", + "networkUser": "roles/compute.networkUser", + "networkViewer": "roles/compute.networkViewer", + "orgFirewallPolicyAdmin": "roles/compute.orgFirewallPolicyAdmin", + "orgFirewallPolicyUser": "roles/compute.orgFirewallPolicyUser", + "orgSecurityPolicyAdmin": "roles/compute.orgSecurityPolicyAdmin", + "orgSecurityPolicyUser": "roles/compute.orgSecurityPolicyUser", + "orgSecurityResourceAdmin": "roles/compute.orgSecurityResourceAdmin", + "osAdminLogin": "roles/compute.osAdminLogin", + "osLogin": "roles/compute.osLogin", + "osLoginExternalUser": "roles/compute.osLoginExternalUser", + "packetMirroringAdmin": "roles/compute.packetMirroringAdmin", + "packetMirroringUser": "roles/compute.packetMirroringUser", + "publicIpAdmin": "roles/compute.publicIpAdmin", + "securityAdmin": "roles/compute.securityAdmin", + "serviceAgent": "roles/compute.serviceAgent", + "soleTenantViewer": "roles/compute.soleTenantViewer", + "storageAdmin": "roles/compute.storageAdmin", + "viewer": "roles/compute.viewer", + "xpnAdmin": "roles/compute.xpnAdmin" + }, + "confidentialcomputing": { + "workloadUser": "roles/confidentialcomputing.workloadUser" + }, + "config": { + "admin": "roles/config.admin", + "agent": "roles/config.agent", + "viewer": "roles/config.viewer" + }, + "configdelivery": { + "configDeliveryAdmin": "roles/configdelivery.configDeliveryAdmin", + "configDeliveryViewer": "roles/configdelivery.configDeliveryViewer", + "resourceBundlePublisher": "roles/configdelivery.resourceBundlePublisher", + "serviceAgent": "roles/configdelivery.serviceAgent" + }, + "connectors": { + "admin": "roles/connectors.admin", + "customConnectorAdmin": "roles/connectors.customConnectorAdmin", + "customConnectorViewer": "roles/connectors.customConnectorViewer", + "endpointAttachmentAdmin": "roles/connectors.endpointAttachmentAdmin", + "endpointAttachmentViewer": "roles/connectors.endpointAttachmentViewer", + "eventSubscriptionAdmin": "roles/connectors.eventSubscriptionAdmin", + "eventSubscriptionViewer": "roles/connectors.eventSubscriptionViewer", + "invoker": "roles/connectors.invoker", + "listener": "roles/connectors.listener", + "managedZoneAdmin": "roles/connectors.managedZoneAdmin", + "managedZoneViewer": "roles/connectors.managedZoneViewer", + "serviceAgent": "roles/connectors.serviceAgent", + "viewer": "roles/connectors.viewer" + }, + "consumerprocurement": { + "entitlementManager": "roles/consumerprocurement.entitlementManager", + "entitlementViewer": "roles/consumerprocurement.entitlementViewer", + "eventsViewer": "roles/consumerprocurement.eventsViewer", + "licensePoolEditor": "roles/consumerprocurement.licensePoolEditor", + "licensePoolViewer": "roles/consumerprocurement.licensePoolViewer", + "orderAdmin": "roles/consumerprocurement.orderAdmin", + "orderViewer": "roles/consumerprocurement.orderViewer", + "procurementAdmin": "roles/consumerprocurement.procurementAdmin", + "procurementViewer": "roles/consumerprocurement.procurementViewer" + }, + "contactcenteraiplatform": { + "admin": "roles/contactcenteraiplatform.admin", + "viewer": "roles/contactcenteraiplatform.viewer" + }, + "contactcenterinsights": { + "editor": "roles/contactcenterinsights.editor", + "serviceAgent": "roles/contactcenterinsights.serviceAgent", + "viewer": "roles/contactcenterinsights.viewer" + }, + "container": { + "admin": "roles/container.admin", + "cloudKmsKeyUser": "roles/container.cloudKmsKeyUser", + "clusterAdmin": "roles/container.clusterAdmin", + "clusterViewer": "roles/container.clusterViewer", + "defaultNodeServiceAccount": "roles/container.defaultNodeServiceAccount", + "developer": "roles/container.developer", + "hostServiceAgentUser": "roles/container.hostServiceAgentUser", + "nodeServiceAgent": "roles/container.nodeServiceAgent", + "serviceAgent": "roles/container.serviceAgent", + "viewer": "roles/container.viewer" + }, + "containeranalysis": { + "ServiceAgent": "roles/containeranalysis.ServiceAgent", + "admin": "roles/containeranalysis.admin", + "notes.attacher": "roles/containeranalysis.notes.attacher", + "notes.editor": "roles/containeranalysis.notes.editor", + "notes.occurrences.viewer": "roles/containeranalysis.notes.occurrences.viewer", + "notes.viewer": "roles/containeranalysis.notes.viewer", + "occurrences.editor": "roles/containeranalysis.occurrences.editor", + "occurrences.viewer": "roles/containeranalysis.occurrences.viewer" + }, + "containerregistry": { + "ServiceAgent": "roles/containerregistry.ServiceAgent" + }, + "containerscanning": { + "ServiceAgent": "roles/containerscanning.ServiceAgent" + }, + "containersecurity": { + "viewer": "roles/containersecurity.viewer" + }, + "containerthreatdetection": { + "serviceAgent": "roles/containerthreatdetection.serviceAgent" + }, + "contentwarehouse": { + "admin": "roles/contentwarehouse.admin", + "documentAdmin": "roles/contentwarehouse.documentAdmin", + "documentCreator": "roles/contentwarehouse.documentCreator", + "documentEditor": "roles/contentwarehouse.documentEditor", + "documentSchemaViewer": "roles/contentwarehouse.documentSchemaViewer", + "documentViewer": "roles/contentwarehouse.documentViewer", + "serviceAgent": "roles/contentwarehouse.serviceAgent" + }, + "databasecenter": { + "viewer": "roles/databasecenter.viewer" + }, + "databaseinsights": { + "eventsViewer": "roles/databaseinsights.eventsViewer", + "monitoringViewer": "roles/databaseinsights.monitoringViewer", + "operationsAdmin": "roles/databaseinsights.operationsAdmin", + "recommendationViewer": "roles/databaseinsights.recommendationViewer", + "viewer": "roles/databaseinsights.viewer" + }, + "datacatalog": { + "admin": "roles/datacatalog.admin", + "categoryAdmin": "roles/datacatalog.categoryAdmin", + "categoryFineGrainedReader": "roles/datacatalog.categoryFineGrainedReader", + "dataSteward": "roles/datacatalog.dataSteward", + "entryGroupCreator": "roles/datacatalog.entryGroupCreator", + "entryGroupOwner": "roles/datacatalog.entryGroupOwner", + "entryOwner": "roles/datacatalog.entryOwner", + "entryViewer": "roles/datacatalog.entryViewer", + "glossaryOwner": "roles/datacatalog.glossaryOwner", + "glossaryUser": "roles/datacatalog.glossaryUser", + "migrationConfigAdmin": "roles/datacatalog.migrationConfigAdmin", + "searchAdmin": "roles/datacatalog.searchAdmin", + "tagEditor": "roles/datacatalog.tagEditor", + "tagTemplateCreator": "roles/datacatalog.tagTemplateCreator", + "tagTemplateOwner": "roles/datacatalog.tagTemplateOwner", + "tagTemplateUser": "roles/datacatalog.tagTemplateUser", + "tagTemplateViewer": "roles/datacatalog.tagTemplateViewer", + "viewer": "roles/datacatalog.viewer" + }, + "dataconnectors": { + "connectorAdmin": "roles/dataconnectors.connectorAdmin", + "connectorUser": "roles/dataconnectors.connectorUser", + "serviceAgent": "roles/dataconnectors.serviceAgent" + }, + "dataflow": { + "admin": "roles/dataflow.admin", + "developer": "roles/dataflow.developer", + "serviceAgent": "roles/dataflow.serviceAgent", + "viewer": "roles/dataflow.viewer", + "worker": "roles/dataflow.worker" + }, + "dataform": { + "admin": "roles/dataform.admin", + "codeCreator": "roles/dataform.codeCreator", + "codeEditor": "roles/dataform.codeEditor", + "codeOwner": "roles/dataform.codeOwner", + "codeViewer": "roles/dataform.codeViewer", + "editor": "roles/dataform.editor", + "serviceAgent": "roles/dataform.serviceAgent", + "viewer": "roles/dataform.viewer" + }, + "datafusion": { + "accessor": "roles/datafusion.accessor", + "admin": "roles/datafusion.admin", + "developer": "roles/datafusion.developer", + "operator": "roles/datafusion.operator", + "runner": "roles/datafusion.runner", + "serviceAgent": "roles/datafusion.serviceAgent", + "viewer": "roles/datafusion.viewer" + }, + "datalabeling": { + "admin": "roles/datalabeling.admin", + "editor": "roles/datalabeling.editor", + "serviceAgent": "roles/datalabeling.serviceAgent", + "viewer": "roles/datalabeling.viewer" + }, + "datalineage": { + "admin": "roles/datalineage.admin", + "editor": "roles/datalineage.editor", + "producer": "roles/datalineage.producer", + "viewer": "roles/datalineage.viewer" + }, + "datamigration": { + "admin": "roles/datamigration.admin", + "serviceAgent": "roles/datamigration.serviceAgent" + }, + "datapipelines": { + "admin": "roles/datapipelines.admin", + "invoker": "roles/datapipelines.invoker", + "serviceAgent": "roles/datapipelines.serviceAgent", + "viewer": "roles/datapipelines.viewer" + }, + "dataplex": { + "admin": "roles/dataplex.admin", + "aspectTypeOwner": "roles/dataplex.aspectTypeOwner", + "aspectTypeUser": "roles/dataplex.aspectTypeUser", + "bindingAdmin": "roles/dataplex.bindingAdmin", + "catalogAdmin": "roles/dataplex.catalogAdmin", + "catalogEditor": "roles/dataplex.catalogEditor", + "catalogViewer": "roles/dataplex.catalogViewer", + "dataOwner": "roles/dataplex.dataOwner", + "dataReader": "roles/dataplex.dataReader", + "dataScanAdmin": "roles/dataplex.dataScanAdmin", + "dataScanCreator": "roles/dataplex.dataScanCreator", + "dataScanDataViewer": "roles/dataplex.dataScanDataViewer", + "dataScanEditor": "roles/dataplex.dataScanEditor", + "dataScanViewer": "roles/dataplex.dataScanViewer", + "dataWriter": "roles/dataplex.dataWriter", + "developer": "roles/dataplex.developer", + "discoveryBigLakePublishingServiceAgent": "roles/dataplex.discoveryBigLakePublishingServiceAgent", + "discoveryPublishingServiceAgent": "roles/dataplex.discoveryPublishingServiceAgent", + "discoveryServiceAgent": "roles/dataplex.discoveryServiceAgent", + "editor": "roles/dataplex.editor", + "encryptionAdmin": "roles/dataplex.encryptionAdmin", + "entryGroupExporter": "roles/dataplex.entryGroupExporter", + "entryGroupImporter": "roles/dataplex.entryGroupImporter", + "entryGroupOwner": "roles/dataplex.entryGroupOwner", + "entryOwner": "roles/dataplex.entryOwner", + "entryTypeOwner": "roles/dataplex.entryTypeOwner", + "entryTypeUser": "roles/dataplex.entryTypeUser", + "metadataJobOwner": "roles/dataplex.metadataJobOwner", + "metadataJobViewer": "roles/dataplex.metadataJobViewer", + "metadataReader": "roles/dataplex.metadataReader", + "metadataWriter": "roles/dataplex.metadataWriter", + "securityAdmin": "roles/dataplex.securityAdmin", + "serviceAgent": "roles/dataplex.serviceAgent", + "storageDataOwner": "roles/dataplex.storageDataOwner", + "storageDataReader": "roles/dataplex.storageDataReader", + "storageDataWriter": "roles/dataplex.storageDataWriter", + "taxonomyAdmin": "roles/dataplex.taxonomyAdmin", + "taxonomyViewer": "roles/dataplex.taxonomyViewer", + "viewer": "roles/dataplex.viewer" + }, + "dataprep": { + "projects.user": "roles/dataprep.projects.user", + "serviceAgent": "roles/dataprep.serviceAgent" + }, + "dataproc": { + "admin": "roles/dataproc.admin", + "editor": "roles/dataproc.editor", + "hubAgent": "roles/dataproc.hubAgent", + "serviceAgent": "roles/dataproc.serviceAgent", + "viewer": "roles/dataproc.viewer", + "worker": "roles/dataproc.worker" + }, + "dataprocessing": { + "admin": "roles/dataprocessing.admin", + "dataSourceManager": "roles/dataprocessing.dataSourceManager" + }, + "dataprocrm": { + "admin": "roles/dataprocrm.admin", + "nodeServiceAgent": "roles/dataprocrm.nodeServiceAgent", + "viewer": "roles/dataprocrm.viewer" + }, + "datastore": { + "backupSchedulesAdmin": "roles/datastore.backupSchedulesAdmin", + "backupSchedulesViewer": "roles/datastore.backupSchedulesViewer", + "backupsAdmin": "roles/datastore.backupsAdmin", + "backupsViewer": "roles/datastore.backupsViewer", + "bulkAdmin": "roles/datastore.bulkAdmin", + "importExportAdmin": "roles/datastore.importExportAdmin", + "indexAdmin": "roles/datastore.indexAdmin", + "keyVisualizerViewer": "roles/datastore.keyVisualizerViewer", + "owner": "roles/datastore.owner", + "restoreAdmin": "roles/datastore.restoreAdmin", + "user": "roles/datastore.user", + "viewer": "roles/datastore.viewer" + }, + "datastream": { + "admin": "roles/datastream.admin", + "serviceAgent": "roles/datastream.serviceAgent", + "viewer": "roles/datastream.viewer" + }, + "datastudio": { + "admin": "roles/datastudio.admin", + "contentManager": "roles/datastudio.contentManager", + "contributor": "roles/datastudio.contributor", + "editor": "roles/datastudio.editor", + "manager": "roles/datastudio.manager", + "serviceAgent": "roles/datastudio.serviceAgent", + "viewer": "roles/datastudio.viewer", + "workspaceViewer": "roles/datastudio.workspaceViewer" + }, + "dellemccloudonefs": { + "admin": "roles/dellemccloudonefs.admin", + "user": "roles/dellemccloudonefs.user", + "viewer": "roles/dellemccloudonefs.viewer" + }, + "deploymentmanager": { + "editor": "roles/deploymentmanager.editor", + "typeEditor": "roles/deploymentmanager.typeEditor", + "typeViewer": "roles/deploymentmanager.typeViewer", + "viewer": "roles/deploymentmanager.viewer" + }, + "designcenter": { + "serviceAgent": "roles/designcenter.serviceAgent" + }, + "developerconnect": { + "admin": "roles/developerconnect.admin", + "readTokenAccessor": "roles/developerconnect.readTokenAccessor", + "tokenAccessor": "roles/developerconnect.tokenAccessor", + "user": "roles/developerconnect.user", + "viewer": "roles/developerconnect.viewer" + }, + "dialogflow": { + "aamAdmin": "roles/dialogflow.aamAdmin", + "aamConversationalArchitect": "roles/dialogflow.aamConversationalArchitect", + "aamDialogDesigner": "roles/dialogflow.aamDialogDesigner", + "aamLeadDialogDesigner": "roles/dialogflow.aamLeadDialogDesigner", + "aamViewer": "roles/dialogflow.aamViewer", + "admin": "roles/dialogflow.admin", + "agentAssistClient": "roles/dialogflow.agentAssistClient", + "client": "roles/dialogflow.client", + "consoleAgentEditor": "roles/dialogflow.consoleAgentEditor", + "consoleSimulatorUser": "roles/dialogflow.consoleSimulatorUser", + "consoleSmartMessagingAllowlistEditor": "roles/dialogflow.consoleSmartMessagingAllowlistEditor", + "conversationManager": "roles/dialogflow.conversationManager", + "entityTypeAdmin": "roles/dialogflow.entityTypeAdmin", + "environmentEditor": "roles/dialogflow.environmentEditor", + "flowEditor": "roles/dialogflow.flowEditor", + "integrationManager": "roles/dialogflow.integrationManager", + "intentAdmin": "roles/dialogflow.intentAdmin", + "reader": "roles/dialogflow.reader", + "serviceAgent": "roles/dialogflow.serviceAgent", + "testCaseAdmin": "roles/dialogflow.testCaseAdmin", + "webhookAdmin": "roles/dialogflow.webhookAdmin" + }, + "discoveryengine": { + "admin": "roles/discoveryengine.admin", + "editor": "roles/discoveryengine.editor", + "serviceAgent": "roles/discoveryengine.serviceAgent", + "user": "roles/discoveryengine.user", + "viewer": "roles/discoveryengine.viewer" + }, + "dlp": { + "admin": "roles/dlp.admin", + "analyzeRiskTemplatesEditor": "roles/dlp.analyzeRiskTemplatesEditor", + "analyzeRiskTemplatesReader": "roles/dlp.analyzeRiskTemplatesReader", + "columnDataProfilesReader": "roles/dlp.columnDataProfilesReader", + "connectionsAdmin": "roles/dlp.connectionsAdmin", + "connectionsReader": "roles/dlp.connectionsReader", + "dataProfilesAdmin": "roles/dlp.dataProfilesAdmin", + "dataProfilesReader": "roles/dlp.dataProfilesReader", + "deidentifyTemplatesEditor": "roles/dlp.deidentifyTemplatesEditor", + "deidentifyTemplatesReader": "roles/dlp.deidentifyTemplatesReader", + "estimatesAdmin": "roles/dlp.estimatesAdmin", + "fileStoreProfilesAdmin": "roles/dlp.fileStoreProfilesAdmin", + "fileStoreProfilesReader": "roles/dlp.fileStoreProfilesReader", + "inspectFindingsReader": "roles/dlp.inspectFindingsReader", + "inspectTemplatesEditor": "roles/dlp.inspectTemplatesEditor", + "inspectTemplatesReader": "roles/dlp.inspectTemplatesReader", + "jobTriggersEditor": "roles/dlp.jobTriggersEditor", + "jobTriggersReader": "roles/dlp.jobTriggersReader", + "jobsEditor": "roles/dlp.jobsEditor", + "jobsReader": "roles/dlp.jobsReader", + "orgdriver": "roles/dlp.orgdriver", + "projectDataProfilesReader": "roles/dlp.projectDataProfilesReader", + "projectdriver": "roles/dlp.projectdriver", + "reader": "roles/dlp.reader", + "serviceAgent": "roles/dlp.serviceAgent", + "storedInfoTypesEditor": "roles/dlp.storedInfoTypesEditor", + "storedInfoTypesReader": "roles/dlp.storedInfoTypesReader", + "subscriptionsAdmin": "roles/dlp.subscriptionsAdmin", + "subscriptionsReader": "roles/dlp.subscriptionsReader", + "tableDataProfilesAdmin": "roles/dlp.tableDataProfilesAdmin", + "tableDataProfilesReader": "roles/dlp.tableDataProfilesReader", + "user": "roles/dlp.user" + }, + "dns": { + "admin": "roles/dns.admin", + "peer": "roles/dns.peer", + "reader": "roles/dns.reader", + "serviceAgent": "roles/dns.serviceAgent" + }, + "documentai": { + "admin": "roles/documentai.admin", + "apiUser": "roles/documentai.apiUser", + "editor": "roles/documentai.editor", + "viewer": "roles/documentai.viewer" + }, + "documentaicore": { + "serviceAgent": "roles/documentaicore.serviceAgent" + }, + "domains": { + "admin": "roles/domains.admin", + "viewer": "roles/domains.viewer" + }, + "dspm": { + "serviceAgent": "roles/dspm.serviceAgent" + }, + "earthengine": { + "admin": "roles/earthengine.admin", + "appsPublisher": "roles/earthengine.appsPublisher", + "viewer": "roles/earthengine.viewer", + "writer": "roles/earthengine.writer" + }, + "edgecontainer": { + "admin": "roles/edgecontainer.admin", + "clusterServiceAgent": "roles/edgecontainer.clusterServiceAgent", + "machineUser": "roles/edgecontainer.machineUser", + "offlineCredentialUser": "roles/edgecontainer.offlineCredentialUser", + "serviceAgent": "roles/edgecontainer.serviceAgent", + "viewer": "roles/edgecontainer.viewer" + }, + "edgenetwork": { + "admin": "roles/edgenetwork.admin", + "viewer": "roles/edgenetwork.viewer" + }, + "editor": { + "": "roles/editor" + }, + "endpoints": { + "serviceAgent": "roles/endpoints.serviceAgent" + }, + "endpointsportal": { + "serviceAgent": "roles/endpointsportal.serviceAgent" + }, + "enterpriseknowledgegraph": { + "admin": "roles/enterpriseknowledgegraph.admin", + "editor": "roles/enterpriseknowledgegraph.editor", + "serviceAgent": "roles/enterpriseknowledgegraph.serviceAgent", + "viewer": "roles/enterpriseknowledgegraph.viewer" + }, + "enterprisepurchasing": { + "admin": "roles/enterprisepurchasing.admin", + "editor": "roles/enterprisepurchasing.editor", + "viewer": "roles/enterprisepurchasing.viewer" + }, + "errorreporting": { + "admin": "roles/errorreporting.admin", + "user": "roles/errorreporting.user", + "viewer": "roles/errorreporting.viewer", + "writer": "roles/errorreporting.writer" + }, + "essentialcontacts": { + "admin": "roles/essentialcontacts.admin", + "viewer": "roles/essentialcontacts.viewer" + }, + "eventarc": { + "admin": "roles/eventarc.admin", + "connectionPublisher": "roles/eventarc.connectionPublisher", + "developer": "roles/eventarc.developer", + "eventReceiver": "roles/eventarc.eventReceiver", + "messageBusAdmin": "roles/eventarc.messageBusAdmin", + "messageBusUser": "roles/eventarc.messageBusUser", + "publisher": "roles/eventarc.publisher", + "serviceAgent": "roles/eventarc.serviceAgent", + "viewer": "roles/eventarc.viewer" + }, + "file": { + "editor": "roles/file.editor", + "serviceAgent": "roles/file.serviceAgent", + "viewer": "roles/file.viewer" + }, + "financialservices": { + "admin": "roles/financialservices.admin", + "viewer": "roles/financialservices.viewer" + }, + "firebase": { + "admin": "roles/firebase.admin", + "analyticsAdmin": "roles/firebase.analyticsAdmin", + "analyticsViewer": "roles/firebase.analyticsViewer", + "appDistributionSdkServiceAgent": "roles/firebase.appDistributionSdkServiceAgent", + "developAdmin": "roles/firebase.developAdmin", + "developViewer": "roles/firebase.developViewer", + "growthAdmin": "roles/firebase.growthAdmin", + "growthViewer": "roles/firebase.growthViewer", + "managementServiceAgent": "roles/firebase.managementServiceAgent", + "qualityAdmin": "roles/firebase.qualityAdmin", + "qualityViewer": "roles/firebase.qualityViewer", + "sdkAdminServiceAgent": "roles/firebase.sdkAdminServiceAgent", + "sdkProvisioningServiceAgent": "roles/firebase.sdkProvisioningServiceAgent", + "viewer": "roles/firebase.viewer" + }, + "firebaseabt": { + "admin": "roles/firebaseabt.admin", + "viewer": "roles/firebaseabt.viewer" + }, + "firebaseappcheck": { + "admin": "roles/firebaseappcheck.admin", + "serviceAgent": "roles/firebaseappcheck.serviceAgent", + "tokenVerifier": "roles/firebaseappcheck.tokenVerifier", + "viewer": "roles/firebaseappcheck.viewer" + }, + "firebaseappdistro": { + "admin": "roles/firebaseappdistro.admin", + "viewer": "roles/firebaseappdistro.viewer" + }, + "firebaseapphosting": { + "serviceAgent": "roles/firebaseapphosting.serviceAgent" + }, + "firebaseauth": { + "admin": "roles/firebaseauth.admin", + "viewer": "roles/firebaseauth.viewer" + }, + "firebasecloudmessaging": { + "admin": "roles/firebasecloudmessaging.admin" + }, + "firebasecrash": { + "symbolMappingsAdmin": "roles/firebasecrash.symbolMappingsAdmin" + }, + "firebasecrashlytics": { + "admin": "roles/firebasecrashlytics.admin", + "viewer": "roles/firebasecrashlytics.viewer" + }, + "firebasedatabase": { + "admin": "roles/firebasedatabase.admin", + "serviceAgent": "roles/firebasedatabase.serviceAgent", + "viewer": "roles/firebasedatabase.viewer" + }, + "firebasedataconnect": { + "admin": "roles/firebasedataconnect.admin", + "dataAdmin": "roles/firebasedataconnect.dataAdmin", + "dataViewer": "roles/firebasedataconnect.dataViewer", + "serviceAgent": "roles/firebasedataconnect.serviceAgent", + "viewer": "roles/firebasedataconnect.viewer" + }, + "firebasedynamiclinks": { + "admin": "roles/firebasedynamiclinks.admin", + "viewer": "roles/firebasedynamiclinks.viewer" + }, + "firebaseextensions": { + "developer": "roles/firebaseextensions.developer", + "viewer": "roles/firebaseextensions.viewer" + }, + "firebaseextensionspublisher": { + "extensionsAdmin": "roles/firebaseextensionspublisher.extensionsAdmin", + "extensionsViewer": "roles/firebaseextensionspublisher.extensionsViewer" + }, + "firebasehosting": { + "admin": "roles/firebasehosting.admin", + "viewer": "roles/firebasehosting.viewer" + }, + "firebaseinappmessaging": { + "admin": "roles/firebaseinappmessaging.admin", + "viewer": "roles/firebaseinappmessaging.viewer" + }, + "firebasemessagingcampaigns": { + "admin": "roles/firebasemessagingcampaigns.admin", + "viewer": "roles/firebasemessagingcampaigns.viewer" + }, + "firebaseml": { + "admin": "roles/firebaseml.admin", + "serviceAgent": "roles/firebaseml.serviceAgent", + "viewer": "roles/firebaseml.viewer" + }, + "firebasemods": { + "serviceAgent": "roles/firebasemods.serviceAgent" + }, + "firebasenotifications": { + "admin": "roles/firebasenotifications.admin", + "viewer": "roles/firebasenotifications.viewer" + }, + "firebaseperformance": { + "admin": "roles/firebaseperformance.admin", + "viewer": "roles/firebaseperformance.viewer" + }, + "firebaserules": { + "admin": "roles/firebaserules.admin", + "firestoreServiceAgent": "roles/firebaserules.firestoreServiceAgent", + "system": "roles/firebaserules.system", + "viewer": "roles/firebaserules.viewer" + }, + "firebasestorage": { + "admin": "roles/firebasestorage.admin", + "serviceAgent": "roles/firebasestorage.serviceAgent", + "viewer": "roles/firebasestorage.viewer" + }, + "firestore": { + "serviceAgent": "roles/firestore.serviceAgent" + }, + "firewallinsights": { + "serviceAgent": "roles/firewallinsights.serviceAgent" + }, + "fleetengine": { + "consumerSdkUser": "roles/fleetengine.consumerSdkUser", + "deliveryAdmin": "roles/fleetengine.deliveryAdmin", + "deliveryConsumer": "roles/fleetengine.deliveryConsumer", + "deliveryFleetReader": "roles/fleetengine.deliveryFleetReader", + "deliverySuperUser": "roles/fleetengine.deliverySuperUser", + "deliveryTrustedDriver": "roles/fleetengine.deliveryTrustedDriver", + "deliveryUntrustedDriver": "roles/fleetengine.deliveryUntrustedDriver", + "driverSdkUser": "roles/fleetengine.driverSdkUser", + "ondemandAdmin": "roles/fleetengine.ondemandAdmin", + "serviceAgent": "roles/fleetengine.serviceAgent", + "serviceSuperUser": "roles/fleetengine.serviceSuperUser" + }, + "gameservices": { + "serviceAgent": "roles/gameservices.serviceAgent" + }, + "gdchardwaremanagement": { + "admin": "roles/gdchardwaremanagement.admin", + "operator": "roles/gdchardwaremanagement.operator", + "reader": "roles/gdchardwaremanagement.reader" + }, + "genomics": { + "admin": "roles/genomics.admin", + "editor": "roles/genomics.editor", + "pipelinesRunner": "roles/genomics.pipelinesRunner", + "serviceAgent": "roles/genomics.serviceAgent", + "viewer": "roles/genomics.viewer" + }, + "gkebackup": { + "admin": "roles/gkebackup.admin", + "backupAdmin": "roles/gkebackup.backupAdmin", + "delegatedBackupAdmin": "roles/gkebackup.delegatedBackupAdmin", + "delegatedRestoreAdmin": "roles/gkebackup.delegatedRestoreAdmin", + "restoreAdmin": "roles/gkebackup.restoreAdmin", + "serviceAgent": "roles/gkebackup.serviceAgent", + "viewer": "roles/gkebackup.viewer" + }, + "gkedataplanemanagement": { + "warpRunServiceAgent": "roles/gkedataplanemanagement.warpRunServiceAgent" + }, + "gkehub": { + "admin": "roles/gkehub.admin", + "connect": "roles/gkehub.connect", + "crossProjectServiceAgent": "roles/gkehub.crossProjectServiceAgent", + "editor": "roles/gkehub.editor", + "gatewayAdmin": "roles/gkehub.gatewayAdmin", + "gatewayEditor": "roles/gkehub.gatewayEditor", + "gatewayReader": "roles/gkehub.gatewayReader", + "scopeAdmin": "roles/gkehub.scopeAdmin", + "scopeEditor": "roles/gkehub.scopeEditor", + "scopeEditorProjectLevel": "roles/gkehub.scopeEditorProjectLevel", + "scopeViewer": "roles/gkehub.scopeViewer", + "scopeViewerProjectLevel": "roles/gkehub.scopeViewerProjectLevel", + "serviceAgent": "roles/gkehub.serviceAgent", + "viewer": "roles/gkehub.viewer" + }, + "gkemulticloud": { + "admin": "roles/gkemulticloud.admin", + "containerServiceAgent": "roles/gkemulticloud.containerServiceAgent", + "controlPlaneMachineServiceAgent": "roles/gkemulticloud.controlPlaneMachineServiceAgent", + "nodePoolMachineServiceAgent": "roles/gkemulticloud.nodePoolMachineServiceAgent", + "serviceAgent": "roles/gkemulticloud.serviceAgent", + "telemetryWriter": "roles/gkemulticloud.telemetryWriter", + "viewer": "roles/gkemulticloud.viewer" + }, + "gkeonprem": { + "admin": "roles/gkeonprem.admin", + "serviceAgent": "roles/gkeonprem.serviceAgent", + "viewer": "roles/gkeonprem.viewer" + }, + "gsuiteaddons": { + "developer": "roles/gsuiteaddons.developer", + "reader": "roles/gsuiteaddons.reader", + "tester": "roles/gsuiteaddons.tester" + }, + "healthcare": { + "annotationEditor": "roles/healthcare.annotationEditor", + "annotationReader": "roles/healthcare.annotationReader", + "annotationStoreAdmin": "roles/healthcare.annotationStoreAdmin", + "annotationStoreViewer": "roles/healthcare.annotationStoreViewer", + "attributeDefinitionEditor": "roles/healthcare.attributeDefinitionEditor", + "attributeDefinitionReader": "roles/healthcare.attributeDefinitionReader", + "consentArtifactAdmin": "roles/healthcare.consentArtifactAdmin", + "consentArtifactEditor": "roles/healthcare.consentArtifactEditor", + "consentArtifactReader": "roles/healthcare.consentArtifactReader", + "consentEditor": "roles/healthcare.consentEditor", + "consentReader": "roles/healthcare.consentReader", + "consentStoreAdmin": "roles/healthcare.consentStoreAdmin", + "consentStoreViewer": "roles/healthcare.consentStoreViewer", + "datasetAdmin": "roles/healthcare.datasetAdmin", + "datasetViewer": "roles/healthcare.datasetViewer", + "dicomEditor": "roles/healthcare.dicomEditor", + "dicomStoreAdmin": "roles/healthcare.dicomStoreAdmin", + "dicomStoreViewer": "roles/healthcare.dicomStoreViewer", + "dicomViewer": "roles/healthcare.dicomViewer", + "fhirResourceEditor": "roles/healthcare.fhirResourceEditor", + "fhirResourceReader": "roles/healthcare.fhirResourceReader", + "fhirStoreAdmin": "roles/healthcare.fhirStoreAdmin", + "fhirStoreViewer": "roles/healthcare.fhirStoreViewer", + "hl7V2Consumer": "roles/healthcare.hl7V2Consumer", + "hl7V2Editor": "roles/healthcare.hl7V2Editor", + "hl7V2Ingest": "roles/healthcare.hl7V2Ingest", + "hl7V2StoreAdmin": "roles/healthcare.hl7V2StoreAdmin", + "hl7V2StoreViewer": "roles/healthcare.hl7V2StoreViewer", + "nlpServiceViewer": "roles/healthcare.nlpServiceViewer", + "serviceAgent": "roles/healthcare.serviceAgent", + "userDataMappingEditor": "roles/healthcare.userDataMappingEditor", + "userDataMappingReader": "roles/healthcare.userDataMappingReader" + }, + "iam": { + "denyAdmin": "roles/iam.denyAdmin", + "denyReviewer": "roles/iam.denyReviewer", + "oauthClientAdmin": "roles/iam.oauthClientAdmin", + "oauthClientViewer": "roles/iam.oauthClientViewer", + "operationViewer": "roles/iam.operationViewer", + "organizationRoleAdmin": "roles/iam.organizationRoleAdmin", + "organizationRoleViewer": "roles/iam.organizationRoleViewer", + "principalAccessBoundaryAdmin": "roles/iam.principalAccessBoundaryAdmin", + "principalAccessBoundaryUser": "roles/iam.principalAccessBoundaryUser", + "principalAccessBoundaryViewer": "roles/iam.principalAccessBoundaryViewer", + "roleAdmin": "roles/iam.roleAdmin", + "roleViewer": "roles/iam.roleViewer", + "securityAdmin": "roles/iam.securityAdmin", + "securityReviewer": "roles/iam.securityReviewer", + "serviceAccountAdmin": "roles/iam.serviceAccountAdmin", + "serviceAccountCreator": "roles/iam.serviceAccountCreator", + "serviceAccountDeleter": "roles/iam.serviceAccountDeleter", + "serviceAccountKeyAdmin": "roles/iam.serviceAccountKeyAdmin", + "serviceAccountOpenIdTokenCreator": "roles/iam.serviceAccountOpenIdTokenCreator", + "serviceAccountTokenCreator": "roles/iam.serviceAccountTokenCreator", + "serviceAccountUser": "roles/iam.serviceAccountUser", + "serviceAccountViewer": "roles/iam.serviceAccountViewer", + "workforcePoolAdmin": "roles/iam.workforcePoolAdmin", + "workforcePoolEditor": "roles/iam.workforcePoolEditor", + "workforcePoolViewer": "roles/iam.workforcePoolViewer", + "workloadIdentityPoolAdmin": "roles/iam.workloadIdentityPoolAdmin", + "workloadIdentityPoolViewer": "roles/iam.workloadIdentityPoolViewer", + "workloadIdentityUser": "roles/iam.workloadIdentityUser", + "workspacePoolAdmin": "roles/iam.workspacePoolAdmin" + }, + "iap": { + "admin": "roles/iap.admin", + "httpsResourceAccessor": "roles/iap.httpsResourceAccessor", + "remediatorUser": "roles/iap.remediatorUser", + "settingsAdmin": "roles/iap.settingsAdmin", + "tunnelDestGroupEditor": "roles/iap.tunnelDestGroupEditor", + "tunnelDestGroupViewer": "roles/iap.tunnelDestGroupViewer", + "tunnelResourceAccessor": "roles/iap.tunnelResourceAccessor" + }, + "identityplatform": { + "admin": "roles/identityplatform.admin", + "viewer": "roles/identityplatform.viewer" + }, + "identitytoolkit": { + "admin": "roles/identitytoolkit.admin", + "serviceAgent": "roles/identitytoolkit.serviceAgent", + "viewer": "roles/identitytoolkit.viewer" + }, + "ids": { + "admin": "roles/ids.admin", + "viewer": "roles/ids.viewer" + }, + "integrations": { + "apigeeIntegrationAdminRole": "roles/integrations.apigeeIntegrationAdminRole", + "apigeeIntegrationDeployerRole": "roles/integrations.apigeeIntegrationDeployerRole", + "apigeeIntegrationEditorRole": "roles/integrations.apigeeIntegrationEditorRole", + "apigeeIntegrationInvokerRole": "roles/integrations.apigeeIntegrationInvokerRole", + "apigeeIntegrationsViewer": "roles/integrations.apigeeIntegrationsViewer", + "apigeeSuspensionResolver": "roles/integrations.apigeeSuspensionResolver", + "certificateViewer": "roles/integrations.certificateViewer", + "integrationAdmin": "roles/integrations.integrationAdmin", + "integrationDeployer": "roles/integrations.integrationDeployer", + "integrationEditor": "roles/integrations.integrationEditor", + "integrationInvoker": "roles/integrations.integrationInvoker", + "integrationViewer": "roles/integrations.integrationViewer", + "securityIntegrationAdmin": "roles/integrations.securityIntegrationAdmin", + "serviceAgent": "roles/integrations.serviceAgent", + "sfdcInstanceAdmin": "roles/integrations.sfdcInstanceAdmin", + "sfdcInstanceEditor": "roles/integrations.sfdcInstanceEditor", + "sfdcInstanceViewer": "roles/integrations.sfdcInstanceViewer", + "suspensionResolver": "roles/integrations.suspensionResolver" + }, + "issuerswitch": { + "accountManagerAdmin": "roles/issuerswitch.accountManagerAdmin", + "accountManagerTransactionsAdmin": "roles/issuerswitch.accountManagerTransactionsAdmin", + "accountManagerTransactionsViewer": "roles/issuerswitch.accountManagerTransactionsViewer", + "admin": "roles/issuerswitch.admin", + "issuerParticipantsAdmin": "roles/issuerswitch.issuerParticipantsAdmin", + "resolutionsAdmin": "roles/issuerswitch.resolutionsAdmin", + "rulesAdmin": "roles/issuerswitch.rulesAdmin", + "rulesViewer": "roles/issuerswitch.rulesViewer", + "transactionsViewer": "roles/issuerswitch.transactionsViewer" + }, + "krmapihosting": { + "admin": "roles/krmapihosting.admin", + "anthosApiEndpointServiceAgent": "roles/krmapihosting.anthosApiEndpointServiceAgent", + "serviceAgent": "roles/krmapihosting.serviceAgent", + "viewer": "roles/krmapihosting.viewer" + }, + "kubernetesmetadata": { + "publisher": "roles/kubernetesmetadata.publisher" + }, + "kuberun": { + "eventsControlPlaneServiceAgent": "roles/kuberun.eventsControlPlaneServiceAgent", + "eventsDataPlaneServiceAgent": "roles/kuberun.eventsDataPlaneServiceAgent" + }, + "licensemanager": { + "admin": "roles/licensemanager.admin", + "viewer": "roles/licensemanager.viewer" + }, + "lifesciences": { + "admin": "roles/lifesciences.admin", + "editor": "roles/lifesciences.editor", + "serviceAgent": "roles/lifesciences.serviceAgent", + "viewer": "roles/lifesciences.viewer", + "workflowsRunner": "roles/lifesciences.workflowsRunner" + }, + "livestream": { + "editor": "roles/livestream.editor", + "serviceAgent": "roles/livestream.serviceAgent", + "viewer": "roles/livestream.viewer" + }, + "logging": { + "admin": "roles/logging.admin", + "bucketWriter": "roles/logging.bucketWriter", + "configWriter": "roles/logging.configWriter", + "fieldAccessor": "roles/logging.fieldAccessor", + "linkViewer": "roles/logging.linkViewer", + "logWriter": "roles/logging.logWriter", + "privateLogViewer": "roles/logging.privateLogViewer", + "serviceAgent": "roles/logging.serviceAgent", + "sqlAlertWriter": "roles/logging.sqlAlertWriter", + "viewAccessor": "roles/logging.viewAccessor", + "viewer": "roles/logging.viewer" + }, + "looker": { + "admin": "roles/looker.admin", + "instanceUser": "roles/looker.instanceUser", + "serviceAgent": "roles/looker.serviceAgent", + "viewer": "roles/looker.viewer" + }, + "lookerstudio": { + "lookerAdmin": "roles/lookerstudio.lookerAdmin", + "proManager": "roles/lookerstudio.proManager" + }, + "managedflink": { + "admin": "roles/managedflink.admin", + "developer": "roles/managedflink.developer", + "serviceAgent": "roles/managedflink.serviceAgent", + "viewer": "roles/managedflink.viewer" + }, + "managedidentities": { + "admin": "roles/managedidentities.admin", + "backupAdmin": "roles/managedidentities.backupAdmin", + "backupViewer": "roles/managedidentities.backupViewer", + "domainAdmin": "roles/managedidentities.domainAdmin", + "domainJoin": "roles/managedidentities.domainJoin", + "peeringAdmin": "roles/managedidentities.peeringAdmin", + "peeringViewer": "roles/managedidentities.peeringViewer", + "serviceAgent": "roles/managedidentities.serviceAgent", + "viewer": "roles/managedidentities.viewer" + }, + "managedkafka": { + "admin": "roles/managedkafka.admin", + "client": "roles/managedkafka.client", + "clusterEditor": "roles/managedkafka.clusterEditor", + "consumerGroupEditor": "roles/managedkafka.consumerGroupEditor", + "serviceAgent": "roles/managedkafka.serviceAgent", + "topicEditor": "roles/managedkafka.topicEditor", + "viewer": "roles/managedkafka.viewer" + }, + "mandiant": { + "attackSurfaceManagementEditor": "roles/mandiant.attackSurfaceManagementEditor", + "attackSurfaceManagementViewer": "roles/mandiant.attackSurfaceManagementViewer", + "digitalThreatMonitoringEditor": "roles/mandiant.digitalThreatMonitoringEditor", + "digitalThreatMonitoringViewer": "roles/mandiant.digitalThreatMonitoringViewer", + "expertiseOnDemandEditor": "roles/mandiant.expertiseOnDemandEditor", + "expertiseOnDemandViewer": "roles/mandiant.expertiseOnDemandViewer", + "threatIntelEditor": "roles/mandiant.threatIntelEditor", + "threatIntelViewer": "roles/mandiant.threatIntelViewer", + "validationEditor": "roles/mandiant.validationEditor", + "validationViewer": "roles/mandiant.validationViewer" + }, + "mapsadmin": { + "admin": "roles/mapsadmin.admin", + "viewer": "roles/mapsadmin.viewer" + }, + "mapsanalytics": { + "mobilitySolutionsOverageViewer": "roles/mapsanalytics.mobilitySolutionsOverageViewer", + "viewer": "roles/mapsanalytics.viewer" + }, + "mapsplatformdatasets": { + "admin": "roles/mapsplatformdatasets.admin", + "viewer": "roles/mapsplatformdatasets.viewer" + }, + "marketplacesolutions": { + "admin": "roles/marketplacesolutions.admin", + "editor": "roles/marketplacesolutions.editor", + "viewer": "roles/marketplacesolutions.viewer" + }, + "mediaasset": { + "serviceAgent": "roles/mediaasset.serviceAgent" + }, + "memcache": { + "admin": "roles/memcache.admin", + "editor": "roles/memcache.editor", + "serviceAgent": "roles/memcache.serviceAgent", + "viewer": "roles/memcache.viewer" + }, + "memorystore": { + "admin": "roles/memorystore.admin", + "dbConnectionUser": "roles/memorystore.dbConnectionUser", + "serviceAgent": "roles/memorystore.serviceAgent", + "viewer": "roles/memorystore.viewer" + }, + "meshconfig": { + "admin": "roles/meshconfig.admin", + "serviceAgent": "roles/meshconfig.serviceAgent", + "viewer": "roles/meshconfig.viewer" + }, + "meshcontrolplane": { + "serviceAgent": "roles/meshcontrolplane.serviceAgent" + }, + "meshdataplane": { + "serviceAgent": "roles/meshdataplane.serviceAgent" + }, + "metastore": { + "admin": "roles/metastore.admin", + "editor": "roles/metastore.editor", + "federationAccessor": "roles/metastore.federationAccessor", + "metadataEditor": "roles/metastore.metadataEditor", + "metadataMutateAdmin": "roles/metastore.metadataMutateAdmin", + "metadataOperator": "roles/metastore.metadataOperator", + "metadataOwner": "roles/metastore.metadataOwner", + "metadataQueryAdmin": "roles/metastore.metadataQueryAdmin", + "metadataUser": "roles/metastore.metadataUser", + "metadataViewer": "roles/metastore.metadataViewer", + "migrationAdmin": "roles/metastore.migrationAdmin", + "serviceAgent": "roles/metastore.serviceAgent", + "user": "roles/metastore.user" + }, + "migrationcenter": { + "admin": "roles/migrationcenter.admin", + "discoveryClient": "roles/migrationcenter.discoveryClient", + "discoveryClientRegistrator": "roles/migrationcenter.discoveryClientRegistrator", + "serviceAgent": "roles/migrationcenter.serviceAgent", + "viewer": "roles/migrationcenter.viewer" + }, + "ml": { + "admin": "roles/ml.admin", + "developer": "roles/ml.developer", + "jobOwner": "roles/ml.jobOwner", + "modelOwner": "roles/ml.modelOwner", + "modelUser": "roles/ml.modelUser", + "operationOwner": "roles/ml.operationOwner", + "serviceAgent": "roles/ml.serviceAgent", + "viewer": "roles/ml.viewer" + }, + "monitoring": { + "admin": "roles/monitoring.admin", + "alertPolicyEditor": "roles/monitoring.alertPolicyEditor", + "alertPolicyViewer": "roles/monitoring.alertPolicyViewer", + "cloudConsoleIncidentEditor": "roles/monitoring.cloudConsoleIncidentEditor", + "cloudConsoleIncidentViewer": "roles/monitoring.cloudConsoleIncidentViewer", + "dashboardEditor": "roles/monitoring.dashboardEditor", + "dashboardViewer": "roles/monitoring.dashboardViewer", + "editor": "roles/monitoring.editor", + "metricWriter": "roles/monitoring.metricWriter", + "metricsScopesAdmin": "roles/monitoring.metricsScopesAdmin", + "metricsScopesViewer": "roles/monitoring.metricsScopesViewer", + "notificationChannelEditor": "roles/monitoring.notificationChannelEditor", + "notificationChannelViewer": "roles/monitoring.notificationChannelViewer", + "notificationServiceAgent": "roles/monitoring.notificationServiceAgent", + "servicesEditor": "roles/monitoring.servicesEditor", + "servicesViewer": "roles/monitoring.servicesViewer", + "snoozeEditor": "roles/monitoring.snoozeEditor", + "snoozeViewer": "roles/monitoring.snoozeViewer", + "uptimeCheckConfigEditor": "roles/monitoring.uptimeCheckConfigEditor", + "uptimeCheckConfigViewer": "roles/monitoring.uptimeCheckConfigViewer", + "viewer": "roles/monitoring.viewer" + }, + "multiclusteringress": { + "serviceAgent": "roles/multiclusteringress.serviceAgent" + }, + "multiclustermetering": { + "serviceAgent": "roles/multiclustermetering.serviceAgent" + }, + "multiclusterservicediscovery": { + "serviceAgent": "roles/multiclusterservicediscovery.serviceAgent" + }, + "nestconsole": { + "homeDeveloperAdmin": "roles/nestconsole.homeDeveloperAdmin", + "homeDeveloperEditor": "roles/nestconsole.homeDeveloperEditor", + "homeDeveloperViewer": "roles/nestconsole.homeDeveloperViewer" + }, + "netapp": { + "admin": "roles/netapp.admin", + "viewer": "roles/netapp.viewer" + }, + "netappcloudvolumes": { + "admin": "roles/netappcloudvolumes.admin", + "viewer": "roles/netappcloudvolumes.viewer" + }, + "networkactions": { + "serviceAgent": "roles/networkactions.serviceAgent" + }, + "networkconnectivity": { + "consumerNetworkAdmin": "roles/networkconnectivity.consumerNetworkAdmin", + "groupUser": "roles/networkconnectivity.groupUser", + "hubAdmin": "roles/networkconnectivity.hubAdmin", + "hubViewer": "roles/networkconnectivity.hubViewer", + "regionalEndpointAdmin": "roles/networkconnectivity.regionalEndpointAdmin", + "regionalEndpointViewer": "roles/networkconnectivity.regionalEndpointViewer", + "serviceAgent": "roles/networkconnectivity.serviceAgent", + "serviceClassUser": "roles/networkconnectivity.serviceClassUser", + "serviceProducerAdmin": "roles/networkconnectivity.serviceProducerAdmin", + "spokeAdmin": "roles/networkconnectivity.spokeAdmin" + }, + "networkmanagement": { + "admin": "roles/networkmanagement.admin", + "serviceAgent": "roles/networkmanagement.serviceAgent", + "viewer": "roles/networkmanagement.viewer" + }, + "networksecurity": { + "mirroringDeploymentAdmin": "roles/networksecurity.mirroringDeploymentAdmin", + "mirroringDeploymentUser": "roles/networksecurity.mirroringDeploymentUser", + "mirroringDeploymentViewer": "roles/networksecurity.mirroringDeploymentViewer", + "mirroringEndpointAdmin": "roles/networksecurity.mirroringEndpointAdmin", + "mirroringEndpointUser": "roles/networksecurity.mirroringEndpointUser", + "mirroringEndpointViewer": "roles/networksecurity.mirroringEndpointViewer" + }, + "networkservices": { + "serviceExtensionsAdmin": "roles/networkservices.serviceExtensionsAdmin", + "serviceExtensionsViewer": "roles/networkservices.serviceExtensionsViewer" + }, + "notebooks": { + "admin": "roles/notebooks.admin", + "legacyAdmin": "roles/notebooks.legacyAdmin", + "legacyViewer": "roles/notebooks.legacyViewer", + "runner": "roles/notebooks.runner", + "serviceAgent": "roles/notebooks.serviceAgent", + "viewer": "roles/notebooks.viewer" + }, + "oauthconfig": { + "editor": "roles/oauthconfig.editor", + "viewer": "roles/oauthconfig.viewer" + }, + "observability": { + "admin": "roles/observability.admin", + "editor": "roles/observability.editor", + "viewer": "roles/observability.viewer" + }, + "oci": { + "serviceAgent": "roles/oci.serviceAgent" + }, + "ondemandscanning": { + "admin": "roles/ondemandscanning.admin", + "serviceAgent": "roles/ondemandscanning.serviceAgent" + }, + "opsconfigmonitoring": { + "resourceMetadata.viewer": "roles/opsconfigmonitoring.resourceMetadata.viewer", + "resourceMetadata.writer": "roles/opsconfigmonitoring.resourceMetadata.writer" + }, + "oracledatabase": { + "admin": "roles/oracledatabase.admin", + "autonomousDatabaseAdmin": "roles/oracledatabase.autonomousDatabaseAdmin", + "autonomousDatabaseViewer": "roles/oracledatabase.autonomousDatabaseViewer", + "cloudExadataInfrastructureAdmin": "roles/oracledatabase.cloudExadataInfrastructureAdmin", + "cloudExadataInfrastructureViewer": "roles/oracledatabase.cloudExadataInfrastructureViewer", + "cloudVmClusterAdmin": "roles/oracledatabase.cloudVmClusterAdmin", + "cloudVmClusterViewer": "roles/oracledatabase.cloudVmClusterViewer", + "viewer": "roles/oracledatabase.viewer" + }, + "orgpolicy": { + "policyAdmin": "roles/orgpolicy.policyAdmin", + "policyViewer": "roles/orgpolicy.policyViewer" + }, + "osconfig": { + "admin": "roles/osconfig.admin", + "guestPolicyAdmin": "roles/osconfig.guestPolicyAdmin", + "guestPolicyEditor": "roles/osconfig.guestPolicyEditor", + "guestPolicyViewer": "roles/osconfig.guestPolicyViewer", + "instanceOSPoliciesComplianceViewer": "roles/osconfig.instanceOSPoliciesComplianceViewer", + "inventoryViewer": "roles/osconfig.inventoryViewer", + "osPolicyAssignmentAdmin": "roles/osconfig.osPolicyAssignmentAdmin", + "osPolicyAssignmentEditor": "roles/osconfig.osPolicyAssignmentEditor", + "osPolicyAssignmentReportViewer": "roles/osconfig.osPolicyAssignmentReportViewer", + "osPolicyAssignmentViewer": "roles/osconfig.osPolicyAssignmentViewer", + "patchDeploymentAdmin": "roles/osconfig.patchDeploymentAdmin", + "patchDeploymentViewer": "roles/osconfig.patchDeploymentViewer", + "patchJobExecutor": "roles/osconfig.patchJobExecutor", + "patchJobViewer": "roles/osconfig.patchJobViewer", + "policyOrchestratorAdmin": "roles/osconfig.policyOrchestratorAdmin", + "policyOrchestratorViewer": "roles/osconfig.policyOrchestratorViewer", + "projectFeatureSettingsEditor": "roles/osconfig.projectFeatureSettingsEditor", + "projectFeatureSettingsViewer": "roles/osconfig.projectFeatureSettingsViewer", + "serviceAgent": "roles/osconfig.serviceAgent", + "upgradeReportViewer": "roles/osconfig.upgradeReportViewer", + "viewer": "roles/osconfig.viewer", + "vulnerabilityReportViewer": "roles/osconfig.vulnerabilityReportViewer" + }, + "owner": { + "": "roles/owner" + }, + "parallelstore": { + "admin": "roles/parallelstore.admin", + "serviceAgent": "roles/parallelstore.serviceAgent", + "viewer": "roles/parallelstore.viewer" + }, + "paymentsresellersubscription": { + "partnerAdmin": "roles/paymentsresellersubscription.partnerAdmin", + "partnerViewer": "roles/paymentsresellersubscription.partnerViewer", + "productViewer": "roles/paymentsresellersubscription.productViewer", + "promotionViewer": "roles/paymentsresellersubscription.promotionViewer", + "subscriptionEditor": "roles/paymentsresellersubscription.subscriptionEditor", + "subscriptionViewer": "roles/paymentsresellersubscription.subscriptionViewer", + "userSessionEditor": "roles/paymentsresellersubscription.userSessionEditor" + }, + "policyanalyzer": { + "activityAnalysisViewer": "roles/policyanalyzer.activityAnalysisViewer" + }, + "policyremediatormanager": { + "policyRemediatorAdmin": "roles/policyremediatormanager.policyRemediatorAdmin", + "policyRemediatorReader": "roles/policyremediatormanager.policyRemediatorReader" + }, + "policysimulator": { + "admin": "roles/policysimulator.admin", + "orgPolicyAdmin": "roles/policysimulator.orgPolicyAdmin" + }, + "privateca": { + "admin": "roles/privateca.admin", + "auditor": "roles/privateca.auditor", + "caManager": "roles/privateca.caManager", + "certificateManager": "roles/privateca.certificateManager", + "certificateRequester": "roles/privateca.certificateRequester", + "poolReader": "roles/privateca.poolReader", + "templateUser": "roles/privateca.templateUser", + "workloadCertificateRequester": "roles/privateca.workloadCertificateRequester" + }, + "privilegedaccessmanager": { + "admin": "roles/privilegedaccessmanager.admin", + "folderServiceAgent": "roles/privilegedaccessmanager.folderServiceAgent", + "organizationServiceAgent": "roles/privilegedaccessmanager.organizationServiceAgent", + "projectServiceAgent": "roles/privilegedaccessmanager.projectServiceAgent", + "serviceAgent": "roles/privilegedaccessmanager.serviceAgent", + "viewer": "roles/privilegedaccessmanager.viewer" + }, + "progressiverollout": { + "serviceAgent": "roles/progressiverollout.serviceAgent" + }, + "proximitybeacon": { + "attachmentEditor": "roles/proximitybeacon.attachmentEditor", + "attachmentPublisher": "roles/proximitybeacon.attachmentPublisher", + "attachmentViewer": "roles/proximitybeacon.attachmentViewer", + "beaconEditor": "roles/proximitybeacon.beaconEditor" + }, + "publicca": { + "externalAccountKeyCreator": "roles/publicca.externalAccountKeyCreator" + }, + "pubsub": { + "admin": "roles/pubsub.admin", + "editor": "roles/pubsub.editor", + "publisher": "roles/pubsub.publisher", + "serviceAgent": "roles/pubsub.serviceAgent", + "subscriber": "roles/pubsub.subscriber", + "viewer": "roles/pubsub.viewer" + }, + "pubsublite": { + "admin": "roles/pubsublite.admin", + "editor": "roles/pubsublite.editor", + "publisher": "roles/pubsublite.publisher", + "serviceAgent": "roles/pubsublite.serviceAgent", + "subscriber": "roles/pubsublite.subscriber", + "viewer": "roles/pubsublite.viewer" + }, + "rapidmigrationassessment": { + "serviceAgent": "roles/rapidmigrationassessment.serviceAgent" + }, + "readerrevenuesubscriptionlinking": { + "admin": "roles/readerrevenuesubscriptionlinking.admin", + "entitlementsViewer": "roles/readerrevenuesubscriptionlinking.entitlementsViewer", + "viewer": "roles/readerrevenuesubscriptionlinking.viewer" + }, + "recaptchaenterprise": { + "admin": "roles/recaptchaenterprise.admin", + "agent": "roles/recaptchaenterprise.agent", + "viewer": "roles/recaptchaenterprise.viewer" + }, + "recommender": { + "alloydbAdmin": "roles/recommender.alloydbAdmin", + "alloydbViewer": "roles/recommender.alloydbViewer", + "bigQueryCapacityCommitmentsAdmin": "roles/recommender.bigQueryCapacityCommitmentsAdmin", + "bigQueryCapacityCommitmentsBillingAccountAdmin": "roles/recommender.bigQueryCapacityCommitmentsBillingAccountAdmin", + "bigQueryCapacityCommitmentsBillingAccountViewer": "roles/recommender.bigQueryCapacityCommitmentsBillingAccountViewer", + "bigQueryCapacityCommitmentsProjectAdmin": "roles/recommender.bigQueryCapacityCommitmentsProjectAdmin", + "bigQueryCapacityCommitmentsProjectViewer": "roles/recommender.bigQueryCapacityCommitmentsProjectViewer", + "bigQueryCapacityCommitmentsViewer": "roles/recommender.bigQueryCapacityCommitmentsViewer", + "bigqueryMaterializedViewAdmin": "roles/recommender.bigqueryMaterializedViewAdmin", + "bigqueryMaterializedViewViewer": "roles/recommender.bigqueryMaterializedViewViewer", + "bigqueryPartitionClusterAdmin": "roles/recommender.bigqueryPartitionClusterAdmin", + "bigqueryPartitionClusterViewer": "roles/recommender.bigqueryPartitionClusterViewer", + "billingAccountCudAdmin": "roles/recommender.billingAccountCudAdmin", + "billingAccountCudViewer": "roles/recommender.billingAccountCudViewer", + "cloudAssetInsightsAdmin": "roles/recommender.cloudAssetInsightsAdmin", + "cloudAssetInsightsViewer": "roles/recommender.cloudAssetInsightsViewer", + "cloudCostRecommendationAdmin": "roles/recommender.cloudCostRecommendationAdmin", + "cloudCostRecommendationViewer": "roles/recommender.cloudCostRecommendationViewer", + "cloudDeprecationRecommendationAdmin": "roles/recommender.cloudDeprecationRecommendationAdmin", + "cloudDeprecationRecommendationViewer": "roles/recommender.cloudDeprecationRecommendationViewer", + "cloudManageabilityRecommendationAdmin": "roles/recommender.cloudManageabilityRecommendationAdmin", + "cloudManageabilityRecommendationViewer": "roles/recommender.cloudManageabilityRecommendationViewer", + "cloudPerformanceRecommendationAdmin": "roles/recommender.cloudPerformanceRecommendationAdmin", + "cloudPerformanceRecommendationViewer": "roles/recommender.cloudPerformanceRecommendationViewer", + "cloudReliabilityRecommendationAdmin": "roles/recommender.cloudReliabilityRecommendationAdmin", + "cloudReliabilityRecommendationViewer": "roles/recommender.cloudReliabilityRecommendationViewer", + "cloudSecurityRecommendationAdmin": "roles/recommender.cloudSecurityRecommendationAdmin", + "cloudSecurityRecommendationViewer": "roles/recommender.cloudSecurityRecommendationViewer", + "cloudsqlAdmin": "roles/recommender.cloudsqlAdmin", + "cloudsqlViewer": "roles/recommender.cloudsqlViewer", + "computeAdmin": "roles/recommender.computeAdmin", + "computeViewer": "roles/recommender.computeViewer", + "containerDiagnosisAdmin": "roles/recommender.containerDiagnosisAdmin", + "containerDiagnosisViewer": "roles/recommender.containerDiagnosisViewer", + "dataflowDiagnosticsAdmin": "roles/recommender.dataflowDiagnosticsAdmin", + "dataflowDiagnosticsViewer": "roles/recommender.dataflowDiagnosticsViewer", + "errorReportingAdmin": "roles/recommender.errorReportingAdmin", + "errorReportingViewer": "roles/recommender.errorReportingViewer", + "exporter": "roles/recommender.exporter", + "firestoredatabasereliabilityAdmin": "roles/recommender.firestoredatabasereliabilityAdmin", + "firestoredatabasereliabilityViewer": "roles/recommender.firestoredatabasereliabilityViewer", + "firewallAdmin": "roles/recommender.firewallAdmin", + "firewallViewer": "roles/recommender.firewallViewer", + "gmpAdmin": "roles/recommender.gmpAdmin", + "gmpViewer": "roles/recommender.gmpViewer", + "iamAdmin": "roles/recommender.iamAdmin", + "iamViewer": "roles/recommender.iamViewer", + "iampolicychangeriskAdmin": "roles/recommender.iampolicychangeriskAdmin", + "iampolicychangeriskViewer": "roles/recommender.iampolicychangeriskViewer", + "networkAnalyzerAdmin": "roles/recommender.networkAnalyzerAdmin", + "networkAnalyzerCloudSqlAdmin": "roles/recommender.networkAnalyzerCloudSqlAdmin", + "networkAnalyzerCloudSqlViewer": "roles/recommender.networkAnalyzerCloudSqlViewer", + "networkAnalyzerDynamicRouteAdmin": "roles/recommender.networkAnalyzerDynamicRouteAdmin", + "networkAnalyzerDynamicRouteViewer": "roles/recommender.networkAnalyzerDynamicRouteViewer", + "networkAnalyzerGkeConnectivityAdmin": "roles/recommender.networkAnalyzerGkeConnectivityAdmin", + "networkAnalyzerGkeConnectivityViewer": "roles/recommender.networkAnalyzerGkeConnectivityViewer", + "networkAnalyzerGkeIpAddressAdmin": "roles/recommender.networkAnalyzerGkeIpAddressAdmin", + "networkAnalyzerGkeIpAddressViewer": "roles/recommender.networkAnalyzerGkeIpAddressViewer", + "networkAnalyzerGkeServiceAccountAdmin": "roles/recommender.networkAnalyzerGkeServiceAccountAdmin", + "networkAnalyzerGkeServiceAccountViewer": "roles/recommender.networkAnalyzerGkeServiceAccountViewer", + "networkAnalyzerIpAddressAdmin": "roles/recommender.networkAnalyzerIpAddressAdmin", + "networkAnalyzerIpAddressViewer": "roles/recommender.networkAnalyzerIpAddressViewer", + "networkAnalyzerLoadBalancerAdmin": "roles/recommender.networkAnalyzerLoadBalancerAdmin", + "networkAnalyzerLoadBalancerViewer": "roles/recommender.networkAnalyzerLoadBalancerViewer", + "networkAnalyzerViewer": "roles/recommender.networkAnalyzerViewer", + "networkAnalyzerVpcConnectivityAdmin": "roles/recommender.networkAnalyzerVpcConnectivityAdmin", + "networkAnalyzerVpcConnectivityViewer": "roles/recommender.networkAnalyzerVpcConnectivityViewer", + "productSuggestionAdmin": "roles/recommender.productSuggestionAdmin", + "productSuggestionViewer": "roles/recommender.productSuggestionViewer", + "projectCudAdmin": "roles/recommender.projectCudAdmin", + "projectCudViewer": "roles/recommender.projectCudViewer", + "projectUtilAdmin": "roles/recommender.projectUtilAdmin", + "projectUtilViewer": "roles/recommender.projectUtilViewer", + "recentChangeConfigAdmin": "roles/recommender.recentChangeConfigAdmin", + "recentchangeriskAdmin": "roles/recommender.recentchangeriskAdmin", + "recentchangeriskViewer": "roles/recommender.recentchangeriskViewer", + "serviceLimitAdmin": "roles/recommender.serviceLimitAdmin", + "serviceLimitViewer": "roles/recommender.serviceLimitViewer", + "serviceaccntchangeriskAdmin": "roles/recommender.serviceaccntchangeriskAdmin", + "serviceaccntchangeriskViewer": "roles/recommender.serviceaccntchangeriskViewer", + "ucsAdmin": "roles/recommender.ucsAdmin", + "ucsViewer": "roles/recommender.ucsViewer", + "viewer": "roles/recommender.viewer" + }, + "redis": { + "admin": "roles/redis.admin", + "dbConnectionUser": "roles/redis.dbConnectionUser", + "editor": "roles/redis.editor", + "serviceAgent": "roles/redis.serviceAgent", + "viewer": "roles/redis.viewer" + }, + "redisenterprisecloud": { + "admin": "roles/redisenterprisecloud.admin", + "viewer": "roles/redisenterprisecloud.viewer" + }, + "remotebuildexecution": { + "actionCacheWriter": "roles/remotebuildexecution.actionCacheWriter", + "artifactAdmin": "roles/remotebuildexecution.artifactAdmin", + "artifactCreator": "roles/remotebuildexecution.artifactCreator", + "artifactViewer": "roles/remotebuildexecution.artifactViewer", + "configurationAdmin": "roles/remotebuildexecution.configurationAdmin", + "configurationViewer": "roles/remotebuildexecution.configurationViewer", + "logstreamWriter": "roles/remotebuildexecution.logstreamWriter", + "reservationAdmin": "roles/remotebuildexecution.reservationAdmin", + "serviceAgent": "roles/remotebuildexecution.serviceAgent", + "worker": "roles/remotebuildexecution.worker" + }, + "remotingcloud": { + "serviceAgent": "roles/remotingcloud.serviceAgent" + }, + "resourcemanager": { + "folderAdmin": "roles/resourcemanager.folderAdmin", + "folderCreator": "roles/resourcemanager.folderCreator", + "folderEditor": "roles/resourcemanager.folderEditor", + "folderIamAdmin": "roles/resourcemanager.folderIamAdmin", + "folderMover": "roles/resourcemanager.folderMover", + "folderViewer": "roles/resourcemanager.folderViewer", + "lienModifier": "roles/resourcemanager.lienModifier", + "organizationAdmin": "roles/resourcemanager.organizationAdmin", + "organizationViewer": "roles/resourcemanager.organizationViewer", + "projectCreator": "roles/resourcemanager.projectCreator", + "projectDeleter": "roles/resourcemanager.projectDeleter", + "projectIamAdmin": "roles/resourcemanager.projectIamAdmin", + "projectMover": "roles/resourcemanager.projectMover", + "tagAdmin": "roles/resourcemanager.tagAdmin", + "tagHoldAdmin": "roles/resourcemanager.tagHoldAdmin", + "tagUser": "roles/resourcemanager.tagUser", + "tagViewer": "roles/resourcemanager.tagViewer" + }, + "resourcesettings": { + "admin": "roles/resourcesettings.admin", + "viewer": "roles/resourcesettings.viewer" + }, + "retail": { + "admin": "roles/retail.admin", + "editor": "roles/retail.editor", + "serviceAgent": "roles/retail.serviceAgent", + "viewer": "roles/retail.viewer" + }, + "riscconfigs": { + "admin": "roles/riscconfigs.admin", + "viewer": "roles/riscconfigs.viewer" + }, + "riskmanager": { + "admin": "roles/riskmanager.admin", + "editor": "roles/riskmanager.editor", + "reviewer": "roles/riskmanager.reviewer", + "serviceAgent": "roles/riskmanager.serviceAgent", + "viewer": "roles/riskmanager.viewer" + }, + "rma": { + "admin": "roles/rma.admin", + "runner": "roles/rma.runner", + "viewer": "roles/rma.viewer" + }, + "routeoptimization": { + "editor": "roles/routeoptimization.editor", + "serviceAgent": "roles/routeoptimization.serviceAgent", + "viewer": "roles/routeoptimization.viewer" + }, + "run": { + "admin": "roles/run.admin", + "builder": "roles/run.builder", + "developer": "roles/run.developer", + "invoker": "roles/run.invoker", + "jobsExecutor": "roles/run.jobsExecutor", + "jobsExecutorWithOverrides": "roles/run.jobsExecutorWithOverrides", + "serviceAgent": "roles/run.serviceAgent", + "servicesInvoker": "roles/run.servicesInvoker", + "sourceDeveloper": "roles/run.sourceDeveloper", + "sourceViewer": "roles/run.sourceViewer", + "viewer": "roles/run.viewer" + }, + "runapps": { + "developer": "roles/runapps.developer", + "operator": "roles/runapps.operator", + "serviceAgent": "roles/runapps.serviceAgent", + "viewer": "roles/runapps.viewer" + }, + "runtimeconfig": { + "admin": "roles/runtimeconfig.admin" + }, + "seclm": { + "serviceAgent": "roles/seclm.serviceAgent" + }, + "secretmanager": { + "admin": "roles/secretmanager.admin", + "secretAccessor": "roles/secretmanager.secretAccessor", + "secretVersionAdder": "roles/secretmanager.secretVersionAdder", + "secretVersionManager": "roles/secretmanager.secretVersionManager", + "viewer": "roles/secretmanager.viewer" + }, + "securedlandingzone": { + "bqdwOrgRemediator": "roles/securedlandingzone.bqdwOrgRemediator", + "bqdwProjectRemediator": "roles/securedlandingzone.bqdwProjectRemediator", + "overwatchActivator": "roles/securedlandingzone.overwatchActivator", + "overwatchAdmin": "roles/securedlandingzone.overwatchAdmin", + "overwatchViewer": "roles/securedlandingzone.overwatchViewer", + "serviceAgent": "roles/securedlandingzone.serviceAgent" + }, + "securesourcemanager": { + "admin": "roles/securesourcemanager.admin", + "instanceAccessor": "roles/securesourcemanager.instanceAccessor", + "instanceManager": "roles/securesourcemanager.instanceManager", + "instanceOwner": "roles/securesourcemanager.instanceOwner", + "instanceRepositoryCreator": "roles/securesourcemanager.instanceRepositoryCreator", + "repoAdmin": "roles/securesourcemanager.repoAdmin", + "repoCreator": "roles/securesourcemanager.repoCreator", + "repoPullRequestApprover": "roles/securesourcemanager.repoPullRequestApprover", + "repoReader": "roles/securesourcemanager.repoReader", + "repoWriter": "roles/securesourcemanager.repoWriter", + "serviceAgent": "roles/securesourcemanager.serviceAgent", + "sshKeyUser": "roles/securesourcemanager.sshKeyUser" + }, + "securitycenter": { + "admin": "roles/securitycenter.admin", + "adminEditor": "roles/securitycenter.adminEditor", + "adminViewer": "roles/securitycenter.adminViewer", + "assetSecurityMarksWriter": "roles/securitycenter.assetSecurityMarksWriter", + "assetsDiscoveryRunner": "roles/securitycenter.assetsDiscoveryRunner", + "assetsViewer": "roles/securitycenter.assetsViewer", + "attackPathsViewer": "roles/securitycenter.attackPathsViewer", + "attackSurfaceManagementScannerServiceAgent": "roles/securitycenter.attackSurfaceManagementScannerServiceAgent", + "automationServiceAgent": "roles/securitycenter.automationServiceAgent", + "bigQueryExportsEditor": "roles/securitycenter.bigQueryExportsEditor", + "bigQueryExportsViewer": "roles/securitycenter.bigQueryExportsViewer", + "complianceReportsViewer": "roles/securitycenter.complianceReportsViewer", + "complianceSnapshotsViewer": "roles/securitycenter.complianceSnapshotsViewer", + "controlServiceAgent": "roles/securitycenter.controlServiceAgent", + "externalSystemsEditor": "roles/securitycenter.externalSystemsEditor", + "findingSecurityMarksWriter": "roles/securitycenter.findingSecurityMarksWriter", + "findingsBulkMuteEditor": "roles/securitycenter.findingsBulkMuteEditor", + "findingsEditor": "roles/securitycenter.findingsEditor", + "findingsMuteSetter": "roles/securitycenter.findingsMuteSetter", + "findingsStateSetter": "roles/securitycenter.findingsStateSetter", + "findingsViewer": "roles/securitycenter.findingsViewer", + "findingsWorkflowStateSetter": "roles/securitycenter.findingsWorkflowStateSetter", + "integrationExecutorServiceAgent": "roles/securitycenter.integrationExecutorServiceAgent", + "muteConfigsEditor": "roles/securitycenter.muteConfigsEditor", + "muteConfigsViewer": "roles/securitycenter.muteConfigsViewer", + "notificationConfigEditor": "roles/securitycenter.notificationConfigEditor", + "notificationConfigViewer": "roles/securitycenter.notificationConfigViewer", + "notificationServiceAgent": "roles/securitycenter.notificationServiceAgent", + "resourceValueConfigsEditor": "roles/securitycenter.resourceValueConfigsEditor", + "resourceValueConfigsViewer": "roles/securitycenter.resourceValueConfigsViewer", + "securityHealthAnalyticsCustomModulesTester": "roles/securitycenter.securityHealthAnalyticsCustomModulesTester", + "securityHealthAnalyticsServiceAgent": "roles/securitycenter.securityHealthAnalyticsServiceAgent", + "securityResponseServiceAgent": "roles/securitycenter.securityResponseServiceAgent", + "serviceAgent": "roles/securitycenter.serviceAgent", + "settingsAdmin": "roles/securitycenter.settingsAdmin", + "settingsEditor": "roles/securitycenter.settingsEditor", + "settingsViewer": "roles/securitycenter.settingsViewer", + "simulationsViewer": "roles/securitycenter.simulationsViewer", + "sourcesAdmin": "roles/securitycenter.sourcesAdmin", + "sourcesEditor": "roles/securitycenter.sourcesEditor", + "sourcesViewer": "roles/securitycenter.sourcesViewer", + "valuedResourcesViewer": "roles/securitycenter.valuedResourcesViewer" + }, + "securitycentermanagement": { + "admin": "roles/securitycentermanagement.admin", + "customModulesEditor": "roles/securitycentermanagement.customModulesEditor", + "customModulesViewer": "roles/securitycentermanagement.customModulesViewer", + "etdCustomModulesEditor": "roles/securitycentermanagement.etdCustomModulesEditor", + "etdCustomModulesViewer": "roles/securitycentermanagement.etdCustomModulesViewer", + "securityCenterServicesEditor": "roles/securitycentermanagement.securityCenterServicesEditor", + "securityCenterServicesViewer": "roles/securitycentermanagement.securityCenterServicesViewer", + "settingsEditor": "roles/securitycentermanagement.settingsEditor", + "settingsViewer": "roles/securitycentermanagement.settingsViewer", + "shaCustomModulesEditor": "roles/securitycentermanagement.shaCustomModulesEditor", + "shaCustomModulesViewer": "roles/securitycentermanagement.shaCustomModulesViewer", + "viewer": "roles/securitycentermanagement.viewer" + }, + "securityposture": { + "admin": "roles/securityposture.admin", + "postureDeployer": "roles/securityposture.postureDeployer", + "postureDeploymentsViewer": "roles/securityposture.postureDeploymentsViewer", + "postureEditor": "roles/securityposture.postureEditor", + "postureViewer": "roles/securityposture.postureViewer", + "reportCreator": "roles/securityposture.reportCreator", + "viewer": "roles/securityposture.viewer" + }, + "serverless": { + "serviceAgent": "roles/serverless.serviceAgent" + }, + "servicebroker": { + "admin": "roles/servicebroker.admin", + "operator": "roles/servicebroker.operator" + }, + "serviceconsumermanagement": { + "tenancyUnitsAdmin": "roles/serviceconsumermanagement.tenancyUnitsAdmin", + "tenancyUnitsViewer": "roles/serviceconsumermanagement.tenancyUnitsViewer" + }, + "servicedirectory": { + "admin": "roles/servicedirectory.admin", + "editor": "roles/servicedirectory.editor", + "networkAttacher": "roles/servicedirectory.networkAttacher", + "pscAuthorizedService": "roles/servicedirectory.pscAuthorizedService", + "serviceAgent": "roles/servicedirectory.serviceAgent", + "viewer": "roles/servicedirectory.viewer" + }, + "servicehealth": { + "viewer": "roles/servicehealth.viewer" + }, + "servicemanagement": { + "admin": "roles/servicemanagement.admin", + "configEditor": "roles/servicemanagement.configEditor", + "quotaAdmin": "roles/servicemanagement.quotaAdmin", + "quotaViewer": "roles/servicemanagement.quotaViewer", + "reporter": "roles/servicemanagement.reporter", + "serviceConsumer": "roles/servicemanagement.serviceConsumer", + "serviceController": "roles/servicemanagement.serviceController" + }, + "servicenetworking": { + "networksAdmin": "roles/servicenetworking.networksAdmin", + "serviceAgent": "roles/servicenetworking.serviceAgent" + }, + "servicesecurityinsights": { + "securityInsightsViewer": "roles/servicesecurityinsights.securityInsightsViewer" + }, + "serviceusage": { + "apiKeysAdmin": "roles/serviceusage.apiKeysAdmin", + "apiKeysViewer": "roles/serviceusage.apiKeysViewer", + "serviceUsageAdmin": "roles/serviceusage.serviceUsageAdmin", + "serviceUsageConsumer": "roles/serviceusage.serviceUsageConsumer", + "serviceUsageViewer": "roles/serviceusage.serviceUsageViewer" + }, + "source": { + "admin": "roles/source.admin", + "reader": "roles/source.reader", + "writer": "roles/source.writer" + }, + "sourcerepo": { + "serviceAgent": "roles/sourcerepo.serviceAgent" + }, + "spanner": { + "admin": "roles/spanner.admin", + "backupAdmin": "roles/spanner.backupAdmin", + "backupWriter": "roles/spanner.backupWriter", + "databaseAdmin": "roles/spanner.databaseAdmin", + "databaseReader": "roles/spanner.databaseReader", + "databaseReaderWithDataBoost": "roles/spanner.databaseReaderWithDataBoost", + "databaseRoleUser": "roles/spanner.databaseRoleUser", + "databaseUser": "roles/spanner.databaseUser", + "fineGrainedAccessUser": "roles/spanner.fineGrainedAccessUser", + "restoreAdmin": "roles/spanner.restoreAdmin", + "serviceAgent": "roles/spanner.serviceAgent", + "viewer": "roles/spanner.viewer" + }, + "speakerid": { + "admin": "roles/speakerid.admin", + "editor": "roles/speakerid.editor", + "verifier": "roles/speakerid.verifier", + "viewer": "roles/speakerid.viewer" + }, + "spectrumsas": { + "serviceAgent": "roles/spectrumsas.serviceAgent" + }, + "speech": { + "admin": "roles/speech.admin", + "client": "roles/speech.client", + "editor": "roles/speech.editor", + "serviceAgent": "roles/speech.serviceAgent" + }, + "stackdriver": { + "accounts.editor": "roles/stackdriver.accounts.editor", + "accounts.viewer": "roles/stackdriver.accounts.viewer", + "resourceMetadata.writer": "roles/stackdriver.resourceMetadata.writer" + }, + "storage": { + "admin": "roles/storage.admin", + "folderAdmin": "roles/storage.folderAdmin", + "hmacKeyAdmin": "roles/storage.hmacKeyAdmin", + "insightsCollectorService": "roles/storage.insightsCollectorService", + "legacyBucketOwner": "roles/storage.legacyBucketOwner", + "legacyBucketReader": "roles/storage.legacyBucketReader", + "legacyBucketWriter": "roles/storage.legacyBucketWriter", + "legacyObjectOwner": "roles/storage.legacyObjectOwner", + "legacyObjectReader": "roles/storage.legacyObjectReader", + "objectAdmin": "roles/storage.objectAdmin", + "objectCreator": "roles/storage.objectCreator", + "objectUser": "roles/storage.objectUser", + "objectViewer": "roles/storage.objectViewer" + }, + "storageinsights": { + "admin": "roles/storageinsights.admin", + "analyst": "roles/storageinsights.analyst", + "serviceAgent": "roles/storageinsights.serviceAgent", + "viewer": "roles/storageinsights.viewer" + }, + "storagetransfer": { + "admin": "roles/storagetransfer.admin", + "serviceAgent": "roles/storagetransfer.serviceAgent", + "transferAgent": "roles/storagetransfer.transferAgent", + "user": "roles/storagetransfer.user", + "viewer": "roles/storagetransfer.viewer" + }, + "stream": { + "admin": "roles/stream.admin", + "contentAdmin": "roles/stream.contentAdmin", + "contentBuilder": "roles/stream.contentBuilder", + "instanceAdmin": "roles/stream.instanceAdmin", + "serviceAgent": "roles/stream.serviceAgent", + "viewer": "roles/stream.viewer" + }, + "subscribewithgoogledeveloper": { + "developer": "roles/subscribewithgoogledeveloper.developer" + }, + "telcoautomation": { + "admin": "roles/telcoautomation.admin", + "blueprintDesigner": "roles/telcoautomation.blueprintDesigner", + "deploymentAdmin": "roles/telcoautomation.deploymentAdmin", + "opsAdminTier1": "roles/telcoautomation.opsAdminTier1", + "opsAdminTier4": "roles/telcoautomation.opsAdminTier4", + "serviceOrchestrator": "roles/telcoautomation.serviceOrchestrator" + }, + "timeseriesinsights": { + "datasetsEditor": "roles/timeseriesinsights.datasetsEditor", + "datasetsOwner": "roles/timeseriesinsights.datasetsOwner", + "datasetsViewer": "roles/timeseriesinsights.datasetsViewer" + }, + "tpu": { + "admin": "roles/tpu.admin", + "serviceAgent": "roles/tpu.serviceAgent", + "viewer": "roles/tpu.viewer", + "xpnAgent": "roles/tpu.xpnAgent" + }, + "trafficdirector": { + "client": "roles/trafficdirector.client" + }, + "transcoder": { + "admin": "roles/transcoder.admin", + "serviceAgent": "roles/transcoder.serviceAgent", + "viewer": "roles/transcoder.viewer" + }, + "transferappliance": { + "admin": "roles/transferappliance.admin", + "viewer": "roles/transferappliance.viewer" + }, + "translationhub": { + "admin": "roles/translationhub.admin", + "portalUser": "roles/translationhub.portalUser" + }, + "videostitcher": { + "admin": "roles/videostitcher.admin", + "user": "roles/videostitcher.user", + "viewer": "roles/videostitcher.viewer" + }, + "viewer": { + "": "roles/viewer" + }, + "visionai": { + "admin": "roles/visionai.admin", + "analysisEditor": "roles/visionai.analysisEditor", + "analysisViewer": "roles/visionai.analysisViewer", + "annotationEditor": "roles/visionai.annotationEditor", + "annotationViewer": "roles/visionai.annotationViewer", + "applicationEditor": "roles/visionai.applicationEditor", + "applicationViewer": "roles/visionai.applicationViewer", + "assetCreator": "roles/visionai.assetCreator", + "assetEditor": "roles/visionai.assetEditor", + "assetViewer": "roles/visionai.assetViewer", + "clusterEditor": "roles/visionai.clusterEditor", + "clusterViewer": "roles/visionai.clusterViewer", + "corpusAdmin": "roles/visionai.corpusAdmin", + "corpusEditor": "roles/visionai.corpusEditor", + "corpusViewer": "roles/visionai.corpusViewer", + "corpusWriter": "roles/visionai.corpusWriter", + "editor": "roles/visionai.editor", + "eventEditor": "roles/visionai.eventEditor", + "eventViewer": "roles/visionai.eventViewer", + "indexEndpointAdmin": "roles/visionai.indexEndpointAdmin", + "indexEndpointEditor": "roles/visionai.indexEndpointEditor", + "indexEndpointViewer": "roles/visionai.indexEndpointViewer", + "indexEndpointWriter": "roles/visionai.indexEndpointWriter", + "operatorEditor": "roles/visionai.operatorEditor", + "operatorViewer": "roles/visionai.operatorViewer", + "packetReceiver": "roles/visionai.packetReceiver", + "packetSender": "roles/visionai.packetSender", + "processorEditor": "roles/visionai.processorEditor", + "processorViewer": "roles/visionai.processorViewer", + "retailcatalogEditor": "roles/visionai.retailcatalogEditor", + "retailcatalogViewer": "roles/visionai.retailcatalogViewer", + "retailendpointEditor": "roles/visionai.retailendpointEditor", + "retailendpointViewer": "roles/visionai.retailendpointViewer", + "seriesEditor": "roles/visionai.seriesEditor", + "seriesViewer": "roles/visionai.seriesViewer", + "serviceAgent": "roles/visionai.serviceAgent", + "streamEditor": "roles/visionai.streamEditor", + "streamViewer": "roles/visionai.streamViewer", + "uiStreamEditor": "roles/visionai.uiStreamEditor", + "uiStreamViewer": "roles/visionai.uiStreamViewer", + "viewer": "roles/visionai.viewer" + }, + "visualinspection": { + "editor": "roles/visualinspection.editor", + "serviceAgent": "roles/visualinspection.serviceAgent", + "usageMetricsReporter": "roles/visualinspection.usageMetricsReporter", + "viewer": "roles/visualinspection.viewer" + }, + "vmmigration": { + "admin": "roles/vmmigration.admin", + "serviceAgent": "roles/vmmigration.serviceAgent", + "viewer": "roles/vmmigration.viewer" + }, + "vmwareengine": { + "serviceAgent": "roles/vmwareengine.serviceAgent", + "vmwareengineAdmin": "roles/vmwareengine.vmwareengineAdmin", + "vmwareengineViewer": "roles/vmwareengine.vmwareengineViewer" + }, + "vpcaccess": { + "admin": "roles/vpcaccess.admin", + "serviceAgent": "roles/vpcaccess.serviceAgent", + "user": "roles/vpcaccess.user", + "viewer": "roles/vpcaccess.viewer" + }, + "websecurityscanner": { + "serviceAgent": "roles/websecurityscanner.serviceAgent" + }, + "workflows": { + "admin": "roles/workflows.admin", + "editor": "roles/workflows.editor", + "invoker": "roles/workflows.invoker", + "serviceAgent": "roles/workflows.serviceAgent", + "viewer": "roles/workflows.viewer" + }, + "workloadcertificate": { + "admin": "roles/workloadcertificate.admin", + "registrationAdmin": "roles/workloadcertificate.registrationAdmin", + "registrationViewer": "roles/workloadcertificate.registrationViewer", + "serviceAgent": "roles/workloadcertificate.serviceAgent", + "viewer": "roles/workloadcertificate.viewer" + }, + "workloadmanager": { + "admin": "roles/workloadmanager.admin", + "deploymentAdmin": "roles/workloadmanager.deploymentAdmin", + "deploymentViewer": "roles/workloadmanager.deploymentViewer", + "evaluationAdmin": "roles/workloadmanager.evaluationAdmin", + "evaluationViewer": "roles/workloadmanager.evaluationViewer", + "insightWriter": "roles/workloadmanager.insightWriter", + "serviceAgent": "roles/workloadmanager.serviceAgent", + "viewer": "roles/workloadmanager.viewer", + "worker": "roles/workloadmanager.worker", + "workloadViewer": "roles/workloadmanager.workloadViewer" + }, + "workstations": { + "admin": "roles/workstations.admin", + "networkAdmin": "roles/workstations.networkAdmin", + "operationViewer": "roles/workstations.operationViewer", + "serviceAgent": "roles/workstations.serviceAgent", + "user": "roles/workstations.user", + "workstationCreator": "roles/workstations.workstationCreator" } -} +} \ No newline at end of file From 6c587bdb3052de652d285daa8b0665e9fde5a8a8 Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Sat, 23 Nov 2024 15:30:17 +0100 Subject: [PATCH 5/7] feat(pulumi): Add Load Balancer and Backend Service Resources - Introduce LoadBalancerResource for GCP load balancer management. - Add BackendServiceBackendsResource for handling backend services. - Enhance DNSResource with new SPF includes and record creation methods. - Extend ServiceAccountResource with 'id' getter. - Utilize centralized IAM roles across various resources. --- packages/pulumi/gcp/index.ts | 2 + .../backend-service-backend.resource.ts | 65 ++++++ .../pulumi/gcp/resources/bucket.resource.ts | 11 +- packages/pulumi/gcp/resources/dns.resource.ts | 38 +-- .../gcp/resources/load-balancer.resource.ts | 219 ++++++++++++++++++ .../pulumi/gcp/resources/queue.resource.ts | 3 +- .../pulumi/gcp/resources/secret.resource.ts | 3 +- .../gcp/resources/service-account.resource.ts | 4 + 8 files changed, 323 insertions(+), 22 deletions(-) create mode 100644 packages/pulumi/gcp/resources/backend-service-backend.resource.ts create mode 100644 packages/pulumi/gcp/resources/load-balancer.resource.ts diff --git a/packages/pulumi/gcp/index.ts b/packages/pulumi/gcp/index.ts index c11a23ee..34b22d78 100644 --- a/packages/pulumi/gcp/index.ts +++ b/packages/pulumi/gcp/index.ts @@ -10,5 +10,7 @@ export * from './resources/iam-custom-role.resource' export * from './resources/pub-sub-topic.resource' export * from './resources/queue.resource' export * from './resources/secret.resource' +export * from './resources/load-balancer.resource' +export * from './resources/backend-service-backend.resource' export * from './resources/service-account.resource' diff --git a/packages/pulumi/gcp/resources/backend-service-backend.resource.ts b/packages/pulumi/gcp/resources/backend-service-backend.resource.ts new file mode 100644 index 00000000..fb7c93e1 --- /dev/null +++ b/packages/pulumi/gcp/resources/backend-service-backend.resource.ts @@ -0,0 +1,65 @@ +import * as gcp from '@pulumi/gcp' +import * as pulumi from '@pulumi/pulumi' + +import { GCP_PROJECT_ID } from '../config' +import { BaseResource } from './base.resource' + +export class BackendServiceBackendsResource extends BaseResource { + + private cloudRun: gcp.types.input.compute.RegionNetworkEndpointGroupCloudRun + private cloudFunction: gcp.types.input.compute.RegionNetworkEndpointGroupCloudFunction + + private regions: string[] = [] + + constructor( + private readonly name: string, + private readonly opts: pulumi.ComponentResourceOptions = {}, + ) { + super('backend-service-backends-resource', name, {}, opts) + } + + public forCloudRun(cloudRun: gcp.types.input.compute.RegionNetworkEndpointGroupCloudRun): Pick { + this.cloudRun = cloudRun + + return this + } + + public forCloudFunction(cloudFunction: gcp.types.input.compute.RegionNetworkEndpointGroupCloudFunction): Pick { + this.cloudFunction = cloudFunction + + return this + } + + public addRegion(region: string): Pick { + this.regions.push(region) + + return this + } + + public create(backendServiceBackend?: Partial): gcp.types.input.compute.BackendServiceBackend[] { + return this.regions.map((region) => { + const name = this.getNegName(region) + + const neg = new gcp.compute.RegionNetworkEndpointGroup(name, { + project: GCP_PROJECT_ID, + name, + networkEndpointType: 'SERVERLESS', + region, + cloudRun: this.cloudRun, + cloudFunction: this.cloudFunction, + }, { + parent: this + }) + + return { + balancingMode: 'UTILIZATION', + ...backendServiceBackend, + group: neg.selfLink + } + }) + } + + private getNegName(region: string): string { + return `${this.name}-neg-${region}` + } +} diff --git a/packages/pulumi/gcp/resources/bucket.resource.ts b/packages/pulumi/gcp/resources/bucket.resource.ts index efe5dc99..54678290 100644 --- a/packages/pulumi/gcp/resources/bucket.resource.ts +++ b/packages/pulumi/gcp/resources/bucket.resource.ts @@ -2,6 +2,7 @@ import * as gcp from '@pulumi/gcp' import * as pulumi from '@pulumi/pulumi' import { GCP_PROJECT_ID } from '../config' +import { iamRoles } from '../iam-roles' import { buildName, getFriendlyRoleName } from '../naming' import { BaseResource } from './base.resource' @@ -28,31 +29,31 @@ export class BucketResource extends BaseResource { } public addLegacyObjectReader(member: pulumi.Output): BucketResource { - this.addMember(member, 'roles/storage.legacyObjectReader') + this.addMember(member, iamRoles.storage.legacyObjectReader) return this } public addLegacyObjectOwner(member: pulumi.Output): BucketResource { - this.addMember(member, 'roles/storage.legacyObjectOwner') + this.addMember(member, iamRoles.storage.legacyObjectOwner) return this } public addObjectAdmin(member: pulumi.Output): BucketResource { - this.addMember(member, 'roles/storage.objectAdmin') + this.addMember(member, iamRoles.storage.objectAdmin) return this } public addObjectViewer(member: pulumi.Output): BucketResource { - this.addMember(member, 'roles/storage.objectViewer') + this.addMember(member, iamRoles.storage.objectViewer) return this } public addObjectCreator(member: pulumi.Output): BucketResource { - this.addMember(member, 'roles/storage.objectCreator') + this.addMember(member, iamRoles.storage.objectCreator) return this } diff --git a/packages/pulumi/gcp/resources/dns.resource.ts b/packages/pulumi/gcp/resources/dns.resource.ts index 24e59ae0..1aadc43e 100644 --- a/packages/pulumi/gcp/resources/dns.resource.ts +++ b/packages/pulumi/gcp/resources/dns.resource.ts @@ -5,11 +5,13 @@ import { GCP_PROJECT_ID } from '../config' import { BaseResource } from './base.resource' export type DNS_TYPE = 'A' | 'AAAA' | 'MX' | 'TXT' | 'CNAME' -export type DNS_VALUES = string | Array +export type DNS_VALUES = string | Array | pulumi.Output export class DNSResource extends BaseResource { public static gmailSpfInclude = 'include:_spf.google.com' + public static firebaseSpfInclude = 'include:_spf.firebasemail.com' + public readonly zone: gcp.dns.ManagedZone private readonly friendlyDomain: string @@ -56,11 +58,6 @@ export class DNSResource extends BaseResource { .createRecord('www', 'CNAME', 'cname.vercel-dns.com.') } - public createCmsRecord(): DNSResource { - return this - .createCNAMERecord('cms', 'ghs.googlehosted.com.') - } - public createGmailMxRecords(): DNSResource { return this .createMxRecord( @@ -102,22 +99,25 @@ export class DNSResource extends BaseResource { } /** - * Creates a SPF records, possible adds other values to the TXT record + * Creates an SPF records, possible adds other values to the TXT record */ public createSpfRecord(subDomain: string, ips: string[], ...values: string[]): DNSResource { - return this - .createTXTRecord(subDomain, `v=spf1 ${ips.join(' ')} -all`, ...values) + return this.createTXTRecord(subDomain, `v=spf1 ${ips.join(' ')} -all`, ...values) } public createDefaultDomainKeyRecord(subDomain = '_domainkey', value = '"o=~"'): DNSResource { - return this - .createRecord(subDomain, 'TXT', value) + return this.createRecord(subDomain, 'TXT', value) } - public createDmarcRecord(subDomain = '_dmarc'): DNSResource { - return this - // add: adkim=s;aspf=s; ? https://support.google.com/a/answer/2466563 - .createTXTRecord(subDomain, `v=DMARC1;p=reject;pct=100;rua=mailto:dmarc-reports@${this.domain}`) + public createDmarcRecord(subDomain = '_dmarc', mailTo?: string): DNSResource { + return this.createTXTRecord(subDomain, [ + 'v=DMARC1', + 'p=reject', + 'pct=100', + mailTo && `rua=mailto:${mailTo}@${this.domain}`, + 'adkim=s', + 'aspf=s' + ].filter(Boolean).join(';')) } public createTXTRecord(subDomain: string, ...values: string[]): DNSResource { @@ -128,6 +128,14 @@ export class DNSResource extends BaseResource { return this.createRecord(subDomain, 'CNAME', ...values) } + public createARecord(subDomain: string, ...values: DNS_VALUES[]): DNSResource { + return this.createRecord(subDomain, 'A', ...values) + } + + public createAAAARecord(subDomain: string, ...values: DNS_VALUES[]): DNSResource { + return this.createRecord(subDomain, 'AAAA', ...values) + } + public createRecord(subDomain: string, type: DNS_TYPE, ...values: DNS_VALUES[]): DNSResource { new gcp.dns.RecordSet(this.resourceName(subDomain, type), { project: GCP_PROJECT_ID, diff --git a/packages/pulumi/gcp/resources/load-balancer.resource.ts b/packages/pulumi/gcp/resources/load-balancer.resource.ts new file mode 100644 index 00000000..34a3bd6a --- /dev/null +++ b/packages/pulumi/gcp/resources/load-balancer.resource.ts @@ -0,0 +1,219 @@ +import * as gcp from '@pulumi/gcp' +import * as pulumi from '@pulumi/pulumi' + +import { GCP_PROJECT_ID } from '../config' +import { BaseResource } from './base.resource' +import { DNSResource } from './dns.resource' + +type Backends = gcp.compute.BackendBucket | gcp.compute.BackendService + +export class LoadBalancerResource extends BaseResource { + + public readonly ipv4Address: gcp.compute.GlobalAddress = new gcp.compute.GlobalAddress(this.buildName('ipv4'), { + project: GCP_PROJECT_ID, + name: this.buildName('ipv4'), + ipVersion: 'IPV4', + addressType: 'EXTERNAL' + }, { + parent: this + }) + + public readonly ipv6Address: gcp.compute.GlobalAddress = new gcp.compute.GlobalAddress(this.buildName('ipv6'), { + project: GCP_PROJECT_ID, + name: this.buildName('ipv6'), + ipVersion: 'IPV6', + addressType: 'EXTERNAL' + }, { + parent: this + }) + + private sslCertificateDomains: string[] = [] + private backends: Map = new Map() + + private rules: Array<{ backendName: string, domain: string }> = [] + + constructor( + private readonly name: string, + private readonly opts: pulumi.ComponentResourceOptions = {} + ) { + super('load-balancer-resource', name, {}, opts) + } + + public addSsl(domain: string) { + this.sslCertificateDomains.push(domain) + + return this + } + + public addBackend(type: 'bucket', options: gcp.compute.BackendBucketArgs): this + public addBackend(type: 'service', options: gcp.compute.BackendServiceArgs): this + public addBackend(type: 'bucket' | 'service', options: gcp.compute.BackendBucketArgs | gcp.compute.BackendServiceArgs) { + if (!options.name) { + throw new Error('"name" is required for backends!') + } + + if (type === 'bucket') { + this.backends.set( + options.name as never as string, + new gcp.compute.BackendBucket( + options.name as never as string, + options as gcp.compute.BackendBucketArgs, + { parent: this } + ) + ) + + } else if (type === 'service') { + this.backends.set( + options.name as never as string, + new gcp.compute.BackendService( + options.name as never as string, + options as gcp.compute.BackendServiceArgs, + { parent: this } + ) + ) + } + + return this + } + + public addRules(rules: Array<{ backendName: string, domain: string }>): this { + this.rules = rules + + return this + } + + public create() { + if (this.rules.length === 0) { + throw new Error('No rules defined!') + } + + const hostRules = this.rules.map(({ domain }) => ({ + hosts: [domain], + pathMatcher: DNSResource.makeDomainFriendly(domain) + })) + + const pathMatchers = this.rules.map(({ domain, backendName }) => ({ + // Link it to the backend + defaultService: this.backends.get(backendName).selfLink, + // Link to hostRule + name: DNSResource.makeDomainFriendly(domain) + })) + + const urlMap = new gcp.compute.URLMap(this.buildName(), { + project: GCP_PROJECT_ID, + name: this.buildName(), + hostRules, + pathMatchers, + defaultService: pathMatchers[0].defaultService + }, { + parent: this + }) + + const sslCertificatesSelfLinks = this.sslCertificateDomains.map((domain) => { + const friendlyDomain = DNSResource.makeDomainFriendly(domain) + + return new gcp.compute.ManagedSslCertificate(`${friendlyDomain}-ssl`, { + project: GCP_PROJECT_ID, + name: `${friendlyDomain}-ssl`, + managed: { + domains: [domain] + } + }, { + parent: urlMap + }).selfLink + }) + + const targetProxyName = this.buildName('target-proxy') + const loadBalancerTargetProxy = new gcp.compute.TargetHttpsProxy(targetProxyName, { + project: GCP_PROJECT_ID, + name: targetProxyName, + sslCertificates: sslCertificatesSelfLinks, + urlMap: urlMap.selfLink + }, { + parent: urlMap + }) + + const globalForwardingRuleIpv4Name = this.buildName('forwarding-rule-ipv4') + new gcp.compute.GlobalForwardingRule(globalForwardingRuleIpv4Name, { + project: GCP_PROJECT_ID, + name: globalForwardingRuleIpv4Name, + loadBalancingScheme: 'EXTERNAL_MANAGED', + portRange: '443', + target: loadBalancerTargetProxy.selfLink, + ipAddress: this.ipv4Address.selfLink, + ipProtocol: 'TCP' + }, { + parent: loadBalancerTargetProxy + }) + + const globalForwardingRuleIpv6Name = this.buildName('forwarding-rule-ipv6') + new gcp.compute.GlobalForwardingRule(globalForwardingRuleIpv6Name, { + project: GCP_PROJECT_ID, + name: globalForwardingRuleIpv6Name, + loadBalancingScheme: 'EXTERNAL_MANAGED', + portRange: '443', + target: loadBalancerTargetProxy.selfLink, + ipAddress: this.ipv6Address.selfLink, + ipProtocol: 'TCP' + }, { + parent: loadBalancerTargetProxy + }) + + return this + } + + public withHttpHttpsRedirect() { + const urlMapName = this.buildName('http-https') + const urlMap = new gcp.compute.URLMap(urlMapName, { + project: GCP_PROJECT_ID, + name: urlMapName, + defaultUrlRedirect: { + httpsRedirect: true, + redirectResponseCode: 'MOVED_PERMANENTLY_DEFAULT', + stripQuery: false + } + }, { + parent: this + }) + + const targetProxyName = this.buildName('http-https-target-proxy') + const targetProxy = new gcp.compute.TargetHttpProxy(targetProxyName, { + project: GCP_PROJECT_ID, + name: targetProxyName, + urlMap: urlMap.selfLink + }, { + parent: urlMap + }) + + const globalForwardingRuleIpv4Name = this.buildName('http-https-forwarding-rule-ipv4') + new gcp.compute.GlobalForwardingRule(globalForwardingRuleIpv4Name, { + project: GCP_PROJECT_ID, + name: globalForwardingRuleIpv4Name, + loadBalancingScheme: 'EXTERNAL_MANAGED', + portRange: '80', + target: targetProxy.selfLink, + ipAddress: this.ipv4Address.selfLink + }, { + parent: targetProxy + }) + + const globalForwardingRuleIpv6Name = this.buildName('http-https-forwarding-rule-ipv6') + new gcp.compute.GlobalForwardingRule(globalForwardingRuleIpv6Name, { + project: GCP_PROJECT_ID, + name: globalForwardingRuleIpv6Name, + loadBalancingScheme: 'EXTERNAL_MANAGED', + portRange: '80', + target: targetProxy.selfLink, + ipAddress: this.ipv6Address.selfLink + }, { + parent: targetProxy + }) + + return this + } + + private buildName(type?: string): string { + return `${this.name}-load-balancer${type ? `-${type}` : ''}` + } + +} diff --git a/packages/pulumi/gcp/resources/queue.resource.ts b/packages/pulumi/gcp/resources/queue.resource.ts index 4c5be434..96972530 100644 --- a/packages/pulumi/gcp/resources/queue.resource.ts +++ b/packages/pulumi/gcp/resources/queue.resource.ts @@ -2,6 +2,7 @@ import * as gcp from '@pulumi/gcp' import * as pulumi from '@pulumi/pulumi' import { GCP_PROJECT_ID } from '../config' +import { iamRoles } from '../iam-roles' import { buildName, getFriendlyMemberName, getFriendlyRoleName } from '../naming' import { BaseResource } from './base.resource' @@ -32,7 +33,7 @@ export class QueueResource extends BaseResource { } public addEnqueuer(member: pulumi.Output): QueueResource { - return this.addMember(member, 'roles/cloudtasks.enqueuer') + return this.addMember(member, iamRoles.cloudtasks.enqueuer) } public addMember(member: pulumi.Output, role: string): QueueResource { diff --git a/packages/pulumi/gcp/resources/secret.resource.ts b/packages/pulumi/gcp/resources/secret.resource.ts index a4faf20d..eef9b804 100644 --- a/packages/pulumi/gcp/resources/secret.resource.ts +++ b/packages/pulumi/gcp/resources/secret.resource.ts @@ -2,6 +2,7 @@ import * as gcp from '@pulumi/gcp' import * as pulumi from '@pulumi/pulumi' import { GCP_PROJECT_ID } from '../config' +import { iamRoles } from '../iam-roles' import { buildName, getFriendlyMemberName, getFriendlyRoleName } from '../naming' import { BaseResource } from './base.resource' @@ -49,7 +50,7 @@ export class SecretResource extends BaseResource { } public addAccessor(member: pulumi.Output): SecretResource { - return this.addMember(member, 'roles/secretmanager.secretAccessor') + return this.addMember(member, iamRoles.secretmanager.secretAccessor) } public addMember(member: pulumi.Output, role: string): SecretResource { diff --git a/packages/pulumi/gcp/resources/service-account.resource.ts b/packages/pulumi/gcp/resources/service-account.resource.ts index b5551441..4484d7d0 100644 --- a/packages/pulumi/gcp/resources/service-account.resource.ts +++ b/packages/pulumi/gcp/resources/service-account.resource.ts @@ -28,6 +28,10 @@ export class ServiceAccountResource extends BaseResource { }) } + public get id(): pulumi.Output { + return this.account.id + } + public get member(): pulumi.Output { return this.account.member } From 1fe4ad30adc69ba1d1f2a46ef6f3cd6cf2b9b0a3 Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Sat, 23 Nov 2024 15:30:23 +0100 Subject: [PATCH 6/7] docs(actions-plan): Update README with detailed target options and examples --- actions/plan/README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/actions/plan/README.md b/actions/plan/README.md index 31b14c3c..f4956fca 100644 --- a/actions/plan/README.md +++ b/actions/plan/README.md @@ -43,13 +43,27 @@ jobs: id: plan uses: tripss/nx-extend/actions/plan@improvements with: + # Plan projects with the following targets targets: | test build e2e + # Available options + # MaxJobs - Amount of max jobs for this target + # Tag - Tag the targets project needs to have (Supports conditional) + # PreTargets - Targets of the targeted project to run before running the target + # postTargets - Targets of the targeted project to run after running the target + # Parallel - Amount of projects it can run in parallel + + # Run build target when project has tag "build=enabled" AND "service" tag is not "vercel" OR has tag "service=react" + targetBuildTag: + build=enabled,service!=vercel + service=react + testMaxJobs: 1 - testTag: tests=enabled + testTag: | + tests=enabled buildMaxJobs: 3 buildPreTargets: | @@ -79,5 +93,7 @@ jobs: index: ${{ matrix.index }} count: ${{ matrix.count }} tag: ${{ matrix.tag }} + parallel: ${{ matrix.parallel }} preTargets: ${{ matrix.preTargets }} + postTargets: ${{ matrix.postTargets }} ``` From c36c6447ffb8d77216741fa6ff27be62f92114a2 Mon Sep 17 00:00:00 2001 From: Tycho Bokdam Date: Sat, 23 Nov 2024 15:56:46 +0100 Subject: [PATCH 7/7] feat(pulumi): Add name getter to BucketResource in pulumi-gcp --- packages/pulumi/gcp/resources/bucket.resource.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/pulumi/gcp/resources/bucket.resource.ts b/packages/pulumi/gcp/resources/bucket.resource.ts index 54678290..642c334f 100644 --- a/packages/pulumi/gcp/resources/bucket.resource.ts +++ b/packages/pulumi/gcp/resources/bucket.resource.ts @@ -28,6 +28,10 @@ export class BucketResource extends BaseResource { }) } + public get name() { + return this.bucket.name + } + public addLegacyObjectReader(member: pulumi.Output): BucketResource { this.addMember(member, iamRoles.storage.legacyObjectReader)