Skip to content
This repository has been archived by the owner on Aug 13, 2020. It is now read-only.

Commit

Permalink
Use ansible open_url function instead of httplib
Browse files Browse the repository at this point in the history
Now using the open_url helper from ansible.module_utils.urls
Udated the GRAFANA_HOST variable disappear in favor of GRAFANA_URL which
is expected to contain the annotations api URL.

Added new environment variables required to use the features coming with
the use of open_url.
  • Loading branch information
rrey committed Mar 18, 2018
1 parent 2b4bd49 commit bede5f6
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 39 deletions.
32 changes: 25 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
language: python
sudo: required
python:
- "2.7"
install:
- '2.6'
stages:
- linter
- test-basic-auth
jobs:
include:
- stage: linter
install:
- pip install -r requirements.txt
script:
- make check
services:
- docker
script:
- make syntax
- stage: test-basic-auth
install:
- pip install -r requirements.txt
env:
- secure: Bv8kXVD9Zy2+nSVcIUcGwupC/3/0hJIzpfsPk9+4fpDKARBxMdCv5AsshoPr6HbuVKucOCALd9sSyTTlTEjOSVGwfmYDvlxtq3tG5b1l0dD6wyoE70B2SzQ+oGcAasufXPe+wrPJbnygG3j8yLZ3IKeSzWkpuDkAc2TxWIPlbrYHTGu2IfouhCxDtZavbxzSQ/U5tXIUdqq7g5Oeb6W0Au8TalAsnVl0bKjTNp0tbxfMJ6DXQNYj20pdpom/Fb2uTY6SA9xiTBLLyrTc1tM6MvYHYtLCTHLLNIcZoEgbug6Bo5lbXp//ODBCzNiktof/Tg9tvtHQLL0nVGWVtHnnYwFn2SfPqq9uCN3YNga9dZwHaLhhJhMTK5tcVdGagyawPLkcjtcRfW//CnWGJg5ZP1SlPnMHANy86esUQb6tqECn0HaNEhBHlvGzDCmHb71R0eS0zHFvmlabnzpm+uIGEI5DFzbeNKAy0pHE8YNrIuoqyQJc5hu32DjYZbozFED4JHVezRn6yuzArRXN/3sTeJYhtW9Jzn3wKejXDw06xOZnbFcvxH9De4MvQ7MW2iI8vQxTY46I22Vxs+ouXtE/x0yUNSfA6ERDl6zvc4QAnaB8ScoLvhymSCYw5VcA+PNKfCaY7lgumYSs3iwc+l12fb5Dt56Qo1WuJexLAxcXaMA=
- secure: onS72up7xaCe+AQ+WGXO51oyCSzAMUHWIH8Yf9DOLXWI3SoGE2a+o96TBmHKpne1+oQFHxB1QVPiOlCefdmeDbphwhvzjl6DxMZXdNgS71YAzRzcg8G5ChE9LZZZrRBXcUu235OFxG6m9dkPlVN37wIwrN3h+g+KBwpBpcJoV7Z8uS0VngYlH3wFudAsQ1fCgq8hfoFQmm6Ji9UD9BxAwzGX2zsHdslwhDKubBJY5WL+c5Sc5rjOzVLh+nFEEvbw0++zVCC7mMs8wX97EVaacAn6xbykzKuEqKMcheDIYB6BivAJAjPW+TKzo5i8MblAL0wJQJrIn6/2DiyMnAD7xoEhc1myh+vX9RH63det+GwYrPLjHabya18IIuOOxaa0I0fAtygQsHnbfnlnDxZp3/EzhCtpcs8H9C8QCs+kTkWjyv5LikJDGKCyYL0KHfkpPKpFCqKbZk+VXfsqJIWQlUrJUdd6cijcmPK3rt2Wj3tjLwf2y+Y1JkbnM5UCNq8qJk+YaQUbs+UHi3GtKpt1wQlvKHNQj2OkYvc+dpVPeDW43kNjJ7eiEa27DBVCCpCA95OrAbxNbvYf+Xb80ZaxmHkU6K+XlWg7S6NlrSp315UI6hHNQzYZ3Mw3NqR55l9tK4YoTKt+TlpFhazPODK/S1dgZvCMbPk0NwBZTMG1k0k=
script:
- make travis-check
- stage: test-token
install:
- pip install -r requirements.txt
env:
- secure: OKohVOEy2nBGdk4qsIVNVBnh/lcDpiXsL76ssgfKLnp2VOal/CjytwnpLw7c48cX9ICMnvNiK8ZixAQ0McXx1rI9FGVpX/9GDqNKN6p/lr/OBGn3QPGtjUehUVeKDjBPi2g28Sd6EEiUdMG2oauBErjX6QzDZ0mFrYwoNKzmuExve1Zbyqaom47Quzx6OdWEk9AuvMC10gj3bObjX05wm+GvZHRPv+InIn2Qd1l4HzC4e4YhYWN+znLo9z18G1b6JXeA1Bdp3pTfXRb/SxRUwjB6pG3tu3O7dHtm9ZzIzJgY3uY0Xtrt2q1ypeu84LMru8g0pyO8UAe7F77afw7xoxeoTE9uxY3soZcqjzhRV+a2lc3dpHQv0r6rPNHh4W2lEncEtj/SCasSr3jsv0KUtZdqe+1882P+gN+bzMnmGxp3wO7bRGQUAb6dsbvL1GmFU6g7eCOqQ3f/P6tFNtZdbIGWekN1M/lpCrlkQ8+rd9kCC8ntrdx52ROWB4yaM1x6XXAnDjOPNf//X5FpM1xO+w2JrjdRQEBMqX2oTz74BIJYkaUZevyFg4OKGUGLXUsHL1+wd/5fM8nWnmMhiTq5u7g90hnpXU/+8GRD1D36woVbg6oS+xstfSXnC7TkkvlJKWQXB80kOIaeVwMrs5MhMQ91HTle8eUZ9YS0Aw37bzo=
script:
- make travis-check
13 changes: 10 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ syntax:
container:
tools/start_grafana.sh

check: container
test-local-token: container
GRAFANA_API_KEY='$(shell python tools/get_or_create_token.py)' ansible-playbook test.yml
#TODO: Check annotations are available in grafana
#TODO: use a test framework like unittest

test-local-basic-auth: container
GRAFANA_USER='admin' GRAFANA_PASSWORD='admin' ansible-playbook test.yml

local-check: test-local-token test-local-basic-auth

# This test will be called multiple times by travis-ci with different env variables.
travis-check:
ansible-playbook test.yml
71 changes: 42 additions & 29 deletions callback_plugins/grafana_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
from base64 import b64encode
from datetime import datetime

try:
import httplib
except ImportError:
# Python 3
import http.client as httplib

from ansible.module_utils.urls import open_url
from ansible.plugins.callback import CallbackBase

DOCUMENTATION = '''
Expand All @@ -28,11 +23,21 @@
requirements:
- whitelisting in configuration
options:
grafana_host:
description: Grafana server address and port
grafana_url:
description: Grafana annotations api URL
env:
- name: GRAFANA_URL
default: http://127.0.0.1:3000/api/annotations
grafana_validate_certs:
description: (bool) validate the SSL certificate of the Grafana server. (For HTTPS url)
env:
- name: GRAFANA_HOST
default: 127.0.0.1:3000
- name: GRAFANA_VALIDATE_CERT
default: True
http_agent:
description: The HTTP 'User-agent' value to set in HTTP requets.
env:
- name: HTTP_AGENT
default: 'Ansible (grafana_annotations callback)'
api_key:
description: Grafana API key, allowing to authenticate when posting on the HTTP API.
If not provided, grafana_login and grafana_password will
Expand Down Expand Up @@ -93,6 +98,15 @@ def to_millis(dt):
return int(dt.strftime('%s')) * 1000


def str2bool(string):
if string in [True, 'True', 'true', '1', 'yes']:
return True
elif string in [False, 'False', 'false', '0', 'no']:
return True
else:
raise Exception("Unsupported value '%s' as boolean" % string)


class CallbackModule(CallbackBase):
"""
ansible grafana callback plugin
Expand All @@ -110,27 +124,27 @@ class CallbackModule(CallbackBase):
def __init__(self):
super(CallbackModule, self).__init__()

self.grafana_host = os.getenv('GRAFANA_HOST', '127.0.0.1:3000')
self.secure = int(os.getenv('GRAFANA_SECURE', 0))
if self.secure not in [0, 1]:
self.secure = 0
api_key = os.getenv('GRAFANA_API_KEY', None)
grafana_user = os.getenv('GRAFANA_USER', None)
grafana_password = os.getenv('GRAFANA_PASSWORD', '')
self.grafana_url = os.getenv('GRAFANA_URL', 'http://127.0.0.1:3000/api/annotations')
self.grafana_validate_certs = str2bool(os.getenv('GRAFANA_VALIDATE_CERT', True))
self.http_agent = os.getenv('HTTP_AGENT', 'Ansible (grafana_annotations callback)')
self.grafana_user = os.getenv('GRAFANA_USER', None)
self.grafana_password = os.getenv('GRAFANA_PASSWORD', None)
self.dashboard_id = os.getenv('GRAFANA_DASHBOARD_ID', None)
self.panel_id = os.getenv('GRAFANA_PANEL_ID', None)
self.force_basic_auth = False

self.headers = {'Content-Type': 'application/json'}

if api_key:
authorization = "Bearer %s" % api_key
elif grafana_user is not None:
authorization = "Basic %s" % b64encode("%s:%s" % (grafana_user, grafana_password))
self.headers['Authorization'] = "Bearer %s" % api_key
elif self.grafana_user is not None and self.grafana_password is not None:
self.force_basic_auth = True
else:
self.disabled = True
self._display.warning("Authentcation required, please set GRAFANA_API_KEY or GRAFANA_USER/GRAFANA_PASSWORD")
return

self.headers = {'Content-Type': 'application/json',
'Authorization': authorization}
self.errors = 0
self.hostname = socket.gethostname()
self.username = getpass.getuser()
Expand Down Expand Up @@ -197,11 +211,10 @@ def v2_runner_on_failed(self, result, **kwargs):
self._send_annotation(json.dumps(data))

def _send_annotation(self, annotation):
if int(self.secure) == 1:
self.http = httplib.HTTPSConnection(self.grafana_host)
else:
self.http = httplib.HTTPConnection(self.grafana_host)
self.http.request("POST", "/api/annotations", annotation, self.headers)
response = self.http.getresponse()
if response.status != 200:
self._display.warning("Grafana server responded with HTTP %d" % response.status)
try:
response = open_url(self.grafana_url, data=annotation, headers=self.headers,
method="POST", validate_certs=self.grafana_validate_certs,
url_username=self.grafana_user, url_password=self.grafana_password,
http_agent=self.http_agent, force_basic_auth=self.force_basic_auth)
except Exception as e:
self._display.warning('Could not submit message to Grafana: %s' % str(e))

0 comments on commit bede5f6

Please sign in to comment.