Initial pass at creating file loader mixins for example CSV invoice class.

This commit is contained in:
Aurynn Shaw 2013-10-03 14:20:11 +13:00
parent 3b1ff457be
commit b2e9daa173
7 changed files with 90 additions and 9 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
*.pyc
*.deb
.vagrant
work
work
*.swp

View File

@ -1,8 +1,9 @@
import os
from csv import writer
from artifice import invoice
import yaml
class Csv(object):
class Csv(invoice.Invoice):
def __init__(self, tenant, config):
self.config = config
@ -11,8 +12,10 @@ class Csv(object):
self.closed = False
self.start = None
self.end = None
# Should the rates information be part of the CSV code,
# or part of the full run?
try:
fh = open(config["rates_file"])
fh = open(config["rates"][ "file" ])
self.costs = yaml.load( fh.read() )
fh.close()
except IOError:
@ -32,7 +35,13 @@ class Csv(object):
if key == "cost":
# Ignore costs for now.
appendee.append(None)
continue
# What do we expect element to be?
if key == "type":
# Fetch the 'pretty' name from the mappings, if any
# The default is that this returns the internal name
appendee.append(self.pretty_name(element.get(key)))
continue
try:
appendee.append( element.get(key) )
except AttributeError:
@ -40,7 +49,8 @@ class Csv(object):
try:
x = self.config["row_layout"].index("cost")
appendee[ x ] = element.amount.volume() * self.costs.get( element.type, 0 )
appendee[ x ] = element.amount.volume() * \
self.costs.get( element.type, 0 )
except ValueError:
# Not in this array. Well okay.
@ -89,4 +99,4 @@ class Csv(object):
total += float(v["cost"])
except (TypeError, ValueError):
total += 0
return total
return total

View File

@ -39,6 +39,7 @@ from .models import resources, tenants, usage
# Most of the time we use date_format
date_format = "%Y-%m-%dT%H:%M:%S"
# Sometimes things also have milliseconds, so we look for that too.
# Because why not be annoying in all the ways?
other_date_format = "%Y-%m-%dT%H:%M:%S.%f"
def get_meter(meter, start, end, auth):
@ -130,6 +131,7 @@ class Artifice(object):
)
self._tenancy = None
def host_to_dc(self, host):
"""
:param host: The name to use.
@ -143,7 +145,8 @@ class Artifice(object):
def tenant(self, name):
"""
Returns a Tenant object describing the specified Tenant by name, or raises a NotFound error.
Returns a Tenant object describing the specified Tenant by
name, or raises a NotFound error.
"""
# Returns a Tenant object for the given name.
# Uses Keystone API to perform a direct name lookup,

View File

@ -60,6 +60,14 @@ class Invoice(object):
def close(self):
raise NotImplementedError("Not implemented in base class")
def pretty_name(self, name):
return name
def rate(self, name):
"""Returns the rate for a given internal name
Expected"""
return 0
def bill(self, usage):
@ -86,4 +94,61 @@ class Invoice(object):
raise NotImplementedError("Not implemented in base class")
def total(self):
raise NotImplementedError("Not implemented in the base class")
raise NotImplementedError("Not implemented in the base class")
import csv
class RatesFile(object):
# Mixin
# Adds a rates file loader, expecting various things from the
# configuration
def rate(self, name):
if not self.__rates:
self.__rates = {}
try:
fh = open(config["rates"][ "file" ])
reader = csv.reader(fh) # Makes no opinions on the file structure
for row in reader:
# The default layout is expected to be:
# location | rate name | rate measurement | rate value
self.__rates[row[1]] = {
"cost": row[3],
"region": row[0],
"measures": row[2]
}
fh.close()
except KeyError:
# couldn't actually find the useful info for rateS?
print "Couldn't find rates info configuration option!"
raise
except IOError:
print "Couldn't open the file!"
raise
return self.__rates[name]["cost"] # ignore the regions-ness for now
class NamesFile(object):
# Mixin
# Adds a name prettifier
#
def pretty_name(self, name):
if not self.__names:
self.__names = {}
try:
fh = open(config["rates"][ "file" ])
reader = csv.reader(fh) # Makes no opinions on the file structure
for row in reader:
# The default layout is expected to be:
# internal name | external name
self.__names[row[0]] = row[1]
fh.close()
except KeyError:
# couldn't actually find the useful info for rateS?
print "Couldn't find rates info configuration option!"
raise
except IOError:
print "Couldn't open the file!"
raise
return self.__names[name]

View File

@ -18,11 +18,13 @@ invoice_object:
- end
- amount
- cost
rates_file: /opt/stack/artifice/etc/artifice/csv_rates.yaml
rates:
file: /opt/stack/artifice/etc/artifice/csv_rates.csv
names: /opt/stack/artifice/etc/artifice/csv_names.csv
main:
invoice:object: billing.csv_invoice:Csv
openstack:
authentication_url: http://localhost:35357/v2.0
default_tenant: demo
username: admin
password: openstack
password: openstack

0
examples/csv_names.csv Normal file
View File

0
examples/csv_rates.csv Normal file
View File