diff --git a/packages/googleapis-common-protos/google/rpc/error_details.proto b/packages/googleapis-common-protos/google/rpc/error_details.proto index 46ef5b864e01..4f9ecff03517 100644 --- a/packages/googleapis-common-protos/google/rpc/error_details.proto +++ b/packages/googleapis-common-protos/google/rpc/error_details.proto @@ -131,6 +131,71 @@ message QuotaFailure { // For example: "Service disabled" or "Daily Limit for read operations // exceeded". string description = 2; + + // The API Service from which the `QuotaFailure.Violation` orginates. In + // some cases, Quota issues originate from an API Service other than the one + // that was called. In other words, a dependency of the called API Service + // could be the cause of the `QuotaFailure`, and this field would have the + // dependency API service name. + // + // For example, if the called API is Kubernetes Engine API + // (container.googleapis.com), and a quota violation occurs in the + // Kubernetes Engine API itself, this field would be + // "container.googleapis.com". On the other hand, if the quota violation + // occurs when the Kubernetes Engine API creates VMs in the Compute Engine + // API (compute.googleapis.com), this field would be + // "compute.googleapis.com". + string api_service = 3; + + // The metric of the violated quota. A quota metric is a named counter to + // measure usage, such as API requests or CPUs. When an activity occurs in a + // service, such as Virtual Machine allocation, one or more quota metrics + // may be affected. + // + // For example, "compute.googleapis.com/cpus_per_vm_family", + // "storage.googleapis.com/internet_egress_bandwidth". + string quota_metric = 4; + + // The id of the violated quota. Also know as "limit name", this is the + // unique identifier of a quota in the context of an API service. + // + // For example, "CPUS-PER-VM-FAMILY-per-project-region". + string quota_id = 5; + + // The dimensions of the violated quota. Every non-global quota is enforced + // on a set of dimensions. While quota metric defines what to count, the + // dimensions specify for what aspects the counter should be increased. + // + // For example, the quota "CPUs per region per VM family" enforces a limit + // on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions + // "region" and "vm_family". And if the violation occurred in region + // "us-central1" and for VM family "n1", the quota_dimensions would be, + // + // { + // "region": "us-central1", + // "vm_family": "n1", + // } + // + // When a quota is enforced globally, the quota_dimensions would always be + // empty. + map quota_dimensions = 6; + + // The enforced quota value at the time of the `QuotaFailure`. + // + // For example, if the enforced quota value at the time of the + // `QuotaFailure` on the number of CPUs is "10", then the value of this + // field would reflect this quantity. + int64 quota_value = 7; + + // The new quota value being rolled out at the time of the violation. At the + // completion of the rollout, this value will be enforced in place of + // quota_value. If no rollout is in progress at the time of the violation, + // this field is not set. + // + // For example, if at the time of the violation a rollout is in progress + // changing the number of CPUs quota from 10 to 20, 20 would be the value of + // this field. + optional int64 future_quota_value = 8; } // Describes all quota violations. diff --git a/packages/googleapis-common-protos/google/rpc/error_details_pb2.py b/packages/googleapis-common-protos/google/rpc/error_details_pb2.py index 6fe54cc964c5..301d23e785cf 100644 --- a/packages/googleapis-common-protos/google/rpc/error_details_pb2.py +++ b/packages/googleapis-common-protos/google/rpc/error_details_pb2.py @@ -31,7 +31,7 @@ from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( - b'\n\x1egoogle/rpc/error_details.proto\x12\ngoogle.rpc\x1a\x1egoogle/protobuf/duration.proto"\x93\x01\n\tErrorInfo\x12\x0e\n\x06reason\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x35\n\x08metadata\x18\x03 \x03(\x0b\x32#.google.rpc.ErrorInfo.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01";\n\tRetryInfo\x12.\n\x0bretry_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration"2\n\tDebugInfo\x12\x15\n\rstack_entries\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t"y\n\x0cQuotaFailure\x12\x36\n\nviolations\x18\x01 \x03(\x0b\x32".google.rpc.QuotaFailure.Violation\x1a\x31\n\tViolation\x12\x0f\n\x07subject\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t"\x95\x01\n\x13PreconditionFailure\x12=\n\nviolations\x18\x01 \x03(\x0b\x32).google.rpc.PreconditionFailure.Violation\x1a?\n\tViolation\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07subject\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xcc\x01\n\nBadRequest\x12?\n\x10\x66ield_violations\x18\x01 \x03(\x0b\x32%.google.rpc.BadRequest.FieldViolation\x1a}\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x37\n\x11localized_message\x18\x04 \x01(\x0b\x32\x1c.google.rpc.LocalizedMessage"7\n\x0bRequestInfo\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x14\n\x0cserving_data\x18\x02 \x01(\t"`\n\x0cResourceInfo\x12\x15\n\rresource_type\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\r\n\x05owner\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t"V\n\x04Help\x12$\n\x05links\x18\x01 \x03(\x0b\x32\x15.google.rpc.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t"3\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\tBl\n\x0e\x63om.google.rpcB\x11\x45rrorDetailsProtoP\x01Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\xa2\x02\x03RPCb\x06proto3' + b'\n\x1egoogle/rpc/error_details.proto\x12\ngoogle.rpc\x1a\x1egoogle/protobuf/duration.proto"\x93\x01\n\tErrorInfo\x12\x0e\n\x06reason\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x35\n\x08metadata\x18\x03 \x03(\x0b\x32#.google.rpc.ErrorInfo.MetadataEntry\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01";\n\tRetryInfo\x12.\n\x0bretry_delay\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration"2\n\tDebugInfo\x12\x15\n\rstack_entries\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t"\x8f\x03\n\x0cQuotaFailure\x12\x36\n\nviolations\x18\x01 \x03(\x0b\x32".google.rpc.QuotaFailure.Violation\x1a\xc6\x02\n\tViolation\x12\x0f\n\x07subject\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x13\n\x0b\x61pi_service\x18\x03 \x01(\t\x12\x14\n\x0cquota_metric\x18\x04 \x01(\t\x12\x10\n\x08quota_id\x18\x05 \x01(\t\x12Q\n\x10quota_dimensions\x18\x06 \x03(\x0b\x32\x37.google.rpc.QuotaFailure.Violation.QuotaDimensionsEntry\x12\x13\n\x0bquota_value\x18\x07 \x01(\x03\x12\x1f\n\x12\x66uture_quota_value\x18\x08 \x01(\x03H\x00\x88\x01\x01\x1a\x36\n\x14QuotaDimensionsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x15\n\x13_future_quota_value"\x95\x01\n\x13PreconditionFailure\x12=\n\nviolations\x18\x01 \x03(\x0b\x32).google.rpc.PreconditionFailure.Violation\x1a?\n\tViolation\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07subject\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t"\xcc\x01\n\nBadRequest\x12?\n\x10\x66ield_violations\x18\x01 \x03(\x0b\x32%.google.rpc.BadRequest.FieldViolation\x1a}\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x37\n\x11localized_message\x18\x04 \x01(\x0b\x32\x1c.google.rpc.LocalizedMessage"7\n\x0bRequestInfo\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x14\n\x0cserving_data\x18\x02 \x01(\t"`\n\x0cResourceInfo\x12\x15\n\rresource_type\x18\x01 \x01(\t\x12\x15\n\rresource_name\x18\x02 \x01(\t\x12\r\n\x05owner\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t"V\n\x04Help\x12$\n\x05links\x18\x01 \x03(\x0b\x32\x15.google.rpc.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t"3\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\tBl\n\x0e\x63om.google.rpcB\x11\x45rrorDetailsProtoP\x01Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\xa2\x02\x03RPCb\x06proto3' ) _globals = globals() @@ -46,6 +46,10 @@ ]._serialized_options = b"\n\016com.google.rpcB\021ErrorDetailsProtoP\001Z?google.golang.org/genproto/googleapis/rpc/errdetails;errdetails\242\002\003RPC" _globals["_ERRORINFO_METADATAENTRY"]._options = None _globals["_ERRORINFO_METADATAENTRY"]._serialized_options = b"8\001" + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._options = None + _globals[ + "_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY" + ]._serialized_options = b"8\001" _globals["_ERRORINFO"]._serialized_start = 79 _globals["_ERRORINFO"]._serialized_end = 226 _globals["_ERRORINFO_METADATAENTRY"]._serialized_start = 179 @@ -54,26 +58,28 @@ _globals["_RETRYINFO"]._serialized_end = 287 _globals["_DEBUGINFO"]._serialized_start = 289 _globals["_DEBUGINFO"]._serialized_end = 339 - _globals["_QUOTAFAILURE"]._serialized_start = 341 - _globals["_QUOTAFAILURE"]._serialized_end = 462 - _globals["_QUOTAFAILURE_VIOLATION"]._serialized_start = 413 - _globals["_QUOTAFAILURE_VIOLATION"]._serialized_end = 462 - _globals["_PRECONDITIONFAILURE"]._serialized_start = 465 - _globals["_PRECONDITIONFAILURE"]._serialized_end = 614 - _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_start = 551 - _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_end = 614 - _globals["_BADREQUEST"]._serialized_start = 617 - _globals["_BADREQUEST"]._serialized_end = 821 - _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_start = 696 - _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_end = 821 - _globals["_REQUESTINFO"]._serialized_start = 823 - _globals["_REQUESTINFO"]._serialized_end = 878 - _globals["_RESOURCEINFO"]._serialized_start = 880 - _globals["_RESOURCEINFO"]._serialized_end = 976 - _globals["_HELP"]._serialized_start = 978 - _globals["_HELP"]._serialized_end = 1064 - _globals["_HELP_LINK"]._serialized_start = 1024 - _globals["_HELP_LINK"]._serialized_end = 1064 - _globals["_LOCALIZEDMESSAGE"]._serialized_start = 1066 - _globals["_LOCALIZEDMESSAGE"]._serialized_end = 1117 + _globals["_QUOTAFAILURE"]._serialized_start = 342 + _globals["_QUOTAFAILURE"]._serialized_end = 741 + _globals["_QUOTAFAILURE_VIOLATION"]._serialized_start = 415 + _globals["_QUOTAFAILURE_VIOLATION"]._serialized_end = 741 + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_start = 664 + _globals["_QUOTAFAILURE_VIOLATION_QUOTADIMENSIONSENTRY"]._serialized_end = 718 + _globals["_PRECONDITIONFAILURE"]._serialized_start = 744 + _globals["_PRECONDITIONFAILURE"]._serialized_end = 893 + _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_start = 830 + _globals["_PRECONDITIONFAILURE_VIOLATION"]._serialized_end = 893 + _globals["_BADREQUEST"]._serialized_start = 896 + _globals["_BADREQUEST"]._serialized_end = 1100 + _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_start = 975 + _globals["_BADREQUEST_FIELDVIOLATION"]._serialized_end = 1100 + _globals["_REQUESTINFO"]._serialized_start = 1102 + _globals["_REQUESTINFO"]._serialized_end = 1157 + _globals["_RESOURCEINFO"]._serialized_start = 1159 + _globals["_RESOURCEINFO"]._serialized_end = 1255 + _globals["_HELP"]._serialized_start = 1257 + _globals["_HELP"]._serialized_end = 1343 + _globals["_HELP_LINK"]._serialized_start = 1303 + _globals["_HELP_LINK"]._serialized_end = 1343 + _globals["_LOCALIZEDMESSAGE"]._serialized_start = 1345 + _globals["_LOCALIZEDMESSAGE"]._serialized_end = 1396 # @@protoc_insertion_point(module_scope) diff --git a/packages/googleapis-common-protos/google/rpc/error_details_pb2.pyi b/packages/googleapis-common-protos/google/rpc/error_details_pb2.pyi index 1316da1fb171..23c63333a461 100644 --- a/packages/googleapis-common-protos/google/rpc/error_details_pb2.pyi +++ b/packages/googleapis-common-protos/google/rpc/error_details_pb2.pyi @@ -74,13 +74,52 @@ class QuotaFailure(_message.Message): __slots__ = ("violations",) class Violation(_message.Message): - __slots__ = ("subject", "description") + __slots__ = ( + "subject", + "description", + "api_service", + "quota_metric", + "quota_id", + "quota_dimensions", + "quota_value", + "future_quota_value", + ) + + class QuotaDimensionsEntry(_message.Message): + __slots__ = ("key", "value") + KEY_FIELD_NUMBER: _ClassVar[int] + VALUE_FIELD_NUMBER: _ClassVar[int] + key: str + value: str + def __init__( + self, key: _Optional[str] = ..., value: _Optional[str] = ... + ) -> None: ... SUBJECT_FIELD_NUMBER: _ClassVar[int] DESCRIPTION_FIELD_NUMBER: _ClassVar[int] + API_SERVICE_FIELD_NUMBER: _ClassVar[int] + QUOTA_METRIC_FIELD_NUMBER: _ClassVar[int] + QUOTA_ID_FIELD_NUMBER: _ClassVar[int] + QUOTA_DIMENSIONS_FIELD_NUMBER: _ClassVar[int] + QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] + FUTURE_QUOTA_VALUE_FIELD_NUMBER: _ClassVar[int] subject: str description: str + api_service: str + quota_metric: str + quota_id: str + quota_dimensions: _containers.ScalarMap[str, str] + quota_value: int + future_quota_value: int def __init__( - self, subject: _Optional[str] = ..., description: _Optional[str] = ... + self, + subject: _Optional[str] = ..., + description: _Optional[str] = ..., + api_service: _Optional[str] = ..., + quota_metric: _Optional[str] = ..., + quota_id: _Optional[str] = ..., + quota_dimensions: _Optional[_Mapping[str, str]] = ..., + quota_value: _Optional[int] = ..., + future_quota_value: _Optional[int] = ..., ) -> None: ... VIOLATIONS_FIELD_NUMBER: _ClassVar[int] violations: _containers.RepeatedCompositeFieldContainer[QuotaFailure.Violation] diff --git a/packages/googleapis-common-protos/noxfile.py b/packages/googleapis-common-protos/noxfile.py index 0acc836b384e..a4a13745db02 100644 --- a/packages/googleapis-common-protos/noxfile.py +++ b/packages/googleapis-common-protos/noxfile.py @@ -385,7 +385,7 @@ def prerelease_deps(session, protobuf_implementation): """ Run all tests with pre-release versions of dependencies installed rather than the standard non pre-release versions. - Pre-releases versions can be installed using + Pre-release versions can be installed using `pip install --pre `. """ @@ -395,16 +395,16 @@ def prerelease_deps(session, protobuf_implementation): # Install all dependencies session.install("-e", ".") - unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES # Install dependencies for the unit test environment + unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES session.install(*unit_deps_all) + # Install dependencies for the system test environment system_deps_all = ( SYSTEM_TEST_STANDARD_DEPENDENCIES + SYSTEM_TEST_EXTERNAL_DEPENDENCIES + SYSTEM_TEST_EXTRAS ) - # Install dependencies for the system test environment session.install(*system_deps_all) # Because we test minimum dependency versions on the minimum Python @@ -429,37 +429,44 @@ def prerelease_deps(session, protobuf_implementation): # Install dependencies specified in `testing/constraints-X.txt`. session.install(*constraints_deps) + # Note: If a dependency is added to the `prerel_deps` list, + # the `core_dependencies_from_source` list in the `core_deps_from_source` + # nox session should also be updated. prerel_deps = [ - "protobuf", - # dependency of grpc - "six", - "grpc-google-iam-v1", "googleapis-common-protos", - "grpcio", - "grpcio-status", "google-api-core", "google-auth", + "grpc-google-iam-v1", + "grpcio", + "grpcio-status", + "protobuf", "proto-plus", - "google-cloud-testutils", - # dependencies of google-cloud-testutils" - "click", ] for dep in prerel_deps: - session.install("--pre", "--no-deps", "--upgrade", dep) - - # Remaining dependencies - other_deps = [ - "requests", - ] - session.install(*other_deps) - - # Print out prerelease package versions - session.run( - "python", "-c", "import google.protobuf; print(google.protobuf.__version__)" - ) - session.run("python", "-c", "import grpc; print(grpc.__version__)") - session.run("python", "-c", "import google.auth; print(google.auth.__version__)") + session.install("--pre", "--no-deps", "--ignore-installed", dep) + # TODO(https://github.com/grpc/grpc/issues/38965): Add `grpcio-status`` + # to the dictionary below once this bug is fixed. + # TODO(https://github.com/googleapis/google-cloud-python/issues/13643): Add + # `googleapis-common-protos` and `grpc-google-iam-v1` to the dictionary below + # once this bug is fixed. + package_namespaces = { + "google-api-core": "google.api_core", + "google-auth": "google.auth", + "grpcio": "grpc", + "protobuf": "google.protobuf", + "proto-plus": "proto", + } + + version_namespace = package_namespaces.get(dep) + + print(f"Installed {dep}") + if version_namespace: + session.run( + "python", + "-c", + f"import {version_namespace}; print({version_namespace}.__version__)", + ) session.run( "py.test", @@ -476,12 +483,12 @@ def prerelease_deps(session, protobuf_implementation): ["python", "upb"], ) def core_deps_from_source(session, protobuf_implementation): - """Run all tests with local versions of core dependencies installed, - rather than pulling core dependencies from PyPI. + """Run all tests with core dependencies installed from source + rather than pulling the dependencies from PyPI. """ # Install all dependencies - session.install(".") + session.install("-e", ".") # Install dependencies for the unit test environment unit_deps_all = UNIT_TEST_STANDARD_DEPENDENCIES + UNIT_TEST_EXTERNAL_DEPENDENCIES @@ -497,7 +504,7 @@ def core_deps_from_source(session, protobuf_implementation): # Because we test minimum dependency versions on the minimum Python # version, the first version we test with in the unit tests sessions has a - # constraints file containing all dependencies and extras that should be installed. + # constraints file containing all dependencies and extras. with open( CURRENT_DIRECTORY / "testing" @@ -517,16 +524,24 @@ def core_deps_from_source(session, protobuf_implementation): # Install dependencies specified in `testing/constraints-X.txt`. session.install(*constraints_deps) + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2358): `grpcio` and + # `grpcio-status` should be added to the list below so that they are installed from source, + # rather than PyPI. + # TODO(https://github.com/googleapis/gapic-generator-python/issues/2357): `protobuf` should be + # added to the list below so that it is installed from source, rather than PyPI + # Note: If a dependency is added to the `core_dependencies_from_source` list, + # the `prerel_deps` list in the `prerelease_deps` nox session should also be updated. core_dependencies_from_source = [ + f"{CURRENT_DIRECTORY}/../googleapis-common-protos", "google-api-core @ git+https://github.com/googleapis/python-api-core.git", "google-auth @ git+https://github.com/googleapis/google-auth-library-python.git", - f"{CURRENT_DIRECTORY}/../googleapis-common-protos", f"{CURRENT_DIRECTORY}/../grpc-google-iam-v1", "proto-plus @ git+https://github.com/googleapis/proto-plus-python.git", ] for dep in core_dependencies_from_source: - session.install(dep, "--ignore-installed", "--no-deps") + session.install(dep, "--no-deps", "--ignore-installed") + print(f"Installed {dep}") session.run( "py.test",