From 0cfc2db0f7847d19756a1ca49d51b7940453ae26 Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Wed, 7 Mar 2018 15:44:34 -0800 Subject: [PATCH 1/8] git ignore .idea folder --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 88ffe46..9306e46 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,6 @@ ENV/ # Rope project settings .ropeproject + +# JetBrains (pyCharm) project settings +.idea \ No newline at end of file From 5d3bbe4e71b283aa5dce691643d71df0dddd9edd Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 10:01:33 -0800 Subject: [PATCH 2/8] add AlertNotificationPolicy class and get_alert_notification_policy() --- src/v310/__init__.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/v310/__init__.py b/src/v310/__init__.py index 98bec80..a253411 100755 --- a/src/v310/__init__.py +++ b/src/v310/__init__.py @@ -107,6 +107,12 @@ class AlertDownloadableReportFilter(TintriEntityV310): _url = 'alert/alertListDownloadable' typeId = 'com.tintri.api.rest.v310.dto.domain.beans.alerts.AlertDownloadableReportFilter' +class AlertNotificationPolicy(TintriEntityV310): + typeId = 'com.tintri.api.rest.v310.dto.domain.NotificationPolicy' + _url = 'alert/notificationPolicy' + _property_map = {'uuid': Uuid, 'lastUpdatedTime': DateTime} + _is_paginated = True + class Alert(TintriEntityV310): typeId = 'com.tintri.api.rest.v310.dto.domain.Alert' _url = 'alert' @@ -1234,6 +1240,25 @@ def get_alert_filter_scope(self): """ return self._get_all(resource_url='alert/filter', response_class=FilterScope) + @api + def get_alert_notification_policy(self, alert_id=None): + """ + Returns alert alert notifications, either all or filtered by alert_id + + **Supported on:** VMstore and TGC (all versions) + + Args: + alert_id (str): specific alert_id to filter by + + Returns: + AlertNotificationPolicy: notification policy object + """ + return self._get_all( + resource_url='alert/notificationPolicy', + query_params={'alertId': alert_id}, + response_class=AlertNotificationPolicy + ) + @api def update_alerts(self, objs, properties_to_update, request=None): """ From 8355306f8cff97eca644633218a763789d30bc7d Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 10:02:25 -0800 Subject: [PATCH 3/8] add example for get_alert_notification_policy() --- examples/alerts/get_notification.py | 134 ++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100755 examples/alerts/get_notification.py diff --git a/examples/alerts/get_notification.py b/examples/alerts/get_notification.py new file mode 100755 index 0000000..d30f80c --- /dev/null +++ b/examples/alerts/get_notification.py @@ -0,0 +1,134 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# The MIT License (MIT) +# +# Copyright (c) 2016 Tintri, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import sys +import time + +from tintri.common import TintriServerError +from tintri.v310 import Tintri + +""" + This scripts shows all notificationPolicies (or only policies for a given alert) + + Command usage: get_notifications.py [] + +""" +# For exhaustive messages on console, make it to True; otherwise keep it False +debug_mode = False +APPLIANCE_URL = "/v310/alert/notificationPolicy" + + +def print_with_prefix(prefix, out): + print(prefix + out) + return + + +def print_debug(out): + if debug_mode: + print_with_prefix("[DEBUG] : ", out) + return + + +def print_info(out): + print_with_prefix("[INFO] : ", out) + return + + +def print_error(out): + print_with_prefix("[ERROR] : ", out) + return + + +def my_timezone(): + tz_hours = time.timezone / -3600 + tz_minutes = time.timezone % 3600 + return "{0:0=+3d}:{1:0=2d}".format(tz_hours, tz_minutes) + + +def print_policies(): + policies = tintri.get_alert_notification_policy(alert_id=alert_id) + + try: + # object is iterable + iter(policies) + except TypeError: + # only one result: make it iterable + policies = (policies,) + + print("Policy Name\tEnabled\tAlert IDs") + for policy in policies: + print("%s\t%s\t%s\t%s" % (policy.uuid.uuid, policy.name, policy.notificationEnabled, ','.join(policy.alertIds))) + pass + + +# main +if len(sys.argv) < 4: + print("\nShows alert policies.\n") + print("Usage: " + sys.argv[0] + " server user_name password [alert_id]") + print(" Where: server - the VMstore name or IP address") + print(" user_name - an administrative user usually 'admin'") + print(" password - the password for user_name") + print(" alert_id - optional: only for this alert ID") + print("") + sys.exit(-1) + +server_name = sys.argv[1] +user_name = sys.argv[2] +password = sys.argv[3] +try: + alert_id = sys.argv[4] +except IndexError: + alert_id = None + +try: + # instantiate the Tintri server. + tintri = Tintri(server_name) + + # Get version and product + version_info = tintri.version + product_name = version_info.productName + if not tintri.is_vmstore(): + raise TintriServerError(0, -1, "Tintri server needs to be VMstore, not " + product_name) + + preferredVersion = version_info.preferredVersion + print("API Version: " + preferredVersion) + + # Login to TGC + tintri.login(user_name, password) + +except TintriServerError as tse: + print_error(tse.__str__()) + sys.exit(2) + +try: + print_policies() + +except TintriServerError as tse: + print_error(tse.__str__()) + tintri.logout() + sys.exit(2) + +# All pau, log out +tintri.logout() From 0320029262c7de6f3bf5dc954ead0ca8bf981993 Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 13:23:37 -0800 Subject: [PATCH 4/8] get_alert_notification_policy() by policy UUID --- src/v310/__init__.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/v310/__init__.py b/src/v310/__init__.py index a253411..16d47da 100755 --- a/src/v310/__init__.py +++ b/src/v310/__init__.py @@ -1241,22 +1241,32 @@ def get_alert_filter_scope(self): return self._get_all(resource_url='alert/filter', response_class=FilterScope) @api - def get_alert_notification_policy(self, alert_id=None): + def get_alert_notification_policy(self, policy_id=None, alert_id=None): """ - Returns alert alert notifications, either all or filtered by alert_id + Returns alert alert notifications, either all or filtered by notification_id or alert_id **Supported on:** VMstore and TGC (all versions) Args: + policy_id (str): uuid of a notification alert_id (str): specific alert_id to filter by Returns: - AlertNotificationPolicy: notification policy object + list|AlertNotificationPolicy: notification policy object """ + url = 'alert/notificationPolicy/' + if policy_id: + url += policy_id + + query_params = {} + if alert_id: + query_params = {'alertId': alert_id} + return self._get_all( - resource_url='alert/notificationPolicy', - query_params={'alertId': alert_id}, - response_class=AlertNotificationPolicy + resource_url=url, + query_params=query_params, + response_class=AlertNotificationPolicy, + ) @api From 3b5ab136141b90e177ccb0ef50ac31b9a93ab41d Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 16:06:34 -0800 Subject: [PATCH 5/8] create/update alert.notificationPolicy --- src/v310/__init__.py | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/v310/__init__.py b/src/v310/__init__.py index 16d47da..3b7b7c3 100755 --- a/src/v310/__init__.py +++ b/src/v310/__init__.py @@ -1243,7 +1243,7 @@ def get_alert_filter_scope(self): @api def get_alert_notification_policy(self, policy_id=None, alert_id=None): """ - Returns alert alert notifications, either all or filtered by notification_id or alert_id + Returns alert notifications. either all or filtered by notification_id or alert_id **Supported on:** VMstore and TGC (all versions) @@ -1252,7 +1252,7 @@ def get_alert_notification_policy(self, policy_id=None, alert_id=None): alert_id (str): specific alert_id to filter by Returns: - list|AlertNotificationPolicy: notification policy object + list|AlertNotificationPolicy: notification policy object(s) """ url = 'alert/notificationPolicy/' if policy_id: @@ -1266,9 +1266,38 @@ def get_alert_notification_policy(self, policy_id=None, alert_id=None): resource_url=url, query_params=query_params, response_class=AlertNotificationPolicy, - ) + @api + def create_alert_notification_policy(self, policy): + """ + Returns alert notifications. either all or filtered by notification_id or alert_id + + **Supported on:** VMstore and TGC (all versions) + + Args: + policy (AlertNotificationPolicy): Instance of AlertNotificationPolicy + + Returns: + list|AlertNotificationPolicy: notification policy object(s) + """ + self._create(policy, request_class=AlertNotificationPolicy) + + @api + def update_alert_notification_policy(self, policy): + """ + Returns alert notifications. either all or filtered by notification_id or alert_id + + **Supported on:** VMstore and TGC (all versions) + + Args: + policy (AlertNotificationPolicy): Instance of AlertNotificationPolicy + + Returns: + list|AlertNotificationPolicy: notification policy object(s) + """ + self._update(policy, request_class=AlertNotificationPolicy, path_params=[policy.uuid.uuid, ]) + @api def update_alerts(self, objs, properties_to_update, request=None): """ From b886432df8168fe0c2a5a0858612e4f747aeae88 Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 16:10:11 -0800 Subject: [PATCH 6/8] example for silencing a list of alerts --- examples/alerts/silence_alerts.py | 137 ++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100755 examples/alerts/silence_alerts.py diff --git a/examples/alerts/silence_alerts.py b/examples/alerts/silence_alerts.py new file mode 100755 index 0000000..9967b3e --- /dev/null +++ b/examples/alerts/silence_alerts.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# The MIT License (MIT) +# +# Copyright (c) 2016 Tintri, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import sys +import time + +from tintri.common import TintriServerError +from tintri.v310 import Tintri, AlertNotificationPolicy + +""" + This scripts creates a notificationPolicy for one or more alerts + + Command usage: + create_notifications.py + +""" +# For exhaustive messages on console, make it to True; otherwise keep it False +debug_mode = True +APPLIANCE_URL = "/v310/alert/notificationPolicy" + + +def print_with_prefix(prefix, out): + print(prefix + out) + return + + +def print_debug(out): + if debug_mode: + print_with_prefix("[DEBUG] : ", out) + return + + +def print_info(out): + print_with_prefix("[INFO] : ", out) + return + + +def print_error(out): + print_with_prefix("[ERROR] : ", out) + return + + +def my_timezone(): + tz_hours = time.timezone / -3600 + tz_minutes = time.timezone % 3600 + return "{0:0=+3d}:{1:0=2d}".format(tz_hours, tz_minutes) + + +def silence_alerts(): + # for easier enabling/disabling we will create one policy for each alert + for alert_id in alerts.split(','): + # get the policy that contains this alert (returns a list with 1 element) + existing_policy = tintri.get_alert_notification_policy(alert_id=alert_id) + # it exists and is enabled + if existing_policy: + # policy exists, but alerts are enabled + if existing_policy[0].notificationEnabled != 'false': + # override and update + existing_policy[0].notificationEnabled = 'false' + tintri.update_alert_notification_policy(existing_policy[0]) + else: + # create a new policy for this alert + obj = AlertNotificationPolicy() + obj.name = 'Disable ' + alert_id + obj.notificationEnabled = False + obj.alertIds = [alert_id, ] + tintri.create_alert_notification_policy(obj) + + +# main +if len(sys.argv) < 5: + print("\nCreates a notificationPolicy.\n") + print("Usage: " + sys.argv[0] + " server user_name password alerts") + print(" Where: server - the VMstore name or IP address") + print(" user_name - an administrative user usually 'admin'") + print(" password - the password for user_name") + print(" alerts - one or more alert IDs, comma separated") + print("") + sys.exit(-1) + +server_name = sys.argv[1] +user_name = sys.argv[2] +password = sys.argv[3] +alerts = sys.argv[4] + +try: + # instantiate the Tintri server. + tintri = Tintri(server_name) + + # Get version and product + version_info = tintri.version + product_name = version_info.productName + if not tintri.is_vmstore(): + raise TintriServerError(0, -1, "Tintri server needs to be VMstore, not " + product_name) + + preferredVersion = version_info.preferredVersion + print("API Version: " + preferredVersion) + + # Login to TGC + tintri.login(user_name, password) + +except TintriServerError as tse: + print_error(tse.__str__()) + sys.exit(2) + +try: + silence_alerts() + +except TintriServerError as tse: + print_error(tse.__str__()) + tintri.logout() + sys.exit(2) + +# All pau, log out +tintri.logout() From 54ae461309a55ebef5d703b26789494835d25b7c Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 16:37:55 -0800 Subject: [PATCH 7/8] delete_alert_notification_policy() by UUID or AlertNotificationPolicy instance --- src/v310/__init__.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/v310/__init__.py b/src/v310/__init__.py index 3b7b7c3..ebb0e5e 100755 --- a/src/v310/__init__.py +++ b/src/v310/__init__.py @@ -1271,7 +1271,7 @@ def get_alert_notification_policy(self, policy_id=None, alert_id=None): @api def create_alert_notification_policy(self, policy): """ - Returns alert notifications. either all or filtered by notification_id or alert_id + Creates a new notificationPolicy **Supported on:** VMstore and TGC (all versions) @@ -1286,7 +1286,7 @@ def create_alert_notification_policy(self, policy): @api def update_alert_notification_policy(self, policy): """ - Returns alert notifications. either all or filtered by notification_id or alert_id + Updates an existing notificationPolicy **Supported on:** VMstore and TGC (all versions) @@ -1298,6 +1298,28 @@ def update_alert_notification_policy(self, policy): """ self._update(policy, request_class=AlertNotificationPolicy, path_params=[policy.uuid.uuid, ]) + @api + def delete_alert_notification_policy(self, policy=None, uuid=None): + """ + Deletes a notificationPolicy + + **Supported on:** VMstore and TGC (all versions) + + Args: + policy (AlertNotificationPolicy): Instance of AlertNotificationPolicy to delete + uuid (str): UUID of the AlertNotificationPolicy to delete + + Returns: + list|AlertNotificationPolicy: notification policy object(s) + """ + if not uuid: + try: + uuid = policy.uuid.uuid + except AttributeError: + raise TintriError("delete_alert_notification_policy reqyires either policy or uuid parameter") + + self._delete(request_class=AlertNotificationPolicy, path_params=[uuid, ]) + @api def update_alerts(self, objs, properties_to_update, request=None): """ From bf2f884d76f896b03bf19787d180fc5e802f6e15 Mon Sep 17 00:00:00 2001 From: Florian Wegscheider Date: Thu, 8 Mar 2018 16:38:22 -0800 Subject: [PATCH 8/8] example for deleting alert notification policies --- examples/alerts/delete_notification.py | 143 +++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100755 examples/alerts/delete_notification.py diff --git a/examples/alerts/delete_notification.py b/examples/alerts/delete_notification.py new file mode 100755 index 0000000..2aa9e36 --- /dev/null +++ b/examples/alerts/delete_notification.py @@ -0,0 +1,143 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# The MIT License (MIT) +# +# Copyright (c) 2016 Tintri, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +import re +import sys +import time + +from tintri.common import TintriServerError, TintriError +from tintri.v310 import Tintri, AlertNotificationPolicy + +""" + This scripts deletes notificationPolicies by one or more policy UUIDs or alertIds + + Command usage: + delete_notifications.py + +""" +# For exhaustive messages on console, make it to True; otherwise keep it False +debug_mode = True +APPLIANCE_URL = "/v310/alert/notificationPolicy" + + +def print_with_prefix(prefix, out): + print(prefix + out) + return + + +def print_debug(out): + if debug_mode: + print_with_prefix("[DEBUG] : ", out) + return + + +def print_info(out): + print_with_prefix("[INFO] : ", out) + return + + +def print_error(out): + print_with_prefix("[ERROR] : ", out) + return + + +def my_timezone(): + tz_hours = time.timezone / -3600 + tz_minutes = time.timezone % 3600 + return "{0:0=+3d}:{1:0=2d}".format(tz_hours, tz_minutes) + + +def delete_notification_policies(): + # regex to check if an identifier is a UUID + uuid_regex = re.compile(r'^[\da-f]{8}-([\da-f]{4}-){3}[\da-f]{12}$', re.IGNORECASE) + uuids = [] + + # loop through the given identifiers and collect the UUIDs + for thing in identifiers.split(','): + if uuid_regex.match(thing): + # it's already a UUID + uuids.append(thing) + else: + # assume it's an alertId and try to get the matching policy + try: + policy = tintri.get_alert_notification_policy(alert_id=thing) + uuids.append(policy[0].uuid.uuid) + except TintriServerError: + print_info(thing + ' not found') + + # loop through the (unique) collected UUIDs and delete each one of them + for uuid in set(uuids): + print_info('delete ' + uuid) + try: + tintri.delete_alert_notification_policy(uuid=uuid) + except TintriError as e: + print_error(e.cause) + + +# main +if len(sys.argv) < 5: + print("\nCreates a notificationPolicy.\n") + print("Usage: " + sys.argv[0] + " server user_name password alerts") + print(" Where: server - the VMstore name or IP address") + print(" user_name - an administrative user usually 'admin'") + print(" password - the password for user_name") + print(" UUIDs|alerts - one or more UUIDs or alert IDs, comma separated") + print("") + sys.exit(-1) + +server_name = sys.argv[1] +user_name = sys.argv[2] +password = sys.argv[3] +identifiers = sys.argv[4] + +try: + # instantiate the Tintri server. + tintri = Tintri(server_name) + + # Get version and product + version_info = tintri.version + product_name = version_info.productName + if not tintri.is_vmstore(): + raise TintriServerError(0, -1, "Tintri server needs to be VMstore, not " + product_name) + + preferredVersion = version_info.preferredVersion + print("API Version: " + preferredVersion) + + # Login to TGC + tintri.login(user_name, password) + +except TintriServerError as tse: + print_error(tse.__str__()) + sys.exit(2) + +try: + delete_notification_policies() + +except TintriServerError as tse: + print_error(tse.__str__()) + tintri.logout() + sys.exit(2) + +# All pau, log out +tintri.logout()