Commit d6b2e6b9 authored by Simon Leinen's avatar Simon Leinen

Add support for cinder volumes

In addition to (Nova) VMs, we now also traverse the list of (Cinder)
volumes for all tenants, and add their sizes to the
tenant/cost-centers' disk usage.
parent 991d0aeb
......@@ -35,6 +35,7 @@ from keystoneclient.auth.identity import v2
from keystoneclient import session
from novaclient.v2 import client as nova_client
from novaclient.exceptions import BadRequest, NotFound
from cinderclient.v2 import client as cinder_client
class UsageAnalyzer:
......@@ -64,6 +65,7 @@ class UsageAnalyzer:
self.cost_centers = None
self.regions = None
self._nova_endpoints = None
self._cinder_endpoints = None
self.cc_re = re.compile(".* \[(.*)\]")
......@@ -103,6 +105,16 @@ class UsageAnalyzer:
self._nova_endpoints = ne
return ne
def cinder_endpoints(self):
if self._cinder_endpoints is not None:
return self._cinder_endpoints
ne = dict()
for region in self.get_regions():
ne[region] = cinder_client.Client(session=self.auth_session,
region_name=region)
self._cinder_endpoints = ne
return ne
def cc_name_from_tenant_1(self, tenant, cc_name, fine_grained=True):
if cc_name:
if cc_name == 'switch.ch':
......@@ -208,6 +220,18 @@ class UsageAnalyzer:
except NotFound as c:
warn("Instance {:s} disappeared".format(server.id))
def collect_volumes(self):
ces = self.cinder_endpoints()
for r in self.get_regions():
ce = ces[r]
volumes = ce.volumes.list(search_opts = {'all_tenants': 1})
for volume in volumes:
try:
v = ce.volumes.get(volume.id)
self.note_usage(v._info['os-vol-tenant-attr:tenant_id'], r, v.status, ram=0, vcpus=0, disk=v.size)
except NotFound as c:
warn("Volume {:s} disappeared".format(volume.id))
def collect_flavors(self):
self.flavors = dict()
nes = self.nova_endpoints()
......@@ -222,10 +246,10 @@ class UsageAnalyzer:
def status_set(active_only, undead_only):
if active_only:
return ['ACTIVE']
return ['ACTIVE', 'in-use']
if undead_only:
return ['ACTIVE', 'SUSPENDED', 'ERROR']
return ['ACTIVE', 'SUSPENDED', 'ERROR', 'SHUTOFF']
return ['ACTIVE', 'in-use', 'available', 'SUSPENDED', 'ERROR']
return ['ACTIVE', 'in-use', 'available', 'SUSPENDED', 'ERROR', 'SHUTOFF']
def title():
return "Status " + ", ".join(status_set(active_only, undead_only))
......@@ -359,7 +383,7 @@ class ResourceUsage:
or self.disk > 0
def tostr(self):
return "{:3d} VMs {:4d} vCPUs {:7d} MB {:5d} GB".\
return "{:3d} VMs {:4d} vCPUs {:7d} MB {:7d} GB".\
format(self.instances, self.vcpus, self.ram, self.disk)
class CostCenter:
......@@ -375,6 +399,9 @@ ua = UsageAnalyzer()
ua.collect_flavors()
ua.collect_servers()
ua.collect_volumes()
ua.tenant_report(active_only=True)
print("")
ua.tenant_report(active_only=False)
print("")
ua.tenant_report(active_only=False, undead_only=False)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment