From 1f761719801d28795963f6b393fb7ce6f5b7f920 Mon Sep 17 00:00:00 2001 From: Xiaozhen Liu Date: Mon, 4 May 2020 15:45:41 -0700 Subject: [PATCH] feat: add asset API to baseline test (#454) * add asset to baseline test * update dependency * update baseline * update baseline * feedback --- baselines/asset/.eslintignore.baseline | 6 + baselines/asset/.eslintrc.json.baseline | 3 + baselines/asset/.gitignore.baseline | 14 + baselines/asset/.jsdoc.js.baseline | 55 + baselines/asset/.mocharc.js.baseline | 33 + baselines/asset/.prettierrc.js.baseline | 22 + baselines/asset/README.md.baseline | 1 + .../asset/linkinator.config.json.baseline | 10 + baselines/asset/package.json | 51 + baselines/asset/package.json.baseline | 1 + baselines/asset/proto.list.baseline | 24 + .../asset/v1/asset_service.proto.baseline | 423 ++++++++ .../cloud/asset/v1/assets.proto.baseline | 172 +++ .../cloud/common_resources.proto.baseline | 52 + .../orgpolicy/v1/orgpolicy.proto.baseline | 315 ++++++ .../type/device_resources.proto.baseline | 85 ++ .../v1/access_level.proto.baseline | 187 ++++ .../v1/access_policy.proto.baseline | 60 ++ .../v1/service_perimeter.proto.baseline | 152 +++ baselines/asset/src/index.ts.baseline | 24 + .../src/v1/asset_service_client.ts.baseline | 995 ++++++++++++++++++ .../asset_service_client_config.json.baseline | 54 + .../v1/asset_service_proto_list.json.baseline | 23 + baselines/asset/src/v1/index.ts.baseline | 19 + .../fixtures/sample/src/index.js.baseline | 27 + .../fixtures/sample/src/index.ts.baseline | 25 + .../asset/system-test/install.ts.baseline | 49 + .../test/gapic_asset_service_v1.ts.baseline | 904 ++++++++++++++++ baselines/asset/tsconfig.json.baseline | 19 + baselines/asset/webpack.config.js.baseline | 64 ++ .../google/cloud/asset/v1/asset_service.proto | 423 ++++++++ .../protos/google/cloud/asset/v1/assets.proto | 172 +++ .../v1/cloudasset_grpc_service_config.json | 31 + .../google/cloud/orgpolicy/v1/orgpolicy.proto | 315 ++++++ .../type/device_resources.proto | 85 ++ .../v1/access_level.proto | 187 ++++ .../v1/access_policy.proto | 60 ++ .../v1/service_perimeter.proto | 152 +++ typescript/test/unit/baselines.ts | 11 + typescript/test/util.ts | 8 +- 40 files changed, 5309 insertions(+), 4 deletions(-) create mode 100644 baselines/asset/.eslintignore.baseline create mode 100644 baselines/asset/.eslintrc.json.baseline create mode 100644 baselines/asset/.gitignore.baseline create mode 100644 baselines/asset/.jsdoc.js.baseline create mode 100644 baselines/asset/.mocharc.js.baseline create mode 100644 baselines/asset/.prettierrc.js.baseline create mode 100644 baselines/asset/README.md.baseline create mode 100644 baselines/asset/linkinator.config.json.baseline create mode 100644 baselines/asset/package.json create mode 120000 baselines/asset/package.json.baseline create mode 100644 baselines/asset/proto.list.baseline create mode 100644 baselines/asset/protos/google/cloud/asset/v1/asset_service.proto.baseline create mode 100644 baselines/asset/protos/google/cloud/asset/v1/assets.proto.baseline create mode 100644 baselines/asset/protos/google/cloud/common_resources.proto.baseline create mode 100644 baselines/asset/protos/google/cloud/orgpolicy/v1/orgpolicy.proto.baseline create mode 100644 baselines/asset/protos/google/identity/accesscontextmanager/type/device_resources.proto.baseline create mode 100644 baselines/asset/protos/google/identity/accesscontextmanager/v1/access_level.proto.baseline create mode 100644 baselines/asset/protos/google/identity/accesscontextmanager/v1/access_policy.proto.baseline create mode 100644 baselines/asset/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto.baseline create mode 100644 baselines/asset/src/index.ts.baseline create mode 100644 baselines/asset/src/v1/asset_service_client.ts.baseline create mode 100644 baselines/asset/src/v1/asset_service_client_config.json.baseline create mode 100644 baselines/asset/src/v1/asset_service_proto_list.json.baseline create mode 100644 baselines/asset/src/v1/index.ts.baseline create mode 100644 baselines/asset/system-test/fixtures/sample/src/index.js.baseline create mode 100644 baselines/asset/system-test/fixtures/sample/src/index.ts.baseline create mode 100644 baselines/asset/system-test/install.ts.baseline create mode 100644 baselines/asset/test/gapic_asset_service_v1.ts.baseline create mode 100644 baselines/asset/tsconfig.json.baseline create mode 100644 baselines/asset/webpack.config.js.baseline create mode 100644 test-fixtures/protos/google/cloud/asset/v1/asset_service.proto create mode 100644 test-fixtures/protos/google/cloud/asset/v1/assets.proto create mode 100755 test-fixtures/protos/google/cloud/asset/v1/cloudasset_grpc_service_config.json create mode 100644 test-fixtures/protos/google/cloud/orgpolicy/v1/orgpolicy.proto create mode 100644 test-fixtures/protos/google/identity/accesscontextmanager/type/device_resources.proto create mode 100644 test-fixtures/protos/google/identity/accesscontextmanager/v1/access_level.proto create mode 100644 test-fixtures/protos/google/identity/accesscontextmanager/v1/access_policy.proto create mode 100644 test-fixtures/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto diff --git a/baselines/asset/.eslintignore.baseline b/baselines/asset/.eslintignore.baseline new file mode 100644 index 000000000..521dc25a2 --- /dev/null +++ b/baselines/asset/.eslintignore.baseline @@ -0,0 +1,6 @@ +**/node_modules +**/.coverage +build/ +docs/ +protos/ +system-test/ diff --git a/baselines/asset/.eslintrc.json.baseline b/baselines/asset/.eslintrc.json.baseline new file mode 100644 index 000000000..782153495 --- /dev/null +++ b/baselines/asset/.eslintrc.json.baseline @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/gts" +} diff --git a/baselines/asset/.gitignore.baseline b/baselines/asset/.gitignore.baseline new file mode 100644 index 000000000..5d32b2378 --- /dev/null +++ b/baselines/asset/.gitignore.baseline @@ -0,0 +1,14 @@ +**/*.log +**/node_modules +.coverage +coverage +.nyc_output +docs/ +out/ +build/ +system-test/secrets.js +system-test/*key.json +*.lock +.DS_Store +package-lock.json +__pycache__ diff --git a/baselines/asset/.jsdoc.js.baseline b/baselines/asset/.jsdoc.js.baseline new file mode 100644 index 000000000..03f79f28b --- /dev/null +++ b/baselines/asset/.jsdoc.js.baseline @@ -0,0 +1,55 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +'use strict'; + +module.exports = { + opts: { + readme: './README.md', + package: './package.json', + template: './node_modules/jsdoc-fresh', + recurse: true, + verbose: true, + destination: './docs/' + }, + plugins: [ + 'plugins/markdown', + 'jsdoc-region-tag' + ], + source: { + excludePattern: '(^|\\/|\\\\)[._]', + include: [ + 'build/src', + 'protos' + ], + includePattern: '\\.js$' + }, + templates: { + copyright: 'Copyright 2020 Google LLC', + includeDate: false, + sourceFiles: false, + systemName: '@google-cloud/asset', + theme: 'lumen', + default: { + outputSourceFiles: false + } + }, + markdown: { + idInHeadings: true + } +}; diff --git a/baselines/asset/.mocharc.js.baseline b/baselines/asset/.mocharc.js.baseline new file mode 100644 index 000000000..22c677c55 --- /dev/null +++ b/baselines/asset/.mocharc.js.baseline @@ -0,0 +1,33 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +const config = { + "enable-source-maps": true, + "throw-deprecation": true, + "timeout": 10000 +} +if (process.env.MOCHA_THROW_DEPRECATION === 'false') { + delete config['throw-deprecation']; +} +if (process.env.MOCHA_REPORTER) { + config.reporter = process.env.MOCHA_REPORTER; +} +if (process.env.MOCHA_REPORTER_OUTPUT) { + config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; +} +module.exports = config diff --git a/baselines/asset/.prettierrc.js.baseline b/baselines/asset/.prettierrc.js.baseline new file mode 100644 index 000000000..ee62d5025 --- /dev/null +++ b/baselines/asset/.prettierrc.js.baseline @@ -0,0 +1,22 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + + +module.exports = { + ...require('gts/.prettierrc.json') +} diff --git a/baselines/asset/README.md.baseline b/baselines/asset/README.md.baseline new file mode 100644 index 000000000..b35f3a5e2 --- /dev/null +++ b/baselines/asset/README.md.baseline @@ -0,0 +1 @@ +Asset: Nodejs Client diff --git a/baselines/asset/linkinator.config.json.baseline b/baselines/asset/linkinator.config.json.baseline new file mode 100644 index 000000000..29a223b6d --- /dev/null +++ b/baselines/asset/linkinator.config.json.baseline @@ -0,0 +1,10 @@ +{ + "recurse": true, + "skip": [ + "https://codecov.io/gh/googleapis/", + "www.googleapis.com", + "img.shields.io" + ], + "silent": true, + "concurrency": 10 +} diff --git a/baselines/asset/package.json b/baselines/asset/package.json new file mode 100644 index 000000000..1574b24d8 --- /dev/null +++ b/baselines/asset/package.json @@ -0,0 +1,51 @@ +{ + "name": "@google-cloud/asset", + "version": "0.1.0", + "description": "Asset client for Node.js", + "repository": "googleapis/nodejs-asset", + "license": "Apache-2.0", + "author": "Google LLC", + "main": "build/src/index.js", + "files": [ + "build/src", + "build/protos" + ], + "scripts": { + "clean": "gts clean", + "compile": "tsc -p . && cp -r protos build/", + "compile-protos": "compileProtos src", + "docs": "jsdoc -c .jsdoc.js", + "predocs-test": "npm run docs", + "docs-test": "linkinator docs", + "fix": "gts fix", + "lint": "gts check", + "prepare": "npm run compile-protos && npm run compile", + "system-test": "c8 mocha build/system-test", + "test": "c8 mocha build/test" + }, + "dependencies": { + "google-gax": "^2.3.1" + }, + "devDependencies": { + "@types/mocha": "^5.2.7", + "@types/node": "^12.12.37", + "@types/sinon": "^9.0.0", + "c8": "^7.1.1", + "gts": "^2.0.0", + "jsdoc": "^3.6.4", + "jsdoc-fresh": "^1.0.2", + "jsdoc-region-tag": "^1.0.4", + "linkinator": "^2.0.6", + "mocha": "^6.2.3", + "null-loader": "^4.0.0", + "pack-n-play": "^1.0.0-2", + "sinon": "^9.0.2", + "ts-loader": "^7.0.2", + "typescript": "~3.8.3", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11" + }, + "engines": { + "node": ">=10.0.0" + } +} diff --git a/baselines/asset/package.json.baseline b/baselines/asset/package.json.baseline new file mode 120000 index 000000000..2ff8622f1 --- /dev/null +++ b/baselines/asset/package.json.baseline @@ -0,0 +1 @@ +package.json \ No newline at end of file diff --git a/baselines/asset/proto.list.baseline b/baselines/asset/proto.list.baseline new file mode 100644 index 000000000..a2e2cc74b --- /dev/null +++ b/baselines/asset/proto.list.baseline @@ -0,0 +1,24 @@ +google/api/http.proto +google/protobuf/descriptor.proto +google/api/annotations.proto +google/api/client.proto +google/api/field_behavior.proto +google/api/resource.proto +google/protobuf/empty.proto +google/protobuf/timestamp.proto +google/cloud/orgpolicy/v1/orgpolicy.proto +google/type/expr.proto +google/iam/v1/policy.proto +google/identity/accesscontextmanager/type/device_resources.proto +google/identity/accesscontextmanager/v1/access_level.proto +google/identity/accesscontextmanager/v1/access_policy.proto +google/identity/accesscontextmanager/v1/service_perimeter.proto +google/protobuf/any.proto +google/protobuf/struct.proto +google/cloud/asset/v1/assets.proto +google/protobuf/duration.proto +google/rpc/status.proto +google/longrunning/operations.proto +google/protobuf/field_mask.proto +google/cloud/asset/v1/asset_service.proto +google/cloud/common_resources.proto diff --git a/baselines/asset/protos/google/cloud/asset/v1/asset_service.proto.baseline b/baselines/asset/protos/google/cloud/asset/v1/asset_service.proto.baseline new file mode 100644 index 000000000..9c7b16d03 --- /dev/null +++ b/baselines/asset/protos/google/cloud/asset/v1/asset_service.proto.baseline @@ -0,0 +1,423 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.asset.v1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/asset/v1/assets.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; +import "google/type/expr.proto"; + +option csharp_namespace = "Google.Cloud.Asset.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/asset/v1;asset"; +option java_multiple_files = true; +option java_outer_classname = "AssetServiceProto"; +option java_package = "com.google.cloud.asset.v1"; +option php_namespace = "Google\\Cloud\\Asset\\V1"; + +// Asset service definition. +service AssetService { + option (google.api.default_host) = "cloudasset.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Exports assets with time and resource types to a given Cloud Storage + // location. The output format is newline-delimited JSON. + // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you + // to keep track of the export. + rpc ExportAssets(ExportAssetsRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/{parent=*/*}:exportAssets" + body: "*" + }; + option (google.longrunning.operation_info) = { + response_type: "google.cloud.asset.v1.ExportAssetsResponse" + metadata_type: "google.cloud.asset.v1.ExportAssetsRequest" + }; + } + + // Batch gets the update history of assets that overlap a time window. + // For RESOURCE content, this API outputs history with asset in both + // non-delete or deleted status. + // For IAM_POLICY content, this API outputs history when the asset and its + // attached IAM POLICY both exist. This can create gaps in the output history. + // If a specified asset does not exist, this API returns an INVALID_ARGUMENT + // error. + rpc BatchGetAssetsHistory(BatchGetAssetsHistoryRequest) returns (BatchGetAssetsHistoryResponse) { + option (google.api.http) = { + get: "/v1/{parent=*/*}:batchGetAssetsHistory" + }; + } + + // Creates a feed in a parent project/folder/organization to listen to its + // asset updates. + rpc CreateFeed(CreateFeedRequest) returns (Feed) { + option (google.api.http) = { + post: "/v1/{parent=*/*}/feeds" + body: "*" + }; + option (google.api.method_signature) = "parent"; + } + + // Gets details about an asset feed. + rpc GetFeed(GetFeedRequest) returns (Feed) { + option (google.api.http) = { + get: "/v1/{name=*/*/feeds/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists all asset feeds in a parent project/folder/organization. + rpc ListFeeds(ListFeedsRequest) returns (ListFeedsResponse) { + option (google.api.http) = { + get: "/v1/{parent=*/*}/feeds" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates an asset feed configuration. + rpc UpdateFeed(UpdateFeedRequest) returns (Feed) { + option (google.api.http) = { + patch: "/v1/{feed.name=*/*/feeds/*}" + body: "*" + }; + option (google.api.method_signature) = "feed"; + } + + // Deletes an asset feed. + rpc DeleteFeed(DeleteFeedRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1/{name=*/*/feeds/*}" + }; + option (google.api.method_signature) = "name"; + } +} + +// Export asset request. +message ExportAssetsRequest { + // Required. The relative name of the root asset. This can only be an + // organization number (such as "organizations/123"), a project ID (such as + // "projects/my-project-id"), or a project number (such as "projects/12345"), + // or a folder number (such as "folders/123"). + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "cloudasset.googleapis.com/Asset" + } + ]; + + // Timestamp to take an asset snapshot. This can only be set to a timestamp + // between the current time and the current time minus 35 days (inclusive). + // If not specified, the current time will be used. Due to delays in resource + // data collection and indexing, there is a volatile window during which + // running the same query may get different results. + google.protobuf.Timestamp read_time = 2; + + // A list of asset types of which to take a snapshot for. For example: + // "compute.googleapis.com/Disk". If specified, only matching assets will be + // returned. See [Introduction to Cloud Asset + // Inventory](https://cloud.google.com/asset-inventory/docs/overview) + // for all supported asset types. + repeated string asset_types = 3; + + // Asset content type. If not specified, no content but the asset name will be + // returned. + ContentType content_type = 4; + + // Required. Output configuration indicating where the results will be output + // to. All results will be in newline delimited JSON format. + OutputConfig output_config = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// The export asset response. This message is returned by the +// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned +// [google.longrunning.Operation.response][google.longrunning.Operation.response] field. +message ExportAssetsResponse { + // Time the snapshot was taken. + google.protobuf.Timestamp read_time = 1; + + // Output configuration indicating where the results were output to. + // All results are in JSON format. + OutputConfig output_config = 2; +} + +// Batch get assets history request. +message BatchGetAssetsHistoryRequest { + // Required. The relative name of the root asset. It can only be an + // organization number (such as "organizations/123"), a project ID (such as + // "projects/my-project-id")", or a project number (such as "projects/12345"). + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "cloudasset.googleapis.com/Asset" + } + ]; + + // A list of the full names of the assets. For example: + // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`. + // See [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // and [Resource Name + // Format](https://cloud.google.com/asset-inventory/docs/resource-name-format) + // for more info. + // + // The request becomes a no-op if the asset name list is empty, and the max + // size of the asset name list is 100 in one request. + repeated string asset_names = 2; + + // Optional. The content type. + ContentType content_type = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The time window for the asset history. Both start_time and + // end_time are optional and if set, it must be after the current time minus + // 35 days. If end_time is not set, it is default to current timestamp. + // If start_time is not set, the snapshot of the assets at end_time will be + // returned. The returned results contain all temporal assets whose time + // window overlap with read_time_window. + TimeWindow read_time_window = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +// Batch get assets history response. +message BatchGetAssetsHistoryResponse { + // A list of assets with valid time windows. + repeated TemporalAsset assets = 1; +} + +// Create asset feed request. +message CreateFeedRequest { + // Required. The name of the project/folder/organization where this feed + // should be created in. It can only be an organization number (such as + // "organizations/123"), a folder number (such as "folders/123"), a project ID + // (such as "projects/my-project-id")", or a project number (such as + // "projects/12345"). + string parent = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. This is the client-assigned asset feed identifier and it needs to + // be unique under a specific parent project/folder/organization. + string feed_id = 2 [(google.api.field_behavior) = REQUIRED]; + + // Required. The feed details. The field `name` must be empty and it will be generated + // in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + Feed feed = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Get asset feed request. +message GetFeedRequest { + // Required. The name of the Feed and it must be in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudasset.googleapis.com/Feed" + } + ]; +} + +// List asset feeds request. +message ListFeedsRequest { + // Required. The parent project/folder/organization whose feeds are to be + // listed. It can only be using project/folder/organization number (such as + // "folders/12345")", or a project ID (such as "projects/my-project-id"). + string parent = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message ListFeedsResponse { + // A list of feeds. + repeated Feed feeds = 1; +} + +// Update asset feed request. +message UpdateFeedRequest { + // Required. The new values of feed details. It must match an existing feed and the + // field `name` must be in the format of: + // projects/project_number/feeds/feed_id or + // folders/folder_number/feeds/feed_id or + // organizations/organization_number/feeds/feed_id. + Feed feed = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. Only updates the `feed` fields indicated by this mask. + // The field mask must not be empty, and it must not contain fields that + // are immutable or only set by the server. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteFeedRequest { + // Required. The name of the feed and it must be in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudasset.googleapis.com/Feed" + } + ]; +} + +// Output configuration for export assets destination. +message OutputConfig { + // Asset export destination. + oneof destination { + // Destination on Cloud Storage. + GcsDestination gcs_destination = 1; + + // Destination on BigQuery. The output table stores the fields in asset + // proto as columns in BigQuery. The resource/iam_policy field is converted + // to a record with each field to a column, except metadata to a single JSON + // string. + BigQueryDestination bigquery_destination = 2; + } +} + +// A Cloud Storage location. +message GcsDestination { + // Required. + oneof object_uri { + // The uri of the Cloud Storage object. It's the same uri that is used by + // gsutil. For example: "gs://bucket_name/object_name". See [Viewing and + // Editing Object + // Metadata](https://cloud.google.com/storage/docs/viewing-editing-metadata) + // for more information. + string uri = 1; + + // The uri prefix of all generated Cloud Storage objects. For example: + // "gs://bucket_name/object_name_prefix". Each object uri is in format: + // "gs://bucket_name/object_name_prefix// and only + // contains assets for that type. starts from 0. For example: + // "gs://bucket_name/object_name_prefix/compute.googleapis.com/Disk/0" is + // the first shard of output objects containing all + // compute.googleapis.com/Disk assets. An INVALID_ARGUMENT error will be + // returned if file with the same name "gs://bucket_name/object_name_prefix" + // already exists. + string uri_prefix = 2; + } +} + +// A BigQuery destination. +message BigQueryDestination { + // Required. The BigQuery dataset in format + // "projects/projectId/datasets/datasetId", to which the snapshot result + // should be exported. If this dataset does not exist, the export call returns + // an INVALID_ARGUMENT error. + string dataset = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The BigQuery table to which the snapshot result should be + // written. If this table does not exist, a new table with the given name + // will be created. + string table = 2 [(google.api.field_behavior) = REQUIRED]; + + // If the destination table already exists and this flag is `TRUE`, the + // table will be overwritten by the contents of assets snapshot. If the flag + // is `FALSE` or unset and the destination table already exists, the export + // call returns an INVALID_ARGUMEMT error. + bool force = 3; +} + +// A Pub/Sub destination. +message PubsubDestination { + // The name of the Pub/Sub topic to publish to. + // For example: `projects/PROJECT_ID/topics/TOPIC_ID`. + string topic = 1; +} + +// Output configuration for asset feed destination. +message FeedOutputConfig { + // Asset feed destination. + oneof destination { + // Destination on Pub/Sub. + PubsubDestination pubsub_destination = 1; + } +} + +// An asset feed used to export asset updates to a destinations. +// An asset feed filter controls what updates are exported. +// The asset feed must be created within a project, organization, or +// folder. Supported destinations are: +// Pub/Sub topics. +message Feed { + option (google.api.resource) = { + type: "cloudasset.googleapis.com/Feed" + pattern: "projects/{project}/feeds/{feed}" + pattern: "folders/{folder}/feeds/{feed}" + pattern: "organizations/{organization}/feeds/{feed}" + history: ORIGINALLY_SINGLE_PATTERN + }; + + // Required. The format will be + // projects/{project_number}/feeds/{client-assigned_feed_identifier} or + // folders/{folder_number}/feeds/{client-assigned_feed_identifier} or + // organizations/{organization_number}/feeds/{client-assigned_feed_identifier} + // + // The client-assigned feed identifier must be unique within the parent + // project/folder/organization. + string name = 1 [(google.api.field_behavior) = REQUIRED]; + + // A list of the full names of the assets to receive updates. You must specify + // either or both of asset_names and asset_types. Only asset updates matching + // specified asset_names and asset_types are exported to the feed. For + // example: + // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`. + // See [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more info. + repeated string asset_names = 2; + + // A list of types of the assets to receive updates. You must specify either + // or both of asset_names and asset_types. Only asset updates matching + // specified asset_names and asset_types are exported to the feed. + // For example: `"compute.googleapis.com/Disk"` + // + // See [this + // topic](https://cloud.google.com/asset-inventory/docs/supported-asset-types) + // for a list of all supported asset types. + repeated string asset_types = 3; + + // Asset content type. If not specified, no content but the asset name and + // type will be returned. + ContentType content_type = 4; + + // Required. Feed output configuration defining where the asset updates are + // published to. + FeedOutputConfig feed_output_config = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// Asset content type. +enum ContentType { + // Unspecified content type. + CONTENT_TYPE_UNSPECIFIED = 0; + + // Resource metadata. + RESOURCE = 1; + + // The actual IAM policy set on a resource. + IAM_POLICY = 2; + + // The Cloud Organization Policy set on an asset. + ORG_POLICY = 4; + + // The Cloud Access context mananger Policy set on an asset. + ACCESS_POLICY = 5; +} diff --git a/baselines/asset/protos/google/cloud/asset/v1/assets.proto.baseline b/baselines/asset/protos/google/cloud/asset/v1/assets.proto.baseline new file mode 100644 index 000000000..1e8b40a11 --- /dev/null +++ b/baselines/asset/protos/google/cloud/asset/v1/assets.proto.baseline @@ -0,0 +1,172 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.asset.v1; + +import "google/api/resource.proto"; +import "google/cloud/orgpolicy/v1/orgpolicy.proto"; +import "google/iam/v1/policy.proto"; +import "google/identity/accesscontextmanager/v1/access_level.proto"; +import "google/identity/accesscontextmanager/v1/access_policy.proto"; +import "google/identity/accesscontextmanager/v1/service_perimeter.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option cc_enable_arenas = true; +option csharp_namespace = "Google.Cloud.Asset.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/asset/v1;asset"; +option java_multiple_files = true; +option java_outer_classname = "AssetProto"; +option java_package = "com.google.cloud.asset.v1"; +option php_namespace = "Google\\Cloud\\Asset\\V1"; + +// An asset in Google Cloud and its temporal metadata, including the time window +// when it was observed and its status during that window. +message TemporalAsset { + // The time window when the asset data and state was observed. + TimeWindow window = 1; + + // Whether the asset has been deleted or not. + bool deleted = 2; + + // An asset in Google Cloud. + Asset asset = 3; +} + +// A time window specified by its "start_time" and "end_time". +message TimeWindow { + // Start time of the time window (exclusive). + google.protobuf.Timestamp start_time = 1; + + // End time of the time window (inclusive). If not specified, the current + // timestamp is used instead. + google.protobuf.Timestamp end_time = 2; +} + +// An asset in Google Cloud. An asset can be any resource in the Google Cloud +// [resource +// hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy), +// a resource outside the Google Cloud resource hierarchy (such as Google +// Kubernetes Engine clusters and objects), or a Cloud IAM policy. +message Asset { + option (google.api.resource) = { + type: "cloudasset.googleapis.com/Asset" + pattern: "*" + }; + + // The full name of the asset. For example: + // "//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1" + // + // See [Resource + // names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more information. + string name = 1; + + // The type of the asset. For example: "compute.googleapis.com/Disk" + // + // See [Supported asset + // types](https://cloud.google.com/asset-inventory/docs/supported-asset-types) + // for more information. + string asset_type = 2; + + // A representation of the resource. + Resource resource = 3; + + // A representation of the Cloud IAM policy set on a Google Cloud resource. + // There can be a maximum of one Cloud IAM policy set on any given resource. + // In addition, Cloud IAM policies inherit their granted access scope from any + // policies set on parent resources in the resource hierarchy. Therefore, the + // effectively policy is the union of both the policy set on this resource + // and each policy set on all of the resource's ancestry resource levels in + // the hierarchy. See + // [this topic](https://cloud.google.com/iam/docs/policies#inheritance) for + // more information. + google.iam.v1.Policy iam_policy = 4; + + // A representation of an [organization + // policy](https://cloud.google.com/resource-manager/docs/organization-policy/overview#organization_policy). + // There can be more than one organization policy with different constraints + // set on a given resource. + repeated google.cloud.orgpolicy.v1.Policy org_policy = 6; + + // A representation of an [access + // policy](https://cloud.google.com/access-context-manager/docs/overview#access-policies). + oneof access_context_policy { + google.identity.accesscontextmanager.v1.AccessPolicy access_policy = 7; + + google.identity.accesscontextmanager.v1.AccessLevel access_level = 8; + + google.identity.accesscontextmanager.v1.ServicePerimeter service_perimeter = 9; + } + + // The ancestry path of an asset in Google Cloud [resource + // hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy), + // represented as a list of relative resource names. An ancestry path starts + // with the closest ancestor in the hierarchy and ends at root. If the asset + // is a project, folder, or organization, the ancestry path starts from the + // asset itself. + // + // For example: `["projects/123456789", "folders/5432", "organizations/1234"]` + repeated string ancestors = 10; +} + +// A representation of a Google Cloud resource. +message Resource { + // The API version. For example: "v1" + string version = 1; + + // The URL of the discovery document containing the resource's JSON schema. + // For example: + // "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest" + // + // This value is unspecified for resources that do not have an API based on a + // discovery document, such as Cloud Bigtable. + string discovery_document_uri = 2; + + // The JSON schema name listed in the discovery document. For example: + // "Project" + // + // This value is unspecified for resources that do not have an API based on a + // discovery document, such as Cloud Bigtable. + string discovery_name = 3; + + // The REST URL for accessing the resource. An HTTP `GET` request using this + // URL returns the resource itself. For example: + // "https://cloudresourcemanager.googleapis.com/v1/projects/my-project-123" + // + // This value is unspecified for resources without a REST API. + string resource_url = 4; + + // The full name of the immediate parent of this resource. See + // [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more information. + // + // For Google Cloud assets, this value is the parent resource defined in the + // [Cloud IAM policy + // hierarchy](https://cloud.google.com/iam/docs/overview#policy_hierarchy). + // For example: + // "//cloudresourcemanager.googleapis.com/projects/my_project_123" + // + // For third-party assets, this field may be set differently. + string parent = 5; + + // The content of the resource, in which some sensitive fields are removed + // and may not be present. + google.protobuf.Struct data = 6; +} diff --git a/baselines/asset/protos/google/cloud/common_resources.proto.baseline b/baselines/asset/protos/google/cloud/common_resources.proto.baseline new file mode 100644 index 000000000..a2f46cea3 --- /dev/null +++ b/baselines/asset/protos/google/cloud/common_resources.proto.baseline @@ -0,0 +1,52 @@ +// Copyright 2020 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This file contains stub messages for common resources in GCP. +// It is not intended to be directly generated, and is instead used by +// other tooling to be able to match common resource patterns. +syntax = "proto3"; + +package google.cloud; + +import "google/api/resource.proto"; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Project" + pattern: "projects/{project}" +}; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Organization" + pattern: "organizations/{organization}" +}; + + +option (google.api.resource_definition) = { + type: "cloudresourcemanager.googleapis.com/Folder" + pattern: "folders/{folder}" +}; + + +option (google.api.resource_definition) = { + type: "cloudbilling.googleapis.com/BillingAccount" + pattern: "billingAccounts/{billing_account}" +}; + +option (google.api.resource_definition) = { + type: "locations.googleapis.com/Location" + pattern: "projects/{project}/locations/{location}" +}; + diff --git a/baselines/asset/protos/google/cloud/orgpolicy/v1/orgpolicy.proto.baseline b/baselines/asset/protos/google/cloud/orgpolicy/v1/orgpolicy.proto.baseline new file mode 100644 index 000000000..fbd62df6f --- /dev/null +++ b/baselines/asset/protos/google/cloud/orgpolicy/v1/orgpolicy.proto.baseline @@ -0,0 +1,315 @@ +// Copyright 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; + +package google.cloud.orgpolicy.v1; + +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Cloud.OrgPolicy.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/orgpolicy/v1;orgpolicy"; +option java_multiple_files = true; +option java_outer_classname = "OrgPolicyProto"; +option java_package = "com.google.cloud.orgpolicy.v1"; +option php_namespace = "Google\\Cloud\\OrgPolicy\\V1"; +option ruby_package = "Google::Cloud::OrgPolicy::V1"; + +// Defines a Cloud Organization `Policy` which is used to specify `Constraints` +// for configurations of Cloud Platform resources. +message Policy { + // Used in `policy_type` to specify how `list_policy` behaves at this + // resource. + // + // `ListPolicy` can define specific values and subtrees of Cloud Resource + // Manager resource hierarchy (`Organizations`, `Folders`, `Projects`) that + // are allowed or denied by setting the `allowed_values` and `denied_values` + // fields. This is achieved by using the `under:` and optional `is:` prefixes. + // The `under:` prefix is used to denote resource subtree values. + // The `is:` prefix is used to denote specific values, and is required only + // if the value contains a ":". Values prefixed with "is:" are treated the + // same as values with no prefix. + // Ancestry subtrees must be in one of the following formats: + // - "projects/", e.g. "projects/tokyo-rain-123" + // - "folders/", e.g. "folders/1234" + // - "organizations/", e.g. "organizations/1234" + // The `supports_under` field of the associated `Constraint` defines whether + // ancestry prefixes can be used. You can set `allowed_values` and + // `denied_values` in the same `Policy` if `all_values` is + // `ALL_VALUES_UNSPECIFIED`. `ALLOW` or `DENY` are used to allow or deny all + // values. If `all_values` is set to either `ALLOW` or `DENY`, + // `allowed_values` and `denied_values` must be unset. + message ListPolicy { + // This enum can be used to set `Policies` that apply to all possible + // configuration values rather than specific values in `allowed_values` or + // `denied_values`. + // + // Settting this to `ALLOW` will mean this `Policy` allows all values. + // Similarly, setting it to `DENY` will mean no values are allowed. If + // set to either `ALLOW` or `DENY, `allowed_values` and `denied_values` + // must be unset. Setting this to `ALL_VALUES_UNSPECIFIED` allows for + // setting `allowed_values` and `denied_values`. + enum AllValues { + // Indicates that allowed_values or denied_values must be set. + ALL_VALUES_UNSPECIFIED = 0; + + // A policy with this set allows all values. + ALLOW = 1; + + // A policy with this set denies all values. + DENY = 2; + } + + // List of values allowed at this resource. Can only be set if `all_values` + // is set to `ALL_VALUES_UNSPECIFIED`. + repeated string allowed_values = 1; + + // List of values denied at this resource. Can only be set if `all_values` + // is set to `ALL_VALUES_UNSPECIFIED`. + repeated string denied_values = 2; + + // The policy all_values state. + AllValues all_values = 3; + + // Optional. The Google Cloud Console will try to default to a configuration + // that matches the value specified in this `Policy`. If `suggested_value` + // is not set, it will inherit the value specified higher in the hierarchy, + // unless `inherit_from_parent` is `false`. + string suggested_value = 4; + + // Determines the inheritance behavior for this `Policy`. + // + // By default, a `ListPolicy` set at a resource supercedes any `Policy` set + // anywhere up the resource hierarchy. However, if `inherit_from_parent` is + // set to `true`, then the values from the effective `Policy` of the parent + // resource are inherited, meaning the values set in this `Policy` are + // added to the values inherited up the hierarchy. + // + // Setting `Policy` hierarchies that inherit both allowed values and denied + // values isn't recommended in most circumstances to keep the configuration + // simple and understandable. However, it is possible to set a `Policy` with + // `allowed_values` set that inherits a `Policy` with `denied_values` set. + // In this case, the values that are allowed must be in `allowed_values` and + // not present in `denied_values`. + // + // For example, suppose you have a `Constraint` + // `constraints/serviceuser.services`, which has a `constraint_type` of + // `list_constraint`, and with `constraint_default` set to `ALLOW`. + // Suppose that at the Organization level, a `Policy` is applied that + // restricts the allowed API activations to {`E1`, `E2`}. Then, if a + // `Policy` is applied to a project below the Organization that has + // `inherit_from_parent` set to `false` and field all_values set to DENY, + // then an attempt to activate any API will be denied. + // + // The following examples demonstrate different possible layerings for + // `projects/bar` parented by `organizations/foo`: + // + // Example 1 (no inherited values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has `inherit_from_parent` `false` and values: + // {allowed_values: "E3" allowed_values: "E4"} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are `E3`, and `E4`. + // + // Example 2 (inherited values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has a `Policy` with values: + // {value: "E3" value: "E4" inherit_from_parent: true} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are `E1`, `E2`, `E3`, and `E4`. + // + // Example 3 (inheriting both allowed and denied values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {denied_values: "E1"} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The value accepted at `projects/bar` is `E2`. + // + // Example 4 (RestoreDefault): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has a `Policy` with values: + // {RestoreDefault: {}} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are either all or none depending on + // the value of `constraint_default` (if `ALLOW`, all; if + // `DENY`, none). + // + // Example 5 (no policy inherits parent policy): + // `organizations/foo` has no `Policy` set. + // `projects/bar` has no `Policy` set. + // The accepted values at both levels are either all or none depending on + // the value of `constraint_default` (if `ALLOW`, all; if + // `DENY`, none). + // + // Example 6 (ListConstraint allowing all): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {all: ALLOW} + // The accepted values at `organizations/foo` are `E1`, E2`. + // Any value is accepted at `projects/bar`. + // + // Example 7 (ListConstraint allowing none): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {all: DENY} + // The accepted values at `organizations/foo` are `E1`, E2`. + // No value is accepted at `projects/bar`. + // + // Example 10 (allowed and denied subtrees of Resource Manager hierarchy): + // Given the following resource hierarchy + // O1->{F1, F2}; F1->{P1}; F2->{P2, P3}, + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "under:organizations/O1"} + // `projects/bar` has a `Policy` with: + // {allowed_values: "under:projects/P3"} + // {denied_values: "under:folders/F2"} + // The accepted values at `organizations/foo` are `organizations/O1`, + // `folders/F1`, `folders/F2`, `projects/P1`, `projects/P2`, + // `projects/P3`. + // The accepted values at `projects/bar` are `organizations/O1`, + // `folders/F1`, `projects/P1`. + bool inherit_from_parent = 5; + } + + // Used in `policy_type` to specify how `boolean_policy` will behave at this + // resource. + message BooleanPolicy { + // If `true`, then the `Policy` is enforced. If `false`, then any + // configuration is acceptable. + // + // Suppose you have a `Constraint` + // `constraints/compute.disableSerialPortAccess` with `constraint_default` + // set to `ALLOW`. A `Policy` for that `Constraint` exhibits the following + // behavior: + // - If the `Policy` at this resource has enforced set to `false`, serial + // port connection attempts will be allowed. + // - If the `Policy` at this resource has enforced set to `true`, serial + // port connection attempts will be refused. + // - If the `Policy` at this resource is `RestoreDefault`, serial port + // connection attempts will be allowed. + // - If no `Policy` is set at this resource or anywhere higher in the + // resource hierarchy, serial port connection attempts will be allowed. + // - If no `Policy` is set at this resource, but one exists higher in the + // resource hierarchy, the behavior is as if the`Policy` were set at + // this resource. + // + // The following examples demonstrate the different possible layerings: + // + // Example 1 (nearest `Constraint` wins): + // `organizations/foo` has a `Policy` with: + // {enforced: false} + // `projects/bar` has no `Policy` set. + // The constraint at `projects/bar` and `organizations/foo` will not be + // enforced. + // + // Example 2 (enforcement gets replaced): + // `organizations/foo` has a `Policy` with: + // {enforced: false} + // `projects/bar` has a `Policy` with: + // {enforced: true} + // The constraint at `organizations/foo` is not enforced. + // The constraint at `projects/bar` is enforced. + // + // Example 3 (RestoreDefault): + // `organizations/foo` has a `Policy` with: + // {enforced: true} + // `projects/bar` has a `Policy` with: + // {RestoreDefault: {}} + // The constraint at `organizations/foo` is enforced. + // The constraint at `projects/bar` is not enforced, because + // `constraint_default` for the `Constraint` is `ALLOW`. + bool enforced = 1; + } + + // Ignores policies set above this resource and restores the + // `constraint_default` enforcement behavior of the specific `Constraint` at + // this resource. + // + // Suppose that `constraint_default` is set to `ALLOW` for the + // `Constraint` `constraints/serviceuser.services`. Suppose that organization + // foo.com sets a `Policy` at their Organization resource node that restricts + // the allowed service activations to deny all service activations. They + // could then set a `Policy` with the `policy_type` `restore_default` on + // several experimental projects, restoring the `constraint_default` + // enforcement of the `Constraint` for only those projects, allowing those + // projects to have all services activated. + message RestoreDefault { + + } + + // Version of the `Policy`. Default version is 0; + int32 version = 1; + + // The name of the `Constraint` the `Policy` is configuring, for example, + // `constraints/serviceuser.services`. + // + // Immutable after creation. + string constraint = 2; + + // An opaque tag indicating the current version of the `Policy`, used for + // concurrency control. + // + // When the `Policy` is returned from either a `GetPolicy` or a + // `ListOrgPolicy` request, this `etag` indicates the version of the current + // `Policy` to use when executing a read-modify-write loop. + // + // When the `Policy` is returned from a `GetEffectivePolicy` request, the + // `etag` will be unset. + // + // When the `Policy` is used in a `SetOrgPolicy` method, use the `etag` value + // that was returned from a `GetOrgPolicy` request as part of a + // read-modify-write loop for concurrency control. Not setting the `etag`in a + // `SetOrgPolicy` request will result in an unconditional write of the + // `Policy`. + bytes etag = 3; + + // The time stamp the `Policy` was previously updated. This is set by the + // server, not specified by the caller, and represents the last time a call to + // `SetOrgPolicy` was made for that `Policy`. Any value set by the client will + // be ignored. + google.protobuf.Timestamp update_time = 4; + + // The field to populate is based on the `constraint_type` value in the + // `Constraint`. + // `list_constraint` => `list_policy` + // `boolean_constraint` => `boolean_policy` + // + // A `restore_default` message may be used with any `Constraint` type. + // + // Providing a *_policy that is incompatible with the `constraint_type` will + // result in an `invalid_argument` error. + // + // Attempting to set a `Policy` with a `policy_type` not set will result in an + // `invalid_argument` error. + oneof policy_type { + // List of values either allowed or disallowed. + ListPolicy list_policy = 5; + + // For boolean `Constraints`, whether to enforce the `Constraint` or not. + BooleanPolicy boolean_policy = 6; + + // Restores the default behavior of the constraint; independent of + // `Constraint` type. + RestoreDefault restore_default = 7; + } +} diff --git a/baselines/asset/protos/google/identity/accesscontextmanager/type/device_resources.proto.baseline b/baselines/asset/protos/google/identity/accesscontextmanager/type/device_resources.proto.baseline new file mode 100644 index 000000000..f05791033 --- /dev/null +++ b/baselines/asset/protos/google/identity/accesscontextmanager/type/device_resources.proto.baseline @@ -0,0 +1,85 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.type; + +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.Type"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/type;type"; +option java_package = "com.google.identity.accesscontextmanager.type"; +option java_multiple_files = true; +option java_outer_classname = "TypeProto"; +option php_namespace = "Google\\Identity\\AccessContextManager\\Type"; +option ruby_package = "Google::Identity::AccessContextManager::Type"; + +// The encryption state of the device. +enum DeviceEncryptionStatus { + // The encryption status of the device is not specified or not known. + ENCRYPTION_UNSPECIFIED = 0; + + // The device does not support encryption. + ENCRYPTION_UNSUPPORTED = 1; + + // The device supports encryption, but is currently unencrypted. + UNENCRYPTED = 2; + + // The device is encrypted. + ENCRYPTED = 3; +} + +// The operating system type of the device. +// Next id: 7 +enum OsType { + // The operating system of the device is not specified or not known. + OS_UNSPECIFIED = 0; + + // A desktop Mac operating system. + DESKTOP_MAC = 1; + + // A desktop Windows operating system. + DESKTOP_WINDOWS = 2; + + // A desktop Linux operating system. + DESKTOP_LINUX = 3; + + // A desktop ChromeOS operating system. + DESKTOP_CHROME_OS = 6; + + // An Android operating system. + ANDROID = 4; + + // An iOS operating system. + IOS = 5; +} + +// The degree to which the device is managed by the Cloud organization. +enum DeviceManagementLevel { + // The device's management level is not specified or not known. + MANAGEMENT_UNSPECIFIED = 0; + + // The device is not managed. + NONE = 1; + + // Basic management is enabled, which is generally limited to monitoring and + // wiping the corporate account. + BASIC = 2; + + // Complete device management. This includes more thorough monitoring and the + // ability to directly manage the device (such as remote wiping). This can be + // enabled through the Android Enterprise Platform. + COMPLETE = 3; +} diff --git a/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_level.proto.baseline b/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_level.proto.baseline new file mode 100644 index 000000000..0ebd1936c --- /dev/null +++ b/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_level.proto.baseline @@ -0,0 +1,187 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/identity/accesscontextmanager/type/device_resources.proto"; +import "google/protobuf/timestamp.proto"; +import "google/type/expr.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "AccessLevelProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// An `AccessLevel` is a label that can be applied to requests to Google Cloud +// services, along with a list of requirements necessary for the label to be +// applied. +message AccessLevel { + // Required. Resource name for the Access Level. The `short_name` component + // must begin with a letter and only include alphanumeric and '_'. Format: + // `accessPolicies/{policy_id}/accessLevels/{short_name}`. The maximum length + // of the `short_name` component is 50 characters. + string name = 1; + + // Human readable title. Must be unique within the Policy. + string title = 2; + + // Description of the `AccessLevel` and its use. Does not affect behavior. + string description = 3; + + // Required. Describes the necessary conditions for the level to apply. + oneof level { + // A `BasicLevel` composed of `Conditions`. + BasicLevel basic = 4; + + // A `CustomLevel` written in the Common Expression Language. + CustomLevel custom = 5; + } + + // Output only. Time the `AccessLevel` was created in UTC. + google.protobuf.Timestamp create_time = 6; + + // Output only. Time the `AccessLevel` was updated in UTC. + google.protobuf.Timestamp update_time = 7; +} + +// `BasicLevel` is an `AccessLevel` using a set of recommended features. +message BasicLevel { + // Options for how the `conditions` list should be combined to determine if + // this `AccessLevel` is applied. Default is AND. + enum ConditionCombiningFunction { + // All `Conditions` must be true for the `BasicLevel` to be true. + AND = 0; + + // If at least one `Condition` is true, then the `BasicLevel` is true. + OR = 1; + } + + // Required. A list of requirements for the `AccessLevel` to be granted. + repeated Condition conditions = 1; + + // How the `conditions` list should be combined to determine if a request is + // granted this `AccessLevel`. If AND is used, each `Condition` in + // `conditions` must be satisfied for the `AccessLevel` to be applied. If OR + // is used, at least one `Condition` in `conditions` must be satisfied for the + // `AccessLevel` to be applied. Default behavior is AND. + ConditionCombiningFunction combining_function = 2; +} + +// A condition necessary for an `AccessLevel` to be granted. The Condition is an +// AND over its fields. So a Condition is true if: 1) the request IP is from one +// of the listed subnetworks AND 2) the originating device complies with the +// listed device policy AND 3) all listed access levels are granted AND 4) the +// request was sent at a time allowed by the DateTimeRestriction. +message Condition { + // CIDR block IP subnetwork specification. May be IPv4 or IPv6. Note that for + // a CIDR IP address block, the specified IP address portion must be properly + // truncated (i.e. all the host bits must be zero) or the input is considered + // malformed. For example, "192.0.2.0/24" is accepted but "192.0.2.1/24" is + // not. Similarly, for IPv6, "2001:db8::/32" is accepted whereas + // "2001:db8::1/32" is not. The originating IP of a request must be in one of + // the listed subnets in order for this Condition to be true. If empty, all IP + // addresses are allowed. + repeated string ip_subnetworks = 1; + + // Device specific restrictions, all restrictions must hold for the + // Condition to be true. If not specified, all devices are allowed. + DevicePolicy device_policy = 2; + + // A list of other access levels defined in the same `Policy`, referenced by + // resource name. Referencing an `AccessLevel` which does not exist is an + // error. All access levels listed must be granted for the Condition + // to be true. Example: + // "`accessPolicies/MY_POLICY/accessLevels/LEVEL_NAME"` + repeated string required_access_levels = 3; + + // Whether to negate the Condition. If true, the Condition becomes a NAND over + // its non-empty fields, each field must be false for the Condition overall to + // be satisfied. Defaults to false. + bool negate = 5; + + // The request must be made by one of the provided user or service + // accounts. Groups are not supported. + // Syntax: + // `user:{emailid}` + // `serviceAccount:{emailid}` + // If not specified, a request may come from any user. + repeated string members = 6; + + // The request must originate from one of the provided countries/regions. + // Must be valid ISO 3166-1 alpha-2 codes. + repeated string regions = 7; +} + +// `CustomLevel` is an `AccessLevel` using the Cloud Common Expression Language +// to represent the necessary conditions for the level to apply to a request. +// See CEL spec at: https://github.com/google/cel-spec +message CustomLevel { + // Required. A Cloud CEL expression evaluating to a boolean. + google.type.Expr expr = 1; +} + +// `DevicePolicy` specifies device specific restrictions necessary to acquire a +// given access level. A `DevicePolicy` specifies requirements for requests from +// devices to be granted access levels, it does not do any enforcement on the +// device. `DevicePolicy` acts as an AND over all specified fields, and each +// repeated field is an OR over its elements. Any unset fields are ignored. For +// example, if the proto is { os_type : DESKTOP_WINDOWS, os_type : +// DESKTOP_LINUX, encryption_status: ENCRYPTED}, then the DevicePolicy will be +// true for requests originating from encrypted Linux desktops and encrypted +// Windows desktops. +message DevicePolicy { + // Whether or not screenlock is required for the DevicePolicy to be true. + // Defaults to `false`. + bool require_screenlock = 1; + + // Allowed encryptions statuses, an empty list allows all statuses. + repeated google.identity.accesscontextmanager.type.DeviceEncryptionStatus allowed_encryption_statuses = 2; + + // Allowed OS versions, an empty list allows all types and all versions. + repeated OsConstraint os_constraints = 3; + + // Allowed device management levels, an empty list allows all management + // levels. + repeated google.identity.accesscontextmanager.type.DeviceManagementLevel allowed_device_management_levels = 6; + + // Whether the device needs to be approved by the customer admin. + bool require_admin_approval = 7; + + // Whether the device needs to be corp owned. + bool require_corp_owned = 8; +} + +// A restriction on the OS type and version of devices making requests. +message OsConstraint { + // Required. The allowed OS type. + google.identity.accesscontextmanager.type.OsType os_type = 1; + + // The minimum allowed OS version. If not set, any version of this OS + // satisfies the constraint. Format: `"major.minor.patch"`. + // Examples: `"10.5.301"`, `"9.2.1"`. + string minimum_version = 2; + + // Only allows requests from devices with a verified Chrome OS. + // Verifications includes requirements that the device is enterprise-managed, + // conformant to domain policies, and the caller has permission to call + // the API targeted by the request. + bool require_verified_chrome_os = 3; +} diff --git a/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_policy.proto.baseline b/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_policy.proto.baseline new file mode 100644 index 000000000..9ec59d1c1 --- /dev/null +++ b/baselines/asset/protos/google/identity/accesscontextmanager/v1/access_policy.proto.baseline @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "PolicyProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// `AccessPolicy` is a container for `AccessLevels` (which define the necessary +// attributes to use Google Cloud services) and `ServicePerimeters` (which +// define regions of services able to freely pass data within a perimeter). An +// access policy is globally visible within an organization, and the +// restrictions it specifies apply to all projects within an organization. +message AccessPolicy { + // Output only. Resource name of the `AccessPolicy`. Format: + // `accessPolicies/{policy_id}` + string name = 1; + + // Required. The parent of this `AccessPolicy` in the Cloud Resource + // Hierarchy. Currently immutable once created. Format: + // `organizations/{organization_id}` + string parent = 2; + + // Required. Human readable title. Does not affect behavior. + string title = 3; + + // Output only. Time the `AccessPolicy` was created in UTC. + google.protobuf.Timestamp create_time = 4; + + // Output only. Time the `AccessPolicy` was updated in UTC. + google.protobuf.Timestamp update_time = 5; + + // Output only. An opaque identifier for the current version of the + // `AccessPolicy`. This will always be a strongly validated etag, meaning that + // two Access Polices will be identical if and only if their etags are + // identical. Clients should not expect this to be in any specific format. + string etag = 6; +} diff --git a/baselines/asset/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto.baseline b/baselines/asset/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto.baseline new file mode 100644 index 000000000..89d76818d --- /dev/null +++ b/baselines/asset/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto.baseline @@ -0,0 +1,152 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "ServicePerimeterProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// `ServicePerimeter` describes a set of Google Cloud resources which can freely +// import and export data amongst themselves, but not export outside of the +// `ServicePerimeter`. If a request with a source within this `ServicePerimeter` +// has a target outside of the `ServicePerimeter`, the request will be blocked. +// Otherwise the request is allowed. There are two types of Service Perimeter - +// Regular and Bridge. Regular Service Perimeters cannot overlap, a single +// Google Cloud project can only belong to a single regular Service Perimeter. +// Service Perimeter Bridges can contain only Google Cloud projects as members, +// a single Google Cloud project may belong to multiple Service Perimeter +// Bridges. +message ServicePerimeter { + // Specifies the type of the Perimeter. There are two types: regular and + // bridge. Regular Service Perimeter contains resources, access levels, and + // restricted services. Every resource can be in at most ONE + // regular Service Perimeter. + // + // In addition to being in a regular service perimeter, a resource can also + // be in zero or more perimeter bridges. A perimeter bridge only contains + // resources. Cross project operations are permitted if all effected + // resources share some perimeter (whether bridge or regular). Perimeter + // Bridge does not contain access levels or services: those are governed + // entirely by the regular perimeter that resource is in. + // + // Perimeter Bridges are typically useful when building more complex toplogies + // with many independent perimeters that need to share some data with a common + // perimeter, but should not be able to share data among themselves. + enum PerimeterType { + // Regular Perimeter. + PERIMETER_TYPE_REGULAR = 0; + + // Perimeter Bridge. + PERIMETER_TYPE_BRIDGE = 1; + } + + // Required. Resource name for the ServicePerimeter. The `short_name` + // component must begin with a letter and only include alphanumeric and '_'. + // Format: `accessPolicies/{policy_id}/servicePerimeters/{short_name}` + string name = 1; + + // Human readable title. Must be unique within the Policy. + string title = 2; + + // Description of the `ServicePerimeter` and its use. Does not affect + // behavior. + string description = 3; + + // Output only. Time the `ServicePerimeter` was created in UTC. + google.protobuf.Timestamp create_time = 4; + + // Output only. Time the `ServicePerimeter` was updated in UTC. + google.protobuf.Timestamp update_time = 5; + + // Perimeter type indicator. A single project is + // allowed to be a member of single regular perimeter, but multiple service + // perimeter bridges. A project cannot be a included in a perimeter bridge + // without being included in regular perimeter. For perimeter bridges, + // the restricted service list as well as access level lists must be + // empty. + PerimeterType perimeter_type = 6; + + // Current ServicePerimeter configuration. Specifies sets of resources, + // restricted services and access levels that determine perimeter + // content and boundaries. + ServicePerimeterConfig status = 7; + + // Proposed (or dry run) ServicePerimeter configuration. This configuration + // allows to specify and test ServicePerimeter configuration without enforcing + // actual access restrictions. Only allowed to be set when the + // "use_explicit_dry_run_spec" flag is set. + ServicePerimeterConfig spec = 8; + + // Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly + // exists for all Service Perimeters, and that spec is identical to the + // status for those Service Perimeters. When this flag is set, it inhibits the + // generation of the implicit spec, thereby allowing the user to explicitly + // provide a configuration ("spec") to use in a dry-run version of the Service + // Perimeter. This allows the user to test changes to the enforced config + // ("status") without actually enforcing them. This testing is done through + // analyzing the differences between currently enforced and suggested + // restrictions. use_explicit_dry_run_spec must bet set to True if any of the + // fields in the spec are set to non-default values. + bool use_explicit_dry_run_spec = 9; +} + +// `ServicePerimeterConfig` specifies a set of Google Cloud resources that +// describe specific Service Perimeter configuration. +message ServicePerimeterConfig { + // Specifies how APIs are allowed to communicate within the Service + // Perimeter. + message VpcAccessibleServices { + // Whether to restrict API calls within the Service Perimeter to the list of + // APIs specified in 'allowed_services'. + bool enable_restriction = 1; + + // The list of APIs usable within the Service Perimeter. Must be empty + // unless 'enable_restriction' is True. + repeated string allowed_services = 2; + } + + // A list of Google Cloud resources that are inside of the service perimeter. + // Currently only projects are allowed. Format: `projects/{project_number}` + repeated string resources = 1; + + // A list of `AccessLevel` resource names that allow resources within the + // `ServicePerimeter` to be accessed from the internet. `AccessLevels` listed + // must be in the same policy as this `ServicePerimeter`. Referencing a + // nonexistent `AccessLevel` is a syntax error. If no `AccessLevel` names are + // listed, resources within the perimeter can only be accessed via Google + // Cloud calls with request origins within the perimeter. Example: + // `"accessPolicies/MY_POLICY/accessLevels/MY_LEVEL"`. + // For Service Perimeter Bridge, must be empty. + repeated string access_levels = 2; + + // Google Cloud services that are subject to the Service Perimeter + // restrictions. For example, if `storage.googleapis.com` is specified, access + // to the storage buckets inside the perimeter must meet the perimeter's + // access restrictions. + repeated string restricted_services = 4; + + // Configuration for APIs allowed within Perimeter. + VpcAccessibleServices vpc_accessible_services = 10; +} diff --git a/baselines/asset/src/index.ts.baseline b/baselines/asset/src/index.ts.baseline new file mode 100644 index 000000000..9b957edcb --- /dev/null +++ b/baselines/asset/src/index.ts.baseline @@ -0,0 +1,24 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import * as v1 from './v1'; +const AssetServiceClient = v1.AssetServiceClient; +export {v1, AssetServiceClient}; +export default {v1, AssetServiceClient}; +import * as protos from '../protos/protos'; +export {protos} diff --git a/baselines/asset/src/v1/asset_service_client.ts.baseline b/baselines/asset/src/v1/asset_service_client.ts.baseline new file mode 100644 index 000000000..5b0af65eb --- /dev/null +++ b/baselines/asset/src/v1/asset_service_client.ts.baseline @@ -0,0 +1,995 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import * as gax from 'google-gax'; +import {Callback, CallOptions, Descriptors, ClientOptions, LROperation} from 'google-gax'; +import * as path from 'path'; + +import * as protos from '../../protos/protos'; +import * as gapicConfig from './asset_service_client_config.json'; +import { operationsProtos } from 'google-gax'; +const version = require('../../../package.json').version; + +/** + * Asset service definition. + * @class + * @memberof v1 + */ +export class AssetServiceClient { + private _terminated = false; + private _opts: ClientOptions; + private _gaxModule: typeof gax | typeof gax.fallback; + private _gaxGrpc: gax.GrpcClient | gax.fallback.GrpcClient; + private _protos: {}; + private _defaults: {[method: string]: gax.CallSettings}; + auth: gax.GoogleAuth; + descriptors: Descriptors = {page: {}, stream: {}, longrunning: {}, batching: {}}; + innerApiCalls: {[name: string]: Function}; + pathTemplates: {[name: string]: gax.PathTemplate}; + operationsClient: gax.OperationsClient; + assetServiceStub?: Promise<{[name: string]: Function}>; + + /** + * Construct an instance of AssetServiceClient. + * + * @param {object} [options] - The configuration object. See the subsequent + * parameters for more details. + * @param {object} [options.credentials] - Credentials object. + * @param {string} [options.credentials.client_email] + * @param {string} [options.credentials.private_key] + * @param {string} [options.email] - Account email address. Required when + * using a .pem or .p12 keyFilename. + * @param {string} [options.keyFilename] - Full path to the a .json, .pem, or + * .p12 key downloaded from the Google Developers Console. If you provide + * a path to a JSON file, the projectId option below is not necessary. + * NOTE: .pem and .p12 require you to specify options.email as well. + * @param {number} [options.port] - The port on which to connect to + * the remote host. + * @param {string} [options.projectId] - The project ID from the Google + * Developer's Console, e.g. 'grape-spaceship-123'. We will also check + * the environment variable GCLOUD_PROJECT for your project ID. If your + * app is running in an environment which supports + * {@link https://developers.google.com/identity/protocols/application-default-credentials Application Default Credentials}, + * your project ID will be detected automatically. + * @param {string} [options.apiEndpoint] - The domain name of the + * API remote host. + */ + + constructor(opts?: ClientOptions) { + // Ensure that options include the service address and port. + const staticMembers = this.constructor as typeof AssetServiceClient; + const servicePath = opts && opts.servicePath ? + opts.servicePath : + ((opts && opts.apiEndpoint) ? opts.apiEndpoint : + staticMembers.servicePath); + const port = opts && opts.port ? opts.port : staticMembers.port; + + if (!opts) { + opts = {servicePath, port}; + } + opts.servicePath = opts.servicePath || servicePath; + opts.port = opts.port || port; + opts.clientConfig = opts.clientConfig || {}; + + const isBrowser = (typeof window !== 'undefined'); + if (isBrowser){ + opts.fallback = true; + } + // If we are in browser, we are already using fallback because of the + // "browser" field in package.json. + // But if we were explicitly requested to use fallback, let's do it now. + this._gaxModule = !isBrowser && opts.fallback ? gax.fallback : gax; + + // Create a `gaxGrpc` object, with any grpc-specific options + // sent to the client. + opts.scopes = (this.constructor as typeof AssetServiceClient).scopes; + this._gaxGrpc = new this._gaxModule.GrpcClient(opts); + + // Save options to use in initialize() method. + this._opts = opts; + + // Save the auth object to the client, for use by other methods. + this.auth = (this._gaxGrpc.auth as gax.GoogleAuth); + + // Determine the client header string. + const clientHeader = [ + `gax/${this._gaxModule.version}`, + `gapic/${version}`, + ]; + if (typeof process !== 'undefined' && 'versions' in process) { + clientHeader.push(`gl-node/${process.versions.node}`); + } else { + clientHeader.push(`gl-web/${this._gaxModule.version}`); + } + if (!opts.fallback) { + clientHeader.push(`grpc/${this._gaxGrpc.grpcVersion}`); + } + if (opts.libName && opts.libVersion) { + clientHeader.push(`${opts.libName}/${opts.libVersion}`); + } + // Load the applicable protos. + // For Node.js, pass the path to JSON proto file. + // For browsers, pass the JSON content. + + const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json'); + this._protos = this._gaxGrpc.loadProto( + opts.fallback ? + // eslint-disable-next-line @typescript-eslint/no-var-requires + require("../../protos/protos.json") : + nodejsProtoPath + ); + + // This API contains "path templates"; forward-slash-separated + // identifiers to uniquely identify resources within the API. + // Create useful helper objects for these. + this.pathTemplates = { + folderFeedPathTemplate: new this._gaxModule.PathTemplate( + 'folders/{folder}/feeds/{feed}' + ), + organizationFeedPathTemplate: new this._gaxModule.PathTemplate( + 'organizations/{organization}/feeds/{feed}' + ), + projectFeedPathTemplate: new this._gaxModule.PathTemplate( + 'projects/{project}/feeds/{feed}' + ), + }; + + // This API contains "long-running operations", which return a + // an Operation object that allows for tracking of the operation, + // rather than holding a request open. + const protoFilesRoot = opts.fallback ? + this._gaxModule.protobuf.Root.fromJSON( + // eslint-disable-next-line @typescript-eslint/no-var-requires + require("../../protos/protos.json")) : + this._gaxModule.protobuf.loadSync(nodejsProtoPath); + + this.operationsClient = this._gaxModule.lro({ + auth: this.auth, + grpc: 'grpc' in this._gaxGrpc ? this._gaxGrpc.grpc : undefined + }).operationsClient(opts); + const exportAssetsResponse = protoFilesRoot.lookup( + '.google.cloud.asset.v1.ExportAssetsResponse') as gax.protobuf.Type; + const exportAssetsMetadata = protoFilesRoot.lookup( + '.google.cloud.asset.v1.ExportAssetsRequest') as gax.protobuf.Type; + + this.descriptors.longrunning = { + exportAssets: new this._gaxModule.LongrunningDescriptor( + this.operationsClient, + exportAssetsResponse.decode.bind(exportAssetsResponse), + exportAssetsMetadata.decode.bind(exportAssetsMetadata)) + }; + + // Put together the default options sent with requests. + this._defaults = this._gaxGrpc.constructSettings( + 'google.cloud.asset.v1.AssetService', gapicConfig as gax.ClientConfig, + opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')}); + + // Set up a dictionary of "inner API calls"; the core implementation + // of calling the API is handled in `google-gax`, with this code + // merely providing the destination and request information. + this.innerApiCalls = {}; + } + + /** + * Initialize the client. + * Performs asynchronous operations (such as authentication) and prepares the client. + * This function will be called automatically when any class method is called for the + * first time, but if you need to initialize it before calling an actual method, + * feel free to call initialize() directly. + * + * You can await on this method if you want to make sure the client is initialized. + * + * @returns {Promise} A promise that resolves to an authenticated service stub. + */ + initialize() { + // If the client stub promise is already initialized, return immediately. + if (this.assetServiceStub) { + return this.assetServiceStub; + } + + // Put together the "service stub" for + // google.cloud.asset.v1.AssetService. + this.assetServiceStub = this._gaxGrpc.createStub( + this._opts.fallback ? + (this._protos as protobuf.Root).lookupService('google.cloud.asset.v1.AssetService') : + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (this._protos as any).google.cloud.asset.v1.AssetService, + this._opts) as Promise<{[method: string]: Function}>; + + // Iterate over each of the methods that the service provides + // and create an API call method for each. + const assetServiceStubMethods = + ['exportAssets', 'batchGetAssetsHistory', 'createFeed', 'getFeed', 'listFeeds', 'updateFeed', 'deleteFeed']; + for (const methodName of assetServiceStubMethods) { + const callPromise = this.assetServiceStub.then( + stub => (...args: Array<{}>) => { + if (this._terminated) { + return Promise.reject('The client has already been closed.'); + } + const func = stub[methodName]; + return func.apply(stub, args); + }, + (err: Error|null|undefined) => () => { + throw err; + }); + + const apiCall = this._gaxModule.createApiCall( + callPromise, + this._defaults[methodName], + this.descriptors.page[methodName] || + this.descriptors.stream[methodName] || + this.descriptors.longrunning[methodName] + ); + + this.innerApiCalls[methodName] = apiCall; + } + + return this.assetServiceStub; + } + + /** + * The DNS address for this API service. + */ + static get servicePath() { + return 'cloudasset.googleapis.com'; + } + + /** + * The DNS address for this API service - same as servicePath(), + * exists for compatibility reasons. + */ + static get apiEndpoint() { + return 'cloudasset.googleapis.com'; + } + + /** + * The port for this API service. + */ + static get port() { + return 443; + } + + /** + * The scopes needed to make gRPC calls for every method defined + * in this service. + */ + static get scopes() { + return [ + 'https://www.googleapis.com/auth/cloud-platform' + ]; + } + + getProjectId(): Promise; + getProjectId(callback: Callback): void; + /** + * Return the project ID used by this class. + * @param {function(Error, string)} callback - the callback to + * be called with the current project Id. + */ + getProjectId(callback?: Callback): + Promise|void { + if (callback) { + this.auth.getProjectId(callback); + return; + } + return this.auth.getProjectId(); + } + + // ------------------- + // -- Service calls -- + // ------------------- + batchGetAssetsHistory( + request: protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|undefined, {}|undefined + ]>; + batchGetAssetsHistory( + request: protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|null|undefined, + {}|null|undefined>): void; + batchGetAssetsHistory( + request: protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest, + callback: Callback< + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|null|undefined, + {}|null|undefined>): void; +/** + * Batch gets the update history of assets that overlap a time window. + * For RESOURCE content, this API outputs history with asset in both + * non-delete or deleted status. + * For IAM_POLICY content, this API outputs history when the asset and its + * attached IAM POLICY both exist. This can create gaps in the output history. + * If a specified asset does not exist, this API returns an INVALID_ARGUMENT + * error. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. The relative name of the root asset. It can only be an + * organization number (such as "organizations/123"), a project ID (such as + * "projects/my-project-id")", or a project number (such as "projects/12345"). + * @param {string[]} request.assetNames + * A list of the full names of the assets. For example: + * `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`. + * See [Resource + * Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + * and [Resource Name + * Format](https://cloud.google.com/asset-inventory/docs/resource-name-format) + * for more info. + * + * The request becomes a no-op if the asset name list is empty, and the max + * size of the asset name list is 100 in one request. + * @param {google.cloud.asset.v1.ContentType} [request.contentType] + * Optional. The content type. + * @param {google.cloud.asset.v1.TimeWindow} [request.readTimeWindow] + * Optional. The time window for the asset history. Both start_time and + * end_time are optional and if set, it must be after the current time minus + * 35 days. If end_time is not set, it is default to current timestamp. + * If start_time is not set, the snapshot of the assets at end_time will be + * returned. The returned results contain all temporal assets whose time + * window overlap with read_time_window. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [BatchGetAssetsHistoryResponse]{@link google.cloud.asset.v1.BatchGetAssetsHistoryResponse}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + batchGetAssetsHistory( + request: protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse, + protos.google.cloud.asset.v1.IBatchGetAssetsHistoryRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'parent': request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.batchGetAssetsHistory(request, options, callback); + } + createFeed( + request: protos.google.cloud.asset.v1.ICreateFeedRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|undefined, {}|undefined + ]>; + createFeed( + request: protos.google.cloud.asset.v1.ICreateFeedRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|null|undefined, + {}|null|undefined>): void; + createFeed( + request: protos.google.cloud.asset.v1.ICreateFeedRequest, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|null|undefined, + {}|null|undefined>): void; +/** + * Creates a feed in a parent project/folder/organization to listen to its + * asset updates. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. The name of the project/folder/organization where this feed + * should be created in. It can only be an organization number (such as + * "organizations/123"), a folder number (such as "folders/123"), a project ID + * (such as "projects/my-project-id")", or a project number (such as + * "projects/12345"). + * @param {string} request.feedId + * Required. This is the client-assigned asset feed identifier and it needs to + * be unique under a specific parent project/folder/organization. + * @param {google.cloud.asset.v1.Feed} request.feed + * Required. The feed details. The field `name` must be empty and it will be generated + * in the format of: + * projects/project_number/feeds/feed_id + * folders/folder_number/feeds/feed_id + * organizations/organization_number/feeds/feed_id + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Feed]{@link google.cloud.asset.v1.Feed}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + createFeed( + request: protos.google.cloud.asset.v1.ICreateFeedRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.ICreateFeedRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'parent': request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.createFeed(request, options, callback); + } + getFeed( + request: protos.google.cloud.asset.v1.IGetFeedRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|undefined, {}|undefined + ]>; + getFeed( + request: protos.google.cloud.asset.v1.IGetFeedRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|null|undefined, + {}|null|undefined>): void; + getFeed( + request: protos.google.cloud.asset.v1.IGetFeedRequest, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|null|undefined, + {}|null|undefined>): void; +/** + * Gets details about an asset feed. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the Feed and it must be in the format of: + * projects/project_number/feeds/feed_id + * folders/folder_number/feeds/feed_id + * organizations/organization_number/feeds/feed_id + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Feed]{@link google.cloud.asset.v1.Feed}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + getFeed( + request: protos.google.cloud.asset.v1.IGetFeedRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IGetFeedRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'name': request.name || '', + }); + this.initialize(); + return this.innerApiCalls.getFeed(request, options, callback); + } + listFeeds( + request: protos.google.cloud.asset.v1.IListFeedsRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|undefined, {}|undefined + ]>; + listFeeds( + request: protos.google.cloud.asset.v1.IListFeedsRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|null|undefined, + {}|null|undefined>): void; + listFeeds( + request: protos.google.cloud.asset.v1.IListFeedsRequest, + callback: Callback< + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|null|undefined, + {}|null|undefined>): void; +/** + * Lists all asset feeds in a parent project/folder/organization. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. The parent project/folder/organization whose feeds are to be + * listed. It can only be using project/folder/organization number (such as + * "folders/12345")", or a project ID (such as "projects/my-project-id"). + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [ListFeedsResponse]{@link google.cloud.asset.v1.ListFeedsResponse}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + listFeeds( + request: protos.google.cloud.asset.v1.IListFeedsRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.cloud.asset.v1.IListFeedsResponse, + protos.google.cloud.asset.v1.IListFeedsRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'parent': request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.listFeeds(request, options, callback); + } + updateFeed( + request: protos.google.cloud.asset.v1.IUpdateFeedRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|undefined, {}|undefined + ]>; + updateFeed( + request: protos.google.cloud.asset.v1.IUpdateFeedRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|null|undefined, + {}|null|undefined>): void; + updateFeed( + request: protos.google.cloud.asset.v1.IUpdateFeedRequest, + callback: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|null|undefined, + {}|null|undefined>): void; +/** + * Updates an asset feed configuration. + * + * @param {Object} request + * The request object that will be sent. + * @param {google.cloud.asset.v1.Feed} request.feed + * Required. The new values of feed details. It must match an existing feed and the + * field `name` must be in the format of: + * projects/project_number/feeds/feed_id or + * folders/folder_number/feeds/feed_id or + * organizations/organization_number/feeds/feed_id. + * @param {google.protobuf.FieldMask} request.updateMask + * Required. Only updates the `feed` fields indicated by this mask. + * The field mask must not be empty, and it must not contain fields that + * are immutable or only set by the server. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Feed]{@link google.cloud.asset.v1.Feed}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + updateFeed( + request: protos.google.cloud.asset.v1.IUpdateFeedRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.cloud.asset.v1.IFeed, + protos.google.cloud.asset.v1.IUpdateFeedRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'feed.name': request.feed!.name || '', + }); + this.initialize(); + return this.innerApiCalls.updateFeed(request, options, callback); + } + deleteFeed( + request: protos.google.cloud.asset.v1.IDeleteFeedRequest, + options?: gax.CallOptions): + Promise<[ + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|undefined, {}|undefined + ]>; + deleteFeed( + request: protos.google.cloud.asset.v1.IDeleteFeedRequest, + options: gax.CallOptions, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|null|undefined, + {}|null|undefined>): void; + deleteFeed( + request: protos.google.cloud.asset.v1.IDeleteFeedRequest, + callback: Callback< + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|null|undefined, + {}|null|undefined>): void; +/** + * Deletes an asset feed. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.name + * Required. The name of the feed and it must be in the format of: + * projects/project_number/feeds/feed_id + * folders/folder_number/feeds/feed_id + * organizations/organization_number/feeds/feed_id + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Empty]{@link google.protobuf.Empty}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + deleteFeed( + request: protos.google.cloud.asset.v1.IDeleteFeedRequest, + optionsOrCallback?: gax.CallOptions|Callback< + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|null|undefined, + {}|null|undefined>, + callback?: Callback< + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|null|undefined, + {}|null|undefined>): + Promise<[ + protos.google.protobuf.IEmpty, + protos.google.cloud.asset.v1.IDeleteFeedRequest|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'name': request.name || '', + }); + this.initialize(); + return this.innerApiCalls.deleteFeed(request, options, callback); + } + + exportAssets( + request: protos.google.cloud.asset.v1.IExportAssetsRequest, + options?: gax.CallOptions): + Promise<[ + LROperation, + protos.google.longrunning.IOperation|undefined, {}|undefined + ]>; + exportAssets( + request: protos.google.cloud.asset.v1.IExportAssetsRequest, + options: gax.CallOptions, + callback: Callback< + LROperation, + protos.google.longrunning.IOperation|null|undefined, + {}|null|undefined>): void; + exportAssets( + request: protos.google.cloud.asset.v1.IExportAssetsRequest, + callback: Callback< + LROperation, + protos.google.longrunning.IOperation|null|undefined, + {}|null|undefined>): void; +/** + * Exports assets with time and resource types to a given Cloud Storage + * location. The output format is newline-delimited JSON. + * This API implements the {@link google.longrunning.Operation|google.longrunning.Operation} API allowing you + * to keep track of the export. + * + * @param {Object} request + * The request object that will be sent. + * @param {string} request.parent + * Required. The relative name of the root asset. This can only be an + * organization number (such as "organizations/123"), a project ID (such as + * "projects/my-project-id"), or a project number (such as "projects/12345"), + * or a folder number (such as "folders/123"). + * @param {google.protobuf.Timestamp} request.readTime + * Timestamp to take an asset snapshot. This can only be set to a timestamp + * between the current time and the current time minus 35 days (inclusive). + * If not specified, the current time will be used. Due to delays in resource + * data collection and indexing, there is a volatile window during which + * running the same query may get different results. + * @param {string[]} request.assetTypes + * A list of asset types of which to take a snapshot for. For example: + * "compute.googleapis.com/Disk". If specified, only matching assets will be + * returned. See [Introduction to Cloud Asset + * Inventory](https://cloud.google.com/asset-inventory/docs/overview) + * for all supported asset types. + * @param {google.cloud.asset.v1.ContentType} request.contentType + * Asset content type. If not specified, no content but the asset name will be + * returned. + * @param {google.cloud.asset.v1.OutputConfig} request.outputConfig + * Required. Output configuration indicating where the results will be output + * to. All results will be in newline delimited JSON format. + * @param {object} [options] + * Call options. See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions} for more details. + * @returns {Promise} - The promise which resolves to an array. + * The first element of the array is an object representing [Operation]{@link google.longrunning.Operation}. + * The promise has a method named "cancel" which cancels the ongoing API call. + */ + exportAssets( + request: protos.google.cloud.asset.v1.IExportAssetsRequest, + optionsOrCallback?: gax.CallOptions|Callback< + LROperation, + protos.google.longrunning.IOperation|null|undefined, + {}|null|undefined>, + callback?: Callback< + LROperation, + protos.google.longrunning.IOperation|null|undefined, + {}|null|undefined>): + Promise<[ + LROperation, + protos.google.longrunning.IOperation|undefined, {}|undefined + ]>|void { + request = request || {}; + let options: gax.CallOptions; + if (typeof optionsOrCallback === 'function' && callback === undefined) { + callback = optionsOrCallback; + options = {}; + } + else { + options = optionsOrCallback as gax.CallOptions; + } + options = options || {}; + options.otherArgs = options.otherArgs || {}; + options.otherArgs.headers = options.otherArgs.headers || {}; + options.otherArgs.headers[ + 'x-goog-request-params' + ] = gax.routingHeader.fromParams({ + 'parent': request.parent || '', + }); + this.initialize(); + return this.innerApiCalls.exportAssets(request, options, callback); + } +/** + * Check the status of the long running operation returned by the exportAssets() method. + * @param {String} name + * The operation name that will be passed. + * @returns {Promise} - The promise which resolves to an object. + * The decoded operation object has result and metadata field to get information from. + * + * @example: + * const decodedOperation = await checkExportAssetsProgress(name); + * console.log(decodedOperation.result); + * console.log(decodedOperation.done); + * console.log(decodedOperation.metadata); + * + */ + async checkExportAssetsProgress(name: string): Promise>{ + const request = new operationsProtos.google.longrunning.GetOperationRequest({name}); + const [operation] = await this.operationsClient.getOperation(request); + const decodeOperation = new gax.Operation(operation, this.descriptors.longrunning.exportAssets, gax.createDefaultBackoffSettings()); + return decodeOperation as LROperation; + } + // -------------------- + // -- Path templates -- + // -------------------- + + /** + * Return a fully-qualified folderFeed resource name string. + * + * @param {string} folder + * @param {string} feed + * @returns {string} Resource name string. + */ + folderFeedPath(folder:string,feed:string) { + return this.pathTemplates.folderFeedPathTemplate.render({ + folder: folder, + feed: feed, + }); + } + + /** + * Parse the folder from FolderFeed resource. + * + * @param {string} folderFeedName + * A fully-qualified path representing folder_feed resource. + * @returns {string} A string representing the folder. + */ + matchFolderFromFolderFeedName(folderFeedName: string) { + return this.pathTemplates.folderFeedPathTemplate.match(folderFeedName).folder; + } + + /** + * Parse the feed from FolderFeed resource. + * + * @param {string} folderFeedName + * A fully-qualified path representing folder_feed resource. + * @returns {string} A string representing the feed. + */ + matchFeedFromFolderFeedName(folderFeedName: string) { + return this.pathTemplates.folderFeedPathTemplate.match(folderFeedName).feed; + } + + /** + * Return a fully-qualified organizationFeed resource name string. + * + * @param {string} organization + * @param {string} feed + * @returns {string} Resource name string. + */ + organizationFeedPath(organization:string,feed:string) { + return this.pathTemplates.organizationFeedPathTemplate.render({ + organization: organization, + feed: feed, + }); + } + + /** + * Parse the organization from OrganizationFeed resource. + * + * @param {string} organizationFeedName + * A fully-qualified path representing organization_feed resource. + * @returns {string} A string representing the organization. + */ + matchOrganizationFromOrganizationFeedName(organizationFeedName: string) { + return this.pathTemplates.organizationFeedPathTemplate.match(organizationFeedName).organization; + } + + /** + * Parse the feed from OrganizationFeed resource. + * + * @param {string} organizationFeedName + * A fully-qualified path representing organization_feed resource. + * @returns {string} A string representing the feed. + */ + matchFeedFromOrganizationFeedName(organizationFeedName: string) { + return this.pathTemplates.organizationFeedPathTemplate.match(organizationFeedName).feed; + } + + /** + * Return a fully-qualified projectFeed resource name string. + * + * @param {string} project + * @param {string} feed + * @returns {string} Resource name string. + */ + projectFeedPath(project:string,feed:string) { + return this.pathTemplates.projectFeedPathTemplate.render({ + project: project, + feed: feed, + }); + } + + /** + * Parse the project from ProjectFeed resource. + * + * @param {string} projectFeedName + * A fully-qualified path representing project_feed resource. + * @returns {string} A string representing the project. + */ + matchProjectFromProjectFeedName(projectFeedName: string) { + return this.pathTemplates.projectFeedPathTemplate.match(projectFeedName).project; + } + + /** + * Parse the feed from ProjectFeed resource. + * + * @param {string} projectFeedName + * A fully-qualified path representing project_feed resource. + * @returns {string} A string representing the feed. + */ + matchFeedFromProjectFeedName(projectFeedName: string) { + return this.pathTemplates.projectFeedPathTemplate.match(projectFeedName).feed; + } + + /** + * Terminate the GRPC channel and close the client. + * + * The client will no longer be usable and all future behavior is undefined. + */ + close(): Promise { + this.initialize(); + if (!this._terminated) { + return this.assetServiceStub!.then(stub => { + this._terminated = true; + stub.close(); + }); + } + return Promise.resolve(); + } +} diff --git a/baselines/asset/src/v1/asset_service_client_config.json.baseline b/baselines/asset/src/v1/asset_service_client_config.json.baseline new file mode 100644 index 000000000..f114f91b5 --- /dev/null +++ b/baselines/asset/src/v1/asset_service_client_config.json.baseline @@ -0,0 +1,54 @@ +{ + "interfaces": { + "google.cloud.asset.v1.AssetService": { + "retry_codes": { + "non_idempotent": [], + "idempotent": [ + "DEADLINE_EXCEEDED", + "UNAVAILABLE" + ] + }, + "retry_params": { + "default": { + "initial_retry_delay_millis": 100, + "retry_delay_multiplier": 1.3, + "max_retry_delay_millis": 60000, + "initial_rpc_timeout_millis": 60000, + "rpc_timeout_multiplier": 1, + "max_rpc_timeout_millis": 60000, + "total_timeout_millis": 600000 + } + }, + "methods": { + "ExportAssets": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "BatchGetAssetsHistory": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "CreateFeed": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "GetFeed": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "ListFeeds": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "UpdateFeed": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + }, + "DeleteFeed": { + "retry_codes_name": "non_idempotent", + "retry_params_name": "default" + } + } + } + } +} diff --git a/baselines/asset/src/v1/asset_service_proto_list.json.baseline b/baselines/asset/src/v1/asset_service_proto_list.json.baseline new file mode 100644 index 000000000..b5bf323ce --- /dev/null +++ b/baselines/asset/src/v1/asset_service_proto_list.json.baseline @@ -0,0 +1,23 @@ +[ + "../../protos/google/api/annotations.proto", + "../../protos/google/api/client.proto", + "../../protos/google/api/field_behavior.proto", + "../../protos/google/api/http.proto", + "../../protos/google/api/resource.proto", + "../../protos/google/cloud/asset/v1/asset_service.proto", + "../../protos/google/cloud/asset/v1/assets.proto", + "../../protos/google/cloud/orgpolicy/v1/orgpolicy.proto", + "../../protos/google/identity/accesscontextmanager/type/device_resources.proto", + "../../protos/google/identity/accesscontextmanager/v1/access_level.proto", + "../../protos/google/identity/accesscontextmanager/v1/access_policy.proto", + "../../protos/google/identity/accesscontextmanager/v1/service_perimeter.proto", + "../../protos/google/protobuf/any.proto", + "../../protos/google/protobuf/descriptor.proto", + "../../protos/google/protobuf/duration.proto", + "../../protos/google/protobuf/empty.proto", + "../../protos/google/protobuf/field_mask.proto", + "../../protos/google/protobuf/struct.proto", + "../../protos/google/protobuf/timestamp.proto", + "../../protos/google/rpc/status.proto", + "../../protos/google/type/expr.proto" +] diff --git a/baselines/asset/src/v1/index.ts.baseline b/baselines/asset/src/v1/index.ts.baseline new file mode 100644 index 000000000..275cf4b6f --- /dev/null +++ b/baselines/asset/src/v1/index.ts.baseline @@ -0,0 +1,19 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +export {AssetServiceClient} from './asset_service_client'; diff --git a/baselines/asset/system-test/fixtures/sample/src/index.js.baseline b/baselines/asset/system-test/fixtures/sample/src/index.js.baseline new file mode 100644 index 000000000..a7b3cddc0 --- /dev/null +++ b/baselines/asset/system-test/fixtures/sample/src/index.js.baseline @@ -0,0 +1,27 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + + +/* eslint-disable node/no-missing-require, no-unused-vars */ +const asset = require('@google-cloud/asset'); + +function main() { + const assetServiceClient = new asset.AssetServiceClient(); +} + +main(); diff --git a/baselines/asset/system-test/fixtures/sample/src/index.ts.baseline b/baselines/asset/system-test/fixtures/sample/src/index.ts.baseline new file mode 100644 index 000000000..f1056a37f --- /dev/null +++ b/baselines/asset/system-test/fixtures/sample/src/index.ts.baseline @@ -0,0 +1,25 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import {AssetServiceClient} from '@google-cloud/asset'; + +function main() { + new AssetServiceClient(); +} + +main(); diff --git a/baselines/asset/system-test/install.ts.baseline b/baselines/asset/system-test/install.ts.baseline new file mode 100644 index 000000000..5e4ed6364 --- /dev/null +++ b/baselines/asset/system-test/install.ts.baseline @@ -0,0 +1,49 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import { packNTest } from 'pack-n-play'; +import { readFileSync } from 'fs'; +import { describe, it } from 'mocha'; + +describe('typescript consumer tests', () => { + + it('should have correct type signature for typescript users', async function() { + this.timeout(300000); + const options = { + packageDir: process.cwd(), // path to your module. + sample: { + description: 'typescript based user can use the type definitions', + ts: readFileSync('./system-test/fixtures/sample/src/index.ts').toString() + } + }; + await packNTest(options); // will throw upon error. + }); + + it('should have correct type signature for javascript users', async function() { + this.timeout(300000); + const options = { + packageDir: process.cwd(), // path to your module. + sample: { + description: 'typescript based user can use the type definitions', + ts: readFileSync('./system-test/fixtures/sample/src/index.js').toString() + } + }; + await packNTest(options); // will throw upon error. + }); + +}); diff --git a/baselines/asset/test/gapic_asset_service_v1.ts.baseline b/baselines/asset/test/gapic_asset_service_v1.ts.baseline new file mode 100644 index 000000000..91d1adc33 --- /dev/null +++ b/baselines/asset/test/gapic_asset_service_v1.ts.baseline @@ -0,0 +1,904 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ** This file is automatically generated by gapic-generator-typescript. ** +// ** https://github.com/googleapis/gapic-generator-typescript ** +// ** All changes to this file may be overwritten. ** + +import * as protos from '../protos/protos'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import {SinonStub} from 'sinon'; +import { describe, it } from 'mocha'; +import * as assetserviceModule from '../src'; + +import {protobuf, LROperation, operationsProtos} from 'google-gax'; + +function generateSampleMessage(instance: T) { + const filledObject = (instance.constructor as typeof protobuf.Message) + .toObject(instance as protobuf.Message, {defaults: true}); + return (instance.constructor as typeof protobuf.Message).fromObject(filledObject) as T; +} + +function stubSimpleCall(response?: ResponseType, error?: Error) { + return error ? sinon.stub().rejects(error) : sinon.stub().resolves([response]); +} + +function stubSimpleCallWithCallback(response?: ResponseType, error?: Error) { + return error ? sinon.stub().callsArgWith(2, error) : sinon.stub().callsArgWith(2, null, response); +} + +function stubLongRunningCall(response?: ResponseType, callError?: Error, lroError?: Error) { + const innerStub = lroError ? sinon.stub().rejects(lroError) : sinon.stub().resolves([response]); + const mockOperation = { + promise: innerStub, + }; + return callError ? sinon.stub().rejects(callError) : sinon.stub().resolves([mockOperation]); +} + +function stubLongRunningCallWithCallback(response?: ResponseType, callError?: Error, lroError?: Error) { + const innerStub = lroError ? sinon.stub().rejects(lroError) : sinon.stub().resolves([response]); + const mockOperation = { + promise: innerStub, + }; + return callError ? sinon.stub().callsArgWith(2, callError) : sinon.stub().callsArgWith(2, null, mockOperation); +} + +describe('v1.AssetServiceClient', () => { + it('has servicePath', () => { + const servicePath = assetserviceModule.v1.AssetServiceClient.servicePath; + assert(servicePath); + }); + + it('has apiEndpoint', () => { + const apiEndpoint = assetserviceModule.v1.AssetServiceClient.apiEndpoint; + assert(apiEndpoint); + }); + + it('has port', () => { + const port = assetserviceModule.v1.AssetServiceClient.port; + assert(port); + assert(typeof port === 'number'); + }); + + it('should create a client with no option', () => { + const client = new assetserviceModule.v1.AssetServiceClient(); + assert(client); + }); + + it('should create a client with gRPC fallback', () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + fallback: true, + }); + assert(client); + }); + + it('has initialize method and supports deferred initialization', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + assert.strictEqual(client.assetServiceStub, undefined); + await client.initialize(); + assert(client.assetServiceStub); + }); + + it('has close method', () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.close(); + }); + + it('has getProjectId method', async () => { + const fakeProjectId = 'fake-project-id'; + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.auth.getProjectId = sinon.stub().resolves(fakeProjectId); + const result = await client.getProjectId(); + assert.strictEqual(result, fakeProjectId); + assert((client.auth.getProjectId as SinonStub).calledWithExactly()); + }); + + it('has getProjectId method with callback', async () => { + const fakeProjectId = 'fake-project-id'; + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: { client_email: 'bogus', private_key: 'bogus' }, + projectId: 'bogus', + }); + client.auth.getProjectId = sinon.stub().callsArgWith(0, null, fakeProjectId); + const promise = new Promise((resolve, reject) => { + client.getProjectId((err?: Error|null, projectId?: string|null) => { + if (err) { + reject(err); + } else { + resolve(projectId); + } + }); + }); + const result = await promise; + assert.strictEqual(result, fakeProjectId); + }); + + describe('batchGetAssetsHistory', () => { + it('invokes batchGetAssetsHistory without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.BatchGetAssetsHistoryRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.BatchGetAssetsHistoryResponse()); + client.innerApiCalls.batchGetAssetsHistory = stubSimpleCall(expectedResponse); + const [response] = await client.batchGetAssetsHistory(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.batchGetAssetsHistory as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes batchGetAssetsHistory without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.BatchGetAssetsHistoryRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.BatchGetAssetsHistoryResponse()); + client.innerApiCalls.batchGetAssetsHistory = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.batchGetAssetsHistory( + request, + (err?: Error|null, result?: protos.google.cloud.asset.v1.IBatchGetAssetsHistoryResponse|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.batchGetAssetsHistory as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes batchGetAssetsHistory with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.BatchGetAssetsHistoryRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.batchGetAssetsHistory = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.batchGetAssetsHistory(request), expectedError); + assert((client.innerApiCalls.batchGetAssetsHistory as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('createFeed', () => { + it('invokes createFeed without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.CreateFeedRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.createFeed = stubSimpleCall(expectedResponse); + const [response] = await client.createFeed(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.createFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes createFeed without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.CreateFeedRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.createFeed = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.createFeed( + request, + (err?: Error|null, result?: protos.google.cloud.asset.v1.IFeed|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.createFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes createFeed with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.CreateFeedRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.createFeed = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.createFeed(request), expectedError); + assert((client.innerApiCalls.createFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('getFeed', () => { + it('invokes getFeed without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.GetFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.getFeed = stubSimpleCall(expectedResponse); + const [response] = await client.getFeed(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.getFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes getFeed without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.GetFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.getFeed = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.getFeed( + request, + (err?: Error|null, result?: protos.google.cloud.asset.v1.IFeed|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.getFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes getFeed with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.GetFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.getFeed = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.getFeed(request), expectedError); + assert((client.innerApiCalls.getFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('listFeeds', () => { + it('invokes listFeeds without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ListFeedsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.ListFeedsResponse()); + client.innerApiCalls.listFeeds = stubSimpleCall(expectedResponse); + const [response] = await client.listFeeds(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.listFeeds as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes listFeeds without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ListFeedsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.ListFeedsResponse()); + client.innerApiCalls.listFeeds = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.listFeeds( + request, + (err?: Error|null, result?: protos.google.cloud.asset.v1.IListFeedsResponse|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.listFeeds as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes listFeeds with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ListFeedsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.listFeeds = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.listFeeds(request), expectedError); + assert((client.innerApiCalls.listFeeds as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('updateFeed', () => { + it('invokes updateFeed without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.UpdateFeedRequest()); + request.feed = {}; + request.feed.name = ''; + const expectedHeaderRequestParams = "feed.name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.updateFeed = stubSimpleCall(expectedResponse); + const [response] = await client.updateFeed(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.updateFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes updateFeed without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.UpdateFeedRequest()); + request.feed = {}; + request.feed.name = ''; + const expectedHeaderRequestParams = "feed.name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.cloud.asset.v1.Feed()); + client.innerApiCalls.updateFeed = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.updateFeed( + request, + (err?: Error|null, result?: protos.google.cloud.asset.v1.IFeed|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.updateFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes updateFeed with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.UpdateFeedRequest()); + request.feed = {}; + request.feed.name = ''; + const expectedHeaderRequestParams = "feed.name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.updateFeed = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.updateFeed(request), expectedError); + assert((client.innerApiCalls.updateFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('deleteFeed', () => { + it('invokes deleteFeed without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.DeleteFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.protobuf.Empty()); + client.innerApiCalls.deleteFeed = stubSimpleCall(expectedResponse); + const [response] = await client.deleteFeed(request); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.deleteFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes deleteFeed without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.DeleteFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.protobuf.Empty()); + client.innerApiCalls.deleteFeed = stubSimpleCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.deleteFeed( + request, + (err?: Error|null, result?: protos.google.protobuf.IEmpty|null) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const response = await promise; + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.deleteFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes deleteFeed with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.DeleteFeedRequest()); + request.name = ''; + const expectedHeaderRequestParams = "name="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.deleteFeed = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.deleteFeed(request), expectedError); + assert((client.innerApiCalls.deleteFeed as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + }); + + describe('exportAssets', () => { + it('invokes exportAssets without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ExportAssetsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.longrunning.Operation()); + client.innerApiCalls.exportAssets = stubLongRunningCall(expectedResponse); + const [operation] = await client.exportAssets(request); + const [response] = await operation.promise(); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.exportAssets as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes exportAssets without error using callback', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ExportAssetsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedResponse = generateSampleMessage(new protos.google.longrunning.Operation()); + client.innerApiCalls.exportAssets = stubLongRunningCallWithCallback(expectedResponse); + const promise = new Promise((resolve, reject) => { + client.exportAssets( + request, + (err?: Error|null, + result?: LROperation|null + ) => { + if (err) { + reject(err); + } else { + resolve(result); + } + }); + }); + const operation = await promise as LROperation; + const [response] = await operation.promise(); + assert.deepStrictEqual(response, expectedResponse); + assert((client.innerApiCalls.exportAssets as SinonStub) + .getCall(0).calledWith(request, expectedOptions /*, callback defined above */)); + }); + + it('invokes exportAssets with call error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ExportAssetsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.exportAssets = stubLongRunningCall(undefined, expectedError); + await assert.rejects(client.exportAssets(request), expectedError); + assert((client.innerApiCalls.exportAssets as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes exportAssets with LRO error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const request = generateSampleMessage(new protos.google.cloud.asset.v1.ExportAssetsRequest()); + request.parent = ''; + const expectedHeaderRequestParams = "parent="; + const expectedOptions = { + otherArgs: { + headers: { + 'x-goog-request-params': expectedHeaderRequestParams, + }, + }, + }; + const expectedError = new Error('expected'); + client.innerApiCalls.exportAssets = stubLongRunningCall(undefined, undefined, expectedError); + const [operation] = await client.exportAssets(request); + await assert.rejects(operation.promise(), expectedError); + assert((client.innerApiCalls.exportAssets as SinonStub) + .getCall(0).calledWith(request, expectedOptions, undefined)); + }); + + it('invokes checkExportAssetsProgress without error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const expectedResponse = generateSampleMessage(new operationsProtos.google.longrunning.Operation()); + expectedResponse.name = 'test'; + expectedResponse.response = {type_url: 'url', value: Buffer.from('')}; + expectedResponse.metadata = {type_url: 'url', value: Buffer.from('')} + + client.operationsClient.getOperation = stubSimpleCall(expectedResponse); + const decodedOperation = await client.checkExportAssetsProgress(expectedResponse.name); + assert.deepStrictEqual(decodedOperation.name, expectedResponse.name); + assert(decodedOperation.metadata); + assert((client.operationsClient.getOperation as SinonStub).getCall(0)); + }); + + it('invokes checkExportAssetsProgress with error', async () => { + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + const expectedError = new Error('expected'); + + client.operationsClient.getOperation = stubSimpleCall(undefined, expectedError); + await assert.rejects(client.checkExportAssetsProgress(''), expectedError); + assert((client.operationsClient.getOperation as SinonStub) + .getCall(0)); + }); + }); + + describe('Path templates', () => { + + describe('folderFeed', () => { + const fakePath = "/rendered/path/folderFeed"; + const expectedParameters = { + folder: "folderValue", + feed: "feedValue", + }; + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.folderFeedPathTemplate.render = + sinon.stub().returns(fakePath); + client.pathTemplates.folderFeedPathTemplate.match = + sinon.stub().returns(expectedParameters); + + it('folderFeedPath', () => { + const result = client.folderFeedPath("folderValue", "feedValue"); + assert.strictEqual(result, fakePath); + assert((client.pathTemplates.folderFeedPathTemplate.render as SinonStub) + .getCall(-1).calledWith(expectedParameters)); + }); + + it('matchFolderFromFolderFeedName', () => { + const result = client.matchFolderFromFolderFeedName(fakePath); + assert.strictEqual(result, "folderValue"); + assert((client.pathTemplates.folderFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + + it('matchFeedFromFolderFeedName', () => { + const result = client.matchFeedFromFolderFeedName(fakePath); + assert.strictEqual(result, "feedValue"); + assert((client.pathTemplates.folderFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + }); + + describe('organizationFeed', () => { + const fakePath = "/rendered/path/organizationFeed"; + const expectedParameters = { + organization: "organizationValue", + feed: "feedValue", + }; + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.organizationFeedPathTemplate.render = + sinon.stub().returns(fakePath); + client.pathTemplates.organizationFeedPathTemplate.match = + sinon.stub().returns(expectedParameters); + + it('organizationFeedPath', () => { + const result = client.organizationFeedPath("organizationValue", "feedValue"); + assert.strictEqual(result, fakePath); + assert((client.pathTemplates.organizationFeedPathTemplate.render as SinonStub) + .getCall(-1).calledWith(expectedParameters)); + }); + + it('matchOrganizationFromOrganizationFeedName', () => { + const result = client.matchOrganizationFromOrganizationFeedName(fakePath); + assert.strictEqual(result, "organizationValue"); + assert((client.pathTemplates.organizationFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + + it('matchFeedFromOrganizationFeedName', () => { + const result = client.matchFeedFromOrganizationFeedName(fakePath); + assert.strictEqual(result, "feedValue"); + assert((client.pathTemplates.organizationFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + }); + + describe('projectFeed', () => { + const fakePath = "/rendered/path/projectFeed"; + const expectedParameters = { + project: "projectValue", + feed: "feedValue", + }; + const client = new assetserviceModule.v1.AssetServiceClient({ + credentials: {client_email: 'bogus', private_key: 'bogus'}, + projectId: 'bogus', + }); + client.initialize(); + client.pathTemplates.projectFeedPathTemplate.render = + sinon.stub().returns(fakePath); + client.pathTemplates.projectFeedPathTemplate.match = + sinon.stub().returns(expectedParameters); + + it('projectFeedPath', () => { + const result = client.projectFeedPath("projectValue", "feedValue"); + assert.strictEqual(result, fakePath); + assert((client.pathTemplates.projectFeedPathTemplate.render as SinonStub) + .getCall(-1).calledWith(expectedParameters)); + }); + + it('matchProjectFromProjectFeedName', () => { + const result = client.matchProjectFromProjectFeedName(fakePath); + assert.strictEqual(result, "projectValue"); + assert((client.pathTemplates.projectFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + + it('matchFeedFromProjectFeedName', () => { + const result = client.matchFeedFromProjectFeedName(fakePath); + assert.strictEqual(result, "feedValue"); + assert((client.pathTemplates.projectFeedPathTemplate.match as SinonStub) + .getCall(-1).calledWith(fakePath)); + }); + }); + }); +}); diff --git a/baselines/asset/tsconfig.json.baseline b/baselines/asset/tsconfig.json.baseline new file mode 100644 index 000000000..613d35597 --- /dev/null +++ b/baselines/asset/tsconfig.json.baseline @@ -0,0 +1,19 @@ +{ + "extends": "./node_modules/gts/tsconfig-google.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "build", + "resolveJsonModule": true, + "lib": [ + "es2016", + "dom" + ] + }, + "include": [ + "src/*.ts", + "src/**/*.ts", + "test/*.ts", + "test/**/*.ts", + "system-test/*.ts" + ] +} diff --git a/baselines/asset/webpack.config.js.baseline b/baselines/asset/webpack.config.js.baseline new file mode 100644 index 000000000..74fffef59 --- /dev/null +++ b/baselines/asset/webpack.config.js.baseline @@ -0,0 +1,64 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +const path = require('path'); + +module.exports = { + entry: './src/index.ts', + output: { + library: 'AssetService', + filename: './asset-service.js', + }, + node: { + child_process: 'empty', + fs: 'empty', + crypto: 'empty', + }, + resolve: { + alias: { + '../../../package.json': path.resolve(__dirname, 'package.json'), + }, + extensions: ['.js', '.json', '.ts'], + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules/ + }, + { + test: /node_modules[\\/]@grpc[\\/]grpc-js/, + use: 'null-loader' + }, + { + test: /node_modules[\\/]grpc/, + use: 'null-loader' + }, + { + test: /node_modules[\\/]retry-request/, + use: 'null-loader' + }, + { + test: /node_modules[\\/]https?-proxy-agent/, + use: 'null-loader' + }, + { + test: /node_modules[\\/]gtoken/, + use: 'null-loader' + }, + ], + }, + mode: 'production', +}; diff --git a/test-fixtures/protos/google/cloud/asset/v1/asset_service.proto b/test-fixtures/protos/google/cloud/asset/v1/asset_service.proto new file mode 100644 index 000000000..9c7b16d03 --- /dev/null +++ b/test-fixtures/protos/google/cloud/asset/v1/asset_service.proto @@ -0,0 +1,423 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.asset.v1; + +import "google/api/annotations.proto"; +import "google/api/client.proto"; +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/cloud/asset/v1/assets.proto"; +import "google/longrunning/operations.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/field_mask.proto"; +import "google/protobuf/timestamp.proto"; +import "google/type/expr.proto"; + +option csharp_namespace = "Google.Cloud.Asset.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/asset/v1;asset"; +option java_multiple_files = true; +option java_outer_classname = "AssetServiceProto"; +option java_package = "com.google.cloud.asset.v1"; +option php_namespace = "Google\\Cloud\\Asset\\V1"; + +// Asset service definition. +service AssetService { + option (google.api.default_host) = "cloudasset.googleapis.com"; + option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/cloud-platform"; + + // Exports assets with time and resource types to a given Cloud Storage + // location. The output format is newline-delimited JSON. + // This API implements the [google.longrunning.Operation][google.longrunning.Operation] API allowing you + // to keep track of the export. + rpc ExportAssets(ExportAssetsRequest) returns (google.longrunning.Operation) { + option (google.api.http) = { + post: "/v1/{parent=*/*}:exportAssets" + body: "*" + }; + option (google.longrunning.operation_info) = { + response_type: "google.cloud.asset.v1.ExportAssetsResponse" + metadata_type: "google.cloud.asset.v1.ExportAssetsRequest" + }; + } + + // Batch gets the update history of assets that overlap a time window. + // For RESOURCE content, this API outputs history with asset in both + // non-delete or deleted status. + // For IAM_POLICY content, this API outputs history when the asset and its + // attached IAM POLICY both exist. This can create gaps in the output history. + // If a specified asset does not exist, this API returns an INVALID_ARGUMENT + // error. + rpc BatchGetAssetsHistory(BatchGetAssetsHistoryRequest) returns (BatchGetAssetsHistoryResponse) { + option (google.api.http) = { + get: "/v1/{parent=*/*}:batchGetAssetsHistory" + }; + } + + // Creates a feed in a parent project/folder/organization to listen to its + // asset updates. + rpc CreateFeed(CreateFeedRequest) returns (Feed) { + option (google.api.http) = { + post: "/v1/{parent=*/*}/feeds" + body: "*" + }; + option (google.api.method_signature) = "parent"; + } + + // Gets details about an asset feed. + rpc GetFeed(GetFeedRequest) returns (Feed) { + option (google.api.http) = { + get: "/v1/{name=*/*/feeds/*}" + }; + option (google.api.method_signature) = "name"; + } + + // Lists all asset feeds in a parent project/folder/organization. + rpc ListFeeds(ListFeedsRequest) returns (ListFeedsResponse) { + option (google.api.http) = { + get: "/v1/{parent=*/*}/feeds" + }; + option (google.api.method_signature) = "parent"; + } + + // Updates an asset feed configuration. + rpc UpdateFeed(UpdateFeedRequest) returns (Feed) { + option (google.api.http) = { + patch: "/v1/{feed.name=*/*/feeds/*}" + body: "*" + }; + option (google.api.method_signature) = "feed"; + } + + // Deletes an asset feed. + rpc DeleteFeed(DeleteFeedRequest) returns (google.protobuf.Empty) { + option (google.api.http) = { + delete: "/v1/{name=*/*/feeds/*}" + }; + option (google.api.method_signature) = "name"; + } +} + +// Export asset request. +message ExportAssetsRequest { + // Required. The relative name of the root asset. This can only be an + // organization number (such as "organizations/123"), a project ID (such as + // "projects/my-project-id"), or a project number (such as "projects/12345"), + // or a folder number (such as "folders/123"). + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "cloudasset.googleapis.com/Asset" + } + ]; + + // Timestamp to take an asset snapshot. This can only be set to a timestamp + // between the current time and the current time minus 35 days (inclusive). + // If not specified, the current time will be used. Due to delays in resource + // data collection and indexing, there is a volatile window during which + // running the same query may get different results. + google.protobuf.Timestamp read_time = 2; + + // A list of asset types of which to take a snapshot for. For example: + // "compute.googleapis.com/Disk". If specified, only matching assets will be + // returned. See [Introduction to Cloud Asset + // Inventory](https://cloud.google.com/asset-inventory/docs/overview) + // for all supported asset types. + repeated string asset_types = 3; + + // Asset content type. If not specified, no content but the asset name will be + // returned. + ContentType content_type = 4; + + // Required. Output configuration indicating where the results will be output + // to. All results will be in newline delimited JSON format. + OutputConfig output_config = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// The export asset response. This message is returned by the +// [google.longrunning.Operations.GetOperation][google.longrunning.Operations.GetOperation] method in the returned +// [google.longrunning.Operation.response][google.longrunning.Operation.response] field. +message ExportAssetsResponse { + // Time the snapshot was taken. + google.protobuf.Timestamp read_time = 1; + + // Output configuration indicating where the results were output to. + // All results are in JSON format. + OutputConfig output_config = 2; +} + +// Batch get assets history request. +message BatchGetAssetsHistoryRequest { + // Required. The relative name of the root asset. It can only be an + // organization number (such as "organizations/123"), a project ID (such as + // "projects/my-project-id")", or a project number (such as "projects/12345"). + string parent = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + child_type: "cloudasset.googleapis.com/Asset" + } + ]; + + // A list of the full names of the assets. For example: + // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`. + // See [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // and [Resource Name + // Format](https://cloud.google.com/asset-inventory/docs/resource-name-format) + // for more info. + // + // The request becomes a no-op if the asset name list is empty, and the max + // size of the asset name list is 100 in one request. + repeated string asset_names = 2; + + // Optional. The content type. + ContentType content_type = 3 [(google.api.field_behavior) = OPTIONAL]; + + // Optional. The time window for the asset history. Both start_time and + // end_time are optional and if set, it must be after the current time minus + // 35 days. If end_time is not set, it is default to current timestamp. + // If start_time is not set, the snapshot of the assets at end_time will be + // returned. The returned results contain all temporal assets whose time + // window overlap with read_time_window. + TimeWindow read_time_window = 4 [(google.api.field_behavior) = OPTIONAL]; +} + +// Batch get assets history response. +message BatchGetAssetsHistoryResponse { + // A list of assets with valid time windows. + repeated TemporalAsset assets = 1; +} + +// Create asset feed request. +message CreateFeedRequest { + // Required. The name of the project/folder/organization where this feed + // should be created in. It can only be an organization number (such as + // "organizations/123"), a folder number (such as "folders/123"), a project ID + // (such as "projects/my-project-id")", or a project number (such as + // "projects/12345"). + string parent = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. This is the client-assigned asset feed identifier and it needs to + // be unique under a specific parent project/folder/organization. + string feed_id = 2 [(google.api.field_behavior) = REQUIRED]; + + // Required. The feed details. The field `name` must be empty and it will be generated + // in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + Feed feed = 3 [(google.api.field_behavior) = REQUIRED]; +} + +// Get asset feed request. +message GetFeedRequest { + // Required. The name of the Feed and it must be in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudasset.googleapis.com/Feed" + } + ]; +} + +// List asset feeds request. +message ListFeedsRequest { + // Required. The parent project/folder/organization whose feeds are to be + // listed. It can only be using project/folder/organization number (such as + // "folders/12345")", or a project ID (such as "projects/my-project-id"). + string parent = 1 [(google.api.field_behavior) = REQUIRED]; +} + +message ListFeedsResponse { + // A list of feeds. + repeated Feed feeds = 1; +} + +// Update asset feed request. +message UpdateFeedRequest { + // Required. The new values of feed details. It must match an existing feed and the + // field `name` must be in the format of: + // projects/project_number/feeds/feed_id or + // folders/folder_number/feeds/feed_id or + // organizations/organization_number/feeds/feed_id. + Feed feed = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. Only updates the `feed` fields indicated by this mask. + // The field mask must not be empty, and it must not contain fields that + // are immutable or only set by the server. + google.protobuf.FieldMask update_mask = 2 [(google.api.field_behavior) = REQUIRED]; +} + +message DeleteFeedRequest { + // Required. The name of the feed and it must be in the format of: + // projects/project_number/feeds/feed_id + // folders/folder_number/feeds/feed_id + // organizations/organization_number/feeds/feed_id + string name = 1 [ + (google.api.field_behavior) = REQUIRED, + (google.api.resource_reference) = { + type: "cloudasset.googleapis.com/Feed" + } + ]; +} + +// Output configuration for export assets destination. +message OutputConfig { + // Asset export destination. + oneof destination { + // Destination on Cloud Storage. + GcsDestination gcs_destination = 1; + + // Destination on BigQuery. The output table stores the fields in asset + // proto as columns in BigQuery. The resource/iam_policy field is converted + // to a record with each field to a column, except metadata to a single JSON + // string. + BigQueryDestination bigquery_destination = 2; + } +} + +// A Cloud Storage location. +message GcsDestination { + // Required. + oneof object_uri { + // The uri of the Cloud Storage object. It's the same uri that is used by + // gsutil. For example: "gs://bucket_name/object_name". See [Viewing and + // Editing Object + // Metadata](https://cloud.google.com/storage/docs/viewing-editing-metadata) + // for more information. + string uri = 1; + + // The uri prefix of all generated Cloud Storage objects. For example: + // "gs://bucket_name/object_name_prefix". Each object uri is in format: + // "gs://bucket_name/object_name_prefix// and only + // contains assets for that type. starts from 0. For example: + // "gs://bucket_name/object_name_prefix/compute.googleapis.com/Disk/0" is + // the first shard of output objects containing all + // compute.googleapis.com/Disk assets. An INVALID_ARGUMENT error will be + // returned if file with the same name "gs://bucket_name/object_name_prefix" + // already exists. + string uri_prefix = 2; + } +} + +// A BigQuery destination. +message BigQueryDestination { + // Required. The BigQuery dataset in format + // "projects/projectId/datasets/datasetId", to which the snapshot result + // should be exported. If this dataset does not exist, the export call returns + // an INVALID_ARGUMENT error. + string dataset = 1 [(google.api.field_behavior) = REQUIRED]; + + // Required. The BigQuery table to which the snapshot result should be + // written. If this table does not exist, a new table with the given name + // will be created. + string table = 2 [(google.api.field_behavior) = REQUIRED]; + + // If the destination table already exists and this flag is `TRUE`, the + // table will be overwritten by the contents of assets snapshot. If the flag + // is `FALSE` or unset and the destination table already exists, the export + // call returns an INVALID_ARGUMEMT error. + bool force = 3; +} + +// A Pub/Sub destination. +message PubsubDestination { + // The name of the Pub/Sub topic to publish to. + // For example: `projects/PROJECT_ID/topics/TOPIC_ID`. + string topic = 1; +} + +// Output configuration for asset feed destination. +message FeedOutputConfig { + // Asset feed destination. + oneof destination { + // Destination on Pub/Sub. + PubsubDestination pubsub_destination = 1; + } +} + +// An asset feed used to export asset updates to a destinations. +// An asset feed filter controls what updates are exported. +// The asset feed must be created within a project, organization, or +// folder. Supported destinations are: +// Pub/Sub topics. +message Feed { + option (google.api.resource) = { + type: "cloudasset.googleapis.com/Feed" + pattern: "projects/{project}/feeds/{feed}" + pattern: "folders/{folder}/feeds/{feed}" + pattern: "organizations/{organization}/feeds/{feed}" + history: ORIGINALLY_SINGLE_PATTERN + }; + + // Required. The format will be + // projects/{project_number}/feeds/{client-assigned_feed_identifier} or + // folders/{folder_number}/feeds/{client-assigned_feed_identifier} or + // organizations/{organization_number}/feeds/{client-assigned_feed_identifier} + // + // The client-assigned feed identifier must be unique within the parent + // project/folder/organization. + string name = 1 [(google.api.field_behavior) = REQUIRED]; + + // A list of the full names of the assets to receive updates. You must specify + // either or both of asset_names and asset_types. Only asset updates matching + // specified asset_names and asset_types are exported to the feed. For + // example: + // `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`. + // See [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more info. + repeated string asset_names = 2; + + // A list of types of the assets to receive updates. You must specify either + // or both of asset_names and asset_types. Only asset updates matching + // specified asset_names and asset_types are exported to the feed. + // For example: `"compute.googleapis.com/Disk"` + // + // See [this + // topic](https://cloud.google.com/asset-inventory/docs/supported-asset-types) + // for a list of all supported asset types. + repeated string asset_types = 3; + + // Asset content type. If not specified, no content but the asset name and + // type will be returned. + ContentType content_type = 4; + + // Required. Feed output configuration defining where the asset updates are + // published to. + FeedOutputConfig feed_output_config = 5 [(google.api.field_behavior) = REQUIRED]; +} + +// Asset content type. +enum ContentType { + // Unspecified content type. + CONTENT_TYPE_UNSPECIFIED = 0; + + // Resource metadata. + RESOURCE = 1; + + // The actual IAM policy set on a resource. + IAM_POLICY = 2; + + // The Cloud Organization Policy set on an asset. + ORG_POLICY = 4; + + // The Cloud Access context mananger Policy set on an asset. + ACCESS_POLICY = 5; +} diff --git a/test-fixtures/protos/google/cloud/asset/v1/assets.proto b/test-fixtures/protos/google/cloud/asset/v1/assets.proto new file mode 100644 index 000000000..1e8b40a11 --- /dev/null +++ b/test-fixtures/protos/google/cloud/asset/v1/assets.proto @@ -0,0 +1,172 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.cloud.asset.v1; + +import "google/api/resource.proto"; +import "google/cloud/orgpolicy/v1/orgpolicy.proto"; +import "google/iam/v1/policy.proto"; +import "google/identity/accesscontextmanager/v1/access_level.proto"; +import "google/identity/accesscontextmanager/v1/access_policy.proto"; +import "google/identity/accesscontextmanager/v1/service_perimeter.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option cc_enable_arenas = true; +option csharp_namespace = "Google.Cloud.Asset.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/asset/v1;asset"; +option java_multiple_files = true; +option java_outer_classname = "AssetProto"; +option java_package = "com.google.cloud.asset.v1"; +option php_namespace = "Google\\Cloud\\Asset\\V1"; + +// An asset in Google Cloud and its temporal metadata, including the time window +// when it was observed and its status during that window. +message TemporalAsset { + // The time window when the asset data and state was observed. + TimeWindow window = 1; + + // Whether the asset has been deleted or not. + bool deleted = 2; + + // An asset in Google Cloud. + Asset asset = 3; +} + +// A time window specified by its "start_time" and "end_time". +message TimeWindow { + // Start time of the time window (exclusive). + google.protobuf.Timestamp start_time = 1; + + // End time of the time window (inclusive). If not specified, the current + // timestamp is used instead. + google.protobuf.Timestamp end_time = 2; +} + +// An asset in Google Cloud. An asset can be any resource in the Google Cloud +// [resource +// hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy), +// a resource outside the Google Cloud resource hierarchy (such as Google +// Kubernetes Engine clusters and objects), or a Cloud IAM policy. +message Asset { + option (google.api.resource) = { + type: "cloudasset.googleapis.com/Asset" + pattern: "*" + }; + + // The full name of the asset. For example: + // "//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1" + // + // See [Resource + // names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more information. + string name = 1; + + // The type of the asset. For example: "compute.googleapis.com/Disk" + // + // See [Supported asset + // types](https://cloud.google.com/asset-inventory/docs/supported-asset-types) + // for more information. + string asset_type = 2; + + // A representation of the resource. + Resource resource = 3; + + // A representation of the Cloud IAM policy set on a Google Cloud resource. + // There can be a maximum of one Cloud IAM policy set on any given resource. + // In addition, Cloud IAM policies inherit their granted access scope from any + // policies set on parent resources in the resource hierarchy. Therefore, the + // effectively policy is the union of both the policy set on this resource + // and each policy set on all of the resource's ancestry resource levels in + // the hierarchy. See + // [this topic](https://cloud.google.com/iam/docs/policies#inheritance) for + // more information. + google.iam.v1.Policy iam_policy = 4; + + // A representation of an [organization + // policy](https://cloud.google.com/resource-manager/docs/organization-policy/overview#organization_policy). + // There can be more than one organization policy with different constraints + // set on a given resource. + repeated google.cloud.orgpolicy.v1.Policy org_policy = 6; + + // A representation of an [access + // policy](https://cloud.google.com/access-context-manager/docs/overview#access-policies). + oneof access_context_policy { + google.identity.accesscontextmanager.v1.AccessPolicy access_policy = 7; + + google.identity.accesscontextmanager.v1.AccessLevel access_level = 8; + + google.identity.accesscontextmanager.v1.ServicePerimeter service_perimeter = 9; + } + + // The ancestry path of an asset in Google Cloud [resource + // hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy), + // represented as a list of relative resource names. An ancestry path starts + // with the closest ancestor in the hierarchy and ends at root. If the asset + // is a project, folder, or organization, the ancestry path starts from the + // asset itself. + // + // For example: `["projects/123456789", "folders/5432", "organizations/1234"]` + repeated string ancestors = 10; +} + +// A representation of a Google Cloud resource. +message Resource { + // The API version. For example: "v1" + string version = 1; + + // The URL of the discovery document containing the resource's JSON schema. + // For example: + // "https://www.googleapis.com/discovery/v1/apis/compute/v1/rest" + // + // This value is unspecified for resources that do not have an API based on a + // discovery document, such as Cloud Bigtable. + string discovery_document_uri = 2; + + // The JSON schema name listed in the discovery document. For example: + // "Project" + // + // This value is unspecified for resources that do not have an API based on a + // discovery document, such as Cloud Bigtable. + string discovery_name = 3; + + // The REST URL for accessing the resource. An HTTP `GET` request using this + // URL returns the resource itself. For example: + // "https://cloudresourcemanager.googleapis.com/v1/projects/my-project-123" + // + // This value is unspecified for resources without a REST API. + string resource_url = 4; + + // The full name of the immediate parent of this resource. See + // [Resource + // Names](https://cloud.google.com/apis/design/resource_names#full_resource_name) + // for more information. + // + // For Google Cloud assets, this value is the parent resource defined in the + // [Cloud IAM policy + // hierarchy](https://cloud.google.com/iam/docs/overview#policy_hierarchy). + // For example: + // "//cloudresourcemanager.googleapis.com/projects/my_project_123" + // + // For third-party assets, this field may be set differently. + string parent = 5; + + // The content of the resource, in which some sensitive fields are removed + // and may not be present. + google.protobuf.Struct data = 6; +} diff --git a/test-fixtures/protos/google/cloud/asset/v1/cloudasset_grpc_service_config.json b/test-fixtures/protos/google/cloud/asset/v1/cloudasset_grpc_service_config.json new file mode 100755 index 000000000..b13314bc7 --- /dev/null +++ b/test-fixtures/protos/google/cloud/asset/v1/cloudasset_grpc_service_config.json @@ -0,0 +1,31 @@ +{ + "methodConfig": [ + { + "name": [ + { + "service": "google.cloud.asset.v1.AssetService", + "method": "ExportAssets" + } + ], + "timeout": "60s" + }, + { + "name": [ + { + "service": "google.cloud.asset.v1.AssetService", + "method": "BatchGetAssetsHistory" + } + ], + "timeout": "60s", + "retryPolicy": { + "initialBackoff": "0.100s", + "maxBackoff": "60s", + "backoffMultiplier": 1.3, + "retryableStatusCodes": [ + "DEADLINE_EXCEEDED", + "UNAVAILABLE" + ] + } + } + ] +} diff --git a/test-fixtures/protos/google/cloud/orgpolicy/v1/orgpolicy.proto b/test-fixtures/protos/google/cloud/orgpolicy/v1/orgpolicy.proto new file mode 100644 index 000000000..fbd62df6f --- /dev/null +++ b/test-fixtures/protos/google/cloud/orgpolicy/v1/orgpolicy.proto @@ -0,0 +1,315 @@ +// Copyright 2019 Google LLC. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +syntax = "proto3"; + +package google.cloud.orgpolicy.v1; + +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Cloud.OrgPolicy.V1"; +option go_package = "google.golang.org/genproto/googleapis/cloud/orgpolicy/v1;orgpolicy"; +option java_multiple_files = true; +option java_outer_classname = "OrgPolicyProto"; +option java_package = "com.google.cloud.orgpolicy.v1"; +option php_namespace = "Google\\Cloud\\OrgPolicy\\V1"; +option ruby_package = "Google::Cloud::OrgPolicy::V1"; + +// Defines a Cloud Organization `Policy` which is used to specify `Constraints` +// for configurations of Cloud Platform resources. +message Policy { + // Used in `policy_type` to specify how `list_policy` behaves at this + // resource. + // + // `ListPolicy` can define specific values and subtrees of Cloud Resource + // Manager resource hierarchy (`Organizations`, `Folders`, `Projects`) that + // are allowed or denied by setting the `allowed_values` and `denied_values` + // fields. This is achieved by using the `under:` and optional `is:` prefixes. + // The `under:` prefix is used to denote resource subtree values. + // The `is:` prefix is used to denote specific values, and is required only + // if the value contains a ":". Values prefixed with "is:" are treated the + // same as values with no prefix. + // Ancestry subtrees must be in one of the following formats: + // - "projects/", e.g. "projects/tokyo-rain-123" + // - "folders/", e.g. "folders/1234" + // - "organizations/", e.g. "organizations/1234" + // The `supports_under` field of the associated `Constraint` defines whether + // ancestry prefixes can be used. You can set `allowed_values` and + // `denied_values` in the same `Policy` if `all_values` is + // `ALL_VALUES_UNSPECIFIED`. `ALLOW` or `DENY` are used to allow or deny all + // values. If `all_values` is set to either `ALLOW` or `DENY`, + // `allowed_values` and `denied_values` must be unset. + message ListPolicy { + // This enum can be used to set `Policies` that apply to all possible + // configuration values rather than specific values in `allowed_values` or + // `denied_values`. + // + // Settting this to `ALLOW` will mean this `Policy` allows all values. + // Similarly, setting it to `DENY` will mean no values are allowed. If + // set to either `ALLOW` or `DENY, `allowed_values` and `denied_values` + // must be unset. Setting this to `ALL_VALUES_UNSPECIFIED` allows for + // setting `allowed_values` and `denied_values`. + enum AllValues { + // Indicates that allowed_values or denied_values must be set. + ALL_VALUES_UNSPECIFIED = 0; + + // A policy with this set allows all values. + ALLOW = 1; + + // A policy with this set denies all values. + DENY = 2; + } + + // List of values allowed at this resource. Can only be set if `all_values` + // is set to `ALL_VALUES_UNSPECIFIED`. + repeated string allowed_values = 1; + + // List of values denied at this resource. Can only be set if `all_values` + // is set to `ALL_VALUES_UNSPECIFIED`. + repeated string denied_values = 2; + + // The policy all_values state. + AllValues all_values = 3; + + // Optional. The Google Cloud Console will try to default to a configuration + // that matches the value specified in this `Policy`. If `suggested_value` + // is not set, it will inherit the value specified higher in the hierarchy, + // unless `inherit_from_parent` is `false`. + string suggested_value = 4; + + // Determines the inheritance behavior for this `Policy`. + // + // By default, a `ListPolicy` set at a resource supercedes any `Policy` set + // anywhere up the resource hierarchy. However, if `inherit_from_parent` is + // set to `true`, then the values from the effective `Policy` of the parent + // resource are inherited, meaning the values set in this `Policy` are + // added to the values inherited up the hierarchy. + // + // Setting `Policy` hierarchies that inherit both allowed values and denied + // values isn't recommended in most circumstances to keep the configuration + // simple and understandable. However, it is possible to set a `Policy` with + // `allowed_values` set that inherits a `Policy` with `denied_values` set. + // In this case, the values that are allowed must be in `allowed_values` and + // not present in `denied_values`. + // + // For example, suppose you have a `Constraint` + // `constraints/serviceuser.services`, which has a `constraint_type` of + // `list_constraint`, and with `constraint_default` set to `ALLOW`. + // Suppose that at the Organization level, a `Policy` is applied that + // restricts the allowed API activations to {`E1`, `E2`}. Then, if a + // `Policy` is applied to a project below the Organization that has + // `inherit_from_parent` set to `false` and field all_values set to DENY, + // then an attempt to activate any API will be denied. + // + // The following examples demonstrate different possible layerings for + // `projects/bar` parented by `organizations/foo`: + // + // Example 1 (no inherited values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has `inherit_from_parent` `false` and values: + // {allowed_values: "E3" allowed_values: "E4"} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are `E3`, and `E4`. + // + // Example 2 (inherited values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has a `Policy` with values: + // {value: "E3" value: "E4" inherit_from_parent: true} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are `E1`, `E2`, `E3`, and `E4`. + // + // Example 3 (inheriting both allowed and denied values): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {denied_values: "E1"} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The value accepted at `projects/bar` is `E2`. + // + // Example 4 (RestoreDefault): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values:"E2"} + // `projects/bar` has a `Policy` with values: + // {RestoreDefault: {}} + // The accepted values at `organizations/foo` are `E1`, `E2`. + // The accepted values at `projects/bar` are either all or none depending on + // the value of `constraint_default` (if `ALLOW`, all; if + // `DENY`, none). + // + // Example 5 (no policy inherits parent policy): + // `organizations/foo` has no `Policy` set. + // `projects/bar` has no `Policy` set. + // The accepted values at both levels are either all or none depending on + // the value of `constraint_default` (if `ALLOW`, all; if + // `DENY`, none). + // + // Example 6 (ListConstraint allowing all): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {all: ALLOW} + // The accepted values at `organizations/foo` are `E1`, E2`. + // Any value is accepted at `projects/bar`. + // + // Example 7 (ListConstraint allowing none): + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "E1" allowed_values: "E2"} + // `projects/bar` has a `Policy` with: + // {all: DENY} + // The accepted values at `organizations/foo` are `E1`, E2`. + // No value is accepted at `projects/bar`. + // + // Example 10 (allowed and denied subtrees of Resource Manager hierarchy): + // Given the following resource hierarchy + // O1->{F1, F2}; F1->{P1}; F2->{P2, P3}, + // `organizations/foo` has a `Policy` with values: + // {allowed_values: "under:organizations/O1"} + // `projects/bar` has a `Policy` with: + // {allowed_values: "under:projects/P3"} + // {denied_values: "under:folders/F2"} + // The accepted values at `organizations/foo` are `organizations/O1`, + // `folders/F1`, `folders/F2`, `projects/P1`, `projects/P2`, + // `projects/P3`. + // The accepted values at `projects/bar` are `organizations/O1`, + // `folders/F1`, `projects/P1`. + bool inherit_from_parent = 5; + } + + // Used in `policy_type` to specify how `boolean_policy` will behave at this + // resource. + message BooleanPolicy { + // If `true`, then the `Policy` is enforced. If `false`, then any + // configuration is acceptable. + // + // Suppose you have a `Constraint` + // `constraints/compute.disableSerialPortAccess` with `constraint_default` + // set to `ALLOW`. A `Policy` for that `Constraint` exhibits the following + // behavior: + // - If the `Policy` at this resource has enforced set to `false`, serial + // port connection attempts will be allowed. + // - If the `Policy` at this resource has enforced set to `true`, serial + // port connection attempts will be refused. + // - If the `Policy` at this resource is `RestoreDefault`, serial port + // connection attempts will be allowed. + // - If no `Policy` is set at this resource or anywhere higher in the + // resource hierarchy, serial port connection attempts will be allowed. + // - If no `Policy` is set at this resource, but one exists higher in the + // resource hierarchy, the behavior is as if the`Policy` were set at + // this resource. + // + // The following examples demonstrate the different possible layerings: + // + // Example 1 (nearest `Constraint` wins): + // `organizations/foo` has a `Policy` with: + // {enforced: false} + // `projects/bar` has no `Policy` set. + // The constraint at `projects/bar` and `organizations/foo` will not be + // enforced. + // + // Example 2 (enforcement gets replaced): + // `organizations/foo` has a `Policy` with: + // {enforced: false} + // `projects/bar` has a `Policy` with: + // {enforced: true} + // The constraint at `organizations/foo` is not enforced. + // The constraint at `projects/bar` is enforced. + // + // Example 3 (RestoreDefault): + // `organizations/foo` has a `Policy` with: + // {enforced: true} + // `projects/bar` has a `Policy` with: + // {RestoreDefault: {}} + // The constraint at `organizations/foo` is enforced. + // The constraint at `projects/bar` is not enforced, because + // `constraint_default` for the `Constraint` is `ALLOW`. + bool enforced = 1; + } + + // Ignores policies set above this resource and restores the + // `constraint_default` enforcement behavior of the specific `Constraint` at + // this resource. + // + // Suppose that `constraint_default` is set to `ALLOW` for the + // `Constraint` `constraints/serviceuser.services`. Suppose that organization + // foo.com sets a `Policy` at their Organization resource node that restricts + // the allowed service activations to deny all service activations. They + // could then set a `Policy` with the `policy_type` `restore_default` on + // several experimental projects, restoring the `constraint_default` + // enforcement of the `Constraint` for only those projects, allowing those + // projects to have all services activated. + message RestoreDefault { + + } + + // Version of the `Policy`. Default version is 0; + int32 version = 1; + + // The name of the `Constraint` the `Policy` is configuring, for example, + // `constraints/serviceuser.services`. + // + // Immutable after creation. + string constraint = 2; + + // An opaque tag indicating the current version of the `Policy`, used for + // concurrency control. + // + // When the `Policy` is returned from either a `GetPolicy` or a + // `ListOrgPolicy` request, this `etag` indicates the version of the current + // `Policy` to use when executing a read-modify-write loop. + // + // When the `Policy` is returned from a `GetEffectivePolicy` request, the + // `etag` will be unset. + // + // When the `Policy` is used in a `SetOrgPolicy` method, use the `etag` value + // that was returned from a `GetOrgPolicy` request as part of a + // read-modify-write loop for concurrency control. Not setting the `etag`in a + // `SetOrgPolicy` request will result in an unconditional write of the + // `Policy`. + bytes etag = 3; + + // The time stamp the `Policy` was previously updated. This is set by the + // server, not specified by the caller, and represents the last time a call to + // `SetOrgPolicy` was made for that `Policy`. Any value set by the client will + // be ignored. + google.protobuf.Timestamp update_time = 4; + + // The field to populate is based on the `constraint_type` value in the + // `Constraint`. + // `list_constraint` => `list_policy` + // `boolean_constraint` => `boolean_policy` + // + // A `restore_default` message may be used with any `Constraint` type. + // + // Providing a *_policy that is incompatible with the `constraint_type` will + // result in an `invalid_argument` error. + // + // Attempting to set a `Policy` with a `policy_type` not set will result in an + // `invalid_argument` error. + oneof policy_type { + // List of values either allowed or disallowed. + ListPolicy list_policy = 5; + + // For boolean `Constraints`, whether to enforce the `Constraint` or not. + BooleanPolicy boolean_policy = 6; + + // Restores the default behavior of the constraint; independent of + // `Constraint` type. + RestoreDefault restore_default = 7; + } +} diff --git a/test-fixtures/protos/google/identity/accesscontextmanager/type/device_resources.proto b/test-fixtures/protos/google/identity/accesscontextmanager/type/device_resources.proto new file mode 100644 index 000000000..f05791033 --- /dev/null +++ b/test-fixtures/protos/google/identity/accesscontextmanager/type/device_resources.proto @@ -0,0 +1,85 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.type; + +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.Type"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/type;type"; +option java_package = "com.google.identity.accesscontextmanager.type"; +option java_multiple_files = true; +option java_outer_classname = "TypeProto"; +option php_namespace = "Google\\Identity\\AccessContextManager\\Type"; +option ruby_package = "Google::Identity::AccessContextManager::Type"; + +// The encryption state of the device. +enum DeviceEncryptionStatus { + // The encryption status of the device is not specified or not known. + ENCRYPTION_UNSPECIFIED = 0; + + // The device does not support encryption. + ENCRYPTION_UNSUPPORTED = 1; + + // The device supports encryption, but is currently unencrypted. + UNENCRYPTED = 2; + + // The device is encrypted. + ENCRYPTED = 3; +} + +// The operating system type of the device. +// Next id: 7 +enum OsType { + // The operating system of the device is not specified or not known. + OS_UNSPECIFIED = 0; + + // A desktop Mac operating system. + DESKTOP_MAC = 1; + + // A desktop Windows operating system. + DESKTOP_WINDOWS = 2; + + // A desktop Linux operating system. + DESKTOP_LINUX = 3; + + // A desktop ChromeOS operating system. + DESKTOP_CHROME_OS = 6; + + // An Android operating system. + ANDROID = 4; + + // An iOS operating system. + IOS = 5; +} + +// The degree to which the device is managed by the Cloud organization. +enum DeviceManagementLevel { + // The device's management level is not specified or not known. + MANAGEMENT_UNSPECIFIED = 0; + + // The device is not managed. + NONE = 1; + + // Basic management is enabled, which is generally limited to monitoring and + // wiping the corporate account. + BASIC = 2; + + // Complete device management. This includes more thorough monitoring and the + // ability to directly manage the device (such as remote wiping). This can be + // enabled through the Android Enterprise Platform. + COMPLETE = 3; +} diff --git a/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_level.proto b/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_level.proto new file mode 100644 index 000000000..0ebd1936c --- /dev/null +++ b/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_level.proto @@ -0,0 +1,187 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/identity/accesscontextmanager/type/device_resources.proto"; +import "google/protobuf/timestamp.proto"; +import "google/type/expr.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "AccessLevelProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// An `AccessLevel` is a label that can be applied to requests to Google Cloud +// services, along with a list of requirements necessary for the label to be +// applied. +message AccessLevel { + // Required. Resource name for the Access Level. The `short_name` component + // must begin with a letter and only include alphanumeric and '_'. Format: + // `accessPolicies/{policy_id}/accessLevels/{short_name}`. The maximum length + // of the `short_name` component is 50 characters. + string name = 1; + + // Human readable title. Must be unique within the Policy. + string title = 2; + + // Description of the `AccessLevel` and its use. Does not affect behavior. + string description = 3; + + // Required. Describes the necessary conditions for the level to apply. + oneof level { + // A `BasicLevel` composed of `Conditions`. + BasicLevel basic = 4; + + // A `CustomLevel` written in the Common Expression Language. + CustomLevel custom = 5; + } + + // Output only. Time the `AccessLevel` was created in UTC. + google.protobuf.Timestamp create_time = 6; + + // Output only. Time the `AccessLevel` was updated in UTC. + google.protobuf.Timestamp update_time = 7; +} + +// `BasicLevel` is an `AccessLevel` using a set of recommended features. +message BasicLevel { + // Options for how the `conditions` list should be combined to determine if + // this `AccessLevel` is applied. Default is AND. + enum ConditionCombiningFunction { + // All `Conditions` must be true for the `BasicLevel` to be true. + AND = 0; + + // If at least one `Condition` is true, then the `BasicLevel` is true. + OR = 1; + } + + // Required. A list of requirements for the `AccessLevel` to be granted. + repeated Condition conditions = 1; + + // How the `conditions` list should be combined to determine if a request is + // granted this `AccessLevel`. If AND is used, each `Condition` in + // `conditions` must be satisfied for the `AccessLevel` to be applied. If OR + // is used, at least one `Condition` in `conditions` must be satisfied for the + // `AccessLevel` to be applied. Default behavior is AND. + ConditionCombiningFunction combining_function = 2; +} + +// A condition necessary for an `AccessLevel` to be granted. The Condition is an +// AND over its fields. So a Condition is true if: 1) the request IP is from one +// of the listed subnetworks AND 2) the originating device complies with the +// listed device policy AND 3) all listed access levels are granted AND 4) the +// request was sent at a time allowed by the DateTimeRestriction. +message Condition { + // CIDR block IP subnetwork specification. May be IPv4 or IPv6. Note that for + // a CIDR IP address block, the specified IP address portion must be properly + // truncated (i.e. all the host bits must be zero) or the input is considered + // malformed. For example, "192.0.2.0/24" is accepted but "192.0.2.1/24" is + // not. Similarly, for IPv6, "2001:db8::/32" is accepted whereas + // "2001:db8::1/32" is not. The originating IP of a request must be in one of + // the listed subnets in order for this Condition to be true. If empty, all IP + // addresses are allowed. + repeated string ip_subnetworks = 1; + + // Device specific restrictions, all restrictions must hold for the + // Condition to be true. If not specified, all devices are allowed. + DevicePolicy device_policy = 2; + + // A list of other access levels defined in the same `Policy`, referenced by + // resource name. Referencing an `AccessLevel` which does not exist is an + // error. All access levels listed must be granted for the Condition + // to be true. Example: + // "`accessPolicies/MY_POLICY/accessLevels/LEVEL_NAME"` + repeated string required_access_levels = 3; + + // Whether to negate the Condition. If true, the Condition becomes a NAND over + // its non-empty fields, each field must be false for the Condition overall to + // be satisfied. Defaults to false. + bool negate = 5; + + // The request must be made by one of the provided user or service + // accounts. Groups are not supported. + // Syntax: + // `user:{emailid}` + // `serviceAccount:{emailid}` + // If not specified, a request may come from any user. + repeated string members = 6; + + // The request must originate from one of the provided countries/regions. + // Must be valid ISO 3166-1 alpha-2 codes. + repeated string regions = 7; +} + +// `CustomLevel` is an `AccessLevel` using the Cloud Common Expression Language +// to represent the necessary conditions for the level to apply to a request. +// See CEL spec at: https://github.com/google/cel-spec +message CustomLevel { + // Required. A Cloud CEL expression evaluating to a boolean. + google.type.Expr expr = 1; +} + +// `DevicePolicy` specifies device specific restrictions necessary to acquire a +// given access level. A `DevicePolicy` specifies requirements for requests from +// devices to be granted access levels, it does not do any enforcement on the +// device. `DevicePolicy` acts as an AND over all specified fields, and each +// repeated field is an OR over its elements. Any unset fields are ignored. For +// example, if the proto is { os_type : DESKTOP_WINDOWS, os_type : +// DESKTOP_LINUX, encryption_status: ENCRYPTED}, then the DevicePolicy will be +// true for requests originating from encrypted Linux desktops and encrypted +// Windows desktops. +message DevicePolicy { + // Whether or not screenlock is required for the DevicePolicy to be true. + // Defaults to `false`. + bool require_screenlock = 1; + + // Allowed encryptions statuses, an empty list allows all statuses. + repeated google.identity.accesscontextmanager.type.DeviceEncryptionStatus allowed_encryption_statuses = 2; + + // Allowed OS versions, an empty list allows all types and all versions. + repeated OsConstraint os_constraints = 3; + + // Allowed device management levels, an empty list allows all management + // levels. + repeated google.identity.accesscontextmanager.type.DeviceManagementLevel allowed_device_management_levels = 6; + + // Whether the device needs to be approved by the customer admin. + bool require_admin_approval = 7; + + // Whether the device needs to be corp owned. + bool require_corp_owned = 8; +} + +// A restriction on the OS type and version of devices making requests. +message OsConstraint { + // Required. The allowed OS type. + google.identity.accesscontextmanager.type.OsType os_type = 1; + + // The minimum allowed OS version. If not set, any version of this OS + // satisfies the constraint. Format: `"major.minor.patch"`. + // Examples: `"10.5.301"`, `"9.2.1"`. + string minimum_version = 2; + + // Only allows requests from devices with a verified Chrome OS. + // Verifications includes requirements that the device is enterprise-managed, + // conformant to domain policies, and the caller has permission to call + // the API targeted by the request. + bool require_verified_chrome_os = 3; +} diff --git a/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_policy.proto b/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_policy.proto new file mode 100644 index 000000000..9ec59d1c1 --- /dev/null +++ b/test-fixtures/protos/google/identity/accesscontextmanager/v1/access_policy.proto @@ -0,0 +1,60 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "PolicyProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// `AccessPolicy` is a container for `AccessLevels` (which define the necessary +// attributes to use Google Cloud services) and `ServicePerimeters` (which +// define regions of services able to freely pass data within a perimeter). An +// access policy is globally visible within an organization, and the +// restrictions it specifies apply to all projects within an organization. +message AccessPolicy { + // Output only. Resource name of the `AccessPolicy`. Format: + // `accessPolicies/{policy_id}` + string name = 1; + + // Required. The parent of this `AccessPolicy` in the Cloud Resource + // Hierarchy. Currently immutable once created. Format: + // `organizations/{organization_id}` + string parent = 2; + + // Required. Human readable title. Does not affect behavior. + string title = 3; + + // Output only. Time the `AccessPolicy` was created in UTC. + google.protobuf.Timestamp create_time = 4; + + // Output only. Time the `AccessPolicy` was updated in UTC. + google.protobuf.Timestamp update_time = 5; + + // Output only. An opaque identifier for the current version of the + // `AccessPolicy`. This will always be a strongly validated etag, meaning that + // two Access Polices will be identical if and only if their etags are + // identical. Clients should not expect this to be in any specific format. + string etag = 6; +} diff --git a/test-fixtures/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto b/test-fixtures/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto new file mode 100644 index 000000000..89d76818d --- /dev/null +++ b/test-fixtures/protos/google/identity/accesscontextmanager/v1/service_perimeter.proto @@ -0,0 +1,152 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.identity.accesscontextmanager.v1; + +import "google/protobuf/timestamp.proto"; +import "google/api/annotations.proto"; + +option csharp_namespace = "Google.Identity.AccessContextManager.V1"; +option go_package = "google.golang.org/genproto/googleapis/identity/accesscontextmanager/v1;accesscontextmanager"; +option java_multiple_files = true; +option java_outer_classname = "ServicePerimeterProto"; +option java_package = "com.google.identity.accesscontextmanager.v1"; +option php_namespace = "Google\\Identity\\AccessContextManager\\V1"; +option ruby_package = "Google::Identity::AccessContextManager::V1"; +option objc_class_prefix = "GACM"; + +// `ServicePerimeter` describes a set of Google Cloud resources which can freely +// import and export data amongst themselves, but not export outside of the +// `ServicePerimeter`. If a request with a source within this `ServicePerimeter` +// has a target outside of the `ServicePerimeter`, the request will be blocked. +// Otherwise the request is allowed. There are two types of Service Perimeter - +// Regular and Bridge. Regular Service Perimeters cannot overlap, a single +// Google Cloud project can only belong to a single regular Service Perimeter. +// Service Perimeter Bridges can contain only Google Cloud projects as members, +// a single Google Cloud project may belong to multiple Service Perimeter +// Bridges. +message ServicePerimeter { + // Specifies the type of the Perimeter. There are two types: regular and + // bridge. Regular Service Perimeter contains resources, access levels, and + // restricted services. Every resource can be in at most ONE + // regular Service Perimeter. + // + // In addition to being in a regular service perimeter, a resource can also + // be in zero or more perimeter bridges. A perimeter bridge only contains + // resources. Cross project operations are permitted if all effected + // resources share some perimeter (whether bridge or regular). Perimeter + // Bridge does not contain access levels or services: those are governed + // entirely by the regular perimeter that resource is in. + // + // Perimeter Bridges are typically useful when building more complex toplogies + // with many independent perimeters that need to share some data with a common + // perimeter, but should not be able to share data among themselves. + enum PerimeterType { + // Regular Perimeter. + PERIMETER_TYPE_REGULAR = 0; + + // Perimeter Bridge. + PERIMETER_TYPE_BRIDGE = 1; + } + + // Required. Resource name for the ServicePerimeter. The `short_name` + // component must begin with a letter and only include alphanumeric and '_'. + // Format: `accessPolicies/{policy_id}/servicePerimeters/{short_name}` + string name = 1; + + // Human readable title. Must be unique within the Policy. + string title = 2; + + // Description of the `ServicePerimeter` and its use. Does not affect + // behavior. + string description = 3; + + // Output only. Time the `ServicePerimeter` was created in UTC. + google.protobuf.Timestamp create_time = 4; + + // Output only. Time the `ServicePerimeter` was updated in UTC. + google.protobuf.Timestamp update_time = 5; + + // Perimeter type indicator. A single project is + // allowed to be a member of single regular perimeter, but multiple service + // perimeter bridges. A project cannot be a included in a perimeter bridge + // without being included in regular perimeter. For perimeter bridges, + // the restricted service list as well as access level lists must be + // empty. + PerimeterType perimeter_type = 6; + + // Current ServicePerimeter configuration. Specifies sets of resources, + // restricted services and access levels that determine perimeter + // content and boundaries. + ServicePerimeterConfig status = 7; + + // Proposed (or dry run) ServicePerimeter configuration. This configuration + // allows to specify and test ServicePerimeter configuration without enforcing + // actual access restrictions. Only allowed to be set when the + // "use_explicit_dry_run_spec" flag is set. + ServicePerimeterConfig spec = 8; + + // Use explicit dry run spec flag. Ordinarily, a dry-run spec implicitly + // exists for all Service Perimeters, and that spec is identical to the + // status for those Service Perimeters. When this flag is set, it inhibits the + // generation of the implicit spec, thereby allowing the user to explicitly + // provide a configuration ("spec") to use in a dry-run version of the Service + // Perimeter. This allows the user to test changes to the enforced config + // ("status") without actually enforcing them. This testing is done through + // analyzing the differences between currently enforced and suggested + // restrictions. use_explicit_dry_run_spec must bet set to True if any of the + // fields in the spec are set to non-default values. + bool use_explicit_dry_run_spec = 9; +} + +// `ServicePerimeterConfig` specifies a set of Google Cloud resources that +// describe specific Service Perimeter configuration. +message ServicePerimeterConfig { + // Specifies how APIs are allowed to communicate within the Service + // Perimeter. + message VpcAccessibleServices { + // Whether to restrict API calls within the Service Perimeter to the list of + // APIs specified in 'allowed_services'. + bool enable_restriction = 1; + + // The list of APIs usable within the Service Perimeter. Must be empty + // unless 'enable_restriction' is True. + repeated string allowed_services = 2; + } + + // A list of Google Cloud resources that are inside of the service perimeter. + // Currently only projects are allowed. Format: `projects/{project_number}` + repeated string resources = 1; + + // A list of `AccessLevel` resource names that allow resources within the + // `ServicePerimeter` to be accessed from the internet. `AccessLevels` listed + // must be in the same policy as this `ServicePerimeter`. Referencing a + // nonexistent `AccessLevel` is a syntax error. If no `AccessLevel` names are + // listed, resources within the perimeter can only be accessed via Google + // Cloud calls with request origins within the perimeter. Example: + // `"accessPolicies/MY_POLICY/accessLevels/MY_LEVEL"`. + // For Service Perimeter Bridge, must be empty. + repeated string access_levels = 2; + + // Google Cloud services that are subject to the Service Perimeter + // restrictions. For example, if `storage.googleapis.com` is specified, access + // to the storage buckets inside the perimeter must meet the perimeter's + // access restrictions. + repeated string restricted_services = 4; + + // Configuration for APIs allowed within Perimeter. + VpcAccessibleServices vpc_accessible_services = 10; +} diff --git a/typescript/test/unit/baselines.ts b/typescript/test/unit/baselines.ts index 8344eb87d..be54fbbd2 100644 --- a/typescript/test/unit/baselines.ts +++ b/typescript/test/unit/baselines.ts @@ -74,6 +74,17 @@ describe('Baseline tests', () => { template: 'typescript_gapic;typescript_packing_test', }); + runBaselineTest({ + baselineName: 'asset', + outputDir: '.test-out-asset', + protoPath: + 'google/cloud/asset/v1/*.proto;google/cloud/orgpolicy/v1/orgpolicy.proto;google/identity/accesscontextmanager/v1/*.proto;google/identity/accesscontextmanager/type/*.proto', + useCommonProto: true, + grpcServiceConfig: + 'google/cloud/asset/v1/cloudasset_grpc_service_config.json', + packageName: '@google-cloud/asset', + }); + runBaselineTest({ baselineName: 'translate', outputDir: '.test-out-translate', diff --git a/typescript/test/util.ts b/typescript/test/util.ts index 2a8b45a82..ab1f61f4d 100644 --- a/typescript/test/util.ts +++ b/typescript/test/util.ts @@ -76,9 +76,9 @@ export function initBaselineTest() { export function runBaselineTest(options: BaselineOptions) { const outputDir = path.join(cwd, options.outputDir); - const protoPath = path.join( - protosDirRoot, - options.protoPath.split('/').join(path.sep) + const protos = options.protoPath.split(';'); + const protoPaths = protos.map(proto => + path.join(protosDirRoot, proto.split('/').join(path.sep)) ); const baselineDir = path.join(baselineRootDir, options.baselineName); const grpcServiceConfig = options.grpcServiceConfig @@ -100,7 +100,7 @@ export function runBaselineTest(options: BaselineOptions) { let commandLine = `node ${startScriptPath} --output_dir=${outputDir} ` + - `-I${protosDirRoot} -I${googleGaxProtosDir} ${protoPath}`; + `-I${protosDirRoot} -I${googleGaxProtosDir} ${protoPaths.join(' ')}`; if (options.useCommonProto) { commandLine += ` ${commonProtoFilePath}`; }