Integrating python-monclient into agent

This commit is contained in:
gary-hessler 2014-05-16 11:13:44 -06:00
parent 5ea3ee3b09
commit 8a6386d5ac
4 changed files with 56 additions and 28 deletions

View File

@ -1,45 +1,52 @@
import json import json
import logging import logging
import requests from threading import Timer
from keystone import Keystone from keystone import Keystone
from monagent.common.util import get_hostname from monagent.common.util import get_hostname
from monclient import client
import monclient.exc as exc
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class MonAPI(object): class MonAPI(object):
"""Sends measurements to MonAPI """Sends measurements to MonAPI
Any errors should raise and exception so the transaction calling this is not committed Any errors should raise an exception so the transaction calling this is not committed
""" """
def __init__(self, config): def __init__(self, config):
""" """
Initialize Mon api connection. Initialize Mon api client connection.
""" """
self.url = config['url'] self.url = config['url']
self.api_version = '2_0'
self.default_dimensions = config['dimensions'] self.default_dimensions = config['dimensions']
self.token_expiration = 1438
if not 'hostname' in self.default_dimensions: # Verify the hostname is set as a dimension if not 'hostname' in self.default_dimensions: # Verify the hostname is set as a dimension
self.default_dimensions['hostname'] = get_hostname() self.default_dimensions['hostname'] = get_hostname()
#todo we should always use keystone, for development the keystone object should just return a dummy token
if config['use_keystone']: if config['use_keystone']:
self.keystone = Keystone(config['keystone_url']) # Get a new token
token = self.keystone.get_token_password_auth(config['username'], config['password'], config['project_id']) self._refresh_token()
self.headers = {'content-type': 'application/json',
'X-Auth-Token': token}
else: else:
self.headers = {'content-type': 'application/json', self.token = config['project_id']
'X-Tenant-Id': config['project_id']}
# construct the mon client
kwargs = {
'token': self.token
}
self.mon_client = client.Client(self.api_version, self.url, **kwargs)
def _post(self, measurements): def _post(self, measurements):
"""Does the actual http post """Does the actual http post
measurements is a list of Measurement measurements is a list of Measurement
""" """
data = json.dumps([m.__dict__ for m in measurements]) data = [m.__dict__ for m in measurements]
kwargs = {
response = requests.post(self.url, data=data, headers=self.headers) 'jsonbody': data
}
try:
response = self.mon_client.metrics.create(**kwargs)
if 200 <= response.status_code <= 299: if 200 <= response.status_code <= 299:
# Good status from web service # Good status from web service
log.debug("Message sent successfully: {0}".format(str(data))) log.debug("Message sent successfully: {0}".format(str(data)))
@ -51,6 +58,8 @@ class MonAPI(object):
response.raise_for_status() response.raise_for_status()
else: # Not a good status else: # Not a good status
response.raise_for_status() response.raise_for_status()
except exc.HTTPException as he:
log.error("Error sending message to mon-api: {0}".format(str(he.message)))
def post_metrics(self, measurements): def post_metrics(self, measurements):
"""post_metrics """post_metrics
@ -61,3 +70,19 @@ class MonAPI(object):
measurement.dimensions.update(self.default_dimensions) measurement.dimensions.update(self.default_dimensions)
self._post(measurements) self._post(measurements)
def _refresh_token(self):
"""_refresh_token
Gets a new token from Keystone and resets the validity timer
"""
token = None
try:
log.debug("Getting token from Keystone")
keystone = Keystone(config['keystone_url'], config['use_keystone'])
self.token = keystone.get_token_password_auth(config['username'], config['password'], config['project_id'])
log.debug("Setting Keystone token expiration timer for {0} minutes".format(str(self.token_expiration)))
self.timer = Timer(self.token_expiration,self._refresh_token)
self.timer.start()
except Exception as ex:
log.error("Error getting token from Keystone: {0}".format(str(ex.message)))
raise ex

View File

@ -54,8 +54,9 @@ class Keystone(object):
} }
} }
def __init__(self, endpoint): def __init__(self, endpoint, use_keystone):
self.endpoint = endpoint self.endpoint = endpoint
self.use_keystone
def get_token_password_auth(self, user_id, password, project_id): def get_token_password_auth(self, user_id, password, project_id):
self.password_auth['auth']['identity']['password']['user']['id'] = user_id self.password_auth['auth']['identity']['password']['user']['id'] = user_id

View File

@ -89,6 +89,7 @@ $(FPM_BUILD) -t deb \
-d "python-httplib2" \ -d "python-httplib2" \
-d "python-ntplib" \ -d "python-ntplib" \
-d "python-yaml" \ -d "python-yaml" \
-d "python-monclient" \
--post-install mon-agent-deb/postinst \ --post-install mon-agent-deb/postinst \
--post-uninstall mon-agent-deb/postrm \ --post-uninstall mon-agent-deb/postrm \
--pre-uninstall mon-agent-deb/prerm \ --pre-uninstall mon-agent-deb/prerm \

View File

@ -21,7 +21,8 @@ install_requires=[
'PyYAML', 'PyYAML',
'redis', 'redis',
'simplejson', 'simplejson',
'tornado' 'tornado',
'python-monclient',
] ]
if sys.platform == 'win32': if sys.platform == 'win32':