Alerting Plugins (#93)
* Alert Plugin Signed-off-by: Arnav Das <[email protected]> * lint file header license Signed-off-by: Arnav Das <[email protected]> * Tests For Alerting[Monitors] Signed-off-by: Arnav Das <[email protected]> * Tests For Alerting[Destinations] Signed-off-by: Arnav Das <[email protected]> * dynamic lookup 90#issuecomment-1003396742 Signed-off-by: Arnav Das <[email protected]> * Alerting Async Signed-off-by: Arnav Das <[email protected]> * Lint Changes Signed-off-by: Arnav Das <[email protected]> * alerting plugins integration tests Signed-off-by: Arnav Das <[email protected]> * Integ UnitTests Skip on OPENSEARCH_VERSION >= 2.0.0 Signed-off-by: Arnav Das <[email protected]> * Unit Test Skip Complete Signed-off-by: Arnav Das <[email protected]> * License Headers fixed Signed-off-by: Arnav Das <[email protected]> * test_urllib3_connection timeout Signed-off-by: Arnav Das <[email protected]> * lint Signed-off-by: Arnav Das <[email protected]> * Fix licenses in all files Signed-off-by: Harsha Vamsi Kalluri <[email protected]> * Remove elastic search licenses on new files Signed-off-by: Harsha Vamsi Kalluri <[email protected]> * Fix formatting Signed-off-by: Harsha Vamsi Kalluri <[email protected]> Signed-off-by: Arnav Das <[email protected]> Signed-off-by: Harsha Vamsi Kalluri <[email protected]> Co-authored-by: Harsha Vamsi Kalluri <[email protected]>
This commit is contained in:
co-authored by
Harsha Vamsi Kalluri
parent
9398975f98
commit
2d03dc773b
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import subprocess
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import gzip
|
||||
import io
|
||||
import json
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
# Licensed to Elasticsearch B.V.under one or more agreements.
|
||||
# Elasticsearch B.V.licenses this file to you under the Apache 2.0 License.
|
||||
# See the LICENSE file in the project root for more information
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
Dynamically generated set of TestCases based on set of yaml files decribing
|
||||
some integration tests. These files are shared among all official OpenSearch
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import asyncio
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
from unittest import SkipTest # noqa: F401
|
||||
from unittest import TestCase
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import warnings
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from test_opensearchpy.test_cases import OpenSearchTestCase
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from test_opensearchpy.test_cases import OpenSearchTestCase
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
from test_opensearchpy.test_cases import OpenSearchTestCase
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# The OpenSearch Contributors require contributions made to
|
||||
# this file be licensed under the Apache-2.0 license or a
|
||||
# compatible open source license.
|
||||
#
|
||||
# Modifications Copyright OpenSearch Contributors. See
|
||||
# GitHub history for details.
|
||||
|
||||
from test_opensearchpy.test_cases import OpenSearchTestCase
|
||||
|
||||
|
||||
class TestAlerting(OpenSearchTestCase):
|
||||
def test_create_monitor(self):
|
||||
# Test Post Method
|
||||
self.client.alerting.create_monitor({})
|
||||
self.assert_url_called("POST", "/_plugins/_alerting/monitors")
|
||||
|
||||
def test_run_monitor(self):
|
||||
self.client.alerting.run_monitor("...")
|
||||
self.assert_url_called("POST", "/_plugins/_alerting/monitors/.../_execute")
|
||||
|
||||
def test_get_monitor(self):
|
||||
# Test Get Method
|
||||
self.client.alerting.get_monitor("...")
|
||||
self.assert_url_called("GET", "/_plugins/_alerting/monitors/...")
|
||||
|
||||
def test_search_monitor(self):
|
||||
# Test Search Method
|
||||
self.client.alerting.search_monitor({})
|
||||
self.assert_url_called("GET", "/_plugins/_alerting/monitors/_search")
|
||||
|
||||
def test_update_monitor(self):
|
||||
# Test Update Method
|
||||
self.client.alerting.update_monitor("...")
|
||||
self.assert_url_called("PUT", "/_plugins/_alerting/monitors/...")
|
||||
|
||||
def test_delete_monitor(self):
|
||||
# Test Delete Method
|
||||
self.client.alerting.delete_monitor("...")
|
||||
self.assert_url_called("DELETE", "/_plugins/_alerting/monitors/...")
|
||||
|
||||
def test_create_destination(self):
|
||||
# Test Post Method
|
||||
self.client.alerting.create_destination({})
|
||||
self.assert_url_called("POST", "/_plugins/_alerting/destinations")
|
||||
|
||||
def test_get_destination(self):
|
||||
# Test Get Method
|
||||
|
||||
# Get a specific destination
|
||||
self.client.alerting.get_destination("...")
|
||||
self.assert_url_called("GET", "/_plugins/_alerting/destinations/...")
|
||||
|
||||
# Get all destinations
|
||||
self.client.alerting.get_destination()
|
||||
self.assert_url_called("GET", "/_plugins/_alerting/destinations")
|
||||
|
||||
def test_update_destination(self):
|
||||
# Test Update Method
|
||||
self.client.alerting.update_destination("...")
|
||||
self.assert_url_called("PUT", "/_plugins/_alerting/destinations/...")
|
||||
|
||||
def test_delete_destination(self):
|
||||
# Test Delete Method
|
||||
self.client.alerting.delete_destination("...")
|
||||
self.assert_url_called("DELETE", "/_plugins/_alerting/destinations/...")
|
||||
|
||||
def test_get_alerts(self):
|
||||
self.client.alerting.get_alerts()
|
||||
self.assert_url_called("GET", "/_plugins/_alerting/monitors/alerts")
|
||||
|
||||
def test_acknowledge_alerts(self):
|
||||
self.client.alerting.acknowledge_alert("...")
|
||||
self.assert_url_called(
|
||||
"POST", "/_plugins/_alerting/monitors/.../_acknowledge/alerts"
|
||||
)
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from opensearchpy.client.utils import _bulk_body, _escape, _make_path, query_params
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import gzip
|
||||
import io
|
||||
import json
|
||||
@@ -784,7 +785,8 @@ class TestConnectionHttpbin:
|
||||
|
||||
def test_urllib3_connection(self):
|
||||
# Defaults
|
||||
conn = Urllib3HttpConnection("httpbin.org", port=443, use_ssl=True)
|
||||
# httpbin.org can be slow sometimes. Hence the timeout
|
||||
conn = Urllib3HttpConnection("httpbin.org", port=443, use_ssl=True, timeout=60)
|
||||
user_agent = conn._get_default_user_agent()
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -798,7 +800,7 @@ class TestConnectionHttpbin:
|
||||
|
||||
# http_compress=False
|
||||
conn = Urllib3HttpConnection(
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=False
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=False, timeout=60
|
||||
)
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -812,7 +814,7 @@ class TestConnectionHttpbin:
|
||||
|
||||
# http_compress=True
|
||||
conn = Urllib3HttpConnection(
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=True
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=True, timeout=60
|
||||
)
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -830,6 +832,7 @@ class TestConnectionHttpbin:
|
||||
use_ssl=True,
|
||||
http_compress=True,
|
||||
headers={"header1": "value1"},
|
||||
timeout=60,
|
||||
)
|
||||
status, data = self.httpbin_anything(
|
||||
conn, headers={"header2": "value2", "header1": "override!"}
|
||||
@@ -851,7 +854,7 @@ class TestConnectionHttpbin:
|
||||
|
||||
def test_requests_connection(self):
|
||||
# Defaults
|
||||
conn = RequestsHttpConnection("httpbin.org", port=443, use_ssl=True)
|
||||
conn = RequestsHttpConnection("httpbin.org", port=443, use_ssl=True, timeout=60)
|
||||
user_agent = conn._get_default_user_agent()
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -865,7 +868,7 @@ class TestConnectionHttpbin:
|
||||
|
||||
# http_compress=False
|
||||
conn = RequestsHttpConnection(
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=False
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=False, timeout=60
|
||||
)
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -879,7 +882,7 @@ class TestConnectionHttpbin:
|
||||
|
||||
# http_compress=True
|
||||
conn = RequestsHttpConnection(
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=True
|
||||
"httpbin.org", port=443, use_ssl=True, http_compress=True, timeout=60
|
||||
)
|
||||
status, data = self.httpbin_anything(conn)
|
||||
assert status == 200
|
||||
@@ -897,6 +900,7 @@ class TestConnectionHttpbin:
|
||||
use_ssl=True,
|
||||
http_compress=True,
|
||||
headers={"header1": "value1"},
|
||||
timeout=60,
|
||||
)
|
||||
status, data = self.httpbin_anything(
|
||||
conn, headers={"header2": "value2", "header1": "override!"}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import time
|
||||
|
||||
from opensearchpy.connection import Connection
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from opensearchpy.exceptions import TransportError
|
||||
|
||||
from .test_cases import TestCase
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import sys
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from unittest import SkipTest
|
||||
|
||||
from opensearchpy.helpers import test
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from . import OpenSearchTestCase
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from mock import patch
|
||||
|
||||
from opensearchpy import TransportError, helpers
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# The OpenSearch Contributors require contributions made to
|
||||
# this file be licensed under the Apache-2.0 license or a
|
||||
# compatible open source license.
|
||||
#
|
||||
# Modifications Copyright OpenSearch Contributors. See
|
||||
# GitHub history for details.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
from opensearchpy.helpers.test import OPENSEARCH_VERSION
|
||||
|
||||
from . import OpenSearchTestCase
|
||||
|
||||
|
||||
class TestAlertingPlugin(OpenSearchTestCase):
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_create_destination(self):
|
||||
# Test to create alert destination
|
||||
dummy_destination = {
|
||||
"name": "my-destination",
|
||||
"type": "slack",
|
||||
"slack": {"url": "http://www.example.com"},
|
||||
}
|
||||
response = self.client.alerting.create_destination(dummy_destination)
|
||||
|
||||
self.assertNotIn("errors", response)
|
||||
self.assertIn("_id", response)
|
||||
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_get_destination(self):
|
||||
# Create a dummy destination
|
||||
self.test_create_destination()
|
||||
|
||||
# Try fetching the destination
|
||||
response = self.client.alerting.get_destination()
|
||||
|
||||
self.assertNotIn("errors", response)
|
||||
self.assertGreaterEqual(response["totalDestinations"], 1)
|
||||
self.assertEqual(response["totalDestinations"], len(response["destinations"]))
|
||||
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_create_monitor(self):
|
||||
# Create a dummy destination
|
||||
self.test_create_destination()
|
||||
|
||||
# Try fetching the destination
|
||||
destination = self.client.alerting.get_destination()
|
||||
self.assertGreaterEqual(
|
||||
destination["totalDestinations"],
|
||||
1,
|
||||
"No destination entries found in the database.",
|
||||
)
|
||||
|
||||
# Select the first destination available
|
||||
destination = destination["destinations"][0]
|
||||
|
||||
# A dummy schedule for 1 minute interval
|
||||
schedule = {"period": {"interval": 1, "unit": "MINUTES"}}
|
||||
|
||||
# A dummy query fetching everything
|
||||
query = {"query": {"query_string": {"query": "*"}}}
|
||||
|
||||
# A dummy action with the dummy destination
|
||||
action = {
|
||||
"name": "test-action",
|
||||
"destination_id": destination["id"],
|
||||
"message_template": {"source": "This is my message body."},
|
||||
"throttle_enabled": True,
|
||||
"throttle": {"value": 27, "unit": "MINUTES"},
|
||||
"subject_template": {"source": "TheSubject"},
|
||||
}
|
||||
|
||||
# A dummy trigger with the dummy action
|
||||
triggers = {
|
||||
"name": "test-trigger",
|
||||
"severity": "1",
|
||||
"condition": {
|
||||
"script": {
|
||||
"source": "ctx.results[0].hits.total.value > 0",
|
||||
"lang": "painless",
|
||||
}
|
||||
},
|
||||
"actions": [action],
|
||||
}
|
||||
|
||||
# A dummy monitor with the dummy schedule, dummy query, dummy trigger
|
||||
monitor = {
|
||||
"type": "monitor",
|
||||
"name": "test-monitor",
|
||||
"monitor_type": "query_level_monitor",
|
||||
"enabled": True,
|
||||
"schedule": schedule,
|
||||
"inputs": [{"search": {"indices": ["*"], "query": query}}],
|
||||
"triggers": [triggers],
|
||||
}
|
||||
|
||||
response = self.client.alerting.create_monitor(monitor)
|
||||
|
||||
self.assertNotIn("errors", response)
|
||||
self.assertIn("_id", response)
|
||||
self.assertIn("monitor", response)
|
||||
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_search_monitor(self):
|
||||
# Create a dummy monitor
|
||||
self.test_create_monitor()
|
||||
|
||||
# Create a monitor search query by it's name
|
||||
query = {"query": {"match": {"monitor.name": "test-monitor"}}}
|
||||
|
||||
# Perform the search with the above query
|
||||
response = self.client.alerting.search_monitor(query)
|
||||
|
||||
self.assertNotIn("errors", response)
|
||||
self.assertIn("hits", response)
|
||||
self.assertEqual(response["hits"]["total"]["value"], 1, "No monitor found.")
|
||||
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_get_monitor(self):
|
||||
# Create a dummy monitor
|
||||
self.test_create_monitor()
|
||||
|
||||
# Create a monitor search query by it's name
|
||||
query = {"query": {"match": {"monitor.name": "test-monitor"}}}
|
||||
|
||||
# Perform the search with the above query
|
||||
response = self.client.alerting.search_monitor(query)
|
||||
|
||||
# Select the first monitor
|
||||
monitor = response["hits"]["hits"][0]
|
||||
|
||||
# Fetch the monitor by id
|
||||
response = self.client.alerting.get_monitor(monitor["_id"])
|
||||
|
||||
self.assertNotIn("errors", response)
|
||||
self.assertIn("_id", response)
|
||||
self.assertIn("monitor", response)
|
||||
|
||||
@unittest.skipUnless(
|
||||
(OPENSEARCH_VERSION) and (OPENSEARCH_VERSION < (2, 0, 0)),
|
||||
"Plugin not supported for opensearch version",
|
||||
)
|
||||
def test_run_monitor(self):
|
||||
# Create a dummy monitor
|
||||
self.test_create_monitor()
|
||||
|
||||
# Create a monitor search query by it's name
|
||||
query = {"query": {"match": {"monitor.name": "test-monitor"}}}
|
||||
|
||||
# Perform the search with the above query
|
||||
response = self.client.alerting.search_monitor(query)
|
||||
|
||||
# Select the first monitor
|
||||
monitor = response["hits"]["hits"][0]
|
||||
|
||||
# Run the monitor by id
|
||||
response = self.client.alerting.run_monitor(monitor["_id"])
|
||||
|
||||
self.assertEqual(response["error"], None)
|
||||
self.assertIn("monitor_name", response)
|
||||
self.assertIn("period_start", response)
|
||||
self.assertIn("period_end", response)
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
Dynamically generated set of TestCases based on set of yaml files describing
|
||||
some integration tests. These files are shared among all official OpenSearch
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from typing import Any, AsyncGenerator, Dict, Generator
|
||||
|
||||
from opensearchpy1 import (
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from typing import Any, AsyncGenerator, Dict
|
||||
|
||||
from opensearchpy import (
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from typing import Any, Dict, Generator
|
||||
|
||||
from opensearchpy import ConnectionPool, OpenSearch, RequestsHttpConnection, Transport
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import time
|
||||
|
||||
from opensearchpy import OpenSearch
|
||||
|
||||
Reference in New Issue
Block a user