Add driver API infrastructure for archiving logs.

This adds an API call to the worker driver interface that will
allow for supporting archiving of the load balancer logs. Only
archiving logs to Swift is supported for now. Note that this
does not add implementation of this new API method to the HAProxy
driver.

Change-Id: I0441cc99261058d23a6e5148ab7899291f28761d
This commit is contained in:
David Shrewsbury 2013-03-21 10:48:47 -04:00
parent 837d9b36e2
commit d4397cc2f9
3 changed files with 159 additions and 0 deletions

View File

@ -24,7 +24,12 @@ class LBaaSController(object):
RESPONSE_SUCCESS = "PASS"
ACTION_FIELD = 'hpcs_action'
RESPONSE_FIELD = 'hpcs_response'
ERROR_FIELD = 'hpcs_error'
LBLIST_FIELD = 'loadBalancers'
OBJ_STORE_TYPE_FIELD = 'hpcs_object_store_type'
OBJ_STORE_BASEPATH_FIELD = 'hpcs_object_store_basepath'
OBJ_STORE_ENDPOINT_FIELD = 'hpcs_object_store_endpoint'
OBJ_STORE_TOKEN_FIELD = 'hpcs_object_store_token'
def __init__(self, logger, driver, json_msg):
self.logger = logger
@ -56,6 +61,8 @@ class LBaaSController(object):
return self._action_delete()
elif action == 'DISCOVER':
return self._action_discover()
elif action == 'ARCHIVE':
return self._action_archive()
else:
self.logger.error("Invalid `%s` value: %s" %
(self.ACTION_FIELD, action))
@ -264,3 +271,63 @@ class LBaaSController(object):
else:
self.msg[self.RESPONSE_FIELD] = self.RESPONSE_SUCCESS
return self.msg
def _action_archive(self):
""" Archive LB log files. """
valid_methods = ['swift']
method = None
params = {}
if self.OBJ_STORE_TYPE_FIELD not in self.msg:
return BadRequest(
"Missing '%s' element" % self.OBJ_STORE_TYPE_FIELD
).to_json()
else:
method = self.msg[self.OBJ_STORE_TYPE_FIELD].lower()
# Validate method type
if method not in valid_methods:
return BadRequest(
"'%s' is not a valid store type" % method
).to_json()
# Get parameters for Swift storage
if method == 'swift':
if self.OBJ_STORE_BASEPATH_FIELD not in self.msg:
return BadRequest(
"Missing '%s' element" % self.OBJ_STORE_BASEPATH_FIELD
).to_json()
if self.OBJ_STORE_ENDPOINT_FIELD not in self.msg:
return BadRequest(
"Missing '%s' element" % self.OBJ_STORE_ENDPOINT_FIELD
).to_json()
if self.OBJ_STORE_TOKEN_FIELD not in self.msg:
return BadRequest(
"Missing '%s' element" % self.OBJ_STORE_TOKEN_FIELD
).to_json()
if self.LBLIST_FIELD not in self.msg:
return BadRequest(
"Missing '%s' element" % self.LBLIST_FIELD
).to_json()
lb_list = self.msg[self.LBLIST_FIELD]
params['protocol'] = lb_list[0]['protocol']
params['basepath'] = self.msg[self.OBJ_STORE_BASEPATH_FIELD]
params['endpoint'] = self.msg[self.OBJ_STORE_ENDPOINT_FIELD]
params['token'] = self.msg[self.OBJ_STORE_TOKEN_FIELD]
try:
self.driver.archive(method, params)
except NotImplementedError:
error = "Selected driver does not support ARCHIVE action."
self.logger.error(error)
self.msg[self.RESPONSE_FIELD] = self.RESPONSE_FAILURE
self.msg[self.ERROR_FIELD] = error
except Exception as e:
self.logger.error("ARCHIVE failed: %s, %s" % (e.__class__, e))
self.msg[self.RESPONSE_FIELD] = self.RESPONSE_FAILURE
self.msg[self.ERROR_FIELD] = str(e)
else:
self.msg[self.RESPONSE_FIELD] = self.RESPONSE_SUCCESS
return self.msg

View File

@ -75,3 +75,7 @@ class LoadBalancerDriver(object):
def get_stats(self, protocol):
""" Get load balancer statistics for specified protocol. """
raise NotImplementedError()
def archive(self, method, params):
""" Archive the load balancer logs using the specified method. """
raise NotImplementedError()

View File

@ -2,6 +2,7 @@ import logging
import testtools
import tests.mock_objects
from libra.worker.controller import LBaaSController as c
from libra.worker.drivers.base import LoadBalancerDriver
from libra.worker.drivers.haproxy.driver import HAProxyDriver
@ -141,3 +142,90 @@ class TestWorkerController(testtools.TestCase):
response = controller.run()
self.assertIn('version', response)
self.assertEquals(response[c.RESPONSE_FIELD], c.RESPONSE_SUCCESS)
def testArchiveMissingMethod(self):
msg = {
c.ACTION_FIELD: 'ARCHIVE'
}
null_driver = LoadBalancerDriver()
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
def testArchiveInvalidMethod(self):
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'bad'
}
null_driver = LoadBalancerDriver()
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
def testArchiveSwiftRequiredParams(self):
null_driver = LoadBalancerDriver()
# Missing basepath field
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'Swift',
c.OBJ_STORE_ENDPOINT_FIELD: "https://example.com",
c.OBJ_STORE_TOKEN_FIELD: "XXXX",
c.LBLIST_FIELD: [{'protocol': 'http'}]
}
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
# Missing endpoint field
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'Swift',
c.OBJ_STORE_BASEPATH_FIELD: "/lbaaslogs",
c.OBJ_STORE_TOKEN_FIELD: "XXXX",
c.LBLIST_FIELD: [{'protocol': 'http'}]
}
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
# Missing token field
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'Swift',
c.OBJ_STORE_BASEPATH_FIELD: "/lbaaslogs",
c.OBJ_STORE_ENDPOINT_FIELD: "https://example.com",
c.LBLIST_FIELD: [{'protocol': 'http'}]
}
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
# Missing load balancer field
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'Swift',
c.OBJ_STORE_BASEPATH_FIELD: "/lbaaslogs",
c.OBJ_STORE_ENDPOINT_FIELD: "https://example.com",
c.OBJ_STORE_TOKEN_FIELD: "XXXX"
}
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertIn('badRequest', response)
def testArchiveNotImplemented(self):
msg = {
c.ACTION_FIELD: 'ARCHIVE',
c.OBJ_STORE_TYPE_FIELD: 'Swift',
c.OBJ_STORE_BASEPATH_FIELD: "/lbaaslogs",
c.OBJ_STORE_ENDPOINT_FIELD: "https://example.com",
c.OBJ_STORE_TOKEN_FIELD: "XXXX",
c.LBLIST_FIELD: [{'protocol': 'http'}]
}
null_driver = LoadBalancerDriver()
controller = c(self.logger, null_driver, msg)
response = controller.run()
self.assertEquals(response[c.RESPONSE_FIELD], c.RESPONSE_FAILURE)
self.assertIn(c.ERROR_FIELD, response)
self.assertEquals(response[c.ERROR_FIELD],
"Selected driver does not support ARCHIVE action.")