Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support Tencent SMS #470

Merged
merged 13 commits into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
- None

## New features
- [OpsGenie] Add support for custom description - [#457](https://github.com/jertel/elastalert2/pull/457) - @nickbabkin
- Added support for markdown style formatting of aggregation tables - [#415](https://github.com/jertel/elastalert2/pull/415) - @Neuro-HSOC
- [OpsGenie] Add support for custom description - [#457](https://github.com/jertel/elastalert2/pull/457), [#460](https://github.com/jertel/elastalert2/pull/460) - @nickbabkin
- [Tencent SMS] Added support for Tencent SMS - [#470](https://github.com/jertel/elastalert2/pull/470) - @liuxingjun

## Other changes
- Fixed typo in default setting accidentally introduced in [#407](https://github.com/jertel/elastalert2/pull/407) - [#413](https://github.com/jertel/elastalert2/pull/413) - @perceptron01
- Fix saving feature which was ignoring --start/--end, and storing no content with default --days value to 0
- [Rule Test] Fix issue related to --start/--end/--days params - [#424](https://github.com/jertel/elastalert2/pull/424), [#433](https://github.com/jertel/elastalert2/pull/433) - @thican
- Changed the wording of ElastAlert to ElastAlert 2 and Update FAQ -[#446](https://github.com/jertel/elastalert2/pull/446) - @nsano-rururu
- Add missing show_ssl_warn and silence_qk_value params to docs - [#469](https://github.com/jertel/elastalert2/pull/469) - @jertel

Expand All @@ -34,7 +34,7 @@
- None

## Other changes
- Fixed config lookup bug accidentally introduced in [#407](https://github.com/jertel/elastalert2/pull/407)
- Fixed typo in default setting accidentally introduced in [#407](https://github.com/jertel/elastalert2/pull/407) - [#413](https://github.com/jertel/elastalert2/pull/413) - @perceptron01

# 2.2.0

Expand Down
1 change: 1 addition & 0 deletions docs/source/elastalert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Currently, we have support built in for these alert types:
- Splunk On-Call (Formerly VictorOps)
- Stomp
- Telegram
- Tencent SMS
- TheHive
- Twilio
- Zabbix
Expand Down
64 changes: 64 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,70 @@ Example usage::
telegram_bot_token: "bot_token"
telegram_room_id: "chat_id"


Tencent SMS
~~~~~~~~~~~

Required:

``tencent_sms_secret_id``: ``SecretID`` is used to identify the API caller.

``tencent_sms_secret_key``: ``SecretKey`` is used to encrypt the string to sign that can be verified on the server. You should keep it private and avoid disclosure.

``tencent_sms_sdk_appid``: SMS application ID, which is the `SdkAppId` generated after an application is added in the `SMS console <https://console.cloud.tencent.com/smsv2>`_, such as 1400006666

``tencent_sms_to_number``: Target mobile number in the E.164 standard (+[country/region code][mobile number])

Example: +8613711112222, which has a + sign followed by 86 (country/region code) and then by 13711112222 (mobile number). Up to 200 mobile numbers are supported

``tencent_sms_template_id``: Template ID. You must enter the ID of an approved template, which can be viewed in the `SMS console <https://console.cloud.tencent.com/smsv2>`_.

If you need to send SMS messages to global mobile numbers, you can only use a Global SMS template.

Optional:

``tencent_sms_sign_name``: Content of the SMS signature, which should be encoded in UTF-8. You must enter an approved signature, such as Tencent Cloud. The signature information can be viewed in the SMS console.
Note: this parameter is required for Mainland China SMS.

``tencent_sms_region``: Region parameter, which is used to identify the region(`Mainland China <https://intl.cloud.tencent.com/document/api/382/40466#region-list>`_ or
`Global <https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8>`_) to which the data you want to work with belongs.

``tencent_sms_template_parm``: The number of template parameters needs to be consistent with the number of variables of the template corresponding to TemplateId.
this value format by `rfc6901 <https://datatracker.ietf.org/doc/html/rfc6901>`_

.. code-block:: json

{
"_index" : "tmec"
"_type" : "fluentd",
"_id" : "PeXLrnsBvusb3d0w6dUl",
"_score" : 1.0,
"_source" : {
"kubernetes" : {
"host" : "9.134.191.187",
"pod_id" : "66ba4e5a-1ad2-4655-9a8e-cffb6b942559",
"labels" : {
"release" : "nginx",
"pod-template-hash" : "6bd96d6f74"
},
"namespace_name" : "app",
"pod_name" : "app.nginx-6bd96d6f74-2ts4x"
},
"time" : "2021-09-04T03:13:24.192875Z",
"message" : "2021-09-03T14:34:08+0000|INFO|vector eps : 192.168.0.2:10000,",
}
}


.. code-block:: yaml

tencent_sms_template_id: "1123835"
tencent_sms_template_parm:
- "/kubernetes/pod_name"




TheHive
~~~~~~~

Expand Down
145 changes: 145 additions & 0 deletions elastalert/alerters/tencentsms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
from elastalert.alerts import Alerter, BasicMatchString
from elastalert.util import EAException, elastalert_logger
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20210111 import sms_client, models
from jsonpointer import resolve_pointer


class TencentSMSAlerter(Alerter):
# en doc: https://intl.cloud.tencent.com/document/product/382/40606
# zh-cn doc: https://cloud.tencent.com/document/product/382/43196
""" Send alert using tencent SMS service """

# By setting required_options to a set of strings
# You can ensure that the rule config file specifies all
# of the options. Otherwise, ElastAlert 2 will throw an exception
# when trying to load the rule.
required_options = frozenset([
'tencent_sms_secret_id',
'tencent_sms_secret_key',
'tencent_sms_sdk_appid',
'tencent_sms_to_number',
'tencent_sms_template_id',
])

def __init__(self, *args):
super(TencentSMSAlerter, self).__init__(*args)
self.tencent_sms_secret_id = self.rule.get('tencent_sms_secret_id')
self.tencent_sms_secret_key = self.rule.get('tencent_sms_secret_key')
self.tencent_sms_sdk_appid = self.rule.get('tencent_sms_sdk_appid')
self.tencent_sms_to_number = self.rule.get('tencent_sms_to_number', [])
self.tencent_sms_region = self.rule.get('tencent_sms_region', 'ap-guangzhou')
self.tencent_sms_sign_name = self.rule.get('tencent_sms_sign_name') # this parameter is required for Mainland China SMS.
self.tencent_sms_template_id = self.rule.get('tencent_sms_template_id')
self.tencent_sms_template_parm = self.rule.get('tencent_sms_template_parm', [])

# Alert is called
def alert(self, matches):
try:
elastalert_logger.debug("matches:%s", json.dumps(matches))
# Required steps:
# Instantiate an authentication object. The Tencent Cloud account key pair `secretId` and `secretKey` need to be passed in as the input parameters.
# The example here uses the way to read from the environment variable, so you need to set these two values in the environment variable first.
# You can also write the key pair directly into the code, but be careful not to copy, upload, or share the code to others;
# otherwise, the key pair may be leaked, causing damage to your properties.
# Query the CAM key: https://console.cloud.tencent.com/cam/capi
cred = credential.Credential(self.tencent_sms_secret_id, self.tencent_sms_secret_key)
# cred = credential.Credential(
# os.environ.get(""),
# os.environ.get("")
# )
# (Optional) Instantiate an HTTP option
httpProfile = HttpProfile()
# If you need to specify the proxy for API access, you can initialize HttpProfile as follows
# httpProfile = HttpProfile(proxy="http://username:password@proxy IP:proxy port")
httpProfile.reqMethod = "POST" # POST request (POST request by default)
httpProfile.reqTimeout = 30 # Request timeout period in seconds (60 seconds by default)
httpProfile.endpoint = "sms.tencentcloudapi.com" # Specify the access region domain name (nearby access by default)
# Optional steps:
# Instantiate a client configuration object. You can specify the timeout period and other configuration items
clientProfile = ClientProfile()
clientProfile.signMethod = "TC3-HMAC-SHA256" # Specify the signature algorithm
clientProfile.language = "en-US"
clientProfile.httpProfile = httpProfile
# Instantiate the client object of the requested product (with SMS as an example)
# The second parameter is the region information. You can directly enter the string `ap-guangzhou` or import the preset constant
client = sms_client.SmsClient(cred, self.tencent_sms_region, clientProfile)
# Instantiate a request object. You can further set the request parameters according to the API called and actual conditions
# You can directly check the SDK source code to determine which attributes of `SendSmsRequest` can be set
# An attribute may be of a basic type or import another data structure
# We recommend you use the IDE for development where you can easily redirect to and view the documentation of each API and data structure
req = models.SendSmsRequest()
# Settings of a basic parameter:
# The SDK uses the pointer style to specify parameters, so even for basic parameters, you need to use pointers to assign values to them.
# The SDK provides encapsulation functions for importing the pointers of basic parameters
# Help link:
# SMS console: https://console.cloud.tencent.com/smsv2
# sms helper: https://intl.cloud.tencent.com/document/product/382/3773?from_cn_redirect=1
# SMS application ID, which is the `SdkAppId` generated after an application is added in the [SMS console], such as 1400006666
# 短信应用ID: 短信SdkAppid在 [短信控制台] 添加应用后生成的实际SdkAppid,示例如 1400006666
req.SmsSdkAppId = self.tencent_sms_sdk_appid

# SMS signature content, which should be encoded in UTF-8. You must enter an approved signature, which can be viewed in the [SMS console]
# 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看
req.SignName = self.tencent_sms_sign_name

# SMS code number extension, which is not activated by default. If you need to activate it, please contact [SMS Helper]
# 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper]
req.ExtendCode = ""

# User session content, which can carry context information such as user-side ID and will be returned as-is by the server
# 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回
# req.SessionContext = "xxx"

# `senderid` for Global SMS, which is not activated by default. If you need to activate it, please contact [SMS Helper] for assistance. This parameter should be left empty for Mainland China SMS
# 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper]
# req.SenderId = ""

# Target mobile number in the E.164 standard (+[country/region code][mobile number])
# Example: +8613711112222, which has a + sign followed by 86 (country/region code) and then by 13711112222 (mobile number). Up to 200 mobile numbers are supported
# 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号]
# 示例如:+8613711112222,其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
req.PhoneNumberSet = self.tencent_sms_to_number

# Template ID. You must enter the ID of an approved template, which can be viewed in the [SMS console]
# 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看
req.TemplateId = self.tencent_sms_template_id

# Template parameters. If there are no template parameters, leave it empty
req.TemplateParamSet = self.create_template_parm(matches)

elastalert_logger.debug("SendSms request :%s", json.dumps(req.__dict__))

# Initialize the request by calling the `DescribeInstances` method on the client object. Note: the request method name corresponds to the request object
# The returned `resp` is an instance of the `DescribeInstancesResponse` class which corresponds to the request object
resp = client.SendSms(req)
# A string return packet in JSON format is outputted
elastalert_logger.debug("SendSms response :%s", resp.to_json_string())
for item in resp.SendStatusSet:
if item.Code != "Ok":
raise EAException(json.dumps(item.__dict__))
except TencentCloudSDKException as e:
raise EAException("Error posting to TencentSMS: %s" % e)
elastalert_logger.info("Alert sent to TencentSMS")

def create_template_parm(self, matches):
esData = matches[0]
templateParam = []
if len(self.tencent_sms_template_parm) == 0:
return []
for key in self.tencent_sms_template_parm:
templateParam.append(resolve_pointer(esData, key))
return templateParam

# get_info is called after an alert is sent to get data that is written back
# to Elasticsearch in the field "alert_info"
# It should return a dict of information relevant to what the alert does
def get_info(self):
return {
'type': 'tencent sms',
'to_number': self.tencent_sms_to_number
}
2 changes: 2 additions & 0 deletions elastalert/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from elastalert.alerters.sns import SnsAlerter
from elastalert.alerters.teams import MsTeamsAlerter
from elastalert.alerters.zabbix import ZabbixAlerter
from elastalert.alerters.tencentsms import TencentSMSAlerter
from elastalert.util import dt_to_ts
from elastalert.util import dt_to_ts_with_format
from elastalert.util import dt_to_unix
Expand Down Expand Up @@ -87,6 +88,7 @@ class RulesLoader(object):

# Used to map names of alerts to their classes
alerts_mapping = {
'tencent_sms': TencentSMSAlerter,
'email': EmailAlerter,
'jira': JiraAlerter,
'opsgenie': OpsGenieAlerter,
Expand Down
10 changes: 10 additions & 0 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,16 @@ properties:
telegram_proxy_login: {type: string}
telegram_proxy_pass: {type: string}

### Tencent SMS
tencent_sms_secret_id: {type: string}
tencent_sms_secret_key: {type: string}
tencent_sms_sdk_appid: {type: string}
tencent_sms_to_number: {type: array, items: {type: string}}
tencent_sms_region: {type: string}
tencent_sms_sign_name: {type: string}
tencent_sms_template_id: {type: string}
tencent_sms_template_parm: {type: array, items: {type: string}}

### Twilio
twilio_account_sid: {type: string}
twilio_auth_token: {type: string}
Expand Down
65 changes: 65 additions & 0 deletions examples/rules/example_tencent_sms.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Alert when the rate of events exceeds a threshold

# (Optional)
# Elasticsearch host
# es_host: elasticsearch.example.com

# (Optional)
# Elasticsearch port
#es_port: 9200

# (OptionaL) Connect with SSL to Elasticsearch
#use_ssl: True

# (Optional) basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword

# (Required)
# Rule name, must be unique
name: tencent_sms

# (Required)
# Type of alert.
# the frequency rule type alerts when num_events events occur with timeframe time
type: frequency

# (Required)
# Index to search, wildcard supported
index: test

# (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 50

# (Required, frequency specific)
# num_events must occur within this amount of time to trigger an alert
timeframe:
hours: 4

# (Required)
# A list of Elasticsearch filters used for find events
# These filters are joined with AND and nested in a filtered query
# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html
filter:
- query:
query_string:
query: "message: err"

timestamp_field: date

# (Required)
# The alert is use when a match is found
alert:
- "tencent_sms"

tencent_sms_secret_id: "secret_id"
tencent_sms_secret_key: "secret_key"
tencent_sms_sdk_appid: "1400006666"
tencent_sms_to_number:
- "+8613711112222"
tencent_sms_region: "ap-guangzhou"
tencent_sms_sign_name: "tencent"
tencent_sms_template_id: "1123835"
tencent_sms_template_parm:
- "/kubernetes/pod_name"
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ texttable>=0.8.8
statsd-tags==3.2.1.post1
twilio>=6.0.0,<6.58
tzlocal<3.0
tencentcloud-sdk-python>=3.0.484
jsonpointer>=2.1
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
'twilio>=6.0.0,<6.58',
'cffi>=1.11.5',
'statsd-tags==3.2.1.post1',
'tzlocal<3.0'
'tzlocal<3.0',
'tencentcloud-sdk-python>=3.0.484',
'jsonpointer>=2.1'
]
)
Loading