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,56 +1,65 @@
import json
import logging
import requests
from threading import Timer
from keystone import Keystone
from monagent.common.util import get_hostname
from monclient import client
import monclient.exc as exc
log = logging.getLogger(__name__)
class MonAPI(object):
"""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):
"""
Initialize Mon api connection.
Initialize Mon api client connection.
"""
self.url = config['url']
self.api_version = '2_0'
self.default_dimensions = config['dimensions']
self.token_expiration = 1438
if not 'hostname' in self.default_dimensions: # Verify the hostname is set as a dimension
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']:
self.keystone = Keystone(config['keystone_url'])
token = self.keystone.get_token_password_auth(config['username'], config['password'], config['project_id'])
self.headers = {'content-type': 'application/json',
'X-Auth-Token': token}
# Get a new token
self._refresh_token()
else:
self.headers = {'content-type': 'application/json',
'X-Tenant-Id': config['project_id']}
self.token = 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):
"""Does the actual http post
measurements is a list of Measurement
"""
data = json.dumps([m.__dict__ for m in measurements])
response = requests.post(self.url, data=data, headers=self.headers)
if 200 <= response.status_code <= 299:
# Good status from web service
log.debug("Message sent successfully: {0}".format(str(data)))
elif 400 <= response.status_code <= 499:
# Good status from web service but some type of issue with the data
error_msg = "Successful web service call but there were issues (Status: {0}," + \
"Status Message: {1}, Message Content: {1})"
log.error(error_msg.format(response.status_code, response.reason, response.text))
response.raise_for_status()
else: # Not a good status
response.raise_for_status()
data = [m.__dict__ for m in measurements]
kwargs = {
'jsonbody': data
}
try:
response = self.mon_client.metrics.create(**kwargs)
if 200 <= response.status_code <= 299:
# Good status from web service
log.debug("Message sent successfully: {0}".format(str(data)))
elif 400 <= response.status_code <= 499:
# Good status from web service but some type of issue with the data
error_msg = "Successful web service call but there were issues (Status: {0}," + \
"Status Message: {1}, Message Content: {1})"
log.error(error_msg.format(response.status_code, response.reason, response.text))
response.raise_for_status()
else: # Not a good 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):
"""post_metrics
@ -61,3 +70,19 @@ class MonAPI(object):
measurement.dimensions.update(self.default_dimensions)
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.use_keystone
def get_token_password_auth(self, user_id, password, project_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-ntplib" \
-d "python-yaml" \
-d "python-monclient" \
--post-install mon-agent-deb/postinst \
--post-uninstall mon-agent-deb/postrm \
--pre-uninstall mon-agent-deb/prerm \

View File

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