summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Lynn <ethanlynnl@vmware.com>2019-04-03 15:57:21 +0800
committerEthan Lynn <ethanlynnl@vmware.com>2019-04-03 16:00:36 +0800
commitd8db2570c5955cf45f058e638253576820b543e5 (patch)
tree6bd0d6792d85aaa2e805678129384dcf448b5572
parent06ee0bf69c4cc48fa1017218611f1a3194137d47 (diff)
Add AZ info in capacity_check
Add AZ info in capacity_check Change-Id: Icb8d6be7034d7ac6cdda324b1e445f027e4fdd39 Issue-ID: MULTICLOUD-564 Signed-off-by: Ethan Lynn <ethanlynnl@vmware.com>
-rw-r--r--vio/vio/pub/vim/drivers/vimsdk/compute.py4
-rw-r--r--vio/vio/pub/vim/vimapi/nova/OperateNova.py6
-rw-r--r--vio/vio/swagger/views/capacity/views.py85
-rw-r--r--vio/vio/tests/test_capacity_view.py12
4 files changed, 87 insertions, 20 deletions
diff --git a/vio/vio/pub/vim/drivers/vimsdk/compute.py b/vio/vio/pub/vim/drivers/vimsdk/compute.py
index e415573..9dccd2a 100644
--- a/vio/vio/pub/vim/drivers/vimsdk/compute.py
+++ b/vio/vio/pub/vim/drivers/vimsdk/compute.py
@@ -142,3 +142,7 @@ class ComputeClient(base.DriverBase):
@sdk.translate_exception
def list_hypervisors(self, **query):
return self.conn.compute.hypervisors(**query)
+
+ @sdk.translate_exception
+ def availability_zones(self, **query):
+ return self.conn.compute.availability_zones(**query)
diff --git a/vio/vio/pub/vim/vimapi/nova/OperateNova.py b/vio/vio/pub/vim/vimapi/nova/OperateNova.py
index 262da57..76dae71 100644
--- a/vio/vio/pub/vim/vimapi/nova/OperateNova.py
+++ b/vio/vio/pub/vim/vimapi/nova/OperateNova.py
@@ -37,3 +37,9 @@ class OperateNova(baseclient):
compute = self.compute(param)
func = getattr(compute, op)
return func(**kwargs)
+
+
+class OperateAZ(OperateNova):
+
+ def list_availability_zones(self, data, **kwargs):
+ return self.request('availability_zones', data, **kwargs)
diff --git a/vio/vio/swagger/views/capacity/views.py b/vio/vio/swagger/views/capacity/views.py
index f679931..5cbd38e 100644
--- a/vio/vio/swagger/views/capacity/views.py
+++ b/vio/vio/swagger/views/capacity/views.py
@@ -21,6 +21,7 @@ from vio.pub.exceptions import VimDriverVioException
from vio.pub.msapi import extsys
from vio.pub.vim.vimapi.nova import OperateHypervisor
from vio.pub.vim.vimapi.nova import OperateLimits
+from vio.pub.vim.vimapi.nova import OperateNova
from cinderclient import client
@@ -69,16 +70,16 @@ class CapacityCheck(APIView):
return False
return True
- def post(self, request, vimid):
+ def _post_handler(self, request, vimid):
try:
requirement = json.loads(request.body)
except ValueError as ex:
- return Response(data={'error': str(ex)},
- status=status.HTTP_400_BAD_REQUEST)
+ return {'error': str(ex),
+ "status_code": status.HTTP_400_BAD_REQUEST}
try:
vim_info = extsys.get_vim_by_id(vimid)
except VimDriverVioException as e:
- return Response(data={'error': str(e)}, status=e.status_code)
+ return {'error': str(e), "status_code": e.status_code}
auth_info = {
"username": vim_info['userName'],
"password": vim_info['password'],
@@ -92,38 +93,86 @@ class CapacityCheck(APIView):
nova_limits = servers_op.get_limits(auth_info, None)
except Exception as e:
logger.exception("get nova limits error %(e)s", {"e": e})
- return Response(data={'error': str(e)}, status=e.status_code)
+ return {'error': str(e), "status_code": e.status_code}
if not self._check_nova_limits(nova_limits, requirement):
- return Response(
- data={'result': False}, status=status.HTTP_200_OK)
+ return {'result': False, "status_code": status.HTTP_200_OK}
# check cinder limits
cinder = client.Client(
- "2", auth_info['username'], auth_info['password'],
+ "3", auth_info['username'], auth_info['password'],
auth_info['project_name'], auth_info['url'], insecure=True)
try:
limits = cinder.limits.get().to_dict()
except Exception as e:
logger.exception("get cinder limits error %(e)s", {"e": e})
- return Response(data={'error': str(e)}, status=e.status_code)
+ return {'error': str(e), "status_code": e.status_code}
if not self._check_cinder_limits(limits, requirement):
- return Response(
- data={'result': False}, status=status.HTTP_200_OK)
+ return {'result': False, "status_code": status.HTTP_200_OK}
+ # Get Availability zones info
+ nova_op = OperateNova.OperateAZ()
+ try:
+ azs = nova_op.list_availability_zones(auth_info, details=True)
+ except Exception as e:
+ logger.exception("get availability_zones error %(e)s", {"e": e})
+ return {'error': str(e), "status_code": e.status_code}
+ availability_zones = []
+ for az in azs:
+ if az.name == "internal":
+ continue
+ availability_zones.append({
+ "availability-zone-name": az.name,
+ "hosts": az.hosts,
+ "vCPUTotal": 0,
+ "vCPUAvail": 0,
+ "MemoryTotal": 0,
+ "MemoryAvail": 0,
+ "StorageTotal": 0,
+ "StorageAvail": 0,
+ })
# check hypervisor resources
hypervisor_op = OperateHypervisor.OperateHypervisor()
try:
hypervisors = hypervisor_op.list_hypervisors(auth_info)
except Exception as e:
logger.exception("get hypervisors error %(e)s", {"e": e})
- return Response(data={'error': str(e)}, status=e.status_code)
+ return {'error': str(e), "status_code": e.status_code}
+ ret = {'result': False, "status_code": status.HTTP_200_OK}
+ # import ipdb; ipdb.set_trace()
for hypervisor in hypervisors:
+ if hypervisor.status != "enabled":
+ continue
hyper = hypervisor_op.get_hypervisor(auth_info, hypervisor.id)
- if self._check_capacity(hyper.to_dict(), requirement):
- return Response(data={'result': True},
- status=status.HTTP_200_OK)
- return Response(data={'result': False}, status=status.HTTP_200_OK)
+ hyper_dict = hyper.to_dict()
+ for az in availability_zones:
+ if az['hosts'].get(hyper_dict["service_details"]['host']):
+ az['vCPUTotal'] += hyper_dict["vcpus"]
+ az['vCPUAvail'] += hyper_dict["vcpus"] - hyper_dict[
+ "vcpus_used"]
+ az['MemoryTotal'] += hyper_dict["memory_size"]
+ az['MemoryAvail'] += hyper_dict["memory_free"]
+ az['StorageTotal'] += hyper_dict["local_disk_size"]
+ az['StorageAvail'] += hyper_dict["local_disk_free"]
+ if self._check_capacity(hyper_dict, requirement):
+ ret["result"] = True
+ if ret["result"]:
+ for az in availability_zones:
+ del az["hosts"]
+ ret["AZs"] = availability_zones
+ return ret
+
+ def post(self, request, vimid):
+ ret = self._post_handler(request, vimid)
+ status_code = ret["status_code"]
+ del ret["status_code"]
+ if ret.get("AZs"):
+ del ret["AZs"]
+ return Response(data=ret, status=status_code)
class CapacityCheckV1(CapacityCheck):
def post(self, request, cloud_owner, cloud_region):
- return super(CapacityCheckV1, self).post(
- request, cloud_owner + "_" + cloud_region)
+ # import ipdb; ipdb.set_trace()
+ vimid = cloud_owner + "_" + cloud_region
+ ret = self._post_handler(request, vimid)
+ status_code = ret["status_code"]
+ del ret["status_code"]
+ return Response(data=ret, status=status_code)
diff --git a/vio/vio/tests/test_capacity_view.py b/vio/vio/tests/test_capacity_view.py
index d27efba..3079bac 100644
--- a/vio/vio/tests/test_capacity_view.py
+++ b/vio/vio/tests/test_capacity_view.py
@@ -18,6 +18,7 @@ from rest_framework import status
from vio.pub.msapi import extsys
from vio.pub.vim.vimapi.nova import OperateHypervisor
from vio.pub.vim.vimapi.nova import OperateLimits
+from vio.pub.vim.vimapi.nova import OperateNova
from vio.swagger.views.capacity.views import CapacityCheck
from cinderclient import client
@@ -32,12 +33,13 @@ class CapacityCheckTest(unittest.TestCase):
def setUp(self):
self.view = CapacityCheck()
+ @mock.patch.object(OperateNova, "OperateAZ")
@mock.patch.object(OperateHypervisor, "OperateHypervisor")
@mock.patch.object(OperateLimits, "OperateLimits")
@mock.patch.object(client, "Client")
@mock.patch.object(extsys, "get_vim_by_id")
def test_check_capacity_success(self, mock_get_vim, mock_cinder,
- mock_limit, mock_hypervisor):
+ mock_limit, mock_hypervisor, mock_az):
mock_get_vim.return_value = VIM_INFO
req = mock.Mock()
req.body = """{
@@ -63,11 +65,17 @@ class CapacityCheckTest(unittest.TestCase):
cclient.limits.get.return_value = climits
mock_cinder.return_value = cclient
+ nazs = [mock.Mock(name="nova", hosts={"compute01": {}})]
+ nclient = mock.Mock()
+ nclient.list_availability_zones.return_value = nazs
+ mock_az.return_value = nclient
+
ophypervisor = mock.Mock()
ophypervisor.list_hypervisors.return_value = [
- mock.Mock(id="compute01")]
+ mock.Mock(id="compute01", status="enabled")]
hyper = mock.Mock()
hyper.to_dict.return_value = {
+ "service_details": {"host": "compute01"},
"vcpus": 20,
"vcpus_used": 1,
"memory_size": 128*1024,