From c7cb4d67a90e6dde24b7d0e516c1d0c787051402 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sun, 14 Oct 2012 10:55:35 -0700 Subject: [PATCH] More work on client * Add status function * Fix tests * Fix options parser --- libra/client/client.py | 3 + libra/client/clientoptions.py | 4 +- libra/client/libraapi.py | 33 ++++++++-- tests/test_lbaas_client.py | 117 ++++++++++++++++++++++++++-------- 4 files changed, 122 insertions(+), 35 deletions(-) diff --git a/libra/client/client.py b/libra/client/client.py index bbf94c93..a3c4b535 100644 --- a/libra/client/client.py +++ b/libra/client/client.py @@ -26,4 +26,7 @@ def main(): if args.command == 'list': api.list_lb() + if args.command == 'status': + api.get_lb(args.lbid) + return 0 diff --git a/libra/client/clientoptions.py b/libra/client/clientoptions.py index df0f0dec..170db1a0 100644 --- a/libra/client/clientoptions.py +++ b/libra/client/clientoptions.py @@ -60,9 +60,10 @@ class ClientOptions(object): subparsers.add_parser( 'modify', help='modify a load balancer' ) - subparsers.add_parser( + sp = subparsers.add_parser( 'status', help='get status of a load balancer' ) + sp.add_argument('lbid', help='Load Balancer ID') subparsers.add_parser( 'node-list', help='list nodes in a load balancer' ) @@ -80,4 +81,5 @@ class ClientOptions(object): ) def run(self): + self._generate() return self.options.parse_args() diff --git a/libra/client/libraapi.py b/libra/client/libraapi.py index 794f1c8a..b0967eef 100644 --- a/libra/client/libraapi.py +++ b/libra/client/libraapi.py @@ -29,20 +29,41 @@ class LibraAPI(object): def list_lb(self): resp, body = self._get('/loadbalaners') - columns = ['Name', 'ID', 'Protocol', 'Port', 'Algorithm', 'Status', - 'Created', 'Updated'] - self._render(columns, body['loadBalancers']) + column_names = ['Name', 'ID', 'Protocol', 'Port', 'Algorithm', + 'Status', 'Created', 'Updated'] + columns = ['name', 'id', 'protocol', 'port', 'algorithm', 'status', + 'created', 'updated'] + self._render_list(column_names, columns, body['loadBalancers']) - def _render(self, columns, data): - table = prettytable.PrettyTable(columns) + def get_lb(self, lbid): + resp, body = self._get('/loadbalancers/{0}'.format(lbid)) + column_names = ['ID', 'Name', 'Protocol', 'Port', 'Algorithm', + 'Status', 'Created', 'Updated', 'IPs', 'Nodes', + 'Persistence Type', 'Connection Throttle'] + columns = ['id', 'name', 'protocol', 'port', 'algorithm', 'status', + 'created', 'updated', 'virtualIps', 'nodes', + 'sessionPersistence', 'connectionThrottle'] + self._render_dict(column_names, columns, body) + + def _render_list(self, column_names, columns, data): + table = prettytable.PrettyTable(column_names) for item in data: row = [] for column in columns: - rdata = item[column.lower()] + rdata = item[column] row.append(rdata) table.add_row(row) print table + def _render_dict(self, column_names, columns, data): + table = prettytable.PrettyTable(column_names) + row = [] + for column in columns: + rdata = data[column] + row.append(rdata) + table.add_row(row) + print table + def _get(self, url, **kwargs): return self.nova.get(url, **kwargs) diff --git a/tests/test_lbaas_client.py b/tests/test_lbaas_client.py index e9e6465d..ef16ed3d 100644 --- a/tests/test_lbaas_client.py +++ b/tests/test_lbaas_client.py @@ -6,34 +6,6 @@ import sys from StringIO import StringIO from libra.client.libraapi import LibraAPI -fake_response = httplib2.Response({"status": '200'}) -fake_body = json.dumps({ - "loadBalancers":[ - { - "name":"lb-site1", - "id":"71", - "protocol":"HTTP", - "port":"80", - "algorithm":"LEAST_CONNECTIONS", - "status":"ACTIVE", - "created":"2010-11-30T03:23:42Z", - "updated":"2010-11-30T03:23:44Z" - }, - { - "name":"lb-site2", - "id":"166", - "protocol":"TCP", - "port":"9123", - "algorithm":"ROUND_ROBIN", - "status":"ACTIVE", - "created":"2010-11-30T03:23:42Z", - "updated":"2010-11-30T03:23:44Z" - } - ] -}) - -mock_request = mock.Mock(return_value=(fake_response, fake_body)) - class TestLBaaSClientLibraAPI(unittest.TestCase): def setUp(self): @@ -45,6 +17,33 @@ class TestLBaaSClientLibraAPI(unittest.TestCase): pass def testListLb(self): + fake_response = httplib2.Response({"status": '200'}) + fake_body = json.dumps({ + "loadBalancers":[ + { + "name":"lb-site1", + "id":"71", + "protocol":"HTTP", + "port":"80", + "algorithm":"LEAST_CONNECTIONS", + "status":"ACTIVE", + "created":"2010-11-30T03:23:42Z", + "updated":"2010-11-30T03:23:44Z" + }, + { + "name":"lb-site2", + "id":"166", + "protocol":"TCP", + "port":"9123", + "algorithm":"ROUND_ROBIN", + "status":"ACTIVE", + "created":"2010-11-30T03:23:42Z", + "updated":"2010-11-30T03:23:44Z" + } + ] + }) + mock_request = mock.Mock(return_value=(fake_response, fake_body)) + with mock.patch.object(httplib2.Http, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): orig = sys.stdout @@ -53,6 +52,68 @@ class TestLBaaSClientLibraAPI(unittest.TestCase): sys.stdout = out self.api.list_lb() output = out.getvalue().strip() + self.assertRegexpMatches(output, 'lb-site1') + self.assertRegexpMatches(output, '71') + self.assertRegexpMatches(output, 'HTTP') + self.assertRegexpMatches(output, '80') self.assertRegexpMatches(output, 'LEAST_CONNECTIONS') + self.assertRegexpMatches(output, 'ACTIVE') + self.assertRegexpMatches(output, '2010-11-30T03:23:42Z') + self.assertRegexpMatches(output, '2010-11-30T03:23:44Z') finally: sys.stdout = orig + + def testGetLb(self): + fake_response = httplib2.Response({"status": '200'}) + fake_body = json.dumps({ + "id": "2000", + "name":"sample-loadbalancer", + "protocol":"HTTP", + "port": "80", + "algorithm":"ROUND_ROBIN", + "status":"ACTIVE", + "created":"2010-11-30T03:23:42Z", + "updated":"2010-11-30T03:23:44Z", + "virtualIps":[ + { + "id": "1000", + "address":"2001:cdba:0000:0000:0000:0000:3257:9652", + "type":"PUBLIC", + "ipVersion":"IPV6" + }], + "nodes": [ + { + "id": "1041", + "address":"10.1.1.1", + "port": "80", + "condition":"ENABLED", + "status":"ONLINE" + }, + { + "id": "1411", + "address":"10.1.1.2", + "port": "80", + "condition":"ENABLED", + "status":"ONLINE" + }], + "sessionPersistence":{ + "persistenceType":"HTTP_COOKIE" + }, + "connectionThrottle":{ + "maxRequestRate": "50", + "rateInterval": "60" + } + }) + mock_request = mock.Mock(return_value=(fake_response, fake_body)) + with mock.patch.object(httplib2.Http, "request", mock_request): + with mock.patch('time.time', mock.Mock(return_value=1234)): + orig = sys.stdout + try: + out = StringIO() + sys.stdout = out + self.api.get_lb('2000') + output = out.getvalue().strip() + self.assertRegexpMatches(output, 'HTTP_COOKIE') + finally: + sys.stdout = orig +