diff --git a/.flake8 b/.flake8
index ed93163..29227d4 100644
--- a/.flake8
+++ b/.flake8
@@ -26,6 +26,7 @@ exclude =
*_pb2.py
# Standard linting exemptions.
+ **/.nox/**
__pycache__,
.git,
*.pyc,
diff --git a/.github/header-checker-lint.yml b/.github/header-checker-lint.yml
new file mode 100644
index 0000000..fc281c0
--- /dev/null
+++ b/.github/header-checker-lint.yml
@@ -0,0 +1,15 @@
+{"allowedCopyrightHolders": ["Google LLC"],
+ "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"],
+ "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt"],
+ "sourceFileExtensions": [
+ "ts",
+ "js",
+ "java",
+ "sh",
+ "Dockerfile",
+ "yaml",
+ "py",
+ "html",
+ "txt"
+ ]
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index b9daa52..b4243ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,8 +50,10 @@ docs.metadata
# Virtual environment
env/
+
+# Test logs
coverage.xml
-sponge_log.xml
+*sponge_log.xml
# System test environment variables.
system_tests/local_test_setup
diff --git a/.kokoro/build.sh b/.kokoro/build.sh
index 3de729b..1309715 100755
--- a/.kokoro/build.sh
+++ b/.kokoro/build.sh
@@ -15,7 +15,11 @@
set -eo pipefail
-cd github/python-monitoring-dashboards
+if [[ -z "${PROJECT_ROOT:-}" ]]; then
+ PROJECT_ROOT="github/python-monitoring-dashboards"
+fi
+
+cd "${PROJECT_ROOT}"
# Disable buffering, so that the logs stream through.
export PYTHONUNBUFFERED=1
@@ -30,16 +34,26 @@ export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json
export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json")
# Remove old nox
-python3.6 -m pip uninstall --yes --quiet nox-automation
+python3 -m pip uninstall --yes --quiet nox-automation
# Install nox
-python3.6 -m pip install --upgrade --quiet nox
-python3.6 -m nox --version
+python3 -m pip install --upgrade --quiet nox
+python3 -m nox --version
+
+# If this is a continuous build, send the test log to the FlakyBot.
+# See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot.
+if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"continuous"* ]]; then
+ cleanup() {
+ chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ }
+ trap cleanup EXIT HUP
+fi
# If NOX_SESSION is set, it only runs the specified session,
# otherwise run all the sessions.
if [[ -n "${NOX_SESSION:-}" ]]; then
- python3.6 -m nox -s "${NOX_SESSION:-}"
+ python3 -m nox -s ${NOX_SESSION:-}
else
- python3.6 -m nox
+ python3 -m nox
fi
diff --git a/.kokoro/docs/docs-presubmit.cfg b/.kokoro/docs/docs-presubmit.cfg
index 1118107..4373076 100644
--- a/.kokoro/docs/docs-presubmit.cfg
+++ b/.kokoro/docs/docs-presubmit.cfg
@@ -15,3 +15,14 @@ env_vars: {
key: "TRAMPOLINE_IMAGE_UPLOAD"
value: "false"
}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-monitoring-dashboards/.kokoro/build.sh"
+}
+
+# Only run this nox session.
+env_vars: {
+ key: "NOX_SESSION"
+ value: "docs docfx"
+}
diff --git a/.kokoro/samples/python3.6/periodic-head.cfg b/.kokoro/samples/python3.6/periodic-head.cfg
new file mode 100644
index 0000000..f9cfcd3
--- /dev/null
+++ b/.kokoro/samples/python3.6/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.7/periodic-head.cfg b/.kokoro/samples/python3.7/periodic-head.cfg
new file mode 100644
index 0000000..f9cfcd3
--- /dev/null
+++ b/.kokoro/samples/python3.7/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/samples/python3.8/periodic-head.cfg b/.kokoro/samples/python3.8/periodic-head.cfg
new file mode 100644
index 0000000..f9cfcd3
--- /dev/null
+++ b/.kokoro/samples/python3.8/periodic-head.cfg
@@ -0,0 +1,11 @@
+# Format: //devtools/kokoro/config/proto/build.proto
+
+env_vars: {
+ key: "INSTALL_LIBRARY_FROM_SOURCE"
+ value: "True"
+}
+
+env_vars: {
+ key: "TRAMPOLINE_BUILD_FILE"
+ value: "github/python-pubsub/.kokoro/test-samples-against-head.sh"
+}
diff --git a/.kokoro/test-samples-against-head.sh b/.kokoro/test-samples-against-head.sh
new file mode 100755
index 0000000..8ba4f7a
--- /dev/null
+++ b/.kokoro/test-samples-against-head.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# 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.
+
+# A customized test runner for samples.
+#
+# For periodic builds, you can specify this file for testing against head.
+
+# `-e` enables the script to automatically fail when a command fails
+# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero
+set -eo pipefail
+# Enables `**` to include files nested inside sub-folders
+shopt -s globstar
+
+cd github/python-monitoring-dashboards
+
+exec .kokoro/test-samples-impl.sh
diff --git a/.kokoro/test-samples-impl.sh b/.kokoro/test-samples-impl.sh
new file mode 100755
index 0000000..cf5de74
--- /dev/null
+++ b/.kokoro/test-samples-impl.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+# Copyright 2021 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.
+
+
+# `-e` enables the script to automatically fail when a command fails
+# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero
+set -eo pipefail
+# Enables `**` to include files nested inside sub-folders
+shopt -s globstar
+
+# Exit early if samples directory doesn't exist
+if [ ! -d "./samples" ]; then
+ echo "No tests run. `./samples` not found"
+ exit 0
+fi
+
+# Disable buffering, so that the logs stream through.
+export PYTHONUNBUFFERED=1
+
+# Debug: show build environment
+env | grep KOKORO
+
+# Install nox
+python3.6 -m pip install --upgrade --quiet nox
+
+# Use secrets acessor service account to get secrets
+if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then
+ gcloud auth activate-service-account \
+ --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \
+ --project="cloud-devrel-kokoro-resources"
+fi
+
+# This script will create 3 files:
+# - testing/test-env.sh
+# - testing/service-account.json
+# - testing/client-secrets.json
+./scripts/decrypt-secrets.sh
+
+source ./testing/test-env.sh
+export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json
+
+# For cloud-run session, we activate the service account for gcloud sdk.
+gcloud auth activate-service-account \
+ --key-file "${GOOGLE_APPLICATION_CREDENTIALS}"
+
+export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json
+
+echo -e "\n******************** TESTING PROJECTS ********************"
+
+# Switch to 'fail at end' to allow all tests to complete before exiting.
+set +e
+# Use RTN to return a non-zero value if the test fails.
+RTN=0
+ROOT=$(pwd)
+# Find all requirements.txt in the samples directory (may break on whitespace).
+for file in samples/**/requirements.txt; do
+ cd "$ROOT"
+ # Navigate to the project folder.
+ file=$(dirname "$file")
+ cd "$file"
+
+ echo "------------------------------------------------------------"
+ echo "- testing $file"
+ echo "------------------------------------------------------------"
+
+ # Use nox to execute the tests for the project.
+ python3.6 -m nox -s "$RUN_TESTS_SESSION"
+ EXIT=$?
+
+ # If this is a periodic build, send the test log to the FlakyBot.
+ # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot.
+ if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then
+ chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ fi
+
+ if [[ $EXIT -ne 0 ]]; then
+ RTN=1
+ echo -e "\n Testing failed: Nox returned a non-zero exit code. \n"
+ else
+ echo -e "\n Testing completed.\n"
+ fi
+
+done
+cd "$ROOT"
+
+# Workaround for Kokoro permissions issue: delete secrets
+rm testing/{test-env.sh,client-secrets.json,service-account.json}
+
+exit "$RTN"
diff --git a/.kokoro/test-samples.sh b/.kokoro/test-samples.sh
index 8cc9434..b12f95e 100755
--- a/.kokoro/test-samples.sh
+++ b/.kokoro/test-samples.sh
@@ -13,6 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# The default test runner for samples.
+#
+# For periodic builds, we rewinds the repo to the latest release, and
+# run test-samples-impl.sh.
# `-e` enables the script to automatically fail when a command fails
# `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero
@@ -24,87 +28,19 @@ cd github/python-monitoring-dashboards
# Run periodic samples tests at latest release
if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then
+ # preserving the test runner implementation.
+ cp .kokoro/test-samples-impl.sh "${TMPDIR}/test-samples-impl.sh"
+ echo "--- IMPORTANT IMPORTANT IMPORTANT ---"
+ echo "Now we rewind the repo back to the latest release..."
LATEST_RELEASE=$(git describe --abbrev=0 --tags)
git checkout $LATEST_RELEASE
-fi
-
-# Exit early if samples directory doesn't exist
-if [ ! -d "./samples" ]; then
- echo "No tests run. `./samples` not found"
- exit 0
-fi
-
-# Disable buffering, so that the logs stream through.
-export PYTHONUNBUFFERED=1
-
-# Debug: show build environment
-env | grep KOKORO
-
-# Install nox
-python3.6 -m pip install --upgrade --quiet nox
-
-# Use secrets acessor service account to get secrets
-if [[ -f "${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" ]]; then
- gcloud auth activate-service-account \
- --key-file="${KOKORO_GFILE_DIR}/secrets_viewer_service_account.json" \
- --project="cloud-devrel-kokoro-resources"
-fi
-
-# This script will create 3 files:
-# - testing/test-env.sh
-# - testing/service-account.json
-# - testing/client-secrets.json
-./scripts/decrypt-secrets.sh
-
-source ./testing/test-env.sh
-export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/testing/service-account.json
-
-# For cloud-run session, we activate the service account for gcloud sdk.
-gcloud auth activate-service-account \
- --key-file "${GOOGLE_APPLICATION_CREDENTIALS}"
-
-export GOOGLE_CLIENT_SECRETS=$(pwd)/testing/client-secrets.json
-
-echo -e "\n******************** TESTING PROJECTS ********************"
-
-# Switch to 'fail at end' to allow all tests to complete before exiting.
-set +e
-# Use RTN to return a non-zero value if the test fails.
-RTN=0
-ROOT=$(pwd)
-# Find all requirements.txt in the samples directory (may break on whitespace).
-for file in samples/**/requirements.txt; do
- cd "$ROOT"
- # Navigate to the project folder.
- file=$(dirname "$file")
- cd "$file"
-
- echo "------------------------------------------------------------"
- echo "- testing $file"
- echo "------------------------------------------------------------"
-
- # Use nox to execute the tests for the project.
- python3.6 -m nox -s "$RUN_TESTS_SESSION"
- EXIT=$?
-
- # If this is a periodic build, send the test log to the FlakyBot.
- # See https://github.com/googleapis/repo-automation-bots/tree/master/packages/flakybot.
- if [[ $KOKORO_BUILD_ARTIFACTS_SUBDIR = *"periodic"* ]]; then
- chmod +x $KOKORO_GFILE_DIR/linux_amd64/flakybot
- $KOKORO_GFILE_DIR/linux_amd64/flakybot
+ echo "The current head is: "
+ echo $(git rev-parse --verify HEAD)
+ echo "--- IMPORTANT IMPORTANT IMPORTANT ---"
+ # move back the test runner implementation if there's no file.
+ if [ ! -f .kokoro/test-samples-impl.sh ]; then
+ cp "${TMPDIR}/test-samples-impl.sh" .kokoro/test-samples-impl.sh
fi
+fi
- if [[ $EXIT -ne 0 ]]; then
- RTN=1
- echo -e "\n Testing failed: Nox returned a non-zero exit code. \n"
- else
- echo -e "\n Testing completed.\n"
- fi
-
-done
-cd "$ROOT"
-
-# Workaround for Kokoro permissions issue: delete secrets
-rm testing/{test-env.sh,client-secrets.json,service-account.json}
-
-exit "$RTN"
+exec .kokoro/test-samples-impl.sh
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..32302e4
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.4.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+- repo: https://github.com/psf/black
+ rev: 19.10b0
+ hooks:
+ - id: black
+- repo: https://gitlab.com/pycqa/flake8
+ rev: 3.9.0
+ hooks:
+ - id: flake8
diff --git a/.trampolinerc b/.trampolinerc
index 995ee29..383b6ec 100644
--- a/.trampolinerc
+++ b/.trampolinerc
@@ -24,6 +24,7 @@ required_envvars+=(
pass_down_envvars+=(
"STAGING_BUCKET"
"V2_STAGING_BUCKET"
+ "NOX_SESSION"
)
# Prevent unintentional override on the default image.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd33027..09537c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,7 @@
### ⚠ BREAKING CHANGES
-* move API to python microgenerator (#26)
+* move API to python microgenerator. See [Migration Guide](https://github.com/googleapis/python-monitoring-dashboards/blob/master/UPGRADING.md). (#26)
### Features
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 118c955..b9f26db 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -21,8 +21,8 @@ In order to add a feature:
- The feature must be documented in both the API and narrative
documentation.
-- The feature must work fully on the following CPython versions: 2.7,
- 3.5, 3.6, 3.7 and 3.8 on both UNIX and Windows.
+- The feature must work fully on the following CPython versions:
+ 3.6, 3.7, 3.8 and 3.9 on both UNIX and Windows.
- The feature must not add unnecessary dependencies (where
"unnecessary" is of course subjective, but new dependencies should
@@ -70,9 +70,14 @@ We use `nox `__ to instrument our tests.
- To test your changes, run unit tests with ``nox``::
$ nox -s unit-2.7
- $ nox -s unit-3.7
+ $ nox -s unit-3.8
$ ...
+- Args to pytest can be passed through the nox command separated by a `--`. For
+ example, to run a single test::
+
+ $ nox -s unit-3.8 -- -k
+
.. note::
The unit tests and system tests are described in the
@@ -93,8 +98,12 @@ On Debian/Ubuntu::
************
Coding Style
************
+- We use the automatic code formatter ``black``. You can run it using
+ the nox session ``blacken``. This will eliminate many lint errors. Run via::
-- PEP8 compliance, with exceptions defined in the linter configuration.
+ $ nox -s blacken
+
+- PEP8 compliance is required, with exceptions defined in the linter configuration.
If you have ``nox`` installed, you can test that you have not introduced
any non-compliant code via::
@@ -111,6 +120,16 @@ Coding Style
should point to the official ``googleapis`` checkout and the
the branch should be the main branch on that remote (``master``).
+- This repository contains configuration for the
+ `pre-commit `__ tool, which automates checking
+ our linters during a commit. If you have it installed on your ``$PATH``,
+ you can enable enforcing those checks via:
+
+.. code-block:: bash
+
+ $ pre-commit install
+ pre-commit installed at .git/hooks/pre-commit
+
Exceptions to PEP8:
- Many unit tests use a helper method, ``_call_fut`` ("FUT" is short for
@@ -123,13 +142,18 @@ Running System Tests
- To run system tests, you can execute::
- $ nox -s system-3.7
+ # Run all system tests
+ $ nox -s system-3.8
$ nox -s system-2.7
+ # Run a single system test
+ $ nox -s system-3.8 -- -k
+
+
.. note::
System tests are only configured to run under Python 2.7 and
- Python 3.7. For expediency, we do not run them in older versions
+ Python 3.8. For expediency, we do not run them in older versions
of Python 3.
This alone will not run the tests. You'll need to change some local
@@ -192,25 +216,24 @@ Supported Python Versions
We support:
-- `Python 3.5`_
- `Python 3.6`_
- `Python 3.7`_
- `Python 3.8`_
+- `Python 3.9`_
-.. _Python 3.5: https://docs.python.org/3.5/
.. _Python 3.6: https://docs.python.org/3.6/
.. _Python 3.7: https://docs.python.org/3.7/
.. _Python 3.8: https://docs.python.org/3.8/
+.. _Python 3.9: https://docs.python.org/3.9/
Supported versions can be found in our ``noxfile.py`` `config`_.
.. _config: https://github.com/googleapis/python-monitoring-dashboards/blob/master/noxfile.py
-Python 2.7 support is deprecated. All code changes should maintain Python 2.7 compatibility until January 1, 2020.
We also explicitly decided to support Python 3 beginning with version
-3.5. Reasons for this include:
+3.6. Reasons for this include:
- Encouraging use of newest versions of Python 3
- Taking the lead of `prominent`_ open-source `projects`_
diff --git a/LICENSE b/LICENSE
index a8ee855..d645695 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,7 @@
- Apache License
+
+ Apache License
Version 2.0, January 2004
- https://www.apache.org/licenses/
+ http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
@@ -192,7 +193,7 @@
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
+ 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,
diff --git a/MANIFEST.in b/MANIFEST.in
index e9e29d1..e783f4c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -16,10 +16,10 @@
# Generated by synthtool. DO NOT EDIT!
include README.rst LICENSE
-recursive-include google *.json *.proto
+recursive-include google *.json *.proto py.typed
recursive-include tests *
global-exclude *.py[co]
global-exclude __pycache__
# Exclude scripts for samples readmegen
-prune scripts/readme-gen
\ No newline at end of file
+prune scripts/readme-gen
diff --git a/UPGRADING.md b/UPGRADING.md
index 698c267..0a15e9e 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -29,10 +29,11 @@ client = monitoring_dashboard_v1.DashboardsServiceClient()
> **WARNING**: Breaking change
Methods expect request objects. We provide a script that will convert most common use cases.
-* Install the library
+
+* Install the library with `libcst`.
```py
-python3 -m pip install google-cloud-monitoring-dashboards
+python3 -m pip install google-cloud-monitoring-dashboards[libcst]
```
* The scripts `fixup_dashboard_v1_keywords.py` shipped with the library. It expects
@@ -118,4 +119,4 @@ response = client.create_dashboard(
},
dashboard=dashboard
)
-```
\ No newline at end of file
+```
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index 0abaf22..bcd37bb 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -1,4 +1,9 @@
div#python2-eol {
border-color: red;
border-width: medium;
-}
\ No newline at end of file
+}
+
+/* Ensure minimum width for 'Parameters' / 'Returns' column */
+dl.field-list > dt {
+ min-width: 100px
+}
diff --git a/docs/dashboard_v1/dashboards_service.rst b/docs/dashboard_v1/dashboards_service.rst
new file mode 100644
index 0000000..edd2880
--- /dev/null
+++ b/docs/dashboard_v1/dashboards_service.rst
@@ -0,0 +1,11 @@
+DashboardsService
+-----------------------------------
+
+.. automodule:: google.cloud.monitoring_dashboard_v1.services.dashboards_service
+ :members:
+ :inherited-members:
+
+
+.. automodule:: google.cloud.monitoring_dashboard_v1.services.dashboards_service.pagers
+ :members:
+ :inherited-members:
diff --git a/docs/dashboard_v1/services.rst b/docs/dashboard_v1/services.rst
index add1e89..bfcc085 100644
--- a/docs/dashboard_v1/services.rst
+++ b/docs/dashboard_v1/services.rst
@@ -1,6 +1,6 @@
Services for Google Monitoring Dashboard v1 API
===============================================
+.. toctree::
+ :maxdepth: 2
-.. automodule:: google.cloud.monitoring_dashboard_v1.services.dashboards_service
- :members:
- :inherited-members:
+ dashboards_service
diff --git a/docs/dashboard_v1/types.rst b/docs/dashboard_v1/types.rst
index 4029818..376e16d 100644
--- a/docs/dashboard_v1/types.rst
+++ b/docs/dashboard_v1/types.rst
@@ -3,4 +3,5 @@ Types for Google Monitoring Dashboard v1 API
.. automodule:: google.cloud.monitoring_dashboard_v1.types
:members:
+ :undoc-members:
:show-inheritance:
diff --git a/google/cloud/monitoring_dashboard/__init__.py b/google/cloud/monitoring_dashboard/__init__.py
index 870fc49..f3b20ee 100644
--- a/google/cloud/monitoring_dashboard/__init__.py
+++ b/google/cloud/monitoring_dashboard/__init__.py
@@ -47,6 +47,7 @@
)
from google.cloud.monitoring_dashboard_v1.types.layouts import ColumnLayout
from google.cloud.monitoring_dashboard_v1.types.layouts import GridLayout
+from google.cloud.monitoring_dashboard_v1.types.layouts import MosaicLayout
from google.cloud.monitoring_dashboard_v1.types.layouts import RowLayout
from google.cloud.monitoring_dashboard_v1.types.metrics import SparkChartType
from google.cloud.monitoring_dashboard_v1.types.metrics import Threshold
@@ -72,6 +73,7 @@
"GridLayout",
"ListDashboardsRequest",
"ListDashboardsResponse",
+ "MosaicLayout",
"PickTimeSeriesFilter",
"RowLayout",
"Scorecard",
diff --git a/google/cloud/monitoring_dashboard_v1/__init__.py b/google/cloud/monitoring_dashboard_v1/__init__.py
index 4c970ee..9f7a33f 100644
--- a/google/cloud/monitoring_dashboard_v1/__init__.py
+++ b/google/cloud/monitoring_dashboard_v1/__init__.py
@@ -28,6 +28,7 @@
from .types.dashboards_service import UpdateDashboardRequest
from .types.layouts import ColumnLayout
from .types.layouts import GridLayout
+from .types.layouts import MosaicLayout
from .types.layouts import RowLayout
from .types.metrics import SparkChartType
from .types.metrics import Threshold
@@ -52,6 +53,7 @@
"GridLayout",
"ListDashboardsRequest",
"ListDashboardsResponse",
+ "MosaicLayout",
"PickTimeSeriesFilter",
"RowLayout",
"Scorecard",
diff --git a/google/cloud/monitoring_dashboard_v1/proto/common.proto b/google/cloud/monitoring_dashboard_v1/proto/common.proto
index 6dedcf0..ad22257 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/common.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/common.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -316,6 +316,8 @@ message Aggregation {
// `ALIGN_NONE` is specified, this field is required or an error is returned.
// If no per-series aligner is specified, or the aligner `ALIGN_NONE` is
// specified, then this field is ignored.
+ //
+ // The maximum value of the `alignment_period` is 2 years, or 104 weeks.
google.protobuf.Duration alignment_period = 1;
// An `Aligner` describes how to bring the data points in a single
diff --git a/google/cloud/monitoring_dashboard_v1/proto/dashboard.proto b/google/cloud/monitoring_dashboard_v1/proto/dashboard.proto
index 7a25776..f155e72 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/dashboard.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/dashboard.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -55,6 +55,10 @@ message Dashboard {
// informational elements like widgets or tiles.
GridLayout grid_layout = 5;
+ // The content is arranged as a grid of tiles, with each content widget
+ // occupying one or more grid blocks.
+ MosaicLayout mosaic_layout = 6;
+
// The content is divided into equally spaced rows and the widgets are
// arranged horizontally.
RowLayout row_layout = 8;
diff --git a/google/cloud/monitoring_dashboard_v1/proto/dashboards_service.proto b/google/cloud/monitoring_dashboard_v1/proto/dashboards_service.proto
index a7cbef5..2202d60 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/dashboards_service.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/dashboards_service.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -40,11 +40,8 @@ service DashboardsService {
"https://www.googleapis.com/auth/monitoring.read,"
"https://www.googleapis.com/auth/monitoring.write";
- // Creates a new custom dashboard.
- //
- // This method requires the `monitoring.dashboards.create` permission
- // on the specified project. For more information, see
- // [Google Cloud IAM](https://cloud.google.com/iam).
+ // Creates a new custom dashboard. For examples on how you can use this API to create dashboards, see [Managing dashboards by API](https://cloud.google.com/monitoring/dashboards/api-dashboard).
+ // This method requires the `monitoring.dashboards.create` permission on the specified project. For more information about permissions, see [Cloud Identity and Access Management](https://cloud.google.com/iam).
rpc CreateDashboard(CreateDashboardRequest) returns (Dashboard) {
option (google.api.http) = {
post: "/v1/{parent=projects/*}/dashboards"
@@ -56,7 +53,7 @@ service DashboardsService {
//
// This method requires the `monitoring.dashboards.list` permission
// on the specified project. For more information, see
- // [Google Cloud IAM](https://cloud.google.com/iam).
+ // [Cloud Identity and Access Management](https://cloud.google.com/iam).
rpc ListDashboards(ListDashboardsRequest) returns (ListDashboardsResponse) {
option (google.api.http) = {
get: "/v1/{parent=projects/*}/dashboards"
@@ -67,7 +64,7 @@ service DashboardsService {
//
// This method requires the `monitoring.dashboards.get` permission
// on the specified dashboard. For more information, see
- // [Google Cloud IAM](https://cloud.google.com/iam).
+ // [Cloud Identity and Access Management](https://cloud.google.com/iam).
rpc GetDashboard(GetDashboardRequest) returns (Dashboard) {
option (google.api.http) = {
get: "/v1/{name=projects/*/dashboards/*}"
@@ -78,7 +75,7 @@ service DashboardsService {
//
// This method requires the `monitoring.dashboards.delete` permission
// on the specified dashboard. For more information, see
- // [Google Cloud IAM](https://cloud.google.com/iam).
+ // [Cloud Identity and Access Management](https://cloud.google.com/iam).
rpc DeleteDashboard(DeleteDashboardRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
delete: "/v1/{name=projects/*/dashboards/*}"
@@ -89,7 +86,7 @@ service DashboardsService {
//
// This method requires the `monitoring.dashboards.update` permission
// on the specified dashboard. For more information, see
- // [Google Cloud IAM](https://cloud.google.com/iam).
+ // [Cloud Identity and Access Management](https://cloud.google.com/iam).
rpc UpdateDashboard(UpdateDashboardRequest) returns (Dashboard) {
option (google.api.http) = {
patch: "/v1/{dashboard.name=projects/*/dashboards/*}"
diff --git a/google/cloud/monitoring_dashboard_v1/proto/drilldowns.proto b/google/cloud/monitoring_dashboard_v1/proto/drilldowns.proto
index 0080df5..1899e57 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/drilldowns.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/drilldowns.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/proto/layouts.proto b/google/cloud/monitoring_dashboard_v1/proto/layouts.proto
index acc0517..dbc6dc4 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/layouts.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/layouts.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -35,6 +35,42 @@ message GridLayout {
repeated Widget widgets = 2;
}
+// A mosaic layout divides the available space into a grid of blocks, and
+// overlays the grid with tiles. Unlike `GridLayout`, tiles may span multiple
+// grid blocks and can be placed at arbitrary locations in the grid.
+message MosaicLayout {
+ // A single tile in the mosaic. The placement and size of the tile are
+ // configurable.
+ message Tile {
+ // The zero-indexed position of the tile in grid blocks relative to the
+ // left edge of the grid. Tiles must be contained within the specified
+ // number of columns. `x_pos` cannot be negative.
+ int32 x_pos = 1;
+
+ // The zero-indexed position of the tile in grid blocks relative to the
+ // top edge of the grid. `y_pos` cannot be negative.
+ int32 y_pos = 2;
+
+ // The width of the tile, measured in grid blocks. Tiles must have a
+ // minimum width of 1.
+ int32 width = 3;
+
+ // The height of the tile, measured in grid blocks. Tiles must have a
+ // minimum height of 1.
+ int32 height = 4;
+
+ // The informational widget contained in the tile. For example an `XyChart`.
+ Widget widget = 5;
+ }
+
+ // The number of columns in the mosaic grid. The number of columns must be
+ // between 1 and 12, inclusive.
+ int32 columns = 1;
+
+ // The tiles to display.
+ repeated Tile tiles = 3;
+}
+
// A simplified layout that divides the available space into rows
// and arranges a set of widgets horizontally in each row.
message RowLayout {
diff --git a/google/cloud/monitoring_dashboard_v1/proto/metrics.proto b/google/cloud/monitoring_dashboard_v1/proto/metrics.proto
index 2fff1d2..5807ee1 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/metrics.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/metrics.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/proto/scorecard.proto b/google/cloud/monitoring_dashboard_v1/proto/scorecard.proto
index 1820c03..7b0ec93 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/scorecard.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/scorecard.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package google.monitoring.dashboard.v1;
import "google/api/field_behavior.proto";
import "google/monitoring/dashboard/v1/metrics.proto";
import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
option go_package = "google.golang.org/genproto/googleapis/monitoring/dashboard/v1;dashboard";
option java_multiple_files = true;
diff --git a/google/cloud/monitoring_dashboard_v1/proto/service.proto b/google/cloud/monitoring_dashboard_v1/proto/service.proto
index 5bb41ec..a0c6488 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/service.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/service.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/proto/text.proto b/google/cloud/monitoring_dashboard_v1/proto/text.proto
index acc1671..5238a5e 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/text.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/text.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/proto/widget.proto b/google/cloud/monitoring_dashboard_v1/proto/widget.proto
index 12b5a69..08e7020 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/widget.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/widget.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/proto/xychart.proto b/google/cloud/monitoring_dashboard_v1/proto/xychart.proto
index d241ae7..0f7b9ff 100644
--- a/google/cloud/monitoring_dashboard_v1/proto/xychart.proto
+++ b/google/cloud/monitoring_dashboard_v1/proto/xychart.proto
@@ -1,4 +1,4 @@
-// Copyright 2020 Google LLC
+// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/async_client.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/async_client.py
index 5f404d7..010cad1 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/async_client.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/async_client.py
@@ -80,7 +80,36 @@ class DashboardsServiceAsyncClient:
DashboardsServiceClient.parse_common_location_path
)
- from_service_account_file = DashboardsServiceClient.from_service_account_file
+ @classmethod
+ def from_service_account_info(cls, info: dict, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials info.
+
+ Args:
+ info (dict): The service account private key info.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ DashboardsServiceAsyncClient: The constructed client.
+ """
+ return DashboardsServiceClient.from_service_account_info.__func__(DashboardsServiceAsyncClient, info, *args, **kwargs) # type: ignore
+
+ @classmethod
+ def from_service_account_file(cls, filename: str, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials
+ file.
+
+ Args:
+ filename (str): The path to the service account private key json
+ file.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ DashboardsServiceAsyncClient: The constructed client.
+ """
+ return DashboardsServiceClient.from_service_account_file.__func__(DashboardsServiceAsyncClient, filename, *args, **kwargs) # type: ignore
+
from_service_account_json = from_service_account_file
@property
@@ -152,14 +181,16 @@ async def create_dashboard(
timeout: float = None,
metadata: Sequence[Tuple[str, str]] = (),
) -> dashboard.Dashboard:
- r"""Creates a new custom dashboard.
-
+ r"""Creates a new custom dashboard. For examples on how you can use
+ this API to create dashboards, see `Managing dashboards by
+ API `__.
This method requires the ``monitoring.dashboards.create``
- permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ permission on the specified project. For more information about
+ permissions, see `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.CreateDashboardRequest`):
+ request (:class:`google.cloud.monitoring_dashboard_v1.types.CreateDashboardRequest`):
The request object. The `CreateDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -169,7 +200,7 @@ async def create_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
@@ -212,10 +243,11 @@ async def list_dashboards(
This method requires the ``monitoring.dashboards.list``
permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.ListDashboardsRequest`):
+ request (:class:`google.cloud.monitoring_dashboard_v1.types.ListDashboardsRequest`):
The request object. The `ListDashboards` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -225,8 +257,8 @@ async def list_dashboards(
sent along with the request as metadata.
Returns:
- ~.pagers.ListDashboardsAsyncPager:
- The ``ListDashboards`` request.
+ google.cloud.monitoring_dashboard_v1.services.dashboards_service.pagers.ListDashboardsAsyncPager:
+ The ListDashboards request.
Iterating over this object will yield results and
resolve additional pages automatically.
@@ -274,10 +306,11 @@ async def get_dashboard(
This method requires the ``monitoring.dashboards.get``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.GetDashboardRequest`):
+ request (:class:`google.cloud.monitoring_dashboard_v1.types.GetDashboardRequest`):
The request object. The `GetDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -287,7 +320,7 @@ async def get_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
@@ -330,10 +363,11 @@ async def delete_dashboard(
This method requires the ``monitoring.dashboards.delete``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.DeleteDashboardRequest`):
+ request (:class:`google.cloud.monitoring_dashboard_v1.types.DeleteDashboardRequest`):
The request object. The `DeleteDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -377,10 +411,11 @@ async def update_dashboard(
This method requires the ``monitoring.dashboards.update``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.UpdateDashboardRequest`):
+ request (:class:`google.cloud.monitoring_dashboard_v1.types.UpdateDashboardRequest`):
The request object. The `UpdateDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -390,7 +425,7 @@ async def update_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/client.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/client.py
index 80db959..0ff3024 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/client.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/client.py
@@ -116,6 +116,22 @@ def _get_default_mtls_endpoint(api_endpoint):
DEFAULT_ENDPOINT
)
+ @classmethod
+ def from_service_account_info(cls, info: dict, *args, **kwargs):
+ """Creates an instance of this client using the provided credentials info.
+
+ Args:
+ info (dict): The service account private key info.
+ args: Additional arguments to pass to the constructor.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ DashboardsServiceClient: The constructed client.
+ """
+ credentials = service_account.Credentials.from_service_account_info(info)
+ kwargs["credentials"] = credentials
+ return cls(*args, **kwargs)
+
@classmethod
def from_service_account_file(cls, filename: str, *args, **kwargs):
"""Creates an instance of this client using the provided credentials
@@ -128,7 +144,7 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
kwargs: Additional arguments to pass to the constructor.
Returns:
- {@api.name}: The constructed client.
+ DashboardsServiceClient: The constructed client.
"""
credentials = service_account.Credentials.from_service_account_file(filename)
kwargs["credentials"] = credentials
@@ -233,10 +249,10 @@ def __init__(
credentials identify the application to the service; if none
are specified, the client will attempt to ascertain the
credentials from the environment.
- transport (Union[str, ~.DashboardsServiceTransport]): The
+ transport (Union[str, DashboardsServiceTransport]): The
transport to use. If set to None, a transport is chosen
automatically.
- client_options (client_options_lib.ClientOptions): Custom options for the
+ client_options (google.api_core.client_options.ClientOptions): Custom options for the
client. It won't take effect if a ``transport`` instance is provided.
(1) The ``api_endpoint`` property can be used to override the
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
@@ -272,21 +288,17 @@ def __init__(
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
)
- ssl_credentials = None
+ client_cert_source_func = None
is_mtls = False
if use_client_cert:
if client_options.client_cert_source:
- import grpc # type: ignore
-
- cert, key = client_options.client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
is_mtls = True
+ client_cert_source_func = client_options.client_cert_source
else:
- creds = SslCredentials()
- is_mtls = creds.is_mtls
- ssl_credentials = creds.ssl_credentials if is_mtls else None
+ is_mtls = mtls.has_default_client_cert_source()
+ client_cert_source_func = (
+ mtls.default_client_cert_source() if is_mtls else None
+ )
# Figure out which api endpoint to use.
if client_options.api_endpoint is not None:
@@ -329,7 +341,7 @@ def __init__(
credentials_file=client_options.credentials_file,
host=api_endpoint,
scopes=client_options.scopes,
- ssl_channel_credentials=ssl_credentials,
+ client_cert_source_for_mtls=client_cert_source_func,
quota_project_id=client_options.quota_project_id,
client_info=client_info,
)
@@ -342,14 +354,16 @@ def create_dashboard(
timeout: float = None,
metadata: Sequence[Tuple[str, str]] = (),
) -> dashboard.Dashboard:
- r"""Creates a new custom dashboard.
-
+ r"""Creates a new custom dashboard. For examples on how you can use
+ this API to create dashboards, see `Managing dashboards by
+ API `__.
This method requires the ``monitoring.dashboards.create``
- permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ permission on the specified project. For more information about
+ permissions, see `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.CreateDashboardRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.CreateDashboardRequest):
The request object. The `CreateDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -359,7 +373,7 @@ def create_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
@@ -403,10 +417,11 @@ def list_dashboards(
This method requires the ``monitoring.dashboards.list``
permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.ListDashboardsRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.ListDashboardsRequest):
The request object. The `ListDashboards` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -416,8 +431,8 @@ def list_dashboards(
sent along with the request as metadata.
Returns:
- ~.pagers.ListDashboardsPager:
- The ``ListDashboards`` request.
+ google.cloud.monitoring_dashboard_v1.services.dashboards_service.pagers.ListDashboardsPager:
+ The ListDashboards request.
Iterating over this object will yield results and
resolve additional pages automatically.
@@ -466,10 +481,11 @@ def get_dashboard(
This method requires the ``monitoring.dashboards.get``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.GetDashboardRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.GetDashboardRequest):
The request object. The `GetDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -479,7 +495,7 @@ def get_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
@@ -523,10 +539,11 @@ def delete_dashboard(
This method requires the ``monitoring.dashboards.delete``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.DeleteDashboardRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.DeleteDashboardRequest):
The request object. The `DeleteDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -571,10 +588,11 @@ def update_dashboard(
This method requires the ``monitoring.dashboards.update``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Args:
- request (:class:`~.dashboards_service.UpdateDashboardRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.UpdateDashboardRequest):
The request object. The `UpdateDashboard` request.
retry (google.api_core.retry.Retry): Designation of what errors, if any,
@@ -584,7 +602,7 @@ def update_dashboard(
sent along with the request as metadata.
Returns:
- ~.dashboard.Dashboard:
+ google.cloud.monitoring_dashboard_v1.types.Dashboard:
A Google Stackdriver dashboard.
Dashboards define the content and layout
of pages in the Stackdriver web
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/pagers.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/pagers.py
index 95dae9a..cda2beb 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/pagers.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/pagers.py
@@ -15,7 +15,16 @@
# limitations under the License.
#
-from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, Sequence, Tuple
+from typing import (
+ Any,
+ AsyncIterable,
+ Awaitable,
+ Callable,
+ Iterable,
+ Sequence,
+ Tuple,
+ Optional,
+)
from google.cloud.monitoring_dashboard_v1.types import dashboard
from google.cloud.monitoring_dashboard_v1.types import dashboards_service
@@ -25,7 +34,7 @@ class ListDashboardsPager:
"""A pager for iterating through ``list_dashboards`` requests.
This class thinly wraps an initial
- :class:`~.dashboards_service.ListDashboardsResponse` object, and
+ :class:`google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse` object, and
provides an ``__iter__`` method to iterate through its
``dashboards`` field.
@@ -34,7 +43,7 @@ class ListDashboardsPager:
through the ``dashboards`` field on the
corresponding responses.
- All the usual :class:`~.dashboards_service.ListDashboardsResponse`
+ All the usual :class:`google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -52,9 +61,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.dashboards_service.ListDashboardsRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.ListDashboardsRequest):
The initial request object.
- response (:class:`~.dashboards_service.ListDashboardsResponse`):
+ response (google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
@@ -87,7 +96,7 @@ class ListDashboardsAsyncPager:
"""A pager for iterating through ``list_dashboards`` requests.
This class thinly wraps an initial
- :class:`~.dashboards_service.ListDashboardsResponse` object, and
+ :class:`google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse` object, and
provides an ``__aiter__`` method to iterate through its
``dashboards`` field.
@@ -96,7 +105,7 @@ class ListDashboardsAsyncPager:
through the ``dashboards`` field on the
corresponding responses.
- All the usual :class:`~.dashboards_service.ListDashboardsResponse`
+ All the usual :class:`google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse`
attributes are available on the pager. If multiple requests are made, only
the most recent response is retained, and thus used for attribute lookup.
"""
@@ -114,9 +123,9 @@ def __init__(
Args:
method (Callable): The method that was originally called, and
which instantiated this pager.
- request (:class:`~.dashboards_service.ListDashboardsRequest`):
+ request (google.cloud.monitoring_dashboard_v1.types.ListDashboardsRequest):
The initial request object.
- response (:class:`~.dashboards_service.ListDashboardsResponse`):
+ response (google.cloud.monitoring_dashboard_v1.types.ListDashboardsResponse):
The initial response object.
metadata (Sequence[Tuple[str, str]]): Strings which should be
sent along with the request as metadata.
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/base.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/base.py
index f2c092f..fc763a4 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/base.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/base.py
@@ -76,10 +76,10 @@ def __init__(
scope (Optional[Sequence[str]]): A list of scopes.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
- client_info (google.api_core.gapic_v1.client_info.ClientInfo):
- The client info used to send a user-agent string along with
- API requests. If ``None``, then default info will be used.
- Generally, you only need to set this if you're developing
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
your own client library.
"""
# Save the hostname. Default to port 443 (HTTPS) if none is specified.
@@ -87,6 +87,9 @@ def __init__(
host += ":443"
self._host = host
+ # Save the scopes.
+ self._scopes = scopes or self.AUTH_SCOPES
+
# If no credentials are provided, then determine the appropriate
# defaults.
if credentials and credentials_file:
@@ -96,20 +99,17 @@ def __init__(
if credentials_file is not None:
credentials, _ = auth.load_credentials_from_file(
- credentials_file, scopes=scopes, quota_project_id=quota_project_id
+ credentials_file, scopes=self._scopes, quota_project_id=quota_project_id
)
elif credentials is None:
credentials, _ = auth.default(
- scopes=scopes, quota_project_id=quota_project_id
+ scopes=self._scopes, quota_project_id=quota_project_id
)
# Save the credentials.
self._credentials = credentials
- # Lifted into its own function so it can be stubbed out during tests.
- self._prep_wrapped_messages(client_info)
-
def _prep_wrapped_messages(self, client_info):
# Precompute the wrapped methods.
self._wrapped_methods = {
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc.py
index f837aef..00e5009 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc.py
@@ -60,6 +60,7 @@ def __init__(
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
ssl_channel_credentials: grpc.ChannelCredentials = None,
+ client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
quota_project_id: Optional[str] = None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -90,6 +91,10 @@ def __init__(
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
for grpc channel. It is ignored if ``channel`` is provided.
+ client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ A callback to provide client certificate bytes and private key bytes,
+ both in PEM format. It is used to configure mutual TLS channel. It is
+ ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
@@ -104,72 +109,60 @@ def __init__(
google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
and ``credentials_file`` are passed.
"""
+ self._grpc_channel = None
self._ssl_channel_credentials = ssl_channel_credentials
+ self._stubs: Dict[str, Callable] = {}
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # Sanity check: Ensure that channel and credentials are not both
- # provided.
+ # Ignore credentials if a channel was passed.
credentials = False
-
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ else:
+ if api_mtls_endpoint:
+ host = api_mtls_endpoint
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ self._ssl_channel_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ self._ssl_channel_credentials = SslCredentials().ssl_credentials
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
-
- # Create SSL credentials with client_cert_source or application
- # default SSL credentials.
- if client_cert_source:
- cert, key = client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
else:
- ssl_credentials = SslCredentials().ssl_credentials
+ if client_cert_source_for_mtls and not ssl_channel_credentials:
+ cert, key = client_cert_source_for_mtls()
+ self._ssl_channel_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
- # create a new channel. The provided one is ignored.
- self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
- credentials_file=credentials_file,
- ssl_credentials=ssl_credentials,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -177,17 +170,8 @@ def __init__(
],
)
- self._stubs = {} # type: Dict[str, Callable]
-
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@classmethod
def create_channel(
@@ -201,7 +185,7 @@ def create_channel(
) -> grpc.Channel:
"""Create and return a gRPC channel object.
Args:
- address (Optional[str]): The host for the channel to use.
+ host (Optional[str]): The host for the channel to use.
credentials (Optional[~.Credentials]): The
authorization credentials to attach to requests. These
credentials identify this application to the service. If
@@ -246,11 +230,13 @@ def create_dashboard(
) -> Callable[[dashboards_service.CreateDashboardRequest], dashboard.Dashboard]:
r"""Return a callable for the create dashboard method over gRPC.
- Creates a new custom dashboard.
-
+ Creates a new custom dashboard. For examples on how you can use
+ this API to create dashboards, see `Managing dashboards by
+ API `__.
This method requires the ``monitoring.dashboards.create``
- permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ permission on the specified project. For more information about
+ permissions, see `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.CreateDashboardRequest],
@@ -283,7 +269,8 @@ def list_dashboards(
This method requires the ``monitoring.dashboards.list``
permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.ListDashboardsRequest],
@@ -313,7 +300,8 @@ def get_dashboard(
This method requires the ``monitoring.dashboards.get``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.GetDashboardRequest],
@@ -343,7 +331,8 @@ def delete_dashboard(
This method requires the ``monitoring.dashboards.delete``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.DeleteDashboardRequest],
@@ -373,7 +362,8 @@ def update_dashboard(
This method requires the ``monitoring.dashboards.update``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.UpdateDashboardRequest],
diff --git a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc_asyncio.py b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc_asyncio.py
index 65d2c06..495d820 100644
--- a/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc_asyncio.py
+++ b/google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc_asyncio.py
@@ -64,7 +64,7 @@ def create_channel(
) -> aio.Channel:
"""Create and return a gRPC AsyncIO channel object.
Args:
- address (Optional[str]): The host for the channel to use.
+ host (Optional[str]): The host for the channel to use.
credentials (Optional[~.Credentials]): The
authorization credentials to attach to requests. These
credentials identify this application to the service. If
@@ -104,6 +104,7 @@ def __init__(
api_mtls_endpoint: str = None,
client_cert_source: Callable[[], Tuple[bytes, bytes]] = None,
ssl_channel_credentials: grpc.ChannelCredentials = None,
+ client_cert_source_for_mtls: Callable[[], Tuple[bytes, bytes]] = None,
quota_project_id=None,
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
) -> None:
@@ -135,12 +136,16 @@ def __init__(
``api_mtls_endpoint`` is None.
ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials
for grpc channel. It is ignored if ``channel`` is provided.
+ client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]):
+ A callback to provide client certificate bytes and private key bytes,
+ both in PEM format. It is used to configure mutual TLS channel. It is
+ ignored if ``channel`` or ``ssl_channel_credentials`` is provided.
quota_project_id (Optional[str]): An optional project to use for billing
and quota.
- client_info (google.api_core.gapic_v1.client_info.ClientInfo):
- The client info used to send a user-agent string along with
- API requests. If ``None``, then default info will be used.
- Generally, you only need to set this if you're developing
+ client_info (google.api_core.gapic_v1.client_info.ClientInfo):
+ The client info used to send a user-agent string along with
+ API requests. If ``None``, then default info will be used.
+ Generally, you only need to set this if you're developing
your own client library.
Raises:
@@ -149,72 +154,60 @@ def __init__(
google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials``
and ``credentials_file`` are passed.
"""
+ self._grpc_channel = None
self._ssl_channel_credentials = ssl_channel_credentials
+ self._stubs: Dict[str, Callable] = {}
+
+ if api_mtls_endpoint:
+ warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning)
+ if client_cert_source:
+ warnings.warn("client_cert_source is deprecated", DeprecationWarning)
if channel:
- # Sanity check: Ensure that channel and credentials are not both
- # provided.
+ # Ignore credentials if a channel was passed.
credentials = False
-
# If a channel was explicitly provided, set it.
self._grpc_channel = channel
self._ssl_channel_credentials = None
- elif api_mtls_endpoint:
- warnings.warn(
- "api_mtls_endpoint and client_cert_source are deprecated",
- DeprecationWarning,
- )
- host = (
- api_mtls_endpoint
- if ":" in api_mtls_endpoint
- else api_mtls_endpoint + ":443"
- )
+ else:
+ if api_mtls_endpoint:
+ host = api_mtls_endpoint
+
+ # Create SSL credentials with client_cert_source or application
+ # default SSL credentials.
+ if client_cert_source:
+ cert, key = client_cert_source()
+ self._ssl_channel_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
+ else:
+ self._ssl_channel_credentials = SslCredentials().ssl_credentials
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
-
- # Create SSL credentials with client_cert_source or application
- # default SSL credentials.
- if client_cert_source:
- cert, key = client_cert_source()
- ssl_credentials = grpc.ssl_channel_credentials(
- certificate_chain=cert, private_key=key
- )
else:
- ssl_credentials = SslCredentials().ssl_credentials
+ if client_cert_source_for_mtls and not ssl_channel_credentials:
+ cert, key = client_cert_source_for_mtls()
+ self._ssl_channel_credentials = grpc.ssl_channel_credentials(
+ certificate_chain=cert, private_key=key
+ )
- # create a new channel. The provided one is ignored.
- self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
- credentials_file=credentials_file,
- ssl_credentials=ssl_credentials,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- options=[
- ("grpc.max_send_message_length", -1),
- ("grpc.max_receive_message_length", -1),
- ],
- )
- self._ssl_channel_credentials = ssl_credentials
- else:
- host = host if ":" in host else host + ":443"
-
- if credentials is None:
- credentials, _ = auth.default(
- scopes=self.AUTH_SCOPES, quota_project_id=quota_project_id
- )
+ # The base transport sets the host, credentials and scopes
+ super().__init__(
+ host=host,
+ credentials=credentials,
+ credentials_file=credentials_file,
+ scopes=scopes,
+ quota_project_id=quota_project_id,
+ client_info=client_info,
+ )
- # create a new channel. The provided one is ignored.
+ if not self._grpc_channel:
self._grpc_channel = type(self).create_channel(
- host,
- credentials=credentials,
+ self._host,
+ credentials=self._credentials,
credentials_file=credentials_file,
- ssl_credentials=ssl_channel_credentials,
- scopes=scopes or self.AUTH_SCOPES,
+ scopes=self._scopes,
+ ssl_credentials=self._ssl_channel_credentials,
quota_project_id=quota_project_id,
options=[
("grpc.max_send_message_length", -1),
@@ -222,17 +215,8 @@ def __init__(
],
)
- # Run the base constructor.
- super().__init__(
- host=host,
- credentials=credentials,
- credentials_file=credentials_file,
- scopes=scopes or self.AUTH_SCOPES,
- quota_project_id=quota_project_id,
- client_info=client_info,
- )
-
- self._stubs = {}
+ # Wrap messages. This must be done after self._grpc_channel exists
+ self._prep_wrapped_messages(client_info)
@property
def grpc_channel(self) -> aio.Channel:
@@ -252,11 +236,13 @@ def create_dashboard(
]:
r"""Return a callable for the create dashboard method over gRPC.
- Creates a new custom dashboard.
-
+ Creates a new custom dashboard. For examples on how you can use
+ this API to create dashboards, see `Managing dashboards by
+ API `__.
This method requires the ``monitoring.dashboards.create``
- permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ permission on the specified project. For more information about
+ permissions, see `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.CreateDashboardRequest],
@@ -289,7 +275,8 @@ def list_dashboards(
This method requires the ``monitoring.dashboards.list``
permission on the specified project. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.ListDashboardsRequest],
@@ -321,7 +308,8 @@ def get_dashboard(
This method requires the ``monitoring.dashboards.get``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.GetDashboardRequest],
@@ -351,7 +339,8 @@ def delete_dashboard(
This method requires the ``monitoring.dashboards.delete``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.DeleteDashboardRequest],
@@ -383,7 +372,8 @@ def update_dashboard(
This method requires the ``monitoring.dashboards.update``
permission on the specified dashboard. For more information, see
- `Google Cloud IAM `__.
+ `Cloud Identity and Access
+ Management `__.
Returns:
Callable[[~.UpdateDashboardRequest],
diff --git a/google/cloud/monitoring_dashboard_v1/types/__init__.py b/google/cloud/monitoring_dashboard_v1/types/__init__.py
index f537e80..ec48e01 100644
--- a/google/cloud/monitoring_dashboard_v1/types/__init__.py
+++ b/google/cloud/monitoring_dashboard_v1/types/__init__.py
@@ -20,57 +20,59 @@
PickTimeSeriesFilter,
StatisticalTimeSeriesFilter,
)
+from .dashboard import Dashboard
+from .dashboards_service import (
+ CreateDashboardRequest,
+ DeleteDashboardRequest,
+ GetDashboardRequest,
+ ListDashboardsRequest,
+ ListDashboardsResponse,
+ UpdateDashboardRequest,
+)
+from .layouts import (
+ ColumnLayout,
+ GridLayout,
+ MosaicLayout,
+ RowLayout,
+)
from .metrics import (
- TimeSeriesQuery,
+ Threshold,
TimeSeriesFilter,
TimeSeriesFilterRatio,
- Threshold,
+ TimeSeriesQuery,
SparkChartType,
)
from .scorecard import Scorecard
from .text import Text
+from .widget import Widget
from .xychart import (
- XyChart,
ChartOptions,
-)
-from .widget import Widget
-from .layouts import (
- GridLayout,
- RowLayout,
- ColumnLayout,
-)
-from .dashboard import Dashboard
-from .dashboards_service import (
- CreateDashboardRequest,
- ListDashboardsRequest,
- ListDashboardsResponse,
- GetDashboardRequest,
- DeleteDashboardRequest,
- UpdateDashboardRequest,
+ XyChart,
)
__all__ = (
"Aggregation",
"PickTimeSeriesFilter",
"StatisticalTimeSeriesFilter",
- "TimeSeriesQuery",
+ "Dashboard",
+ "CreateDashboardRequest",
+ "DeleteDashboardRequest",
+ "GetDashboardRequest",
+ "ListDashboardsRequest",
+ "ListDashboardsResponse",
+ "UpdateDashboardRequest",
+ "ColumnLayout",
+ "GridLayout",
+ "MosaicLayout",
+ "RowLayout",
+ "Threshold",
"TimeSeriesFilter",
"TimeSeriesFilterRatio",
- "Threshold",
+ "TimeSeriesQuery",
"SparkChartType",
"Scorecard",
"Text",
- "XyChart",
- "ChartOptions",
"Widget",
- "GridLayout",
- "RowLayout",
- "ColumnLayout",
- "Dashboard",
- "CreateDashboardRequest",
- "ListDashboardsRequest",
- "ListDashboardsResponse",
- "GetDashboardRequest",
- "DeleteDashboardRequest",
- "UpdateDashboardRequest",
+ "ChartOptions",
+ "XyChart",
)
diff --git a/google/cloud/monitoring_dashboard_v1/types/common.py b/google/cloud/monitoring_dashboard_v1/types/common.py
index b90f9c6..3405b1d 100644
--- a/google/cloud/monitoring_dashboard_v1/types/common.py
+++ b/google/cloud/monitoring_dashboard_v1/types/common.py
@@ -58,7 +58,7 @@ class Aggregation(proto.Message):
aggregation `__.
Attributes:
- alignment_period (~.duration.Duration):
+ alignment_period (google.protobuf.duration_pb2.Duration):
The ``alignment_period`` specifies a time interval, in
seconds, that is used to divide the data in all the [time
series][google.monitoring.v3.TimeSeries] into consistent
@@ -70,7 +70,10 @@ class Aggregation(proto.Message):
is required or an error is returned. If no per-series
aligner is specified, or the aligner ``ALIGN_NONE`` is
specified, then this field is ignored.
- per_series_aligner (~.common.Aggregation.Aligner):
+
+ The maximum value of the ``alignment_period`` is 2 years, or
+ 104 weeks.
+ per_series_aligner (google.cloud.monitoring_dashboard_v1.types.Aggregation.Aligner):
An ``Aligner`` describes how to bring the data points in a
single time series into temporal alignment. Except for
``ALIGN_NONE``, all alignments cause all the data points in
@@ -90,7 +93,7 @@ class Aggregation(proto.Message):
specified, then ``per_series_aligner`` must be specified and
not equal to ``ALIGN_NONE`` and ``alignment_period`` must be
specified; otherwise, an error is returned.
- cross_series_reducer (~.common.Aggregation.Reducer):
+ cross_series_reducer (google.cloud.monitoring_dashboard_v1.types.Aggregation.Reducer):
The reduction operation to be used to combine time series
into a single time series, where the value of each data
point in the resulting series is a function of all the
@@ -203,14 +206,14 @@ class PickTimeSeriesFilter(proto.Message):
mean values will pass through the filter.
Attributes:
- ranking_method (~.common.PickTimeSeriesFilter.Method):
+ ranking_method (google.cloud.monitoring_dashboard_v1.types.PickTimeSeriesFilter.Method):
``ranking_method`` is applied to each time series
independently to produce the value which will be used to
compare the time series to other time series.
num_time_series (int):
How many time series to allow to pass through
the filter.
- direction (~.common.PickTimeSeriesFilter.Direction):
+ direction (google.cloud.monitoring_dashboard_v1.types.PickTimeSeriesFilter.Direction):
How to use the ranking to select time series
that pass through the filter.
"""
@@ -246,7 +249,7 @@ class StatisticalTimeSeriesFilter(proto.Message):
API.
Attributes:
- ranking_method (~.common.StatisticalTimeSeriesFilter.Method):
+ ranking_method (google.cloud.monitoring_dashboard_v1.types.StatisticalTimeSeriesFilter.Method):
``rankingMethod`` is applied to a set of time series, and
then the produced value for each individual time series is
used to compare a given time series to others. These are
diff --git a/google/cloud/monitoring_dashboard_v1/types/dashboard.py b/google/cloud/monitoring_dashboard_v1/types/dashboard.py
index 5077b48..689f93c 100644
--- a/google/cloud/monitoring_dashboard_v1/types/dashboard.py
+++ b/google/cloud/monitoring_dashboard_v1/types/dashboard.py
@@ -45,14 +45,18 @@ class Dashboard(proto.Message):
that their change will be applied to the same version of the
Dashboard configuration. The field should not be passed
during dashboard creation.
- grid_layout (~.layouts.GridLayout):
+ grid_layout (google.cloud.monitoring_dashboard_v1.types.GridLayout):
Content is arranged with a basic layout that
re-flows a simple list of informational elements
like widgets or tiles.
- row_layout (~.layouts.RowLayout):
+ mosaic_layout (google.cloud.monitoring_dashboard_v1.types.MosaicLayout):
+ The content is arranged as a grid of tiles,
+ with each content widget occupying one or more
+ grid blocks.
+ row_layout (google.cloud.monitoring_dashboard_v1.types.RowLayout):
The content is divided into equally spaced
rows and the widgets are arranged horizontally.
- column_layout (~.layouts.ColumnLayout):
+ column_layout (google.cloud.monitoring_dashboard_v1.types.ColumnLayout):
The content is divided into equally spaced
columns and the widgets are arranged vertically.
"""
@@ -67,6 +71,10 @@ class Dashboard(proto.Message):
proto.MESSAGE, number=5, oneof="layout", message=layouts.GridLayout,
)
+ mosaic_layout = proto.Field(
+ proto.MESSAGE, number=6, oneof="layout", message=layouts.MosaicLayout,
+ )
+
row_layout = proto.Field(
proto.MESSAGE, number=8, oneof="layout", message=layouts.RowLayout,
)
diff --git a/google/cloud/monitoring_dashboard_v1/types/dashboards_service.py b/google/cloud/monitoring_dashboard_v1/types/dashboards_service.py
index 92cd956..1e866ac 100644
--- a/google/cloud/monitoring_dashboard_v1/types/dashboards_service.py
+++ b/google/cloud/monitoring_dashboard_v1/types/dashboards_service.py
@@ -48,7 +48,7 @@ class CreateDashboardRequest(proto.Message):
The ``[PROJECT_ID_OR_NUMBER]`` must match the dashboard
resource name.
- dashboard (~.gmd_dashboard.Dashboard):
+ dashboard (google.cloud.monitoring_dashboard_v1.types.Dashboard):
Required. The initial dashboard
specification.
"""
@@ -91,7 +91,7 @@ class ListDashboardsResponse(proto.Message):
r"""The ``ListDashboards`` request.
Attributes:
- dashboards (Sequence[~.gmd_dashboard.Dashboard]):
+ dashboards (Sequence[google.cloud.monitoring_dashboard_v1.types.Dashboard]):
The list of requested dashboards.
next_page_token (str):
If there are more results than have been returned, then this
@@ -146,7 +146,7 @@ class UpdateDashboardRequest(proto.Message):
r"""The ``UpdateDashboard`` request.
Attributes:
- dashboard (~.gmd_dashboard.Dashboard):
+ dashboard (google.cloud.monitoring_dashboard_v1.types.Dashboard):
Required. The dashboard that will replace the
existing dashboard.
"""
diff --git a/google/cloud/monitoring_dashboard_v1/types/layouts.py b/google/cloud/monitoring_dashboard_v1/types/layouts.py
index 683f6f3..f87385a 100644
--- a/google/cloud/monitoring_dashboard_v1/types/layouts.py
+++ b/google/cloud/monitoring_dashboard_v1/types/layouts.py
@@ -18,12 +18,12 @@
import proto # type: ignore
-from google.cloud.monitoring_dashboard_v1.types import widget
+from google.cloud.monitoring_dashboard_v1.types import widget as gmd_widget
__protobuf__ = proto.module(
package="google.monitoring.dashboard.v1",
- manifest={"GridLayout", "RowLayout", "ColumnLayout",},
+ manifest={"GridLayout", "MosaicLayout", "RowLayout", "ColumnLayout",},
)
@@ -37,14 +37,69 @@ class GridLayout(proto.Message):
The number of columns into which the view's
width is divided. If omitted or set to zero, a
system default will be used while rendering.
- widgets (Sequence[~.widget.Widget]):
+ widgets (Sequence[google.cloud.monitoring_dashboard_v1.types.Widget]):
The informational elements that are arranged
into the columns row-first.
"""
columns = proto.Field(proto.INT64, number=1)
- widgets = proto.RepeatedField(proto.MESSAGE, number=2, message=widget.Widget,)
+ widgets = proto.RepeatedField(proto.MESSAGE, number=2, message=gmd_widget.Widget,)
+
+
+class MosaicLayout(proto.Message):
+ r"""A mosaic layout divides the available space into a grid of blocks,
+ and overlays the grid with tiles. Unlike ``GridLayout``, tiles may
+ span multiple grid blocks and can be placed at arbitrary locations
+ in the grid.
+
+ Attributes:
+ columns (int):
+ The number of columns in the mosaic grid. The
+ number of columns must be between 1 and 12,
+ inclusive.
+ tiles (Sequence[google.cloud.monitoring_dashboard_v1.types.MosaicLayout.Tile]):
+ The tiles to display.
+ """
+
+ class Tile(proto.Message):
+ r"""A single tile in the mosaic. The placement and size of the
+ tile are configurable.
+
+ Attributes:
+ x_pos (int):
+ The zero-indexed position of the tile in grid blocks
+ relative to the left edge of the grid. Tiles must be
+ contained within the specified number of columns. ``x_pos``
+ cannot be negative.
+ y_pos (int):
+ The zero-indexed position of the tile in grid blocks
+ relative to the top edge of the grid. ``y_pos`` cannot be
+ negative.
+ width (int):
+ The width of the tile, measured in grid
+ blocks. Tiles must have a minimum width of 1.
+ height (int):
+ The height of the tile, measured in grid
+ blocks. Tiles must have a minimum height of 1.
+ widget (google.cloud.monitoring_dashboard_v1.types.Widget):
+ The informational widget contained in the tile. For example
+ an ``XyChart``.
+ """
+
+ x_pos = proto.Field(proto.INT32, number=1)
+
+ y_pos = proto.Field(proto.INT32, number=2)
+
+ width = proto.Field(proto.INT32, number=3)
+
+ height = proto.Field(proto.INT32, number=4)
+
+ widget = proto.Field(proto.MESSAGE, number=5, message=gmd_widget.Widget,)
+
+ columns = proto.Field(proto.INT32, number=1)
+
+ tiles = proto.RepeatedField(proto.MESSAGE, number=3, message=Tile,)
class RowLayout(proto.Message):
@@ -52,7 +107,7 @@ class RowLayout(proto.Message):
rows and arranges a set of widgets horizontally in each row.
Attributes:
- rows (Sequence[~.layouts.RowLayout.Row]):
+ rows (Sequence[google.cloud.monitoring_dashboard_v1.types.RowLayout.Row]):
The rows of content to display.
"""
@@ -67,14 +122,16 @@ class Row(proto.Message):
weight, greater the height of the row on the
screen. If omitted, a value of 1 is used while
rendering.
- widgets (Sequence[~.widget.Widget]):
+ widgets (Sequence[google.cloud.monitoring_dashboard_v1.types.Widget]):
The display widgets arranged horizontally in
this row.
"""
weight = proto.Field(proto.INT64, number=1)
- widgets = proto.RepeatedField(proto.MESSAGE, number=2, message=widget.Widget,)
+ widgets = proto.RepeatedField(
+ proto.MESSAGE, number=2, message=gmd_widget.Widget,
+ )
rows = proto.RepeatedField(proto.MESSAGE, number=1, message=Row,)
@@ -85,7 +142,7 @@ class ColumnLayout(proto.Message):
each column.
Attributes:
- columns (Sequence[~.layouts.ColumnLayout.Column]):
+ columns (Sequence[google.cloud.monitoring_dashboard_v1.types.ColumnLayout.Column]):
The columns of content to display.
"""
@@ -100,14 +157,16 @@ class Column(proto.Message):
Greater the weight, greater the width of the
column on the screen. If omitted, a value of 1
is used while rendering.
- widgets (Sequence[~.widget.Widget]):
+ widgets (Sequence[google.cloud.monitoring_dashboard_v1.types.Widget]):
The display widgets arranged vertically in
this column.
"""
weight = proto.Field(proto.INT64, number=1)
- widgets = proto.RepeatedField(proto.MESSAGE, number=2, message=widget.Widget,)
+ widgets = proto.RepeatedField(
+ proto.MESSAGE, number=2, message=gmd_widget.Widget,
+ )
columns = proto.RepeatedField(proto.MESSAGE, number=1, message=Column,)
diff --git a/google/cloud/monitoring_dashboard_v1/types/metrics.py b/google/cloud/monitoring_dashboard_v1/types/metrics.py
index 5eb7570..7526cb9 100644
--- a/google/cloud/monitoring_dashboard_v1/types/metrics.py
+++ b/google/cloud/monitoring_dashboard_v1/types/metrics.py
@@ -47,9 +47,9 @@ class TimeSeriesQuery(proto.Message):
querying time series data from the Stackdriver metrics API.
Attributes:
- time_series_filter (~.metrics.TimeSeriesFilter):
+ time_series_filter (google.cloud.monitoring_dashboard_v1.types.TimeSeriesFilter):
Filter parameters to fetch time series.
- time_series_filter_ratio (~.metrics.TimeSeriesFilterRatio):
+ time_series_filter_ratio (google.cloud.monitoring_dashboard_v1.types.TimeSeriesFilterRatio):
Parameters to fetch a ratio between two time
series filters.
time_series_query_language (str):
@@ -87,15 +87,15 @@ class TimeSeriesFilter(proto.Message):
filter `__
that identifies the metric types, resources, and projects to
query.
- aggregation (~.common.Aggregation):
+ aggregation (google.cloud.monitoring_dashboard_v1.types.Aggregation):
By default, the raw time series data is
returned. Use this field to combine multiple
time series for different views of the data.
- secondary_aggregation (~.common.Aggregation):
+ secondary_aggregation (google.cloud.monitoring_dashboard_v1.types.Aggregation):
Apply a second aggregation after ``aggregation`` is applied.
- pick_time_series_filter (~.common.PickTimeSeriesFilter):
+ pick_time_series_filter (google.cloud.monitoring_dashboard_v1.types.PickTimeSeriesFilter):
Ranking based time series filter.
- statistical_time_series_filter (~.common.StatisticalTimeSeriesFilter):
+ statistical_time_series_filter (google.cloud.monitoring_dashboard_v1.types.StatisticalTimeSeriesFilter):
Statistics based time series filter.
Note: This field is deprecated and completely
ignored by the API.
@@ -131,16 +131,16 @@ class TimeSeriesFilterRatio(proto.Message):
series.
Attributes:
- numerator (~.metrics.TimeSeriesFilterRatio.RatioPart):
+ numerator (google.cloud.monitoring_dashboard_v1.types.TimeSeriesFilterRatio.RatioPart):
The numerator of the ratio.
- denominator (~.metrics.TimeSeriesFilterRatio.RatioPart):
+ denominator (google.cloud.monitoring_dashboard_v1.types.TimeSeriesFilterRatio.RatioPart):
The denominator of the ratio.
- secondary_aggregation (~.common.Aggregation):
+ secondary_aggregation (google.cloud.monitoring_dashboard_v1.types.Aggregation):
Apply a second aggregation after the ratio is
computed.
- pick_time_series_filter (~.common.PickTimeSeriesFilter):
+ pick_time_series_filter (google.cloud.monitoring_dashboard_v1.types.PickTimeSeriesFilter):
Ranking based time series filter.
- statistical_time_series_filter (~.common.StatisticalTimeSeriesFilter):
+ statistical_time_series_filter (google.cloud.monitoring_dashboard_v1.types.StatisticalTimeSeriesFilter):
Statistics based time series filter.
Note: This field is deprecated and completely
ignored by the API.
@@ -156,7 +156,7 @@ class RatioPart(proto.Message):
filter `__
that identifies the metric types, resources, and projects to
query.
- aggregation (~.common.Aggregation):
+ aggregation (google.cloud.monitoring_dashboard_v1.types.Aggregation):
By default, the raw time series data is
returned. Use this field to combine multiple
time series for different views of the data.
@@ -198,10 +198,10 @@ class Threshold(proto.Message):
value (float):
The value of the threshold. The value should
be defined in the native scale of the metric.
- color (~.metrics.Threshold.Color):
+ color (google.cloud.monitoring_dashboard_v1.types.Threshold.Color):
The state color for this threshold. Color is
not allowed in a XyChart.
- direction (~.metrics.Threshold.Direction):
+ direction (google.cloud.monitoring_dashboard_v1.types.Threshold.Direction):
The direction for the current threshold.
Direction is not allowed in a XyChart.
"""
diff --git a/google/cloud/monitoring_dashboard_v1/types/scorecard.py b/google/cloud/monitoring_dashboard_v1/types/scorecard.py
index 420ab73..e03bd14 100644
--- a/google/cloud/monitoring_dashboard_v1/types/scorecard.py
+++ b/google/cloud/monitoring_dashboard_v1/types/scorecard.py
@@ -32,16 +32,16 @@ class Scorecard(proto.Message):
value relates to one or more thresholds.
Attributes:
- time_series_query (~.metrics.TimeSeriesQuery):
+ time_series_query (google.cloud.monitoring_dashboard_v1.types.TimeSeriesQuery):
Required. Fields for querying time series
data from the Stackdriver metrics API.
- gauge_view (~.scorecard.Scorecard.GaugeView):
+ gauge_view (google.cloud.monitoring_dashboard_v1.types.Scorecard.GaugeView):
Will cause the scorecard to show a gauge
chart.
- spark_chart_view (~.scorecard.Scorecard.SparkChartView):
+ spark_chart_view (google.cloud.monitoring_dashboard_v1.types.Scorecard.SparkChartView):
Will cause the scorecard to show a spark
chart.
- thresholds (Sequence[~.metrics.Threshold]):
+ thresholds (Sequence[google.cloud.monitoring_dashboard_v1.types.Threshold]):
The thresholds used to determine the state of
the scorecard given the time series' current
value. For an actual value x, the scorecard is
@@ -111,10 +111,10 @@ class SparkChartView(proto.Message):
showing recent trends of the scorecard's timeseries.
Attributes:
- spark_chart_type (~.metrics.SparkChartType):
+ spark_chart_type (google.cloud.monitoring_dashboard_v1.types.SparkChartType):
Required. The type of sparkchart to show in
this chartView.
- min_alignment_period (~.duration.Duration):
+ min_alignment_period (google.protobuf.duration_pb2.Duration):
The lower bound on data point frequency in
the chart implemented by specifying the minimum
alignment period to use in a time series query.
diff --git a/google/cloud/monitoring_dashboard_v1/types/text.py b/google/cloud/monitoring_dashboard_v1/types/text.py
index 33e4da4..e282af2 100644
--- a/google/cloud/monitoring_dashboard_v1/types/text.py
+++ b/google/cloud/monitoring_dashboard_v1/types/text.py
@@ -29,7 +29,7 @@ class Text(proto.Message):
Attributes:
content (str):
The text content to be displayed.
- format_ (~.text.Text.Format):
+ format_ (google.cloud.monitoring_dashboard_v1.types.Text.Format):
How the text content is formatted.
"""
diff --git a/google/cloud/monitoring_dashboard_v1/types/widget.py b/google/cloud/monitoring_dashboard_v1/types/widget.py
index 8cd78e4..282b2b0 100644
--- a/google/cloud/monitoring_dashboard_v1/types/widget.py
+++ b/google/cloud/monitoring_dashboard_v1/types/widget.py
@@ -36,14 +36,14 @@ class Widget(proto.Message):
Attributes:
title (str):
Optional. The title of the widget.
- xy_chart (~.xychart.XyChart):
+ xy_chart (google.cloud.monitoring_dashboard_v1.types.XyChart):
A chart of time series data.
- scorecard (~.gmd_scorecard.Scorecard):
+ scorecard (google.cloud.monitoring_dashboard_v1.types.Scorecard):
A scorecard summarizing time series data.
- text (~.gmd_text.Text):
+ text (google.cloud.monitoring_dashboard_v1.types.Text):
A raw string or markdown displaying textual
content.
- blank (~.empty.Empty):
+ blank (google.protobuf.empty_pb2.Empty):
A blank space.
"""
diff --git a/google/cloud/monitoring_dashboard_v1/types/xychart.py b/google/cloud/monitoring_dashboard_v1/types/xychart.py
index 2b57f7c..16a975d 100644
--- a/google/cloud/monitoring_dashboard_v1/types/xychart.py
+++ b/google/cloud/monitoring_dashboard_v1/types/xychart.py
@@ -31,9 +31,9 @@ class XyChart(proto.Message):
r"""A chart that displays data on a 2D (X and Y axes) plane.
Attributes:
- data_sets (Sequence[~.xychart.XyChart.DataSet]):
+ data_sets (Sequence[google.cloud.monitoring_dashboard_v1.types.XyChart.DataSet]):
Required. The data displayed in this chart.
- timeshift_duration (~.duration.Duration):
+ timeshift_duration (google.protobuf.duration_pb2.Duration):
The duration used to display a comparison
chart. A comparison chart simultaneously shows
values from two similar-length time periods
@@ -41,14 +41,14 @@ class XyChart(proto.Message):
The duration must be positive, and it can only
be applied to charts with data sets of LINE plot
type.
- thresholds (Sequence[~.metrics.Threshold]):
+ thresholds (Sequence[google.cloud.monitoring_dashboard_v1.types.Threshold]):
Threshold lines drawn horizontally across the
chart.
- x_axis (~.xychart.XyChart.Axis):
+ x_axis (google.cloud.monitoring_dashboard_v1.types.XyChart.Axis):
The properties applied to the X axis.
- y_axis (~.xychart.XyChart.Axis):
+ y_axis (google.cloud.monitoring_dashboard_v1.types.XyChart.Axis):
The properties applied to the Y axis.
- chart_options (~.xychart.ChartOptions):
+ chart_options (google.cloud.monitoring_dashboard_v1.types.ChartOptions):
Display options for the chart.
"""
@@ -56,17 +56,17 @@ class DataSet(proto.Message):
r"""Groups a time series query definition with charting options.
Attributes:
- time_series_query (~.metrics.TimeSeriesQuery):
+ time_series_query (google.cloud.monitoring_dashboard_v1.types.TimeSeriesQuery):
Required. Fields for querying time series
data from the Stackdriver metrics API.
- plot_type (~.xychart.XyChart.DataSet.PlotType):
+ plot_type (google.cloud.monitoring_dashboard_v1.types.XyChart.DataSet.PlotType):
How this data should be plotted on the chart.
legend_template (str):
A template string for naming ``TimeSeries`` in the resulting
data set. This should be a string with interpolations of the
form ``${label_name}``, which will resolve to the label's
value.
- min_alignment_period (~.duration.Duration):
+ min_alignment_period (google.protobuf.duration_pb2.Duration):
Optional. The lower bound on data point frequency for this
data set, implemented by specifying the minimum alignment
period to use in a time series query For example, if the
@@ -102,7 +102,7 @@ class Axis(proto.Message):
Attributes:
label (str):
The label of the axis.
- scale (~.xychart.XyChart.Axis.Scale):
+ scale (google.cloud.monitoring_dashboard_v1.types.XyChart.Axis.Scale):
The axis scale. By default, a linear scale is
used.
"""
@@ -138,7 +138,7 @@ class ChartOptions(proto.Message):
r"""Options to control visual rendering of a chart.
Attributes:
- mode (~.xychart.ChartOptions.Mode):
+ mode (google.cloud.monitoring_dashboard_v1.types.ChartOptions.Mode):
The chart mode.
"""
diff --git a/noxfile.py b/noxfile.py
index 2f17d2b..b038287 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -18,6 +18,7 @@
from __future__ import absolute_import
import os
+import pathlib
import shutil
import nox
@@ -30,6 +31,22 @@
SYSTEM_TEST_PYTHON_VERSIONS = ["3.8"]
UNIT_TEST_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]
+CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute()
+
+# 'docfx' is excluded since it only needs to run in 'docs-presubmit'
+nox.options.sessions = [
+ "unit",
+ "system",
+ "cover",
+ "lint",
+ "lint_setup_py",
+ "blacken",
+ "docs",
+]
+
+# Error if a python version is missing
+nox.options.error_on_missing_interpreters = True
+
@nox.session(python=DEFAULT_PYTHON_VERSION)
def lint(session):
@@ -70,20 +87,23 @@ def lint_setup_py(session):
def default(session):
# Install all test dependencies, then install this package in-place.
- session.install("asyncmock", "pytest-asyncio")
- session.install(
- "mock", "pytest", "pytest-cov",
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
)
- session.install("-e", ".")
+ session.install("asyncmock", "pytest-asyncio", "-c", constraints_path)
+
+ session.install("mock", "pytest", "pytest-cov", "-c", constraints_path)
+
+ session.install("-e", ".", "-c", constraints_path)
# Run py.test against the unit tests.
session.run(
"py.test",
"--quiet",
- "--cov=google.cloud.monitoring-dashboards",
- "--cov=google.cloud",
- "--cov=tests.unit",
+ f"--junitxml=unit_{session.python}_sponge_log.xml",
+ "--cov=google/cloud",
+ "--cov=tests/unit",
"--cov-append",
"--cov-config=.coveragerc",
"--cov-report=",
@@ -102,6 +122,9 @@ def unit(session):
@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS)
def system(session):
"""Run the system test suite."""
+ constraints_path = str(
+ CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt"
+ )
system_test_path = os.path.join("tests", "system.py")
system_test_folder_path = os.path.join("tests", "system")
@@ -111,6 +134,9 @@ def system(session):
# Sanity check: Only run tests if the environment variable is set.
if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""):
session.skip("Credentials must be set via environment variable")
+ # Install pyopenssl for mTLS testing.
+ if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true":
+ session.install("pyopenssl")
system_test_exists = os.path.exists(system_test_path)
system_test_folder_exists = os.path.exists(system_test_folder_path)
@@ -123,16 +149,26 @@ def system(session):
# Install all test dependencies, then install this package into the
# virtualenv's dist-packages.
- session.install(
- "mock", "pytest", "google-cloud-testutils",
- )
- session.install("-e", ".")
+ session.install("mock", "pytest", "google-cloud-testutils", "-c", constraints_path)
+ session.install("-e", ".", "-c", constraints_path)
# Run py.test against the system tests.
if system_test_exists:
- session.run("py.test", "--quiet", system_test_path, *session.posargs)
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_path,
+ *session.posargs,
+ )
if system_test_folder_exists:
- session.run("py.test", "--quiet", system_test_folder_path, *session.posargs)
+ session.run(
+ "py.test",
+ "--quiet",
+ f"--junitxml=system_{session.python}_sponge_log.xml",
+ system_test_folder_path,
+ *session.posargs,
+ )
@nox.session(python=DEFAULT_PYTHON_VERSION)
@@ -143,7 +179,7 @@ def cover(session):
test runs (not system test runs), and then erases coverage data.
"""
session.install("coverage", "pytest-cov")
- session.run("coverage", "report", "--show-missing", "--fail-under=100")
+ session.run("coverage", "report", "--show-missing", "--fail-under=96")
session.run("coverage", "erase")
@@ -153,7 +189,7 @@ def docs(session):
"""Build the docs for this library."""
session.install("-e", ".")
- session.install("sphinx<3.0.0", "alabaster", "recommonmark")
+ session.install("sphinx", "alabaster", "recommonmark")
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
session.run(
@@ -175,9 +211,7 @@ def docfx(session):
"""Build the docfx yaml files for this library."""
session.install("-e", ".")
- # sphinx-docfx-yaml supports up to sphinx version 1.5.5.
- # https://github.com/docascode/sphinx-docfx-yaml/issues/97
- session.install("sphinx==1.5.5", "alabaster", "recommonmark", "sphinx-docfx-yaml")
+ session.install("sphinx", "alabaster", "recommonmark", "gcp-sphinx-docfx-yaml")
shutil.rmtree(os.path.join("docs", "_build"), ignore_errors=True)
session.run(
diff --git a/renovate.json b/renovate.json
index 4fa9493..f08bc22 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,5 +1,6 @@
{
"extends": [
"config:base", ":preserveSemverRanges"
- ]
+ ],
+ "ignorePaths": [".pre-commit-config.yaml"]
}
diff --git a/setup.py b/setup.py
index 1a79a2f..5a7688f 100644
--- a/setup.py
+++ b/setup.py
@@ -25,11 +25,12 @@
version = "2.0.0"
release_status = "Development Status :: 5 - Production/Stable"
dependencies = [
- "google-api-core[grpc] >= 1.22.0, < 2.0.0dev",
+ "google-api-core[grpc] >= 1.22.2, < 2.0.0dev",
"proto-plus >= 0.4.0",
- "libcst >= 0.2.5",
]
+extras = {"libcst": "libcst >= 0.2.5"}
+
package_root = os.path.abspath(os.path.dirname(__file__))
readme_filename = os.path.join(package_root, "README.rst")
diff --git a/synth.metadata b/synth.metadata
index 6806b03..71777e7 100644
--- a/synth.metadata
+++ b/synth.metadata
@@ -3,30 +3,30 @@
{
"git": {
"name": ".",
- "remote": "https://github.com/googleapis/python-monitoring-dashboards.git",
- "sha": "8e00d80b19618d42e79833cff20e2f62c08fcede"
+ "remote": "git@github.com:googleapis/python-monitoring-dashboards",
+ "sha": "7bed1832c1284558c98fa72cdfb8245f899679ce"
}
},
{
"git": {
"name": "googleapis",
"remote": "https://github.com/googleapis/googleapis.git",
- "sha": "dd372aa22ded7a8ba6f0e03a80e06358a3fa0907",
- "internalRef": "347055288"
+ "sha": "95dd24960cf9f794ef583e59ad9f1fabe1c4a924",
+ "internalRef": "365882072"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "a073c873f3928c561bdf87fdfbf1d081d1998984"
+ "sha": "551dd78ca04f7989abc9e63e392f8b8cfa1a0ef9"
}
},
{
"git": {
"name": "synthtool",
"remote": "https://github.com/googleapis/synthtool.git",
- "sha": "a073c873f3928c561bdf87fdfbf1d081d1998984"
+ "sha": "551dd78ca04f7989abc9e63e392f8b8cfa1a0ef9"
}
}
],
@@ -40,113 +40,5 @@
"generator": "bazel"
}
}
- ],
- "generatedFiles": [
- ".flake8",
- ".github/CONTRIBUTING.md",
- ".github/ISSUE_TEMPLATE/bug_report.md",
- ".github/ISSUE_TEMPLATE/feature_request.md",
- ".github/ISSUE_TEMPLATE/support_request.md",
- ".github/PULL_REQUEST_TEMPLATE.md",
- ".github/release-please.yml",
- ".github/snippet-bot.yml",
- ".gitignore",
- ".kokoro/build.sh",
- ".kokoro/continuous/common.cfg",
- ".kokoro/continuous/continuous.cfg",
- ".kokoro/docker/docs/Dockerfile",
- ".kokoro/docker/docs/fetch_gpg_keys.sh",
- ".kokoro/docs/common.cfg",
- ".kokoro/docs/docs-presubmit.cfg",
- ".kokoro/docs/docs.cfg",
- ".kokoro/populate-secrets.sh",
- ".kokoro/presubmit/common.cfg",
- ".kokoro/presubmit/presubmit.cfg",
- ".kokoro/publish-docs.sh",
- ".kokoro/release.sh",
- ".kokoro/release/common.cfg",
- ".kokoro/release/release.cfg",
- ".kokoro/samples/lint/common.cfg",
- ".kokoro/samples/lint/continuous.cfg",
- ".kokoro/samples/lint/periodic.cfg",
- ".kokoro/samples/lint/presubmit.cfg",
- ".kokoro/samples/python3.6/common.cfg",
- ".kokoro/samples/python3.6/continuous.cfg",
- ".kokoro/samples/python3.6/periodic.cfg",
- ".kokoro/samples/python3.6/presubmit.cfg",
- ".kokoro/samples/python3.7/common.cfg",
- ".kokoro/samples/python3.7/continuous.cfg",
- ".kokoro/samples/python3.7/periodic.cfg",
- ".kokoro/samples/python3.7/presubmit.cfg",
- ".kokoro/samples/python3.8/common.cfg",
- ".kokoro/samples/python3.8/continuous.cfg",
- ".kokoro/samples/python3.8/periodic.cfg",
- ".kokoro/samples/python3.8/presubmit.cfg",
- ".kokoro/test-samples.sh",
- ".kokoro/trampoline.sh",
- ".kokoro/trampoline_v2.sh",
- ".trampolinerc",
- "CODE_OF_CONDUCT.md",
- "CONTRIBUTING.rst",
- "LICENSE",
- "MANIFEST.in",
- "docs/_static/custom.css",
- "docs/_templates/layout.html",
- "docs/conf.py",
- "docs/dashboard_v1/services.rst",
- "docs/dashboard_v1/types.rst",
- "docs/multiprocessing.rst",
- "google/cloud/monitoring_dashboard/__init__.py",
- "google/cloud/monitoring_dashboard/py.typed",
- "google/cloud/monitoring_dashboard_v1/__init__.py",
- "google/cloud/monitoring_dashboard_v1/proto/common.proto",
- "google/cloud/monitoring_dashboard_v1/proto/dashboard.proto",
- "google/cloud/monitoring_dashboard_v1/proto/dashboards_service.proto",
- "google/cloud/monitoring_dashboard_v1/proto/drilldowns.proto",
- "google/cloud/monitoring_dashboard_v1/proto/layouts.proto",
- "google/cloud/monitoring_dashboard_v1/proto/metrics.proto",
- "google/cloud/monitoring_dashboard_v1/proto/scorecard.proto",
- "google/cloud/monitoring_dashboard_v1/proto/service.proto",
- "google/cloud/monitoring_dashboard_v1/proto/text.proto",
- "google/cloud/monitoring_dashboard_v1/proto/widget.proto",
- "google/cloud/monitoring_dashboard_v1/proto/xychart.proto",
- "google/cloud/monitoring_dashboard_v1/py.typed",
- "google/cloud/monitoring_dashboard_v1/services/__init__.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/__init__.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/async_client.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/client.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/pagers.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/__init__.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/base.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc.py",
- "google/cloud/monitoring_dashboard_v1/services/dashboards_service/transports/grpc_asyncio.py",
- "google/cloud/monitoring_dashboard_v1/types/__init__.py",
- "google/cloud/monitoring_dashboard_v1/types/common.py",
- "google/cloud/monitoring_dashboard_v1/types/dashboard.py",
- "google/cloud/monitoring_dashboard_v1/types/dashboards_service.py",
- "google/cloud/monitoring_dashboard_v1/types/drilldowns.py",
- "google/cloud/monitoring_dashboard_v1/types/layouts.py",
- "google/cloud/monitoring_dashboard_v1/types/metrics.py",
- "google/cloud/monitoring_dashboard_v1/types/scorecard.py",
- "google/cloud/monitoring_dashboard_v1/types/service.py",
- "google/cloud/monitoring_dashboard_v1/types/text.py",
- "google/cloud/monitoring_dashboard_v1/types/widget.py",
- "google/cloud/monitoring_dashboard_v1/types/xychart.py",
- "noxfile.py",
- "renovate.json",
- "samples/AUTHORING_GUIDE.md",
- "samples/CONTRIBUTING.md",
- "scripts/decrypt-secrets.sh",
- "scripts/fixup_dashboard_v1_keywords.py",
- "scripts/readme-gen/readme_gen.py",
- "scripts/readme-gen/templates/README.tmpl.rst",
- "scripts/readme-gen/templates/auth.tmpl.rst",
- "scripts/readme-gen/templates/auth_api_key.tmpl.rst",
- "scripts/readme-gen/templates/install_deps.tmpl.rst",
- "scripts/readme-gen/templates/install_portaudio.tmpl.rst",
- "setup.cfg",
- "testing/.gitignore",
- "tests/unit/gapic/dashboard_v1/__init__.py",
- "tests/unit/gapic/dashboard_v1/test_dashboards_service.py"
]
}
\ No newline at end of file
diff --git a/synth.py b/synth.py
index bf7e99f..414b6bc 100644
--- a/synth.py
+++ b/synth.py
@@ -68,14 +68,13 @@
templated_files = common.py_library(
samples=False, # set to True only if there are samples
microgenerator=True,
+ cov_level=96
)
s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good .coveragerc file
-# TODO(busunkim): Use latest sphinx after microgenerator transition
-s.replace("noxfile.py", """['"]sphinx['"]""", '"sphinx<3.0.0"')
# Temporarily disable warnings due to
# https://github.com/googleapis/gapic-generator-python/issues/525
s.replace("noxfile.py", '[\"\']-W[\"\']', '# "-W"')
-s.shell.run(["nox", "-s", "blacken"], hide_output=False)
\ No newline at end of file
+s.shell.run(["nox", "-s", "blacken"], hide_output=False)
diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt
index 6cc7211..2a5b1cb 100644
--- a/testing/constraints-3.6.txt
+++ b/testing/constraints-3.6.txt
@@ -5,6 +5,6 @@
#
# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
# Then this file should have foo==1.14.0
-google-api-core==1.22.0
+google-api-core==1.22.2
proto-plus==0.4.0
-libcst==0.2.5
\ No newline at end of file
+libcst==0.2.5
diff --git a/tests/unit/gapic/dashboard_v1/__init__.py b/tests/unit/gapic/dashboard_v1/__init__.py
index 8b13789..42ffdf2 100644
--- a/tests/unit/gapic/dashboard_v1/__init__.py
+++ b/tests/unit/gapic/dashboard_v1/__init__.py
@@ -1 +1,16 @@
+# -*- coding: utf-8 -*-
+# 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.
+#
diff --git a/tests/unit/gapic/dashboard_v1/test_dashboards_service.py b/tests/unit/gapic/dashboard_v1/test_dashboards_service.py
index bfa1bda..7b1fb14 100644
--- a/tests/unit/gapic/dashboard_v1/test_dashboards_service.py
+++ b/tests/unit/gapic/dashboard_v1/test_dashboards_service.py
@@ -99,7 +99,24 @@ def test__get_default_mtls_endpoint():
@pytest.mark.parametrize(
- "client_class", [DashboardsServiceClient, DashboardsServiceAsyncClient]
+ "client_class", [DashboardsServiceClient, DashboardsServiceAsyncClient,]
+)
+def test_dashboards_service_client_from_service_account_info(client_class):
+ creds = credentials.AnonymousCredentials()
+ with mock.patch.object(
+ service_account.Credentials, "from_service_account_info"
+ ) as factory:
+ factory.return_value = creds
+ info = {"valid": True}
+ client = client_class.from_service_account_info(info)
+ assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
+
+ assert client.transport._host == "monitoring.googleapis.com:443"
+
+
+@pytest.mark.parametrize(
+ "client_class", [DashboardsServiceClient, DashboardsServiceAsyncClient,]
)
def test_dashboards_service_client_from_service_account_file(client_class):
creds = credentials.AnonymousCredentials()
@@ -109,16 +126,21 @@ def test_dashboards_service_client_from_service_account_file(client_class):
factory.return_value = creds
client = client_class.from_service_account_file("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
client = client_class.from_service_account_json("dummy/file/path.json")
assert client.transport._credentials == creds
+ assert isinstance(client, client_class)
assert client.transport._host == "monitoring.googleapis.com:443"
def test_dashboards_service_client_get_transport_class():
transport = DashboardsServiceClient.get_transport_class()
- assert transport == transports.DashboardsServiceGrpcTransport
+ available_transports = [
+ transports.DashboardsServiceGrpcTransport,
+ ]
+ assert transport in available_transports
transport = DashboardsServiceClient.get_transport_class("grpc")
assert transport == transports.DashboardsServiceGrpcTransport
@@ -169,7 +191,7 @@ def test_dashboards_service_client_client_options(
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -185,7 +207,7 @@ def test_dashboards_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -201,7 +223,7 @@ def test_dashboards_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_MTLS_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -229,7 +251,7 @@ def test_dashboards_service_client_client_options(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id="octopus",
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -290,29 +312,25 @@ def test_dashboards_service_client_mtls_env_auto(
client_cert_source=client_cert_source_callback
)
with mock.patch.object(transport_class, "__init__") as patched:
- ssl_channel_creds = mock.Mock()
- with mock.patch(
- "grpc.ssl_channel_credentials", return_value=ssl_channel_creds
- ):
- patched.return_value = None
- client = client_class(client_options=options)
+ patched.return_value = None
+ client = client_class(client_options=options)
- if use_client_cert_env == "false":
- expected_ssl_channel_creds = None
- expected_host = client.DEFAULT_ENDPOINT
- else:
- expected_ssl_channel_creds = ssl_channel_creds
- expected_host = client.DEFAULT_MTLS_ENDPOINT
+ if use_client_cert_env == "false":
+ expected_client_cert_source = None
+ expected_host = client.DEFAULT_ENDPOINT
+ else:
+ expected_client_cert_source = client_cert_source_callback
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=expected_host,
+ scopes=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
# Check the case ADC client cert is provided. Whether client cert is used depends on
# GOOGLE_API_USE_CLIENT_CERTIFICATE value.
@@ -321,66 +339,53 @@ def test_dashboards_service_client_mtls_env_auto(
):
with mock.patch.object(transport_class, "__init__") as patched:
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=True,
):
with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.ssl_credentials",
- new_callable=mock.PropertyMock,
- ) as ssl_credentials_mock:
- if use_client_cert_env == "false":
- is_mtls_mock.return_value = False
- ssl_credentials_mock.return_value = None
- expected_host = client.DEFAULT_ENDPOINT
- expected_ssl_channel_creds = None
- else:
- is_mtls_mock.return_value = True
- ssl_credentials_mock.return_value = mock.Mock()
- expected_host = client.DEFAULT_MTLS_ENDPOINT
- expected_ssl_channel_creds = (
- ssl_credentials_mock.return_value
- )
-
- patched.return_value = None
- client = client_class()
- patched.assert_called_once_with(
- credentials=None,
- credentials_file=None,
- host=expected_host,
- scopes=None,
- ssl_channel_credentials=expected_ssl_channel_creds,
- quota_project_id=None,
- client_info=transports.base.DEFAULT_CLIENT_INFO,
- )
+ "google.auth.transport.mtls.default_client_cert_source",
+ return_value=client_cert_source_callback,
+ ):
+ if use_client_cert_env == "false":
+ expected_host = client.DEFAULT_ENDPOINT
+ expected_client_cert_source = None
+ else:
+ expected_host = client.DEFAULT_MTLS_ENDPOINT
+ expected_client_cert_source = client_cert_source_callback
- # Check the case client_cert_source and ADC client cert are not provided.
- with mock.patch.dict(
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
- ):
- with mock.patch.object(transport_class, "__init__") as patched:
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.__init__", return_value=None
- ):
- with mock.patch(
- "google.auth.transport.grpc.SslCredentials.is_mtls",
- new_callable=mock.PropertyMock,
- ) as is_mtls_mock:
- is_mtls_mock.return_value = False
patched.return_value = None
client = client_class()
patched.assert_called_once_with(
credentials=None,
credentials_file=None,
- host=client.DEFAULT_ENDPOINT,
+ host=expected_host,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=expected_client_cert_source,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
+ # Check the case client_cert_source and ADC client cert are not provided.
+ with mock.patch.dict(
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": use_client_cert_env}
+ ):
+ with mock.patch.object(transport_class, "__init__") as patched:
+ with mock.patch(
+ "google.auth.transport.mtls.has_default_client_cert_source",
+ return_value=False,
+ ):
+ patched.return_value = None
+ client = client_class()
+ patched.assert_called_once_with(
+ credentials=None,
+ credentials_file=None,
+ host=client.DEFAULT_ENDPOINT,
+ scopes=None,
+ client_cert_source_for_mtls=None,
+ quota_project_id=None,
+ client_info=transports.base.DEFAULT_CLIENT_INFO,
+ )
+
@pytest.mark.parametrize(
"client_class,transport_class,transport_name",
@@ -406,7 +411,7 @@ def test_dashboards_service_client_client_options_scopes(
credentials_file=None,
host=client.DEFAULT_ENDPOINT,
scopes=["1", "2"],
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -436,7 +441,7 @@ def test_dashboards_service_client_client_options_credentials_file(
credentials_file="credentials.json",
host=client.DEFAULT_ENDPOINT,
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -455,7 +460,7 @@ def test_dashboards_service_client_client_options_from_dict():
credentials_file=None,
host="squid.clam.whelk",
scopes=None,
- ssl_channel_credentials=None,
+ client_cert_source_for_mtls=None,
quota_project_id=None,
client_info=transports.base.DEFAULT_CLIENT_INFO,
)
@@ -505,6 +510,22 @@ def test_create_dashboard_from_dict():
test_create_dashboard(request_type=dict)
+def test_create_dashboard_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = DashboardsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.create_dashboard), "__call__") as call:
+ client.create_dashboard()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == dashboards_service.CreateDashboardRequest()
+
+
@pytest.mark.asyncio
async def test_create_dashboard_async(
transport: str = "grpc_asyncio",
@@ -638,6 +659,22 @@ def test_list_dashboards_from_dict():
test_list_dashboards(request_type=dict)
+def test_list_dashboards_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = DashboardsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.list_dashboards), "__call__") as call:
+ client.list_dashboards()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == dashboards_service.ListDashboardsRequest()
+
+
@pytest.mark.asyncio
async def test_list_dashboards_async(
transport: str = "grpc_asyncio",
@@ -922,6 +959,22 @@ def test_get_dashboard_from_dict():
test_get_dashboard(request_type=dict)
+def test_get_dashboard_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = DashboardsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.get_dashboard), "__call__") as call:
+ client.get_dashboard()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == dashboards_service.GetDashboardRequest()
+
+
@pytest.mark.asyncio
async def test_get_dashboard_async(
transport: str = "grpc_asyncio", request_type=dashboards_service.GetDashboardRequest
@@ -1049,6 +1102,22 @@ def test_delete_dashboard_from_dict():
test_delete_dashboard(request_type=dict)
+def test_delete_dashboard_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = DashboardsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.delete_dashboard), "__call__") as call:
+ client.delete_dashboard()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == dashboards_service.DeleteDashboardRequest()
+
+
@pytest.mark.asyncio
async def test_delete_dashboard_async(
transport: str = "grpc_asyncio",
@@ -1179,6 +1248,22 @@ def test_update_dashboard_from_dict():
test_update_dashboard(request_type=dict)
+def test_update_dashboard_empty_call():
+ # This test is a coverage failsafe to make sure that totally empty calls,
+ # i.e. request == None and no flattened fields passed, work.
+ client = DashboardsServiceClient(
+ credentials=credentials.AnonymousCredentials(), transport="grpc",
+ )
+
+ # Mock the actual call within the gRPC stub, and fake the request.
+ with mock.patch.object(type(client.transport.update_dashboard), "__call__") as call:
+ client.update_dashboard()
+ call.assert_called()
+ _, args, _ = call.mock_calls[0]
+
+ assert args[0] == dashboards_service.UpdateDashboardRequest()
+
+
@pytest.mark.asyncio
async def test_update_dashboard_async(
transport: str = "grpc_asyncio",
@@ -1457,6 +1542,56 @@ def test_dashboards_service_transport_auth_adc():
)
+@pytest.mark.parametrize(
+ "transport_class",
+ [
+ transports.DashboardsServiceGrpcTransport,
+ transports.DashboardsServiceGrpcAsyncIOTransport,
+ ],
+)
+def test_dashboards_service_grpc_transport_client_cert_source_for_mtls(transport_class):
+ cred = credentials.AnonymousCredentials()
+
+ # Check ssl_channel_credentials is used if provided.
+ with mock.patch.object(transport_class, "create_channel") as mock_create_channel:
+ mock_ssl_channel_creds = mock.Mock()
+ transport_class(
+ host="squid.clam.whelk",
+ credentials=cred,
+ ssl_channel_credentials=mock_ssl_channel_creds,
+ )
+ mock_create_channel.assert_called_once_with(
+ "squid.clam.whelk:443",
+ credentials=cred,
+ credentials_file=None,
+ scopes=(
+ "https://www.googleapis.com/auth/cloud-platform",
+ "https://www.googleapis.com/auth/monitoring",
+ "https://www.googleapis.com/auth/monitoring.read",
+ "https://www.googleapis.com/auth/monitoring.write",
+ ),
+ ssl_credentials=mock_ssl_channel_creds,
+ quota_project_id=None,
+ options=[
+ ("grpc.max_send_message_length", -1),
+ ("grpc.max_receive_message_length", -1),
+ ],
+ )
+
+ # Check if ssl_channel_credentials is not provided, then client_cert_source_for_mtls
+ # is used.
+ with mock.patch.object(transport_class, "create_channel", return_value=mock.Mock()):
+ with mock.patch("grpc.ssl_channel_credentials") as mock_ssl_cred:
+ transport_class(
+ credentials=cred,
+ client_cert_source_for_mtls=client_cert_source_callback,
+ )
+ expected_cert, expected_key = client_cert_source_callback()
+ mock_ssl_cred.assert_called_once_with(
+ certificate_chain=expected_cert, private_key=expected_key
+ )
+
+
def test_dashboards_service_host_no_port():
client = DashboardsServiceClient(
credentials=credentials.AnonymousCredentials(),
@@ -1478,7 +1613,7 @@ def test_dashboards_service_host_with_port():
def test_dashboards_service_grpc_transport_channel():
- channel = grpc.insecure_channel("http://localhost/")
+ channel = grpc.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.DashboardsServiceGrpcTransport(
@@ -1490,7 +1625,7 @@ def test_dashboards_service_grpc_transport_channel():
def test_dashboards_service_grpc_asyncio_transport_channel():
- channel = aio.insecure_channel("http://localhost/")
+ channel = aio.secure_channel("http://localhost/", grpc.local_channel_credentials())
# Check that channel is used if provided.
transport = transports.DashboardsServiceGrpcAsyncIOTransport(
@@ -1501,6 +1636,8 @@ def test_dashboards_service_grpc_asyncio_transport_channel():
assert transport._ssl_channel_credentials == None
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[
@@ -1515,7 +1652,7 @@ def test_dashboards_service_transport_channel_mtls_with_client_cert_source(
"grpc.ssl_channel_credentials", autospec=True
) as grpc_ssl_channel_cred:
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_ssl_cred = mock.Mock()
grpc_ssl_channel_cred.return_value = mock_ssl_cred
@@ -1558,6 +1695,8 @@ def test_dashboards_service_transport_channel_mtls_with_client_cert_source(
assert transport._ssl_channel_credentials == mock_ssl_cred
+# Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
+# removed from grpc/grpc_asyncio transport constructor.
@pytest.mark.parametrize(
"transport_class",
[
@@ -1573,7 +1712,7 @@ def test_dashboards_service_transport_channel_mtls_with_adc(transport_class):
ssl_credentials=mock.PropertyMock(return_value=mock_ssl_cred),
):
with mock.patch.object(
- transport_class, "create_channel", autospec=True
+ transport_class, "create_channel"
) as grpc_create_channel:
mock_grpc_channel = mock.Mock()
grpc_create_channel.return_value = mock_grpc_channel