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 ...@@ -35,6 +35,7 @@ from keystoneclient.auth.identity import v2
from keystoneclient import session from keystoneclient import session
from novaclient.v2 import client as nova_client from novaclient.v2 import client as nova_client
from novaclient.exceptions import BadRequest, NotFound from novaclient.exceptions import BadRequest, NotFound
from cinderclient.v2 import client as cinder_client
class UsageAnalyzer: class UsageAnalyzer:
...@@ -64,6 +65,7 @@ class UsageAnalyzer: ...@@ -64,6 +65,7 @@ class UsageAnalyzer:
self.cost_centers = None self.cost_centers = None
self.regions = None self.regions = None
self._nova_endpoints = None self._nova_endpoints = None
self._cinder_endpoints = None
self.cc_re = re.compile(".* \[(.*)\]") self.cc_re = re.compile(".* \[(.*)\]")
...@@ -103,6 +105,16 @@ class UsageAnalyzer: ...@@ -103,6 +105,16 @@ class UsageAnalyzer:
self._nova_endpoints = ne self._nova_endpoints = ne
return 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): def cc_name_from_tenant_1(self, tenant, cc_name, fine_grained=True):
if cc_name: if cc_name:
if cc_name == 'switch.ch': if cc_name == 'switch.ch':
...@@ -208,6 +220,18 @@ class UsageAnalyzer: ...@@ -208,6 +220,18 @@ class UsageAnalyzer:
except NotFound as c: except NotFound as c:
warn("Instance {:s} disappeared".format(server.id)) 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): def collect_flavors(self):
self.flavors = dict() self.flavors = dict()
nes = self.nova_endpoints() nes = self.nova_endpoints()
...@@ -222,10 +246,10 @@ class UsageAnalyzer: ...@@ -222,10 +246,10 @@ class UsageAnalyzer:
def status_set(active_only, undead_only): def status_set(active_only, undead_only):
if active_only: if active_only:
return ['ACTIVE'] return ['ACTIVE', 'in-use']
if undead_only: if undead_only:
return ['ACTIVE', 'SUSPENDED', 'ERROR'] return ['ACTIVE', 'in-use', 'available', 'SUSPENDED', 'ERROR']
return ['ACTIVE', 'SUSPENDED', 'ERROR', 'SHUTOFF'] return ['ACTIVE', 'in-use', 'available', 'SUSPENDED', 'ERROR', 'SHUTOFF']
def title(): def title():
return "Status " + ", ".join(status_set(active_only, undead_only)) return "Status " + ", ".join(status_set(active_only, undead_only))
...@@ -359,7 +383,7 @@ class ResourceUsage: ...@@ -359,7 +383,7 @@ class ResourceUsage:
or self.disk > 0 or self.disk > 0
def tostr(self): 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) format(self.instances, self.vcpus, self.ram, self.disk)
class CostCenter: class CostCenter:
...@@ -375,6 +399,9 @@ ua = UsageAnalyzer() ...@@ -375,6 +399,9 @@ ua = UsageAnalyzer()
ua.collect_flavors() ua.collect_flavors()
ua.collect_servers() ua.collect_servers()
ua.collect_volumes()
ua.tenant_report(active_only=True) ua.tenant_report(active_only=True)
print("")
ua.tenant_report(active_only=False) ua.tenant_report(active_only=False)
print("")
ua.tenant_report(active_only=False, undead_only=False) 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