ADMIN_API: Fixes to make admin_api work with current tools
* Hack to get 'usage' routing working * Devices list output needed to be in 'devices' dict * PUT/POST don't wait on gearman so should return 200 instead of 202 * Pool MGM and statsd need to specify json content (WSME is stricter than the Java thing we used) Change-Id: I2fef129ef81045d7b7929e52f09670608c47d801
This commit is contained in:
@@ -19,16 +19,12 @@ from pecan import expose, response, abort
|
||||
from pecan.rest import RestController
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
from wsme.exc import ClientSideError
|
||||
from usage import UsageController
|
||||
from libra.admin_api.model.validators import DeviceResp, DevicePost, DevicePut
|
||||
from libra.admin_api.model.lbaas import LoadBalancer, Device, session
|
||||
from libra.admin_api.model.lbaas import loadbalancers_devices
|
||||
|
||||
|
||||
class DevicesController(RestController):
|
||||
|
||||
usage = UsageController()
|
||||
|
||||
def __init__(self, devid=None):
|
||||
# Required for PUT requests. See _lookup() below
|
||||
self.devid = devid
|
||||
@@ -55,7 +51,7 @@ class DevicesController(RestController):
|
||||
# if we don't have an id then we want a list of all devices
|
||||
if not device_id:
|
||||
# return all devices
|
||||
device = []
|
||||
device = {'devices': []}
|
||||
|
||||
if marker is None:
|
||||
marker = 0
|
||||
@@ -85,10 +81,14 @@ class DevicesController(RestController):
|
||||
if lbs:
|
||||
for item in lbs:
|
||||
lb = item._asdict()
|
||||
lb['hpcs_tenantid'] = lb['tenantid']
|
||||
del(lb['tenantid'])
|
||||
dev['loadBalancers'].append(lb)
|
||||
|
||||
device.append(dev)
|
||||
device['devices'].append(dev)
|
||||
|
||||
elif device_id == 'usage':
|
||||
return self.usage()
|
||||
else:
|
||||
# return device detail
|
||||
device = session.query(
|
||||
@@ -128,7 +128,7 @@ class DevicesController(RestController):
|
||||
response.status = 200
|
||||
return device
|
||||
|
||||
@wsme_pecan.wsexpose(DeviceResp, body=DevicePost, status_code=202)
|
||||
@wsme_pecan.wsexpose(DeviceResp, body=DevicePost)
|
||||
def post(self, body=None):
|
||||
""" Creates a new device entry in devices table.
|
||||
:param None
|
||||
@@ -196,7 +196,7 @@ class DevicesController(RestController):
|
||||
session.rollback()
|
||||
raise ClientSideError(errstr)
|
||||
|
||||
@wsme_pecan.wsexpose(None, body=DevicePut, status_code=202)
|
||||
@wsme_pecan.wsexpose(None, body=DevicePut)
|
||||
def put(self, body=None):
|
||||
""" Updates a device entry in devices table with new status.
|
||||
Also, updates status of loadbalancers using this device
|
||||
@@ -280,7 +280,6 @@ class DevicesController(RestController):
|
||||
session.query(Device).filter(Device.id == device_id).delete()
|
||||
session.flush()
|
||||
session.commit()
|
||||
response.status = 202
|
||||
return None
|
||||
except:
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -291,6 +290,27 @@ class DevicesController(RestController):
|
||||
faultstring="Error deleting device from pool"
|
||||
)
|
||||
|
||||
# Kludge to get to here because Pecan has a hard time with URL params
|
||||
# and paths
|
||||
def usage(self):
|
||||
"""Reports the device usage statistics for total, taken, and free
|
||||
:param None
|
||||
Url:
|
||||
GET /devices/usage
|
||||
Returns: dict
|
||||
"""
|
||||
total = session.query(Device).count()
|
||||
free = session.query(Device).filter(Device.status == 'OFFLINE').\
|
||||
count()
|
||||
session.commit()
|
||||
response.status = 200
|
||||
|
||||
return dict(
|
||||
total=total,
|
||||
free=free,
|
||||
taken=total - free
|
||||
)
|
||||
|
||||
@expose('json')
|
||||
def _lookup(self, devid, *remainder):
|
||||
"""Routes more complex url mapping for PUT
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from pecan import expose, response
|
||||
from libra.admin_api.model.lbaas import Device, session
|
||||
from libra.admin_api.model.responses import Responses
|
||||
from pecan.rest import RestController
|
||||
|
||||
|
||||
class UsageController(RestController):
|
||||
|
||||
@expose('json')
|
||||
def get(self):
|
||||
"""Reports the device usage statistics for total, taken, and free
|
||||
:param None
|
||||
Url:
|
||||
GET /devices/usage
|
||||
Returns: dict
|
||||
"""
|
||||
total = session.query(Device).count()
|
||||
free = session.query(Device).filter(Device.status == 'OFFLINE').\
|
||||
count()
|
||||
session.commit()
|
||||
response.status = 200
|
||||
|
||||
return dict(
|
||||
total=total,
|
||||
free=free,
|
||||
taken=total - free
|
||||
)
|
||||
|
||||
@expose('json')
|
||||
def _default(self):
|
||||
"""default route.. acts as catch all for any wrong urls.
|
||||
For now it returns a 404 because no action is defined for /"""
|
||||
response.status = 404
|
||||
return Responses._default
|
||||
@@ -26,6 +26,7 @@ class HPRestDriver(MgmDriver):
|
||||
|
||||
def __init__(self, addresses, logger):
|
||||
self.logger = logger
|
||||
self.headers = {'Content-type': 'application/json'}
|
||||
random.shuffle(addresses)
|
||||
for address in addresses:
|
||||
self.url = 'https://{0}/{1}'.format(address, API_VERSION)
|
||||
@@ -93,7 +94,10 @@ class HPRestDriver(MgmDriver):
|
||||
|
||||
def _post(self, url, node_data):
|
||||
try:
|
||||
r = requests.post(url, data=json.dumps(node_data), verify=False)
|
||||
r = requests.post(
|
||||
url, data=json.dumps(node_data), verify=False,
|
||||
headers=self.headers
|
||||
)
|
||||
except requests.exceptions.RequestException:
|
||||
self.logger.error('Exception communicating to server: {exc}'
|
||||
.format(exc=sys.exc_info()[0]))
|
||||
|
||||
@@ -25,6 +25,7 @@ class APIError(Exception):
|
||||
class AdminAPI(object):
|
||||
def __init__(self, addresses, logger):
|
||||
self.logger = logger
|
||||
self.headers = {'Content-type': 'application/json'}
|
||||
random.shuffle(addresses)
|
||||
for address in addresses:
|
||||
self.url = 'https://{0}/v1'.format(address)
|
||||
@@ -113,7 +114,9 @@ class AdminAPI(object):
|
||||
|
||||
def _put(self, url, data):
|
||||
try:
|
||||
r = requests.put(url, data=json.dumps(data), verify=False)
|
||||
r = requests.put(
|
||||
url, data=json.dumps(data), verify=False, headers=self.headers
|
||||
)
|
||||
except requests.exceptions.RequestException:
|
||||
self.logger.exception('Exception communicating to server')
|
||||
return False, None
|
||||
|
||||
Reference in New Issue
Block a user