Skip to content

Commit

Permalink
feat: Jira plugin (#355)
Browse files Browse the repository at this point in the history
* New plugin - jira

alerta_jira is used to create tasks in Jira whenever a new critical entry is made in the alerta. The attribute with the task key in Jira is also placed in the entry that occurred in the alerta.

* Update alerta_jira.py
  • Loading branch information
aazedo authored Oct 18, 2021
1 parent f23bf5f commit e743cdd
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 0 deletions.
67 changes: 67 additions & 0 deletions plugins/jira/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Jira Plugin
===========

Creates a task in Jira and adds the Jira Task attribute in alarm. The created attribute is a link to the Jira task and opens in a new tab.


Installation
------------

Clone the GitHub repo and run:

$ python setup.py install

Or, to install remotely from GitHub run:

$ pip install git+https://github.com/alerta/alerta-contrib.git#subdirectory=plugins/jira

Note: If Alerta is installed in a python virtual environment then plugins
need to be installed into the same environment for Alerta to dynamically
discover them.

Configuration
-------------

Add `jira` to the list of enabled `PLUGINS` in `alertad.conf` server
configuration file and set plugin-specific variables either in the
server configuration file or as environment variables.

```python
PLUGINS = ['jira']
JIRA_PROJECT = '' #project name in jira
JIRA_URL = '' #url access to the jira
JIRA_USER = '' #defined to the according to the jira access data
JIRA_PASS = '' #defined to the according to the jira access data
```

Troubleshooting
---------------

Restart Alerta API and confirm that the plugin has been loaded and enabled.

Set `DEBUG=True` in the `alertad.conf` configuration file and look for log
entries similar to below:

```
--------------------------------------------------------------------------------
2021-04-28 13:43:43,185 alerta.plugins[35]: [DEBUG] Server plugin 'jira' found. [in /venv/lib/python3.7/site-packages/alerta/utils/plugin.py:34]
--------------------------------------------------------------------------------
2021-04-28 13:43:43,707 alerta.plugins[35]: [INFO] Server plugin 'jira' loaded. [in /venv/lib/python3.7/site-packages/alerta/utils/plugin.py:42]
--------------------------------------------------------------------------------
2021-04-28 13:43:43,707 alerta.plugins[35]: [INFO] All server plugins enabled: reject, heartbeat, blackout, telegram, logstash, jira [in /venv/lib/python3.7/site-packages/alerta/utils/plugin.py:45]
--------------------------------------------------------------------------------
2021-04-28 13:43:54,540 alerta.plugins.jira[50]: [INFO] Jira: Received an alert request_id=dbf9e6a1-2c65-4284-887f-792873981c49 ip=10.100.100.239
--------------------------------------------------------------------------------
2021-04-28 13:43:54,541 alerta.plugins.jira[50]: [INFO] JIRA: Create task ... request_id=dbf9e6a1-2c65-4284-887f-792873981c49 ip=10.100.100.239
--------------------------------------------------------------------------------
```

References
----------

* Jira REST API: https://blog.developer.atlassian.com/creating-a-jira-cloud-issue-in-a-single-rest-call/



Copyright (c) 2021 Alexandre Azedo.
94 changes: 94 additions & 0 deletions plugins/jira/alerta_jira.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import logging
import os
import http.client
import json
from base64 import b64encode

try:
from alerta.plugins import app # alerta >= 5.0
except ImportError:
from alerta.app import app # alerta < 5.0
from alerta.plugins import PluginBase

# set plugin logger
LOG = logging.getLogger('alerta.plugins.jira')

# retrieve plugin configurations
JIRA_URL = app.config.get('JIRA_URL') or os.environ.get('JIRA_URL')
JIRA_PROJECT = app.config.get('JIRA_PROJECT') or os.environ.get('JIRA_PROJECT')
JIRA_USER = app.config.get('JIRA_USER') or os.environ.get('JIRA_USER')
JIRA_PASS = app.config.get('JIRA_PASS') or os.environ.get('JIRA_PASS')

class JiraCreate(PluginBase):

def _sendjira(self, host, event, value, chart, text, severity):
LOG.info('JIRA: Create task ...')
userpass = "%s:%s" %(JIRA_USER, JIRA_PASS)
userAndPass = b64encode(bytes(userpass, "utf-8")).decode("ascii")
LOG.debug('JIRA_URL: {}'.format(JIRA_URL))
conn = http.client.HTTPSConnection("%s" %(JIRA_URL))

payload_dict = {
"fields": {
"project":
{
"key": "%s" %(JIRA_PROJECT)
},
"summary": "Server %s: alert %s in chart %s - Severity: %s" %(host.upper(), event.upper(), chart.upper(), severity.upper()),
"description": "The chart %s INFO: %s. \nVALUE: %s." %(chart, text, value),
"issuetype": {
"name": "Bug"
},
}
}
payload = json.dumps(payload_dict, indent = 4)
headers = {
'Content-Type': "application/json",
'Authorization': "Basic %s" % userAndPass
}

conn.request("POST", '/rest/api/2/issue/', payload, headers)
res = conn.getresponse()
data = res.read()
data = json.loads(data)
return data["key"]

# reject or modify an alert before it hits the database
def pre_receive(self, alert):
return alert

# after alert saved in database, forward alert to external systems
def post_receive(self, alert):
try:
# if the alert is critical and don't duplicate, create task in Jira
if alert.status not in ['ack', 'closed', 'shelved'] and alert.duplicate_count == 0:
LOG.info("Jira: Received an alert")
LOG.debug("Jira: ALERT {}".format(alert))
LOG.debug("Jira: ID {}".format(alert.id))
LOG.debug("Jira: RESOURCE {}".format(alert.resource))
LOG.debug("Jira: EVENT {}".format(alert.event))
LOG.debug("Jira: SEVERITY {}".format(alert.severity))
LOG.debug("Jira: TEXT {}".format(alert.text))

# get basic info from alert
host = alert.resource.split(':')[0]
LOG.debug("JIRA: HOST {}".format(host))
chart = ".".join(alert.event.split('.')[:-1])
LOG.debug("JIRA: CHART {}".format(chart))
event = alert.event.split('.')[-1]
LOG.debug("JIRA: EVENT {}".format(event))

# call the _sendjira and modify de text (discription)
task = self._sendjira(host, event, alert.value, chart, alert.text, alert.severity)
task_url = "https://" + JIRA_URL + "/browse/" + task
href = '<a href="%s" target="_blank">%s</a>' %(task_url, task)
alert.attributes = {'Jira Task': href}
return alert

except Exception as e:
LOG.error('Jira: Failed to create task: %s', e)
return

# triggered by external status changes, used by integrations
def status_change(self, alert, status, text):
return
22 changes: 22 additions & 0 deletions plugins/jira/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from setuptools import setup, find_packages

version = '1.0.0'

setup(
name="alerta-jira",
version=version,
description='Alerta plugin for create tasks in jira',
url='https://github.com/alerta/alerta-contrib',
license='MIT',
author='Alexandre Azedo',
author_email='[email protected]',
packages=find_packages(),
py_modules=['alerta_jira'],
include_package_data=True,
zip_safe=True,
entry_points={
'alerta.plugins': [
'jira = alerta_jira:JiraCreate'
]
}
)

0 comments on commit e743cdd

Please sign in to comment.