From f7bca562ad2c66b0007e11c9fca0a7476143b758 Mon Sep 17 00:00:00 2001 From: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Date: Mon, 28 Sep 2020 15:52:17 -0700 Subject: [PATCH] move monitoring samples from python-docs-samples (#51) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Monitoring v3 Samples Refactor v2 samples in to separate directory Add v3 Samples Renamed auth to list_env * Update requirements * Fix metric.name All the filters should be metric.type (API change, name is now the fully qualified REST resource). * Monitoring Doc Fixups * Use Main Project (now whitelisted) * Fix minor typo in custom_metric.py * Mark Monitoring As Flaky * Updating requirements. Change-Id: I95c7ddfe77430a2800d09e329f23ba8b2b939be2 * Don’t send name in create custom metric * updating requirements [(#358)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/358) Change-Id: I6177a17fad021e26ed76679d9db34848c17b62a8 * Update Reqs * Fix flaky custom metric test. Change-Id: Ia2628f205537099d28415412fe302763f17c3081 * Update requirements. [(#436)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/436) * Remove output only fields [(#454)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/454) * Auto-update dependencies. [(#459)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/459) * Fix import order lint errors Change-Id: Ieaf7237fc6f925daec46a07d2e81a452b841198a * bump Change-Id: I02e7767d13ba267ee9fc72c5b68a57013bb8b8d3 * Auto-update dependencies. [(#470)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/470) * Auto-update dependencies. [(#476)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/476) * Auto-update dependencies. [(#486)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/486) * Stackdriver product rename [(#508)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/508) * Auto-update dependencies. [(#537)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/537) * Fix lint issues Change-Id: I0af78055cf33393a737f44acea2ba14555f494e1 * Fix monitoring test Change-Id: I31c4dc368617996bc5b95c1414a39b9d45e11ebe * Auto-update dependencies. [(#584)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/584) * Generate readmes for most service samples [(#599)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/599) * Auto-update dependencies. [(#609)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/609) * Auto-update dependencies. [(#625)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/625) * Auto-update dependencies. [(#629)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/629) * Auto-update dependencies. [(#735)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/735) * Auto-update dependencies. * Fix language OCR sample * Remove unused import * Add region tags for writing time series [(#757)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/757) * Auto-update dependencies. [(#762)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/762) * Cleanup metric descriptors [(#776)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/776) * Auto-update dependencies. [(#783)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/783) * Auto-update dependencies. [(#785)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/785) * Auto-update dependencies. [(#790)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/790) * Add Monitoring Google Cloud Samples [(#789)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/789) * Add Monitoring Google Cloud Samples * jon wayne review * fixups * Fix tests * jonwayne * Auto-update dependencies. [(#794)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/794) * Monitoring Region Tags [(#796)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/796) * Add get metric descriptor [(#797)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/797) * Fix mon reginos [(#798)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/798) * Fix monitoring tests [(#799)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/799) * Fix monitoring tests * Fixing monitoring tests Change-Id: I9e5d2a1143381430cc790085f90e210f9495d630 * Remove usage of GoogleCredentials [(#810)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/810) * Update monitoring region tags [(#830)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/830) * Remove cloud config fixture [(#887)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/887) * Remove cloud config fixture * Fix client secrets * Fix bigtable instance * Remove resource [(#890)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/890) * Remove resource fixture * Remove remote resource * De-flake metric test * Fix lint issues * Fix reference to our testing tools * Auto-update dependencies. [(#914)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/914) * Auto-update dependencies. * xfail the error reporting test * Fix lint * Re-generate all readmes * Fix README rst links [(#962)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/962) * Fix README rst links * Update all READMEs * Auto-update dependencies. [(#1004)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1004) * Auto-update dependencies. * Fix natural language samples * Fix pubsub iam samples * Fix language samples * Fix bigquery samples * Auto-update dependencies. [(#1055)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1055) * Auto-update dependencies. * Explicitly use latest bigtable client Change-Id: Id71e9e768f020730e4ca9514a0d7ebaa794e7d9e * Revert language update for now Change-Id: I8867f154e9a5aae00d0047c9caf880e5e8f50c53 * Remove pdb. smh Change-Id: I5ff905fadc026eebbcd45512d4e76e003e3b2b43 * Update monitoring samples to use more descriptive variable names [(#1058)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1058) Change-Id: I648cd686a10399b7f92373fdcd48708396fd7140 * Auto-update dependencies. [(#1093)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1093) * Auto-update dependencies. * Fix storage notification poll sample Change-Id: I6afbc79d15e050531555e4c8e51066996717a0f3 * Fix spanner samples Change-Id: I40069222c60d57e8f3d3878167591af9130895cb * Drop coverage because it's not useful Change-Id: Iae399a7083d7866c3c7b9162d0de244fbff8b522 * Try again to fix flaky logging test Change-Id: I6225c074701970c17c426677ef1935bb6d7e36b4 * Auto-update dependencies. [(#1094)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1094) * Auto-update dependencies. * Relax assertions in the ocr_nl sample Change-Id: I6d37e5846a8d6dd52429cb30d501f448c52cbba1 * Drop unused logging apiary samples Change-Id: I545718283773cb729a5e0def8a76ebfa40829d51 * Update all generated readme auth instructions [(#1121)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1121) Change-Id: I03b5eaef8b17ac3dc3c0339fd2c7447bd3e11bd2 * Auto-update dependencies. [(#1133)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1133) * Auto-update dependencies. * Fix missing http library Change-Id: I99faa600f2f3f1f50f57694fc9835d7f35bda250 * Added Link to Python Setup Guide [(#1158)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1158) * Update Readme.rst to add Python setup guide As requested in b/64770713. This sample is linked in documentation https://cloud.google.com/bigtable/docs/scaling, and it would make more sense to update the guide here than in the documentation. * Update README.rst * Update README.rst * Update README.rst * Update README.rst * Update README.rst * Update install_deps.tmpl.rst * Updated readmegen scripts and re-generated related README files * Fixed the lint error * Auto-update dependencies. [(#1186)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1186) * Auto-update dependencies. [(#1217)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1217) * Added "Open in Cloud Shell" buttons to README files [(#1254)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1254) * Auto-update dependencies. [(#1309)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1309) * Auto-update dependencies. [(#1320)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1320) * Auto-update dependencies. [(#1355)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1355) * Auto-update dependencies. [(#1359)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1359) * Auto-update dependencies. [(#1377)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1377) * Auto-update dependencies. * Update requirements.txt * Fix client instantiation [(#1396)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1396) * Auto-update dependencies. * Regenerate the README files and fix the Open in Cloud Shell link for some samples [(#1441)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1441) * Update READMEs to fix numbering and add git clone [(#1464)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1464) * Fix monitoring region tags. [(#1472)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1472) * Sample's for stackdriver's uptime check api. [(#1478)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1478) * Sample's for stackdriver's uptime check api. * Add doc tags. * Stackdriver monitoring alerts sample. [(#1475)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1475) * Stackdriver monitoring alerts sample. * Lint * py27 tests pass * Accomodate reviewer's comments. * Add spaces around code blocks, Inc => LLC, and add docstring. * Reformat doc comments to look like Google doc comments. * Add more doc tags to alerts sample. [(#1483)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1483) * Add more doc tags to alerts sample. * lint * Update monitoring samples to use version 0.29.0 of the client library. [(#1495)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1495) * Update monitoring samples to use version 0.29.0 of the client library. * Fix typo. * Add sample to update a cloud monitoring uptime check. [(#1508)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1508) * Add sample to update a cloud monitoring uptime check. * Replace double quotes with single quotes. * Auto-update dependencies. [(#1658)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1658) * Auto-update dependencies. * Rollback appengine/standard/bigquery/. * Rollback appengine/standard/iap/. * Rollback bigtable/metricscaler. * Rolledback appengine/flexible/datastore. * Rollback dataproc/ * Rollback jobs/api_client * Rollback vision/cloud-client. * Rollback functions/ocr/app. * Rollback iot/api-client/end_to_end_example. * Rollback storage/cloud-client. * Rollback kms/api-client. * Rollback dlp/ * Rollback bigquery/cloud-client. * Rollback iot/api-client/manager. * Rollback appengine/flexible/cloudsql_postgresql. * Time series tests use random unique name to avoid limits [(#1776)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1776) * Time series tests use random unique name to avoid limits * Lint wants another blank line here * Use current debian image family * Restore to old state. Work should be on different branch. * Update snippets.py * Added new region tag [(#1844)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1844) * Auto-update dependencies. [(#1846)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1846) ACK, merging. * New snippet to delete notification channel [(#1920)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1920) New snippet to delete notification channel * Auto-update dependencies. [(#1980)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/1980) * Auto-update dependencies. * Update requirements.txt * Update requirements.txt * monitoring/metrics: update from 5 to 20 minutes [(#2210)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2210) * Make backup/restore file name a parameter [(#2248)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2248) * Make backup/restore file a parameter Previously was hard coded as 'backup.json' * Added parameter to test function calls * Adds split updates for Firebase ... opencensus [(#2438)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2438) * Auto-update dependencies. [(#2005)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2005) * Auto-update dependencies. * Revert update of appengine/flexible/datastore. * revert update of appengine/flexible/scipy * revert update of bigquery/bqml * revert update of bigquery/cloud-client * revert update of bigquery/datalab-migration * revert update of bigtable/quickstart * revert update of compute/api * revert update of container_registry/container_analysis * revert update of dataflow/run_template * revert update of datastore/cloud-ndb * revert update of dialogflow/cloud-client * revert update of dlp * revert update of functions/imagemagick * revert update of functions/ocr/app * revert update of healthcare/api-client/fhir * revert update of iam/api-client * revert update of iot/api-client/gcs_file_to_device * revert update of iot/api-client/mqtt_example * revert update of language/automl * revert update of run/image-processing * revert update of vision/automl * revert update testing/requirements.txt * revert update of vision/cloud-client/detect * revert update of vision/cloud-client/product_search * revert update of jobs/v2/api_client * revert update of jobs/v3/api_client * revert update of opencensus * revert update of translate/cloud-client * revert update to speech/cloud-client Co-authored-by: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Co-authored-by: Doug Mahugh * fix: monitoring tests [(#2995)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2995) * fix: monitoring tests * Add eventually consistent to flaky test * chore(deps): update dependency google-auth to v1.11.2 [(#2724)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2724) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> * Simplify noxfile setup. [(#2806)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/2806) * chore(deps): update dependency requests to v2.23.0 * Simplify noxfile and add version control. * Configure appengine/standard to only test Python 2.7. * Update Kokokro configs to match noxfile. * Add requirements-test to each folder. * Remove Py2 versions from everything execept appengine/standard. * Remove conftest.py. * Remove appengine/standard/conftest.py * Remove 'no-sucess-flaky-report' from pytest.ini. * Add GAE SDK back to appengine/standard tests. * Fix typo. * Roll pytest to python 2 version. * Add a bunch of testing requirements. * Remove typo. * Add appengine lib directory back in. * Add some additional requirements. * Fix issue with flake8 args. * Even more requirements. * Readd appengine conftest.py. * Add a few more requirements. * Even more Appengine requirements. * Add webtest for appengine/standard/mailgun. * Add some additional requirements. * Add workaround for issue with mailjet-rest. * Add responses for appengine/standard/mailjet. Co-authored-by: Renovate Bot * [monitoring] fix: use retrying module in the fixture class [(#3285)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3285) * fix: use retrying module in the fixture class fixes #2971 fixes #2972 fixes #2973 fixes #3085 It will likely fix those issues, not guaranteed, but it's worth a try. * [monitoring] testing: mitigate 409 conflicts [(#3311)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3311) * [monitoring] testing: mitigate 409 conflicts fixes #2971 * retry on ServiceUnavailable too * reduce the number of api calls * mark tests as flaky instead of having retries * fix the rerun_filter implementation * add randomness to the sleep calls * lonter wait, better teardown * allow both messages * switch to regular flaky in monitoring [(#3333)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3333) * switch to regular flaky * minor assertion adjustment * address nit * Update dependency tabulate to v0.8.7 [(#3202)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3202) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> The error is a known error that does not have to do with this dependency change * Update dependency google-auth to v1.14.0 [(#3148)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3148) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> * chore(deps): update dependency google-api-python-client to v1.8.0 [(#3100)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3100) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-api-python-client](https://togithub.com/google/google-api-python-client) | minor | `==1.7.11` -> `==1.8.0` | --- ### Release Notes
google/google-api-python-client ### [`v1.8.0`](https://togithub.com/google/google-api-python-client/releases/v1.8.0) [Compare Source](https://togithub.com/google/google-api-python-client/compare/v1.7.12...v1.8.0) Release to support API endpoint override. New Features - Add api endpoint override. ([#​829](https://togithub.com/googleapis/google-api-python-client/pull/829)) Implementation Changes - Don't set http.redirect_codes if the attr doesn't exist and allow more httplib2 versions. ([#​841](https://togithub.com/googleapis/google-api-python-client/pull/841)) ### [`v1.7.12`](https://togithub.com/google/google-api-python-client/releases/v1.7.12) [Compare Source](https://togithub.com/google/google-api-python-client/compare/v1.7.11...v1.7.12) Bugfix release Implementation Changes - Look for field 'detail' in error message. ([#​739](https://togithub.com/googleapis/google-api-python-client/pull/739)) - Exclude 308s from httplib2 redirect codes list ([#​813](https://togithub.com/googleapis/google-api-python-client/pull/813)) Documentation - Remove oauth2client from docs ([#​738](https://togithub.com/googleapis/google-api-python-client/pull/738)) - Fix typo. ([#​745](https://togithub.com/googleapis/google-api-python-client/pull/745)) - Remove compatibility badges. ([#​746](https://togithub.com/googleapis/google-api-python-client/pull/746)) - Fix TypeError: search_analytics_api_sample.py [#​732](https://togithub.com/google/google-api-python-client/issues/732) ([#​742](https://togithub.com/googleapis/google-api-python-client/pull/742)) - Correct response access ([#​750](https://togithub.com/googleapis/google-api-python-client/pull/750)) - Fix link to API explorer ([#​760](https://togithub.com/googleapis/google-api-python-client/pull/760)) - Fix argument typo in oauth2 code example ([#​763](https://togithub.com/googleapis/google-api-python-client/pull/763)) - Recommend install with virtualenv ([#​768](https://togithub.com/googleapis/google-api-python-client/pull/768)) - Fix capitalization in docs/README.md ([#​770](https://togithub.com/googleapis/google-api-python-client/pull/770)) - Remove compatibility badges ([#​796](https://togithub.com/googleapis/google-api-python-client/pull/796)) - Remove mentions of pycrypto ([#​799](https://togithub.com/googleapis/google-api-python-client/pull/799)) - Fix typo in model.py - Add note about Google Ads llibrary ([#​814](https://togithub.com/googleapis/google-api-python-client/pull/814)) Internal / Testing Changes - Blacken ([#​772](https://togithub.com/googleapis/google-api-python-client/pull/722)) - Move kokoro configs ([#​832](https://togithub.com/googleapis/google-api-python-client/pull/832))
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * chore(deps): update dependency google-cloud-monitoring to v0.35.0 [(#3459)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3459) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> * [monitoring] chore: remove gcp-devrel-py-tools [(#3480)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3480) * [monitoring] chore: remove gcp-devrel-py-tools * fixed the infinite loop * fix 404 error * Update dependency google-api-python-client to v1.8.2 [(#3452)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3452) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-api-python-client](https://togithub.com/google/google-api-python-client) | patch | `==1.8.0` -> `==1.8.2` | | [google-api-python-client](https://togithub.com/google/google-api-python-client) | minor | `==1.7.11` -> `==1.8.2` | --- ### Release Notes
google/google-api-python-client ### [`v1.8.2`](https://togithub.com/google/google-api-python-client/blob/master/CHANGELOG.md#​182-httpswwwgithubcomgoogleapisgoogle-api-python-clientcomparev181v182-2020-04-21) [Compare Source](https://togithub.com/google/google-api-python-client/compare/v1.8.1...v1.8.2) ### [`v1.8.1`](https://togithub.com/google/google-api-python-client/blob/master/CHANGELOG.md#​181-httpswwwgithubcomgoogleapisgoogle-api-python-clientcomparev180v181-2020-04-20) [Compare Source](https://togithub.com/google/google-api-python-client/compare/v1.8.0...v1.8.1)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * testing: replace @flaky with @pytest.mark.flaky [(#3496)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3496) * testing: replace @flaky with @pytest.mark.flaky * lint * mark few tests as flaky that involves LRO polling. * lint * chore(deps): update dependency google-auth to v1.14.1 [(#3464)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3464) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-auth](https://togithub.com/googleapis/google-auth-library-python) | patch | `==1.14.0` -> `==1.14.1` | | [google-auth](https://togithub.com/googleapis/google-auth-library-python) | minor | `==1.11.2` -> `==1.14.1` | --- ### Release Notes
googleapis/google-auth-library-python ### [`v1.14.1`](https://togithub.com/googleapis/google-auth-library-python/blob/master/CHANGELOG.md#​1141-httpswwwgithubcomgoogleapisgoogle-auth-library-pythoncomparev1140v1141-2020-04-21) [Compare Source](https://togithub.com/googleapis/google-auth-library-python/compare/v1.14.0...v1.14.1)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * [monitoring] fix: use backoff for writing the value [(#3697)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3697) * [monitoring] fix: use backoff for writing the value fixes #3694 * use uuid * chore(deps): update dependency google-auth to v1.14.2 [(#3724)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3724) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-auth](https://togithub.com/googleapis/google-auth-library-python) | patch | `==1.14.1` -> `==1.14.2` | --- ### Release Notes
googleapis/google-auth-library-python ### [`v1.14.2`](https://togithub.com/googleapis/google-auth-library-python/blob/master/CHANGELOG.md#​1142-httpswwwgithubcomgoogleapisgoogle-auth-library-pythoncomparev1141v1142-2020-05-07) [Compare Source](https://togithub.com/googleapis/google-auth-library-python/compare/v1.14.1...v1.14.2)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * chore: some lint fixes [(#3748)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3748) * chore(deps): update dependency google-auth to v1.14.3 [(#3728)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3728) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-auth](https://togithub.com/googleapis/google-auth-library-python) | patch | `==1.14.2` -> `==1.14.3` | --- ### Release Notes
googleapis/google-auth-library-python ### [`v1.14.3`](https://togithub.com/googleapis/google-auth-library-python/blob/master/CHANGELOG.md#​1143-httpswwwgithubcomgoogleapisgoogle-auth-library-pythoncomparev1142v1143-2020-05-11) [Compare Source](https://togithub.com/googleapis/google-auth-library-python/compare/v1.14.2...v1.14.3)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [x] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * Add request_method to create example. [(#3745)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3745) Co-authored-by: Takashi Matsuo * testing: multi project noxfile-template.py [(#3700)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3700) * testing: prototpe for multi project noxfile.py * correct project names * introduce TEST_CONFIG * modify noxfile-template, add default config * changed how we import user config * fix stale comments * use different project for python 3.6 and 3.7 * fix a bug * changed the filename also simplified the config stop runnint `gcloud update` add a warning about editing noxfile.py * add BUILD_SPECIFIC_GCLOUD_PROJECT * use session.skip * print debuggin * more print debuggin * adding cwd to sys.path * removed debug print, display details of ImportError * use the usual test project * stop setting gcloud project * simplified the noxfile-template * [monitoring] testing: start using build specific projects [(#3771)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3771) Also added `required_api_url` and `required_role` field in `README.rst.in`. A part of #3310 Note: Now the service account has permission only on the project for py36 build, so py37 build should fail. * chore(deps): update dependency google-cloud-monitoring to v0.36.0 [(#3783)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3783) Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> * update google-auth to 1.15.0 final part [(#3819)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3819) * update google-api-python-client to 1.8.3 final part [(#3827)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3827) * chore(deps): update dependency google-api-python-client to v1.8.4 [(#3881)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3881) Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Co-authored-by: gcf-merge-on-green[bot] <60162190+gcf-merge-on-green[bot]@users.noreply.github.com> * [monitoring] fix: use the same random value for retry [(#3900)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3900) * [monitoring] fix: use the same random value for retry fixes #3875 * Just reseed in `write_value()` * revert comment * chore(deps): update dependency google-auth to v1.16.0 [(#3903)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3903) * chore(deps): update dependency google-api-python-client to v1.9.1 [(#3930)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3930) * chore(deps): update dependency google-cloud-monitoring to v1 [(#3950)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3950) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-cloud-monitoring](https://togithub.com/googleapis/python-monitoring) | major | `==0.36.0` -> `==1.0.0` | --- ### Release Notes
googleapis/python-monitoring ### [`v1.0.0`](https://togithub.com/googleapis/python-monitoring/blob/master/CHANGELOG.md#​100-httpswwwgithubcomgoogleapispython-monitoringcomparev0360v100-2020-06-03) [Compare Source](https://togithub.com/googleapis/python-monitoring/compare/v0.36.0...v1.0.0) ##### Features - set release_status to Production/Stable ([#​8](https://www.github.com/googleapis/python-monitoring/issues/8)) ([a99d67a](https://www.github.com/googleapis/python-monitoring/commit/a99d67a4f1399b9a74f189c6332cd85e56149fac))
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * final update for google-auth [(#3967)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3967) * testing: start using btlr [(#3959)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/3959) * testing: start using btlr The binary is at gs://cloud-devrel-kokoro-resources/btlr/v0.0.1/btlr * add period after DIFF_FROM * use array for btlr args * fix websocket tests * add debug message * wait longer for the server to spin up * dlp: bump the wait timeout to 10 minutes * [run] copy noxfile.py to child directory to avoid gcloud issue * [iam] fix: only display description when the key exists * use uuid4 instead of uuid1 * [iot] testing: use the same format for registry id * Stop asserting Out of memory not in the output * fix missing imports * [dns] testing: more retries with delay * [dlp] testing: longer timeout * use the max-concurrency flag * use 30 workers * [monitoring] use multiple projects * [dlp] testing: longer timeout * Replace GCLOUD_PROJECT with GOOGLE_CLOUD_PROJECT. [(#4022)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4022) * Update dependency google-api-python-client to v1.9.2 [(#4038)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4038) * Update dependency google-auth to v1.17.0 [(#4058)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4058) * chore(deps): update dependency google-auth to v1.17.1 [(#4073)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4073) * Update dependency google-auth to v1.17.2 [(#4083)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4083) * Update dependency google-api-python-client to v1.9.3 [(#4057)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4057) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-api-python-client](https://togithub.com/googleapis/google-api-python-client) | patch | `==1.9.2` -> `==1.9.3` | --- ### Release Notes
googleapis/google-api-python-client ### [`v1.9.3`](https://togithub.com/googleapis/google-api-python-client/blob/master/CHANGELOG.md#​193-httpswwwgithubcomgoogleapisgoogle-api-python-clientcomparev192v193-2020-06-10) [Compare Source](https://togithub.com/googleapis/google-api-python-client/compare/v1.9.2...v1.9.3)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * Update dependency google-auth to v1.18.0 [(#4125)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4125) * [monitoring] fix: mitigate flake [(#4153)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4153) fixes #4150 * fix(monitoring): also retry upon DeadlineExceeded [(#4202)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4202) fixes #4180 Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> * Create example for POST check. [(#4082)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4082) * Add create example for POST check. * Small fixes for POST check stuff. * Have create example be one tag block * Syntax fixes * Small fixes. * Ran black linter. Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> * Update dependency google-auth-httplib2 to v0.0.4 [(#4255)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4255) Co-authored-by: Takashi Matsuo * chore(deps): pin dependencies [(#4280)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4280) * chore(deps): pin dependencies * specify python version for appengine standard Co-authored-by: Leah Cole * chore(deps): update dependency pytest to v5.4.3 [(#4279)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4279) * chore(deps): update dependency pytest to v5.4.3 * specify pytest for python 2 in appengine Co-authored-by: Leah Cole * chore(deps): update dependency mock to v4 [(#4287)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4287) * chore(deps): update dependency mock to v4 * specify mock version for appengine python 2 Co-authored-by: Leah Cole * chore(deps): update dependency google-auth to v1.19.0 [(#4293)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4293) * Update dependency flaky to v3.7.0 [(#4300)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4300) * Update dependency google-api-python-client to v1.10.0 [(#4302)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4302) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-api-python-client](https://togithub.com/googleapis/google-api-python-client) | minor | `==1.9.3` -> `==1.10.0` | --- ### Release Notes
googleapis/google-api-python-client ### [`v1.10.0`](https://togithub.com/googleapis/google-api-python-client/blob/master/CHANGELOG.md#​1100-httpswwwgithubcomgoogleapisgoogle-api-python-clientcomparev193v1100-2020-07-15) [Compare Source](https://togithub.com/googleapis/google-api-python-client/compare/v1.9.3...v1.10.0) ##### Features - allow to use 'six.moves.collections_abc.Mapping' in 'client_options.from_dict()' ([#​943](https://www.github.com/googleapis/google-api-python-client/issues/943)) ([21af37b](https://www.github.com/googleapis/google-api-python-client/commit/21af37b11ea2d6a89b3df484e1b2fa1d12849510)) - Build universal wheels ([#​948](https://www.github.com/googleapis/google-api-python-client/issues/948)) ([3e28a1e](https://www.github.com/googleapis/google-api-python-client/commit/3e28a1e0d47f829182cd92f37475ab91fa5e4afc)) - discovery supports retries ([#​967](https://www.github.com/googleapis/google-api-python-client/issues/967)) ([f3348f9](https://www.github.com/googleapis/google-api-python-client/commit/f3348f98bf91a88a28bf61b12b95e391cc3be1ff)), closes [#​848](https://www.github.com/googleapis/google-api-python-client/issues/848) ##### Documentation - consolidating and updating the Contribution Guide ([#​964](https://www.github.com/googleapis/google-api-python-client/issues/964)) ([63f97f3](https://www.github.com/googleapis/google-api-python-client/commit/63f97f37daee37a725eb05df3097b20d5d4eaaf0)), closes [#​963](https://www.github.com/googleapis/google-api-python-client/issues/963) ##### [1.9.3](https://www.github.com/googleapis/google-api-python-client/compare/v1.9.2...v1.9.3) (2020-06-10) ##### Bug Fixes - update GOOGLE_API_USE_MTLS values ([#​940](https://www.github.com/googleapis/google-api-python-client/issues/940)) ([19908ed](https://www.github.com/googleapis/google-api-python-client/commit/19908edcd8a3df1db41e34100acc1f15c3c99397)) ##### [1.9.2](https://www.github.com/googleapis/google-api-python-client/compare/v1.9.1...v1.9.2) (2020-06-04) ##### Bug Fixes - bump api-core version ([#​936](https://www.github.com/googleapis/google-api-python-client/issues/936)) ([ee53b3b](https://www.github.com/googleapis/google-api-python-client/commit/ee53b3b32a050874ba4cfb491fb384f94682c824)) ##### [1.9.1](https://www.github.com/googleapis/google-api-python-client/compare/v1.9.0...v1.9.1) (2020-06-02) ##### Bug Fixes - fix python-api-core dependency issue ([#​931](https://www.github.com/googleapis/google-api-python-client/issues/931)) ([42028ed](https://www.github.com/googleapis/google-api-python-client/commit/42028ed2b2be47f85b70eb813185264f1f573d01))
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * chore(deps): update dependency google-auth to v1.19.1 [(#4304)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4304) * chore(deps): update dependency google-auth to v1.19.2 [(#4321)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4321) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [google-auth](https://togithub.com/googleapis/google-auth-library-python) | patch | `==1.19.1` -> `==1.19.2` | --- ### Release Notes
googleapis/google-auth-library-python ### [`v1.19.2`](https://togithub.com/googleapis/google-auth-library-python/blob/master/CHANGELOG.md#​1192-httpswwwgithubcomgoogleapisgoogle-auth-library-pythoncomparev1191v1192-2020-07-17) [Compare Source](https://togithub.com/googleapis/google-auth-library-python/compare/v1.19.1...v1.19.2)
--- ### Renovate configuration :date: **Schedule**: At any time (no schedule defined). :vertical_traffic_light: **Automerge**: Disabled by config. Please merge this manually once you are satisfied. :recycle: **Rebasing**: Never, or you tick the rebase/retry checkbox. :no_bell: **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [WhiteSource Renovate](https://renovate.whitesourcesoftware.com). View repository job log [here](https://app.renovatebot.com/dashboard#GoogleCloudPlatform/python-docs-samples). * Update dependency google-auth to v1.20.0 [(#4387)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4387) * Update dependency pytest to v6 [(#4390)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4390) * chore(deps): update dependency google-auth to v1.20.1 [(#4452)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4452) * chore(deps): update dependency google-api-python-client to v1.10.1 [(#4557)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4557) * chore(deps): update dependency google-api-python-client to v1.10.1 * Update requirements.txt Co-authored-by: Takashi Matsuo * chore(deps): update dependency google-cloud-monitoring to v1.1.0 [(#4561)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4561) * Update dependency google-auth to v1.21.0 [(#4588)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4588) * Update dependency google-api-python-client to v1.11.0 [(#4587)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4587) Co-authored-by: Takashi Matsuo * chore(deps): update dependency google-auth to v1.21.1 [(#4634)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4634) * chore(deps): update dependency google-auth to v1.21.2 [(#4684)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4684) * fix(monitoring): retry in the test setup [(#4702)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4702) fixes #4687 fixes #4688 fixes #4689 fixes #4690 * chore(deps): update dependency google-api-python-client to v1.12.1 [(#4674)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4674) * chore(deps): update dependency google-auth to v1.21.3 [(#4754)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4754) * chore(deps): update dependency google-api-python-client to v1.12.2 [(#4751)](https://github.com/GoogleCloudPlatform/python-docs-samples/issues/4751) * chore: update template * chore: add BUILD_SPECIFIC_GCLOUD_PROJECT env var Co-authored-by: Bill Prin Co-authored-by: Bill Prin Co-authored-by: Jon Wayne Parrott Co-authored-by: Greg Taylor Co-authored-by: Jon Wayne Parrott Co-authored-by: DPE bot Co-authored-by: Takashi Matsuo Co-authored-by: michaelawyu Co-authored-by: Campion Fellin Co-authored-by: Frank Natividad Co-authored-by: Jason Dobry Co-authored-by: Jeffrey Rennie Co-authored-by: michaelawyu Co-authored-by: Charles Engelke Co-authored-by: Adam Ross Co-authored-by: Charles Engelke Co-authored-by: Gus Class Co-authored-by: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Co-authored-by: Doug Mahugh Co-authored-by: Leah E. Cole <6719667+leahecole@users.noreply.github.com> Co-authored-by: Renovate Bot Co-authored-by: Shi Zhang Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Co-authored-by: gcf-merge-on-green[bot] <60162190+gcf-merge-on-green[bot]@users.noreply.github.com> Co-authored-by: Leah Cole --- monitoring/AUTHORING_GUIDE.md | 1 + monitoring/CONTRIBUTING.md | 1 + .../snippets/v3/alerts-client/.gitignore | 1 + .../snippets/v3/alerts-client/README.rst | 138 +++++++ .../snippets/v3/alerts-client/README.rst.in | 33 ++ .../snippets/v3/alerts-client/noxfile.py | 224 ++++++++++++ .../v3/alerts-client/noxfile_config.py | 42 +++ .../v3/alerts-client/requirements-test.txt | 3 + .../v3/alerts-client/requirements.txt | 2 + .../snippets/v3/alerts-client/snippets.py | 343 ++++++++++++++++++ .../v3/alerts-client/snippets_test.py | 195 ++++++++++ .../v3/alerts-client/test_alert_policy.json | 31 ++ .../test_notification_channel.json | 15 + .../snippets/v3/cloud-client/README.rst | 147 ++++++++ .../snippets/v3/cloud-client/README.rst.in | 35 ++ .../snippets/v3/cloud-client/noxfile.py | 224 ++++++++++++ .../v3/cloud-client/noxfile_config.py | 42 +++ .../snippets/v3/cloud-client/quickstart.py | 43 +++ .../v3/cloud-client/quickstart_test.py | 46 +++ .../v3/cloud-client/requirements-test.txt | 3 + .../snippets/v3/cloud-client/requirements.txt | 1 + .../snippets/v3/cloud-client/snippets.py | 310 ++++++++++++++++ .../snippets/v3/cloud-client/snippets_test.py | 117 ++++++ .../v3/uptime-check-client/README.rst | 115 ++++++ .../v3/uptime-check-client/README.rst.in | 26 ++ .../v3/uptime-check-client/noxfile.py | 224 ++++++++++++ .../uptime-check-client/requirements-test.txt | 2 + .../v3/uptime-check-client/requirements.txt | 2 + .../v3/uptime-check-client/snippets.py | 257 +++++++++++++ .../v3/uptime-check-client/snippets_test.py | 105 ++++++ 30 files changed, 2728 insertions(+) create mode 100644 monitoring/AUTHORING_GUIDE.md create mode 100644 monitoring/CONTRIBUTING.md create mode 100644 monitoring/snippets/v3/alerts-client/.gitignore create mode 100644 monitoring/snippets/v3/alerts-client/README.rst create mode 100644 monitoring/snippets/v3/alerts-client/README.rst.in create mode 100644 monitoring/snippets/v3/alerts-client/noxfile.py create mode 100644 monitoring/snippets/v3/alerts-client/noxfile_config.py create mode 100644 monitoring/snippets/v3/alerts-client/requirements-test.txt create mode 100644 monitoring/snippets/v3/alerts-client/requirements.txt create mode 100644 monitoring/snippets/v3/alerts-client/snippets.py create mode 100644 monitoring/snippets/v3/alerts-client/snippets_test.py create mode 100644 monitoring/snippets/v3/alerts-client/test_alert_policy.json create mode 100644 monitoring/snippets/v3/alerts-client/test_notification_channel.json create mode 100644 monitoring/snippets/v3/cloud-client/README.rst create mode 100644 monitoring/snippets/v3/cloud-client/README.rst.in create mode 100644 monitoring/snippets/v3/cloud-client/noxfile.py create mode 100644 monitoring/snippets/v3/cloud-client/noxfile_config.py create mode 100644 monitoring/snippets/v3/cloud-client/quickstart.py create mode 100644 monitoring/snippets/v3/cloud-client/quickstart_test.py create mode 100644 monitoring/snippets/v3/cloud-client/requirements-test.txt create mode 100644 monitoring/snippets/v3/cloud-client/requirements.txt create mode 100644 monitoring/snippets/v3/cloud-client/snippets.py create mode 100644 monitoring/snippets/v3/cloud-client/snippets_test.py create mode 100644 monitoring/snippets/v3/uptime-check-client/README.rst create mode 100644 monitoring/snippets/v3/uptime-check-client/README.rst.in create mode 100644 monitoring/snippets/v3/uptime-check-client/noxfile.py create mode 100644 monitoring/snippets/v3/uptime-check-client/requirements-test.txt create mode 100644 monitoring/snippets/v3/uptime-check-client/requirements.txt create mode 100644 monitoring/snippets/v3/uptime-check-client/snippets.py create mode 100644 monitoring/snippets/v3/uptime-check-client/snippets_test.py diff --git a/monitoring/AUTHORING_GUIDE.md b/monitoring/AUTHORING_GUIDE.md new file mode 100644 index 000000000000..55c97b32f4c1 --- /dev/null +++ b/monitoring/AUTHORING_GUIDE.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/AUTHORING_GUIDE.md \ No newline at end of file diff --git a/monitoring/CONTRIBUTING.md b/monitoring/CONTRIBUTING.md new file mode 100644 index 000000000000..34c882b6f1a3 --- /dev/null +++ b/monitoring/CONTRIBUTING.md @@ -0,0 +1 @@ +See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/CONTRIBUTING.md \ No newline at end of file diff --git a/monitoring/snippets/v3/alerts-client/.gitignore b/monitoring/snippets/v3/alerts-client/.gitignore new file mode 100644 index 000000000000..de0a466d79c3 --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/.gitignore @@ -0,0 +1 @@ +backup.json diff --git a/monitoring/snippets/v3/alerts-client/README.rst b/monitoring/snippets/v3/alerts-client/README.rst new file mode 100644 index 000000000000..bb59aad5feeb --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/README.rst @@ -0,0 +1,138 @@ +.. This file is automatically generated. Do not edit this file directly. + +Google Stackdriver Alerting API Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/alerts-client/README.rst + + +This directory contains samples for Google Stackdriver Alerting API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver's Alerting API allows you to create, delete, and make back up copies of your alert policies. + + + + +.. _Google Stackdriver Alerting API: https://cloud.google.com/monitoring/alerts/ + +To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/monitoring.googleapis.com + +To run the sample, you need to have `Monitoring Admin` role. + +Please visit [the Cloud Console UI of this API](https://console.cloud.google.com/monitoring) and [create a new Workspace with the same name of your Cloud project](https://cloud.google.com/monitoring/workspaces/create). + + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +Snippets ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/alerts-client/snippets.py,monitoring/api/v3/alerts-client/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python snippets.py + + usage: snippets.py [-h] + {list-alert-policies,list-notification-channels,enable-alert-policies,disable-alert-policies,replace-notification-channels,backup,restore} + ... + + Demonstrates AlertPolicy API operations. + + positional arguments: + {list-alert-policies,list-notification-channels,enable-alert-policies,disable-alert-policies,replace-notification-channels,backup,restore} + list-alert-policies + list-notification-channels + enable-alert-policies + Enable or disable alert policies in a project. + Arguments: project_name (str) enable (bool): Enable or + disable the policies. filter_ (str, optional): Only + enable/disable alert policies that match this filter_. + See + https://cloud.google.com/monitoring/api/v3/sorting- + and-filtering + disable-alert-policies + Enable or disable alert policies in a project. + Arguments: project_name (str) enable (bool): Enable or + disable the policies. filter_ (str, optional): Only + enable/disable alert policies that match this filter_. + See + https://cloud.google.com/monitoring/api/v3/sorting- + and-filtering + replace-notification-channels + backup + restore + + optional arguments: + -h, --help show this help message and exit + + + + + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ diff --git a/monitoring/snippets/v3/alerts-client/README.rst.in b/monitoring/snippets/v3/alerts-client/README.rst.in new file mode 100644 index 000000000000..00b280124ea4 --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/README.rst.in @@ -0,0 +1,33 @@ +# This file is used to generate README.rst + +product: + name: Google Stackdriver Alerting API + short_name: Stackdriver Alerting API + url: https://cloud.google.com/monitoring/alerts/ + description: > + Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, + application instrumentation, and a variety of common application + components including Cassandra, Nginx, Apache Web Server, Elasticsearch + and many others. Stackdriver's Alerting API allows you to create, + delete, and make back up copies of your alert policies. + +required_api_url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com +required_role: Monitoring Admin +other_required_steps: > + Please visit [the Cloud Console UI of this + API](https://console.cloud.google.com/monitoring) and create a new + Workspace with the same name of your Cloud project. + +setup: +- auth +- install_deps + +samples: +- name: Snippets + file: snippets.py + show_help: true + +cloud_client_library: true + +folder: monitoring/api/v3/alerts-client diff --git a/monitoring/snippets/v3/alerts-client/noxfile.py b/monitoring/snippets/v3/alerts-client/noxfile.py new file mode 100644 index 000000000000..ba55d7ce53ca --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/monitoring/snippets/v3/alerts-client/noxfile_config.py b/monitoring/snippets/v3/alerts-client/noxfile_config.py new file mode 100644 index 000000000000..664c58309d70 --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/noxfile_config.py @@ -0,0 +1,42 @@ +# 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # Declare optional test sessions you want to opt-in. Currently we + # have the following optional test sessions: + # 'cloud_run' # Test session for Cloud Run application. + 'opt_in_sessions': [], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + # 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} diff --git a/monitoring/snippets/v3/alerts-client/requirements-test.txt b/monitoring/snippets/v3/alerts-client/requirements-test.txt new file mode 100644 index 000000000000..ec623710c6ef --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/requirements-test.txt @@ -0,0 +1,3 @@ +pytest==6.0.1 +retrying==1.3.3 +flaky==3.7.0 diff --git a/monitoring/snippets/v3/alerts-client/requirements.txt b/monitoring/snippets/v3/alerts-client/requirements.txt new file mode 100644 index 000000000000..bc7a2fe57c8b --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-monitoring==1.1.0 +tabulate==0.8.7 diff --git a/monitoring/snippets/v3/alerts-client/snippets.py b/monitoring/snippets/v3/alerts-client/snippets.py new file mode 100644 index 000000000000..80254232e6af --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/snippets.py @@ -0,0 +1,343 @@ +# Copyright 2018 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. + +from __future__ import print_function + +import argparse +import json +import os + +from google.cloud import monitoring_v3 +import google.protobuf.json_format +import tabulate + + +# [START monitoring_alert_list_policies] +def list_alert_policies(project_name): + client = monitoring_v3.AlertPolicyServiceClient() + policies = client.list_alert_policies(project_name) + print(tabulate.tabulate( + [(policy.name, policy.display_name) for policy in policies], + ('name', 'display_name'))) +# [END monitoring_alert_list_policies] + + +# [START monitoring_alert_list_channels] +def list_notification_channels(project_name): + client = monitoring_v3.NotificationChannelServiceClient() + channels = client.list_notification_channels(project_name) + print(tabulate.tabulate( + [(channel.name, channel.display_name) for channel in channels], + ('name', 'display_name'))) +# [END monitoring_alert_list_channels] + + +# [START monitoring_alert_enable_policies] +def enable_alert_policies(project_name, enable, filter_=None): + """Enable or disable alert policies in a project. + + Arguments: + project_name (str) + enable (bool): Enable or disable the policies. + filter_ (str, optional): Only enable/disable alert policies that match + this filter_. See + https://cloud.google.com/monitoring/api/v3/sorting-and-filtering + """ + + client = monitoring_v3.AlertPolicyServiceClient() + policies = client.list_alert_policies(project_name, filter_=filter_) + + for policy in policies: + if bool(enable) == policy.enabled.value: + print('Policy', policy.name, 'is already', + 'enabled' if policy.enabled.value else 'disabled') + else: + policy.enabled.value = bool(enable) + mask = monitoring_v3.types.field_mask_pb2.FieldMask() + mask.paths.append('enabled') + client.update_alert_policy(policy, mask) + print('Enabled' if enable else 'Disabled', policy.name) +# [END monitoring_alert_enable_policies] + + +# [START monitoring_alert_replace_channels] +def replace_notification_channels(project_name, alert_policy_id, channel_ids): + _, project_id = project_name.split('/') + alert_client = monitoring_v3.AlertPolicyServiceClient() + channel_client = monitoring_v3.NotificationChannelServiceClient() + policy = monitoring_v3.types.alert_pb2.AlertPolicy() + policy.name = alert_client.alert_policy_path(project_id, alert_policy_id) + + for channel_id in channel_ids: + policy.notification_channels.append( + channel_client.notification_channel_path(project_id, channel_id)) + + mask = monitoring_v3.types.field_mask_pb2.FieldMask() + mask.paths.append('notification_channels') + updated_policy = alert_client.update_alert_policy(policy, mask) + print('Updated', updated_policy.name) +# [END monitoring_alert_replace_channels] + + +# [START monitoring_alert_delete_channel] +def delete_notification_channels(project_name, channel_ids, force=None): + channel_client = monitoring_v3.NotificationChannelServiceClient() + for channel_id in channel_ids: + channel_name = '{}/notificationChannels/{}'.format( + project_name, channel_id) + try: + channel_client.delete_notification_channel( + channel_name, force=force) + print('Channel {} deleted'.format(channel_name)) + except ValueError: + print('The parameters are invalid') + except Exception as e: + print('API call failed: {}'.format(e)) +# [END monitoring_alert_delete_channel] + + +# [START monitoring_alert_backup_policies] +def backup(project_name, backup_filename): + alert_client = monitoring_v3.AlertPolicyServiceClient() + channel_client = monitoring_v3.NotificationChannelServiceClient() + record = {'project_name': project_name, + 'policies': list(alert_client.list_alert_policies(project_name)), + 'channels': list(channel_client.list_notification_channels( + project_name))} + json.dump(record, open(backup_filename, 'wt'), cls=ProtoEncoder, indent=2) + print('Backed up alert policies and notification channels to {}.'.format( + backup_filename) + ) + + +class ProtoEncoder(json.JSONEncoder): + """Uses google.protobuf.json_format to encode protobufs as json.""" + def default(self, obj): + if type(obj) in (monitoring_v3.types.alert_pb2.AlertPolicy, + monitoring_v3.types.notification_pb2. + NotificationChannel): + text = google.protobuf.json_format.MessageToJson(obj) + return json.loads(text) + return super(ProtoEncoder, self).default(obj) +# [END monitoring_alert_backup_policies] + + +# [START monitoring_alert_restore_policies] +# [START monitoring_alert_create_policy] +# [START monitoring_alert_create_channel] +# [START monitoring_alert_update_channel] +# [START monitoring_alert_enable_channel] +def restore(project_name, backup_filename): + print('Loading alert policies and notification channels from {}.'.format( + backup_filename) + ) + record = json.load(open(backup_filename, 'rt')) + is_same_project = project_name == record['project_name'] + # Convert dicts to AlertPolicies. + policies_json = [json.dumps(policy) for policy in record['policies']] + policies = [google.protobuf.json_format.Parse( + policy_json, monitoring_v3.types.alert_pb2.AlertPolicy()) + for policy_json in policies_json] + # Convert dicts to NotificationChannels + channels_json = [json.dumps(channel) for channel in record['channels']] + channels = [google.protobuf.json_format.Parse( + channel_json, monitoring_v3.types.notification_pb2. + NotificationChannel()) for channel_json in channels_json] + + # Restore the channels. + channel_client = monitoring_v3.NotificationChannelServiceClient() + channel_name_map = {} + + for channel in channels: + updated = False + print('Updating channel', channel.display_name) + # This field is immutable and it is illegal to specify a + # non-default value (UNVERIFIED or VERIFIED) in the + # Create() or Update() operations. + channel.verification_status = monitoring_v3.enums.NotificationChannel.\ + VerificationStatus.VERIFICATION_STATUS_UNSPECIFIED + + if is_same_project: + try: + channel_client.update_notification_channel(channel) + updated = True + except google.api_core.exceptions.NotFound: + pass # The channel was deleted. Create it below. + + if not updated: + # The channel no longer exists. Recreate it. + old_name = channel.name + channel.ClearField("name") + new_channel = channel_client.create_notification_channel( + project_name, channel) + channel_name_map[old_name] = new_channel.name + + # Restore the alerts + alert_client = monitoring_v3.AlertPolicyServiceClient() + + for policy in policies: + print('Updating policy', policy.display_name) + # These two fields cannot be set directly, so clear them. + policy.ClearField('creation_record') + policy.ClearField('mutation_record') + + # Update old channel names with new channel names. + for i, channel in enumerate(policy.notification_channels): + new_channel = channel_name_map.get(channel) + if new_channel: + policy.notification_channels[i] = new_channel + + updated = False + + if is_same_project: + try: + alert_client.update_alert_policy(policy) + updated = True + except google.api_core.exceptions.NotFound: + pass # The policy was deleted. Create it below. + except google.api_core.exceptions.InvalidArgument: + # Annoying that API throws InvalidArgument when the policy + # does not exist. Seems like it should throw NotFound. + pass # The policy was deleted. Create it below. + + if not updated: + # The policy no longer exists. Recreate it. + old_name = policy.name + policy.ClearField("name") + for condition in policy.conditions: + condition.ClearField("name") + policy = alert_client.create_alert_policy(project_name, policy) + print('Updated', policy.name) +# [END monitoring_alert_enable_channel] +# [END monitoring_alert_restore_policies] +# [END monitoring_alert_create_policy] +# [END monitoring_alert_create_channel] +# [END monitoring_alert_update_channel] + + +class MissingProjectIdError(Exception): + pass + + +def project_id(): + """Retreieves the project id from the environment variable. + + Raises: + MissingProjectIdError -- When not set. + + Returns: + str -- the project name + """ + project_id = os.environ['GOOGLE_CLOUD_PROJECT'] + + if not project_id: + raise MissingProjectIdError( + 'Set the environment variable ' + + 'GCLOUD_PROJECT to your Google Cloud Project Id.') + return project_id + + +def project_name(): + return 'projects/' + project_id() + + +if __name__ == '__main__': + + parser = argparse.ArgumentParser( + description='Demonstrates AlertPolicy API operations.') + + subparsers = parser.add_subparsers(dest='command') + + list_alert_policies_parser = subparsers.add_parser( + 'list-alert-policies', + help=list_alert_policies.__doc__ + ) + + list_notification_channels_parser = subparsers.add_parser( + 'list-notification-channels', + help=list_alert_policies.__doc__ + ) + + enable_alert_policies_parser = subparsers.add_parser( + 'enable-alert-policies', + help=enable_alert_policies.__doc__ + ) + enable_alert_policies_parser.add_argument( + '--filter', + ) + + disable_alert_policies_parser = subparsers.add_parser( + 'disable-alert-policies', + help=enable_alert_policies.__doc__ + ) + disable_alert_policies_parser.add_argument( + '--filter', + ) + + replace_notification_channels_parser = subparsers.add_parser( + 'replace-notification-channels', + help=replace_notification_channels.__doc__ + ) + replace_notification_channels_parser.add_argument( + '-p', '--alert_policy_id', + required=True + ) + replace_notification_channels_parser.add_argument( + '-c', '--notification_channel_id', + required=True, + action='append' + ) + + backup_parser = subparsers.add_parser( + 'backup', + help=backup.__doc__ + ) + backup_parser.add_argument( + '--backup_to_filename', + required=True + ) + + restore_parser = subparsers.add_parser( + 'restore', + help=restore.__doc__ + ) + restore_parser.add_argument( + '--restore_from_filename', + required=True + ) + + args = parser.parse_args() + + if args.command == 'list-alert-policies': + list_alert_policies(project_name()) + + elif args.command == 'list-notification-channels': + list_notification_channels(project_name()) + + elif args.command == 'enable-alert-policies': + enable_alert_policies(project_name(), enable=True, filter_=args.filter) + + elif args.command == 'disable-alert-policies': + enable_alert_policies(project_name(), enable=False, + filter_=args.filter) + + elif args.command == 'replace-notification-channels': + replace_notification_channels(project_name(), args.alert_policy_id, + args.notification_channel_id) + + elif args.command == 'backup': + backup(project_name(), args.backup_to_filename) + + elif args.command == 'restore': + restore(project_name(), args.restore_from_filename) diff --git a/monitoring/snippets/v3/alerts-client/snippets_test.py b/monitoring/snippets/v3/alerts-client/snippets_test.py new file mode 100644 index 000000000000..550a8dc97596 --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/snippets_test.py @@ -0,0 +1,195 @@ +# Copyright 2018 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. + +from __future__ import print_function + +import random +import string +import time + +from google.api_core.exceptions import Aborted +from google.api_core.exceptions import DeadlineExceeded +from google.api_core.exceptions import NotFound +from google.api_core.exceptions import ServiceUnavailable +from google.cloud import monitoring_v3 +import google.protobuf.json_format +import pytest +from retrying import retry + +import snippets + + +# We assume we have access to good randomness source. +random.seed() + + +def random_name(length): + return ''.join( + [random.choice(string.ascii_lowercase) for i in range(length)]) + + +def retry_on_exceptions(exception): + return isinstance( + exception, (Aborted, ServiceUnavailable, DeadlineExceeded)) + + +def delay_on_aborted(err, *args): + if retry_on_exceptions(err[1]): + # add randomness for avoiding continuous conflict + time.sleep(5 + (random.randint(0, 9) * 0.1)) + return True + return False + + +class PochanFixture: + """A test fixture that creates an alert POlicy and a notification CHANnel, + hence the name, pochan. + """ + + def __init__(self): + self.project_id = snippets.project_id() + self.project_name = snippets.project_name() + self.alert_policy_client = monitoring_v3.AlertPolicyServiceClient() + self.notification_channel_client = ( + monitoring_v3.NotificationChannelServiceClient()) + + def __enter__(self): + @retry(wait_exponential_multiplier=1000, wait_exponential_max=10000, + stop_max_attempt_number=10, + retry_on_exception=retry_on_exceptions) + def setup(): + # Create a policy. + policy = monitoring_v3.types.alert_pb2.AlertPolicy() + json = open('test_alert_policy.json').read() + google.protobuf.json_format.Parse(json, policy) + policy.display_name = 'snippets-test-' + random_name(10) + self.alert_policy = self.alert_policy_client.create_alert_policy( + self.project_name, policy) + # Create a notification channel. + notification_channel = ( + monitoring_v3.types.notification_pb2.NotificationChannel()) + json = open('test_notification_channel.json').read() + google.protobuf.json_format.Parse(json, notification_channel) + notification_channel.display_name = ( + 'snippets-test-' + random_name(10)) + self.notification_channel = ( + self.notification_channel_client.create_notification_channel( + self.project_name, notification_channel)) + setup() + return self + + def __exit__(self, type, value, traceback): + # Delete the policy and channel we created. + @retry(wait_exponential_multiplier=1000, wait_exponential_max=10000, + stop_max_attempt_number=10, + retry_on_exception=retry_on_exceptions) + def teardown(): + try: + self.alert_policy_client.delete_alert_policy( + self.alert_policy.name) + except NotFound: + print("Ignored NotFound when deleting a policy.") + try: + if self.notification_channel.name: + self.notification_channel_client\ + .delete_notification_channel( + self.notification_channel.name) + except NotFound: + print("Ignored NotFound when deleting a channel.") + teardown() + + +@pytest.fixture(scope='session') +def pochan(): + with PochanFixture() as pochan: + yield pochan + + +def test_list_alert_policies(capsys, pochan): + snippets.list_alert_policies(pochan.project_name) + out, _ = capsys.readouterr() + assert pochan.alert_policy.display_name in out + + +@pytest.mark.flaky(rerun_filter=delay_on_aborted, max_runs=5) +def test_enable_alert_policies(capsys, pochan): + # These sleep calls are for mitigating the following error: + # "409 Too many concurrent edits to the project configuration. + # Please try again." + # Having multiple projects will void these `sleep()` calls. + # See also #3310 + time.sleep(2) + snippets.enable_alert_policies(pochan.project_name, True) + out, _ = capsys.readouterr() + assert "Enabled {0}".format(pochan.project_name) in out \ + or "{} is already enabled".format(pochan.alert_policy.name) in out + + time.sleep(2) + snippets.enable_alert_policies(pochan.project_name, False) + out, _ = capsys.readouterr() + assert "Disabled {}".format(pochan.project_name) in out \ + or "{} is already disabled".format(pochan.alert_policy.name) in out + + +@pytest.mark.flaky(rerun_filter=delay_on_aborted, max_runs=5) +def test_replace_channels(capsys, pochan): + alert_policy_id = pochan.alert_policy.name.split('/')[-1] + notification_channel_id = pochan.notification_channel.name.split('/')[-1] + + # This sleep call is for mitigating the following error: + # "409 Too many concurrent edits to the project configuration. + # Please try again." + # Having multiple projects will void this `sleep()` call. + # See also #3310 + time.sleep(2) + snippets.replace_notification_channels( + pochan.project_name, alert_policy_id, [notification_channel_id]) + out, _ = capsys.readouterr() + assert "Updated {0}".format(pochan.alert_policy.name) in out + + +@pytest.mark.flaky(rerun_filter=delay_on_aborted, max_runs=5) +def test_backup_and_restore(capsys, pochan): + # These sleep calls are for mitigating the following error: + # "409 Too many concurrent edits to the project configuration. + # Please try again." + # Having multiple projects will void this `sleep()` call. + # See also #3310 + time.sleep(2) + snippets.backup(pochan.project_name, 'backup.json') + out, _ = capsys.readouterr() + + time.sleep(2) + snippets.restore(pochan.project_name, 'backup.json') + out, _ = capsys.readouterr() + assert "Updated {0}".format(pochan.alert_policy.name) in out + assert "Updating channel {0}".format( + pochan.notification_channel.display_name) in out + + +@pytest.mark.flaky(rerun_filter=delay_on_aborted, max_runs=5) +def test_delete_channels(capsys, pochan): + notification_channel_id = pochan.notification_channel.name.split('/')[-1] + + # This sleep call is for mitigating the following error: + # "409 Too many concurrent edits to the project configuration. + # Please try again." + # Having multiple projects will void these `sleep()` calls. + # See also #3310 + time.sleep(2) + snippets.delete_notification_channels( + pochan.project_name, [notification_channel_id], force=True) + out, _ = capsys.readouterr() + assert "{0} deleted".format(notification_channel_id) in out + pochan.notification_channel.name = '' # So teardown is not tried diff --git a/monitoring/snippets/v3/alerts-client/test_alert_policy.json b/monitoring/snippets/v3/alerts-client/test_alert_policy.json new file mode 100644 index 000000000000..d728949f9bb3 --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/test_alert_policy.json @@ -0,0 +1,31 @@ +{ + "displayName": "test_alert_policy.json", + "combiner": "OR", + "conditions": [ + { + "conditionThreshold": { + "filter": "metric.label.state=\"blocked\" AND metric.type=\"agent.googleapis.com/processes/count_by_state\" AND resource.type=\"gce_instance\"", + "comparison": "COMPARISON_GT", + "thresholdValue": 100, + "duration": "900s", + "trigger": { + "percent": 0 + }, + "aggregations": [ + { + "alignmentPeriod": "60s", + "perSeriesAligner": "ALIGN_MEAN", + "crossSeriesReducer": "REDUCE_MEAN", + "groupByFields": [ + "project", + "resource.label.instance_id", + "resource.label.zone" + ] + } + ] + }, + "displayName": "test_alert_policy.json" + } + ], + "enabled": false +} \ No newline at end of file diff --git a/monitoring/snippets/v3/alerts-client/test_notification_channel.json b/monitoring/snippets/v3/alerts-client/test_notification_channel.json new file mode 100644 index 000000000000..6a0d53c00cdd --- /dev/null +++ b/monitoring/snippets/v3/alerts-client/test_notification_channel.json @@ -0,0 +1,15 @@ +{ + "type": "email", + "displayName": "Email joe.", + "description": "test_notification_channel.json", + "labels": { + "email_address": "joe@example.com" + }, + "userLabels": { + "office": "california_westcoast_usa", + "division": "fulfillment", + "role": "operations", + "level": "5" + }, + "enabled": true +} \ No newline at end of file diff --git a/monitoring/snippets/v3/cloud-client/README.rst b/monitoring/snippets/v3/cloud-client/README.rst new file mode 100644 index 000000000000..280f9c4e0a79 --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/README.rst @@ -0,0 +1,147 @@ +.. This file is automatically generated. Do not edit this file directly. + +Google Stackdriver Monitoring API Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/cloud-client/README.rst + + +This directory contains samples for Google Stackdriver Monitoring API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch + and many others. Stackdriver ingests that data and generates insights + via dashboards, charts, and alerts. + + + + +.. _Google Stackdriver Monitoring API: https://cloud.google.com/monitoring/docs/ + +To run the sample, you need to enable the API at: https://console.cloud.google.com/apis/library/monitoring.googleapis.com + +To run the sample, you need to have `Monitoring Admin` role. + + +Please visit [the Cloud Console UI of this API](https://console.cloud.google.com/monitoring) and create a new Workspace with the same name of your Cloud project. + + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +Quickstart ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/cloud-client/quickstart.py,monitoring/api/v3/cloud-client/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python quickstart.py + + +Snippets ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/cloud-client/snippets.py,monitoring/api/v3/cloud-client/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python snippets.py + + usage: snippets.py [-h] + {create-metric-descriptor,list-metric-descriptors,get-metric-descriptor,delete-metric-descriptor,list-resources,get-resource,write-time-series,list-time-series,list-time-series-header,list-time-series-reduce,list-time-series-aggregate} + ... + + Demonstrates Monitoring API operations. + + positional arguments: + {create-metric-descriptor,list-metric-descriptors,get-metric-descriptor,delete-metric-descriptor,list-resources,get-resource,write-time-series,list-time-series,list-time-series-header,list-time-series-reduce,list-time-series-aggregate} + create-metric-descriptor + list-metric-descriptors + get-metric-descriptor + delete-metric-descriptor + list-resources + get-resource + write-time-series + list-time-series + list-time-series-header + list-time-series-reduce + list-time-series-aggregate + + optional arguments: + -h, --help show this help message and exit + + + + + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/monitoring/snippets/v3/cloud-client/README.rst.in b/monitoring/snippets/v3/cloud-client/README.rst.in new file mode 100644 index 000000000000..0ab6b2258b78 --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/README.rst.in @@ -0,0 +1,35 @@ +# This file is used to generate README.rst + +product: + name: Google Stackdriver Monitoring API + short_name: Stackdriver Monitoring API + url: https://cloud.google.com/monitoring/docs/ + description: > + Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, + application instrumentation, and a variety of common application + components including Cassandra, Nginx, Apache Web Server, Elasticsearch + and many others. Stackdriver ingests that data and generates insights + via dashboards, charts, and alerts. + +required_api_url: https://console.cloud.google.com/apis/library/monitoring.googleapis.com +required_role: Monitoring Admin +other_required_steps: > + Please visit [the Cloud Console UI of this + API](https://console.cloud.google.com/monitoring) and create a new + Workspace with the same name of your Cloud project. + +setup: +- auth +- install_deps + +samples: +- name: Quickstart + file: quickstart.py +- name: Snippets + file: snippets.py + show_help: true + +cloud_client_library: true + +folder: monitoring/api/v3/cloud-client diff --git a/monitoring/snippets/v3/cloud-client/noxfile.py b/monitoring/snippets/v3/cloud-client/noxfile.py new file mode 100644 index 000000000000..ba55d7ce53ca --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/monitoring/snippets/v3/cloud-client/noxfile_config.py b/monitoring/snippets/v3/cloud-client/noxfile_config.py new file mode 100644 index 000000000000..664c58309d70 --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/noxfile_config.py @@ -0,0 +1,42 @@ +# 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. + +# Default TEST_CONFIG_OVERRIDE for python repos. + +# You can copy this file into your directory, then it will be inported from +# the noxfile.py. + +# The source of truth: +# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py + +TEST_CONFIG_OVERRIDE = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # Declare optional test sessions you want to opt-in. Currently we + # have the following optional test sessions: + # 'cloud_run' # Test session for Cloud Run application. + 'opt_in_sessions': [], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + # 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} diff --git a/monitoring/snippets/v3/cloud-client/quickstart.py b/monitoring/snippets/v3/cloud-client/quickstart.py new file mode 100644 index 000000000000..0527acae545e --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/quickstart.py @@ -0,0 +1,43 @@ +# Copyright 2017 Google Inc. +# +# 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. + + +def run_quickstart(): + # [START monitoring_quickstart] + from google.cloud import monitoring_v3 + + import time + + client = monitoring_v3.MetricServiceClient() + project = 'my-project' # TODO: Update to your project ID. + project_name = client.project_path(project) + + series = monitoring_v3.types.TimeSeries() + series.metric.type = 'custom.googleapis.com/my_metric' + series.resource.type = 'gce_instance' + series.resource.labels['instance_id'] = '1234567890123456789' + series.resource.labels['zone'] = 'us-central1-f' + point = series.points.add() + point.value.double_value = 3.14 + now = time.time() + point.interval.end_time.seconds = int(now) + point.interval.end_time.nanos = int( + (now - point.interval.end_time.seconds) * 10**9) + client.create_time_series(project_name, [series]) + print('Successfully wrote time series.') + # [END monitoring_quickstart] + + +if __name__ == '__main__': + run_quickstart() diff --git a/monitoring/snippets/v3/cloud-client/quickstart_test.py b/monitoring/snippets/v3/cloud-client/quickstart_test.py new file mode 100644 index 000000000000..fd0191aafc12 --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/quickstart_test.py @@ -0,0 +1,46 @@ +# Copyright 2017 Google Inc. +# +# 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. + +import os + +import backoff +import mock +import pytest + +import quickstart + + +PROJECT = os.environ['GOOGLE_CLOUD_PROJECT'] + + +@pytest.fixture +def mock_project_path(): + """Mock out project and replace with project from environment.""" + project_patch = mock.patch( + 'google.cloud.monitoring_v3.MetricServiceClient.' + 'project_path') + + with project_patch as project_mock: + project_mock.return_value = 'projects/{}'.format(PROJECT) + yield project_mock + + +def test_quickstart(capsys, mock_project_path): + @backoff.on_exception(backoff.expo, AssertionError, max_time=60) + def eventually_consistent_test(): + quickstart.run_quickstart() + out, _ = capsys.readouterr() + assert 'wrote' in out + + eventually_consistent_test() diff --git a/monitoring/snippets/v3/cloud-client/requirements-test.txt b/monitoring/snippets/v3/cloud-client/requirements-test.txt new file mode 100644 index 000000000000..b04e65e37c9c --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/requirements-test.txt @@ -0,0 +1,3 @@ +backoff==1.10.0 +pytest==6.0.1 +mock==4.0.2 diff --git a/monitoring/snippets/v3/cloud-client/requirements.txt b/monitoring/snippets/v3/cloud-client/requirements.txt new file mode 100644 index 000000000000..10c88fc2f9ae --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/requirements.txt @@ -0,0 +1 @@ +google-cloud-monitoring==1.1.0 diff --git a/monitoring/snippets/v3/cloud-client/snippets.py b/monitoring/snippets/v3/cloud-client/snippets.py new file mode 100644 index 000000000000..64b3853fd7cc --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/snippets.py @@ -0,0 +1,310 @@ +# Copyright 2017 Google Inc. +# +# 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. + +import argparse +import os +import pprint +import time +import uuid + +from google.cloud import monitoring_v3 + + +PROJECT_ID = os.environ['GOOGLE_CLOUD_PROJECT'] + + +def create_metric_descriptor(project_id): + # [START monitoring_create_metric] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + descriptor = monitoring_v3.types.MetricDescriptor() + descriptor.type = 'custom.googleapis.com/my_metric' + str(uuid.uuid4()) + descriptor.metric_kind = ( + monitoring_v3.enums.MetricDescriptor.MetricKind.GAUGE) + descriptor.value_type = ( + monitoring_v3.enums.MetricDescriptor.ValueType.DOUBLE) + descriptor.description = 'This is a simple example of a custom metric.' + descriptor = client.create_metric_descriptor(project_name, descriptor) + print('Created {}.'.format(descriptor.name)) + # [END monitoring_create_metric] + + +def delete_metric_descriptor(descriptor_name): + # [START monitoring_delete_metric] + client = monitoring_v3.MetricServiceClient() + client.delete_metric_descriptor(descriptor_name) + print('Deleted metric descriptor {}.'.format(descriptor_name)) + # [END monitoring_delete_metric] + + +def write_time_series(project_id): + # [START monitoring_write_timeseries] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + + series = monitoring_v3.types.TimeSeries() + series.metric.type = 'custom.googleapis.com/my_metric' + str(uuid.uuid4()) + series.resource.type = 'gce_instance' + series.resource.labels['instance_id'] = '1234567890123456789' + series.resource.labels['zone'] = 'us-central1-f' + point = series.points.add() + point.value.double_value = 3.14 + now = time.time() + point.interval.end_time.seconds = int(now) + point.interval.end_time.nanos = int( + (now - point.interval.end_time.seconds) * 10**9) + client.create_time_series(project_name, [series]) + # [END monitoring_write_timeseries] + + +def list_time_series(project_id): + # [START monitoring_read_timeseries_simple] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + interval = monitoring_v3.types.TimeInterval() + now = time.time() + interval.end_time.seconds = int(now) + interval.end_time.nanos = int( + (now - interval.end_time.seconds) * 10**9) + interval.start_time.seconds = int(now - 1200) + interval.start_time.nanos = interval.end_time.nanos + results = client.list_time_series( + project_name, + 'metric.type = "compute.googleapis.com/instance/cpu/utilization"', + interval, + monitoring_v3.enums.ListTimeSeriesRequest.TimeSeriesView.FULL) + for result in results: + print(result) + # [END monitoring_read_timeseries_simple] + + +def list_time_series_header(project_id): + # [START monitoring_read_timeseries_fields] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + interval = monitoring_v3.types.TimeInterval() + now = time.time() + interval.end_time.seconds = int(now) + interval.end_time.nanos = int( + (now - interval.end_time.seconds) * 10**9) + interval.start_time.seconds = int(now - 1200) + interval.start_time.nanos = interval.end_time.nanos + results = client.list_time_series( + project_name, + 'metric.type = "compute.googleapis.com/instance/cpu/utilization"', + interval, + monitoring_v3.enums.ListTimeSeriesRequest.TimeSeriesView.HEADERS) + for result in results: + print(result) + # [END monitoring_read_timeseries_fields] + + +def list_time_series_aggregate(project_id): + # [START monitoring_read_timeseries_align] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + interval = monitoring_v3.types.TimeInterval() + now = time.time() + interval.end_time.seconds = int(now) + interval.end_time.nanos = int( + (now - interval.end_time.seconds) * 10**9) + interval.start_time.seconds = int(now - 3600) + interval.start_time.nanos = interval.end_time.nanos + aggregation = monitoring_v3.types.Aggregation() + aggregation.alignment_period.seconds = 1200 # 20 minutes + aggregation.per_series_aligner = ( + monitoring_v3.enums.Aggregation.Aligner.ALIGN_MEAN) + + results = client.list_time_series( + project_name, + 'metric.type = "compute.googleapis.com/instance/cpu/utilization"', + interval, + monitoring_v3.enums.ListTimeSeriesRequest.TimeSeriesView.FULL, + aggregation) + for result in results: + print(result) + # [END monitoring_read_timeseries_align] + + +def list_time_series_reduce(project_id): + # [START monitoring_read_timeseries_reduce] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + interval = monitoring_v3.types.TimeInterval() + now = time.time() + interval.end_time.seconds = int(now) + interval.end_time.nanos = int( + (now - interval.end_time.seconds) * 10**9) + interval.start_time.seconds = int(now - 3600) + interval.start_time.nanos = interval.end_time.nanos + aggregation = monitoring_v3.types.Aggregation() + aggregation.alignment_period.seconds = 1200 # 20 minutes + aggregation.per_series_aligner = ( + monitoring_v3.enums.Aggregation.Aligner.ALIGN_MEAN) + aggregation.cross_series_reducer = ( + monitoring_v3.enums.Aggregation.Reducer.REDUCE_MEAN) + aggregation.group_by_fields.append('resource.zone') + + results = client.list_time_series( + project_name, + 'metric.type = "compute.googleapis.com/instance/cpu/utilization"', + interval, + monitoring_v3.enums.ListTimeSeriesRequest.TimeSeriesView.FULL, + aggregation) + for result in results: + print(result) + # [END monitoring_read_timeseries_reduce] + + +def list_metric_descriptors(project_id): + # [START monitoring_list_descriptors] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + for descriptor in client.list_metric_descriptors(project_name): + print(descriptor.type) + # [END monitoring_list_descriptors] + + +def list_monitored_resources(project_id): + # [START monitoring_list_resources] + client = monitoring_v3.MetricServiceClient() + project_name = client.project_path(project_id) + resource_descriptors = ( + client.list_monitored_resource_descriptors(project_name)) + for descriptor in resource_descriptors: + print(descriptor.type) + # [END monitoring_list_resources] + + +def get_monitored_resource_descriptor(project_id, resource_type_name): + # [START monitoring_get_resource] + client = monitoring_v3.MetricServiceClient() + resource_path = client.monitored_resource_descriptor_path( + project_id, resource_type_name) + pprint.pprint(client.get_monitored_resource_descriptor(resource_path)) + # [END monitoring_get_resource] + + +def get_metric_descriptor(metric_name): + # [START monitoring_get_descriptor] + client = monitoring_v3.MetricServiceClient() + descriptor = client.get_metric_descriptor(metric_name) + pprint.pprint(descriptor) + # [END monitoring_get_descriptor] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description='Demonstrates Monitoring API operations.') + + subparsers = parser.add_subparsers(dest='command') + + create_metric_descriptor_parser = subparsers.add_parser( + 'create-metric-descriptor', + help=create_metric_descriptor.__doc__ + ) + + list_metric_descriptor_parser = subparsers.add_parser( + 'list-metric-descriptors', + help=list_metric_descriptors.__doc__ + ) + + get_metric_descriptor_parser = subparsers.add_parser( + 'get-metric-descriptor', + help=get_metric_descriptor.__doc__ + ) + + get_metric_descriptor_parser.add_argument( + '--metric-type-name', + help='The metric type of the metric descriptor to see details about.', + required=True + ) + + delete_metric_descriptor_parser = subparsers.add_parser( + 'delete-metric-descriptor', + help=list_metric_descriptors.__doc__ + ) + + delete_metric_descriptor_parser.add_argument( + '--metric-descriptor-name', + help='Metric descriptor to delete', + required=True + ) + + list_resources_parser = subparsers.add_parser( + 'list-resources', + help=list_monitored_resources.__doc__ + ) + + get_resource_parser = subparsers.add_parser( + 'get-resource', + help=get_monitored_resource_descriptor.__doc__ + ) + + get_resource_parser.add_argument( + '--resource-type-name', + help='Monitored resource to view more information about.', + required=True + ) + + write_time_series_parser = subparsers.add_parser( + 'write-time-series', + help=write_time_series.__doc__ + ) + + list_time_series_parser = subparsers.add_parser( + 'list-time-series', + help=list_time_series.__doc__ + ) + + list_time_series_header_parser = subparsers.add_parser( + 'list-time-series-header', + help=list_time_series_header.__doc__ + ) + + read_time_series_reduce = subparsers.add_parser( + 'list-time-series-reduce', + help=list_time_series_reduce.__doc__ + ) + + read_time_series_aggregate = subparsers.add_parser( + 'list-time-series-aggregate', + help=list_time_series_aggregate.__doc__ + ) + + args = parser.parse_args() + + if args.command == 'create-metric-descriptor': + create_metric_descriptor(PROJECT_ID) + if args.command == 'list-metric-descriptors': + list_metric_descriptors(PROJECT_ID) + if args.command == 'get-metric-descriptor': + get_metric_descriptor(args.metric_type_name) + if args.command == 'delete-metric-descriptor': + delete_metric_descriptor(args.metric_descriptor_name) + if args.command == 'list-resources': + list_monitored_resources(PROJECT_ID) + if args.command == 'get-resource': + get_monitored_resource_descriptor( + PROJECT_ID, args.resource_type_name) + if args.command == 'write-time-series': + write_time_series(PROJECT_ID) + if args.command == 'list-time-series': + list_time_series(PROJECT_ID) + if args.command == 'list-time-series-header': + list_time_series_header(PROJECT_ID) + if args.command == 'list-time-series-reduce': + list_time_series_reduce(PROJECT_ID) + if args.command == 'list-time-series-aggregate': + list_time_series_aggregate(PROJECT_ID) diff --git a/monitoring/snippets/v3/cloud-client/snippets_test.py b/monitoring/snippets/v3/cloud-client/snippets_test.py new file mode 100644 index 000000000000..5aabbda83922 --- /dev/null +++ b/monitoring/snippets/v3/cloud-client/snippets_test.py @@ -0,0 +1,117 @@ +# Copyright 2017 Google Inc. +# +# 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. + +import os +import re + +import backoff +from google.api_core.exceptions import InternalServerError +from google.api_core.exceptions import NotFound +import pytest + +import snippets + + +PROJECT_ID = os.environ['GOOGLE_CLOUD_PROJECT'] + + +@pytest.fixture(scope="function") +def custom_metric_descriptor(capsys): + snippets.create_metric_descriptor(PROJECT_ID) + out, _ = capsys.readouterr() + match = re.search(r'Created (.*)\.', out) + metric_name = match.group(1) + yield metric_name + + # teardown + try: + snippets.delete_metric_descriptor(metric_name) + except NotFound: + print("Metric descriptor already deleted") + + +@pytest.fixture(scope="module") +def write_time_series(): + + @backoff.on_exception(backoff.expo, InternalServerError, max_time=120) + def write(): + snippets.write_time_series(PROJECT_ID) + + write() + yield + + +def test_get_delete_metric_descriptor(capsys, custom_metric_descriptor): + try: + @backoff.on_exception( + backoff.expo, (AssertionError, NotFound), max_time=60) + def eventually_consistent_test(): + snippets.get_metric_descriptor(custom_metric_descriptor) + out, _ = capsys.readouterr() + assert 'DOUBLE' in out + + eventually_consistent_test() + finally: + snippets.delete_metric_descriptor(custom_metric_descriptor) + out, _ = capsys.readouterr() + assert 'Deleted metric' in out + + +def test_list_metric_descriptors(capsys): + snippets.list_metric_descriptors(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'logging.googleapis.com/byte_count' in out + + +def test_list_resources(capsys): + snippets.list_monitored_resources(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'pubsub_topic' in out + + +def test_get_resources(capsys): + snippets.get_monitored_resource_descriptor( + PROJECT_ID, 'pubsub_topic') + out, _ = capsys.readouterr() + assert 'A topic in Google Cloud Pub/Sub' in out + + +def test_list_time_series(capsys, write_time_series): + snippets.list_time_series(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'gce_instance' in out + + +def test_list_time_series_header(capsys, write_time_series): + snippets.list_time_series_header(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'gce_instance' in out + + +def test_list_time_series_aggregate(capsys, write_time_series): + snippets.list_time_series_aggregate(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'points' in out + assert 'interval' in out + assert 'start_time' in out + assert 'end_time' in out + + +def test_list_time_series_reduce(capsys, write_time_series): + snippets.list_time_series_reduce(PROJECT_ID) + out, _ = capsys.readouterr() + assert 'points' in out + assert 'interval' in out + assert 'start_time' in out + assert 'end_time' in out diff --git a/monitoring/snippets/v3/uptime-check-client/README.rst b/monitoring/snippets/v3/uptime-check-client/README.rst new file mode 100644 index 000000000000..30046bdef9d2 --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/README.rst @@ -0,0 +1,115 @@ +.. This file is automatically generated. Do not edit this file directly. + +Google Stackdriver Uptime Checks API Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/uptime-check-client/README.rst + + +This directory contains samples for Google Stackdriver Uptime Checks API. Stackdriver Monitoring collects metrics, events, and metadata from Google Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, application instrumentation, and a variety of common application components including Cassandra, Nginx, Apache Web Server, Elasticsearch and many others. Stackdriver's Uptime Checks API allows you to create, delete, and list your project's Uptime Checks. + + + + +.. _Google Stackdriver Uptime Checks API: https://cloud.google.com/monitoring/uptime-checks/management + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone python-docs-samples and change directory to the sample directory you want to use. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +Snippets ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=monitoring/api/v3/uptime-check-client/snippets.py,monitoring/api/v3/uptime-check-client/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python snippets.py + + usage: snippets.py [-h] + {list-uptime-check-configs,list-uptime-check-ips,create-uptime-check,get-uptime-check-config,delete-uptime-check-config} + ... + + Demonstrates Uptime Check API operations. + + positional arguments: + {list-uptime-check-configs,list-uptime-check-ips,create-uptime-check,get-uptime-check-config,delete-uptime-check-config} + list-uptime-check-configs + list-uptime-check-ips + create-uptime-check + get-uptime-check-config + delete-uptime-check-config + + optional arguments: + -h, --help show this help message and exit + + + + + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ \ No newline at end of file diff --git a/monitoring/snippets/v3/uptime-check-client/README.rst.in b/monitoring/snippets/v3/uptime-check-client/README.rst.in new file mode 100644 index 000000000000..1174962e48d1 --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/README.rst.in @@ -0,0 +1,26 @@ +# This file is used to generate README.rst + +product: + name: Google Stackdriver Uptime Checks API + short_name: Stackdriver Uptime Checks API + url: https://cloud.google.com/monitoring/uptime-checks/management + description: > + Stackdriver Monitoring collects metrics, events, and metadata from Google + Cloud Platform, Amazon Web Services (AWS), hosted uptime probes, + application instrumentation, and a variety of common application + components including Cassandra, Nginx, Apache Web Server, Elasticsearch + and many others. Stackdriver's Uptime Checks API allows you to create, + delete, and list your project's Uptime Checks. + +setup: +- auth +- install_deps + +samples: +- name: Snippets + file: snippets.py + show_help: true + +cloud_client_library: true + +folder: monitoring/api/v3/uptime-check-client \ No newline at end of file diff --git a/monitoring/snippets/v3/uptime-check-client/noxfile.py b/monitoring/snippets/v3/uptime-check-client/noxfile.py new file mode 100644 index 000000000000..ba55d7ce53ca --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/noxfile.py @@ -0,0 +1,224 @@ +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import os +from pathlib import Path +import sys + +import nox + + +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING +# DO NOT EDIT THIS FILE EVER! +# WARNING - WARNING - WARNING - WARNING - WARNING +# WARNING - WARNING - WARNING - WARNING - WARNING + +# Copy `noxfile_config.py` to your directory and modify it instead. + + +# `TEST_CONFIG` dict is a configuration hook that allows users to +# modify the test configurations. The values here should be in sync +# with `noxfile_config.py`. Users will copy `noxfile_config.py` into +# their directory and modify it. + +TEST_CONFIG = { + # You can opt out from the test for specific Python versions. + 'ignored_versions': ["2.7"], + + # An envvar key for determining the project id to use. Change it + # to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a + # build specific Cloud project. You can also use your own string + # to use your own Cloud project. + 'gcloud_project_env': 'GOOGLE_CLOUD_PROJECT', + # 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT', + + # A dictionary you want to inject into your test. Don't put any + # secrets here. These values will override predefined values. + 'envs': {}, +} + + +try: + # Ensure we can import noxfile_config in the project's directory. + sys.path.append('.') + from noxfile_config import TEST_CONFIG_OVERRIDE +except ImportError as e: + print("No user noxfile_config found: detail: {}".format(e)) + TEST_CONFIG_OVERRIDE = {} + +# Update the TEST_CONFIG with the user supplied values. +TEST_CONFIG.update(TEST_CONFIG_OVERRIDE) + + +def get_pytest_env_vars(): + """Returns a dict for pytest invocation.""" + ret = {} + + # Override the GCLOUD_PROJECT and the alias. + env_key = TEST_CONFIG['gcloud_project_env'] + # This should error out if not set. + ret['GOOGLE_CLOUD_PROJECT'] = os.environ[env_key] + + # Apply user supplied envs. + ret.update(TEST_CONFIG['envs']) + return ret + + +# DO NOT EDIT - automatically generated. +# All versions used to tested samples. +ALL_VERSIONS = ["2.7", "3.6", "3.7", "3.8"] + +# Any default versions that should be ignored. +IGNORED_VERSIONS = TEST_CONFIG['ignored_versions'] + +TESTED_VERSIONS = sorted([v for v in ALL_VERSIONS if v not in IGNORED_VERSIONS]) + +INSTALL_LIBRARY_FROM_SOURCE = bool(os.environ.get("INSTALL_LIBRARY_FROM_SOURCE", False)) +# +# Style Checks +# + + +def _determine_local_import_names(start_dir): + """Determines all import names that should be considered "local". + + This is used when running the linter to insure that import order is + properly checked. + """ + file_ext_pairs = [os.path.splitext(path) for path in os.listdir(start_dir)] + return [ + basename + for basename, extension in file_ext_pairs + if extension == ".py" + or os.path.isdir(os.path.join(start_dir, basename)) + and basename not in ("__pycache__") + ] + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--import-order-style=google", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session +def lint(session): + session.install("flake8", "flake8-import-order") + + local_names = _determine_local_import_names(".") + args = FLAKE8_COMMON_ARGS + [ + "--application-import-names", + ",".join(local_names), + "." + ] + session.run("flake8", *args) + + +# +# Sample Tests +# + + +PYTEST_COMMON_ARGS = ["--junitxml=sponge_log.xml"] + + +def _session_tests(session, post_install=None): + """Runs py.test for a particular project.""" + if os.path.exists("requirements.txt"): + session.install("-r", "requirements.txt") + + if os.path.exists("requirements-test.txt"): + session.install("-r", "requirements-test.txt") + + if INSTALL_LIBRARY_FROM_SOURCE: + session.install("-e", _get_repo_root()) + + if post_install: + post_install(session) + + session.run( + "pytest", + *(PYTEST_COMMON_ARGS + session.posargs), + # Pytest will return 5 when no tests are collected. This can happen + # on travis where slow and flaky tests are excluded. + # See http://doc.pytest.org/en/latest/_modules/_pytest/main.html + success_codes=[0, 5], + env=get_pytest_env_vars() + ) + + +@nox.session(python=ALL_VERSIONS) +def py(session): + """Runs py.test for a sample using the specified version of Python.""" + if session.python in TESTED_VERSIONS: + _session_tests(session) + else: + session.skip("SKIPPED: {} tests are disabled for this sample.".format( + session.python + )) + + +# +# Readmegen +# + + +def _get_repo_root(): + """ Returns the root folder of the project. """ + # Get root of this repository. Assume we don't have directories nested deeper than 10 items. + p = Path(os.getcwd()) + for i in range(10): + if p is None: + break + if Path(p / ".git").exists(): + return str(p) + p = p.parent + raise Exception("Unable to detect repository root.") + + +GENERATED_READMES = sorted([x for x in Path(".").rglob("*.rst.in")]) + + +@nox.session +@nox.parametrize("path", GENERATED_READMES) +def readmegen(session, path): + """(Re-)generates the readme for a sample.""" + session.install("jinja2", "pyyaml") + dir_ = os.path.dirname(path) + + if os.path.exists(os.path.join(dir_, "requirements.txt")): + session.install("-r", os.path.join(dir_, "requirements.txt")) + + in_file = os.path.join(dir_, "README.rst.in") + session.run( + "python", _get_repo_root() + "/scripts/readme-gen/readme_gen.py", in_file + ) diff --git a/monitoring/snippets/v3/uptime-check-client/requirements-test.txt b/monitoring/snippets/v3/uptime-check-client/requirements-test.txt new file mode 100644 index 000000000000..d0029c6de49e --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/requirements-test.txt @@ -0,0 +1,2 @@ +backoff==1.10.0 +pytest==6.0.1 diff --git a/monitoring/snippets/v3/uptime-check-client/requirements.txt b/monitoring/snippets/v3/uptime-check-client/requirements.txt new file mode 100644 index 000000000000..bc7a2fe57c8b --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/requirements.txt @@ -0,0 +1,2 @@ +google-cloud-monitoring==1.1.0 +tabulate==0.8.7 diff --git a/monitoring/snippets/v3/uptime-check-client/snippets.py b/monitoring/snippets/v3/uptime-check-client/snippets.py new file mode 100644 index 000000000000..dcde3b58650d --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/snippets.py @@ -0,0 +1,257 @@ +# Copyright 2018 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. + +from __future__ import print_function + +import argparse +import os +import pprint + +from google.cloud import monitoring_v3 +import tabulate + + +# [START monitoring_uptime_check_create] +def create_uptime_check_config_get(project_name, host_name=None, display_name=None): + config = monitoring_v3.types.uptime_pb2.UptimeCheckConfig() + config.display_name = display_name or "New GET uptime check" + config.monitored_resource.type = "uptime_url" + config.monitored_resource.labels.update({"host": host_name or "example.com"}) + config.http_check.request_method = ( + monitoring_v3.enums.UptimeCheckConfig.HttpCheck.RequestMethod.GET + ) + config.http_check.path = "/" + config.http_check.port = 80 + config.timeout.seconds = 10 + config.period.seconds = 300 + + client = monitoring_v3.UptimeCheckServiceClient() + new_config = client.create_uptime_check_config(project_name, config) + pprint.pprint(new_config) + return new_config + + +def create_uptime_check_config_post(project_name, host_name=None, display_name=None): + config = monitoring_v3.types.uptime_pb2.UptimeCheckConfig() + config.display_name = display_name or "New POST uptime check" + config.monitored_resource.type = "uptime_url" + config.monitored_resource.labels.update({"host": host_name or "example.com"}) + config.http_check.request_method = ( + monitoring_v3.enums.UptimeCheckConfig.HttpCheck.RequestMethod.POST + ) + config.http_check.content_type = ( + monitoring_v3.enums.UptimeCheckConfig.HttpCheck.ContentType.URL_ENCODED + ) + config.http_check.body = "foo=bar".encode("utf-8") + config.http_check.path = "/" + config.http_check.port = 80 + config.timeout.seconds = 10 + config.period.seconds = 300 + + client = monitoring_v3.UptimeCheckServiceClient() + new_config = client.create_uptime_check_config(project_name, config) + pprint.pprint(new_config) + return new_config + + +# [END monitoring_uptime_check_create] + +# [START monitoring_uptime_check_update] +def update_uptime_check_config( + config_name, new_display_name=None, new_http_check_path=None +): + client = monitoring_v3.UptimeCheckServiceClient() + config = client.get_uptime_check_config(config_name) + field_mask = monitoring_v3.types.FieldMask() + if new_display_name: + field_mask.paths.append("display_name") + config.display_name = new_display_name + if new_http_check_path: + field_mask.paths.append("http_check.path") + config.http_check.path = new_http_check_path + client.update_uptime_check_config(config, field_mask) + + +# [END monitoring_uptime_check_update] + + +# [START monitoring_uptime_check_list_configs] +def list_uptime_check_configs(project_name): + client = monitoring_v3.UptimeCheckServiceClient() + configs = client.list_uptime_check_configs(project_name) + + for config in configs: + pprint.pprint(config) + + +# [END monitoring_uptime_check_list_configs] + + +# [START monitoring_uptime_check_list_ips] +def list_uptime_check_ips(): + client = monitoring_v3.UptimeCheckServiceClient() + ips = client.list_uptime_check_ips() + print( + tabulate.tabulate( + [(ip.region, ip.location, ip.ip_address) for ip in ips], + ("region", "location", "ip_address"), + ) + ) + + +# [END monitoring_uptime_check_list_ips] + + +# [START monitoring_uptime_check_get] +def get_uptime_check_config(config_name): + client = monitoring_v3.UptimeCheckServiceClient() + config = client.get_uptime_check_config(config_name) + pprint.pprint(config) + + +# [END monitoring_uptime_check_get] + + +# [START monitoring_uptime_check_delete] +# `config_name` is the `name` field of an UptimeCheckConfig. +# See https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.uptimeCheckConfigs#UptimeCheckConfig. +def delete_uptime_check_config(config_name): + client = monitoring_v3.UptimeCheckServiceClient() + client.delete_uptime_check_config(config_name) + print("Deleted ", config_name) + + +# [END monitoring_uptime_check_delete] + + +class MissingProjectIdError(Exception): + pass + + +def project_id(): + """Retreieves the project id from the environment variable. + + Raises: + MissingProjectIdError -- When not set. + + Returns: + str -- the project name + """ + project_id = os.environ["GOOGLE_CLOUD_PROJECT"] + + if not project_id: + raise MissingProjectIdError( + "Set the environment variable " + + "GCLOUD_PROJECT to your Google Cloud Project Id." + ) + return project_id + + +def project_name(): + return "projects/" + project_id() + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser( + description="Demonstrates Uptime Check API operations." + ) + + subparsers = parser.add_subparsers(dest="command") + + list_uptime_check_configs_parser = subparsers.add_parser( + "list-uptime-check-configs", help=list_uptime_check_configs.__doc__ + ) + + list_uptime_check_ips_parser = subparsers.add_parser( + "list-uptime-check-ips", help=list_uptime_check_ips.__doc__ + ) + + create_uptime_check_config_get_parser = subparsers.add_parser( + "create-uptime-check-get", help=create_uptime_check_config_get.__doc__ + ) + create_uptime_check_config_get_parser.add_argument( + "-d", "--display_name", required=False, + ) + create_uptime_check_config_get_parser.add_argument( + "-o", "--host_name", required=False, + ) + + create_uptime_check_config_post_parser = subparsers.add_parser( + "create-uptime-check-post", help=create_uptime_check_config_post.__doc__ + ) + create_uptime_check_config_post_parser.add_argument( + "-d", "--display_name", required=False, + ) + create_uptime_check_config_post_parser.add_argument( + "-o", "--host_name", required=False, + ) + + get_uptime_check_config_parser = subparsers.add_parser( + "get-uptime-check-config", help=get_uptime_check_config.__doc__ + ) + get_uptime_check_config_parser.add_argument( + "-m", "--name", required=True, + ) + + delete_uptime_check_config_parser = subparsers.add_parser( + "delete-uptime-check-config", help=delete_uptime_check_config.__doc__ + ) + delete_uptime_check_config_parser.add_argument( + "-m", "--name", required=True, + ) + + update_uptime_check_config_parser = subparsers.add_parser( + "update-uptime-check-config", help=update_uptime_check_config.__doc__ + ) + update_uptime_check_config_parser.add_argument( + "-m", "--name", required=True, + ) + update_uptime_check_config_parser.add_argument( + "-d", "--display_name", required=False, + ) + update_uptime_check_config_parser.add_argument( + "-p", "--uptime_check_path", required=False, + ) + + args = parser.parse_args() + + if args.command == "list-uptime-check-configs": + list_uptime_check_configs(project_name()) + + elif args.command == "list-uptime-check-ips": + list_uptime_check_ips() + + elif args.command == "create-uptime-check-get": + create_uptime_check_config_get( + project_name(), args.host_name, args.display_name + ) + elif args.command == "create-uptime-check-post": + create_uptime_check_config_post( + project_name(), args.host_name, args.display_name + ) + + elif args.command == "get-uptime-check-config": + get_uptime_check_config(args.name) + + elif args.command == "delete-uptime-check-config": + delete_uptime_check_config(args.name) + + elif args.command == "update-uptime-check-config": + if not args.display_name and not args.uptime_check_path: + print("Nothing to update. Pass --display_name or " "--uptime_check_path.") + else: + update_uptime_check_config( + args.name, args.display_name, args.uptime_check_path + ) diff --git a/monitoring/snippets/v3/uptime-check-client/snippets_test.py b/monitoring/snippets/v3/uptime-check-client/snippets_test.py new file mode 100644 index 000000000000..81d2b247372c --- /dev/null +++ b/monitoring/snippets/v3/uptime-check-client/snippets_test.py @@ -0,0 +1,105 @@ +# Copyright 2018 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. + +from __future__ import print_function + +import random +import string + +import backoff +from google.api_core.exceptions import DeadlineExceeded +import pytest + +import snippets + + +def random_name(length): + return "".join([random.choice(string.ascii_lowercase) for i in range(length)]) + + +class UptimeFixture: + """A test fixture that creates uptime check config. + """ + + def __init__(self): + self.project_id = snippets.project_id() + self.project_name = snippets.project_name() + + def __enter__(self): + # Create an uptime check config (GET request). + self.config_get = snippets.create_uptime_check_config_get( + self.project_name, display_name=random_name(10) + ) + # Create an uptime check config (POST request). + self.config_post = snippets.create_uptime_check_config_post( + self.project_name, display_name=random_name(10) + ) + return self + + def __exit__(self, type, value, traceback): + # Delete the config. + snippets.delete_uptime_check_config(self.config_get.name) + snippets.delete_uptime_check_config(self.config_post.name) + + +@pytest.fixture(scope="session") +def uptime(): + with UptimeFixture() as uptime: + yield uptime + + +def test_create_and_delete(capsys): + # create and delete happen in uptime fixture. + with UptimeFixture(): + pass + + +def test_update_uptime_config(capsys): + # create and delete happen in uptime fixture. + new_display_name = random_name(10) + new_uptime_check_path = "/" + random_name(10) + with UptimeFixture() as fixture: + # We sometimes see the permission error saying the resource + # may not exist. Weirdly DeadlineExceeded instance is raised + # in this case. + @backoff.on_exception(backoff.expo, DeadlineExceeded, max_time=120) + def call_sample(): + snippets.update_uptime_check_config( + fixture.config_get.name, new_display_name, new_uptime_check_path) + + call_sample() + + out, _ = capsys.readouterr() + snippets.get_uptime_check_config(fixture.config_get.name) + out, _ = capsys.readouterr() + assert new_display_name in out + assert new_uptime_check_path in out + + +def test_get_uptime_check_config(capsys, uptime): + snippets.get_uptime_check_config(uptime.config_get.name) + out, _ = capsys.readouterr() + assert uptime.config_get.display_name in out + + +def test_list_uptime_check_configs(capsys, uptime): + snippets.list_uptime_check_configs(uptime.project_name) + out, _ = capsys.readouterr() + assert uptime.config_get.display_name in out + + +def test_list_uptime_check_ips(capsys): + snippets.list_uptime_check_ips() + out, _ = capsys.readouterr() + assert "Singapore" in out