Altered the csv formatting, and added reliance on clerk for rates collection.
This commit is contained in:
parent
ede6e2ecf0
commit
2a4714fdad
@ -1,11 +1,12 @@
|
||||
import os
|
||||
from csv import writer
|
||||
from artifice import invoice
|
||||
from artifice import clerk_mixins
|
||||
import yaml
|
||||
from decimal import *
|
||||
|
||||
|
||||
class Csv(invoice.RatesFileMixin, invoice.Invoice):
|
||||
class Csv(clerk_mixins.ClerkRatesMixin, invoice.Invoice):
|
||||
|
||||
def __init__(self, tenant, start, end, config):
|
||||
self.config = config
|
||||
@ -19,26 +20,33 @@ class Csv(invoice.RatesFileMixin, invoice.Invoice):
|
||||
def bill(self):
|
||||
# Usage is one of VMs, Storage, or Volumes.
|
||||
for element in self.tenant.resources.values():
|
||||
appendee = []
|
||||
print " * " + element.metadata['type']
|
||||
|
||||
print " - resource id: " + str(element.id)
|
||||
appendee.append(element.id)
|
||||
self.add_line(element.metadata['type'], [element.id])
|
||||
|
||||
appendee = []
|
||||
appendee2 = []
|
||||
for key, value in element.metadata.iteritems():
|
||||
print " - " + key + ": " + str(value)
|
||||
appendee.append(value)
|
||||
appendee.append(key + str(":"))
|
||||
appendee2.append(value)
|
||||
|
||||
self.add_line(element.metadata['type'], appendee)
|
||||
self.add_line(element.metadata['type'], appendee2)
|
||||
|
||||
total_cost = Decimal(0.0)
|
||||
appendee = ["", "service:", "usage:", "rate:", "cost:"]
|
||||
appendee = ["service:", "usage:", "rate:", "cost:"]
|
||||
self.add_line(element.metadata['type'], appendee)
|
||||
for strategy in element.usage_strategies.values():
|
||||
appendee = ["-"]
|
||||
appendee = []
|
||||
cost = Decimal(0.0)
|
||||
usage = Decimal(strategy.volume)
|
||||
rate = self.rate(strategy.service)
|
||||
|
||||
# GET REGION FROM CONFIG:
|
||||
region = 'wellington'
|
||||
|
||||
rate = self.rate(strategy.service, region)
|
||||
cost = usage * rate
|
||||
total_cost += cost
|
||||
appendee.append(strategy.service)
|
||||
@ -47,11 +55,11 @@ class Csv(invoice.RatesFileMixin, invoice.Invoice):
|
||||
appendee.append(round(cost, 2))
|
||||
print " - " + strategy.service + ": " + str(usage)
|
||||
print " - rate: " + str(rate)
|
||||
print " - cost: " + str(cost)
|
||||
print " - cost: " + str(round(cost))
|
||||
self.add_line(element.metadata['type'], appendee)
|
||||
appendee = ["total cost:", round(total_cost, 2)]
|
||||
self.add_line(element.metadata['type'], appendee)
|
||||
print " - total cost: " + str(total_cost)
|
||||
print " - total cost: " + str(round(total_cost))
|
||||
|
||||
self.add_line(element.metadata['type'], [])
|
||||
self.total += total_cost
|
||||
|
@ -1,6 +1,5 @@
|
||||
import requests
|
||||
from decimal import Decimal
|
||||
from artifice import NotFound
|
||||
|
||||
|
||||
class ClerkNamesMixin(object):
|
||||
@ -14,14 +13,13 @@ class ClerkNamesMixin(object):
|
||||
return str(response.json()['pretty_name'])
|
||||
elif response.status_code == 404:
|
||||
print "not found"
|
||||
raise NotFound
|
||||
|
||||
|
||||
class ClerkRatesMixin(object):
|
||||
|
||||
def rate(self, name, loc_name):
|
||||
url = self.config["clerk"]["url"]
|
||||
url = (url + "locations/" + loc_name +
|
||||
url = "http://10.5.36.32/"
|
||||
url = (url + "regions/" + loc_name +
|
||||
"/services/" + name + "/rates/current/")
|
||||
response = requests.get(url,
|
||||
headers={"Content-Type": "application/json"})
|
||||
@ -29,4 +27,3 @@ class ClerkRatesMixin(object):
|
||||
return Decimal(response.json()['rate'])
|
||||
elif response.status_code == 404:
|
||||
print "not found"
|
||||
raise NotFound
|
||||
|
@ -1,5 +1,4 @@
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.sql import exists
|
||||
from .models.db_models import Tenant as tenant_model
|
||||
from .models.db_models import UsageEntry, Resource
|
||||
from .models import billing, Base
|
||||
@ -40,13 +39,12 @@ class Database(object):
|
||||
filter(Resource.resource_id == element.get("resource_id"))
|
||||
if query.count() == 0:
|
||||
el_type = element.type
|
||||
if el_type != 'virtual_machine':
|
||||
if el_type not in ('virtual_machine', 'volume'):
|
||||
info = json.dumps({'type': el_type})
|
||||
else:
|
||||
info = json.dumps({'type': el_type,
|
||||
'name': element.name})
|
||||
# info should really be a json...
|
||||
# but is just a dict cast to a str for now
|
||||
|
||||
self.session.add(Resource(resource_id=
|
||||
element.get("resource_id"),
|
||||
info=str(info)))
|
||||
@ -90,8 +88,8 @@ class Database(object):
|
||||
for entry in query:
|
||||
# since there is no field for volume after the sum, we must
|
||||
# access the entry by index
|
||||
usage_strat = billing.UsageStrategy(entry.service,
|
||||
Decimal(entry[3]))
|
||||
volume = Decimal(entry[3])
|
||||
usage_strat = billing.UsageStrategy(entry.service, volume)
|
||||
|
||||
# does this tenant exist yet?
|
||||
if entry.tenant_id not in tenants_dict:
|
||||
|
@ -86,10 +86,10 @@ class VM(BaseModelConstruct):
|
||||
# sometimes instance_type is needed instead....
|
||||
try:
|
||||
# print "\"flavor.name\" was used"
|
||||
return self._raw["metadata"]["flavor.name"]
|
||||
return self._raw["metadata"]["flavor.name"].replace(".", "_")
|
||||
except KeyError:
|
||||
# print "\"instance_type\" was used"
|
||||
return self._raw["metadata"]["instance_type"]
|
||||
return self._raw["metadata"]["instance_type"].replace(".", "_")
|
||||
|
||||
@property
|
||||
def memory(self):
|
||||
@ -157,6 +157,10 @@ class Volume(BaseModelConstruct):
|
||||
# Size of the thing over time.
|
||||
return Decimal(to_mb(self.usage()["volume.size"].volume()))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._raw["metadata"]["display_name"]
|
||||
|
||||
|
||||
class Network(BaseModelConstruct):
|
||||
relevant_meters = ["network.outgoing.bytes", "network.incoming.bytes"]
|
||||
|
@ -64,22 +64,22 @@ class TestDatabaseModels(test_interface.TestInterface):
|
||||
print " " + resource.id
|
||||
|
||||
if resource.id == "db8037b2-9f1c-4dd2-94dd-ea72f49a21d7":
|
||||
strat = resource.usage_strategies["m1.nano"]
|
||||
strat = resource.usage_strategies["m1_nano"]
|
||||
self.assertEqual(strat.volume, 1)
|
||||
if resource.id == "9a9e7c74-2a2f-4a30-bc75-fadcbc5f304a":
|
||||
strat = resource.usage_strategies["m1.micro"]
|
||||
strat = resource.usage_strategies["m1_micro"]
|
||||
self.assertEqual(strat.volume, 1)
|
||||
if resource.id == "0a57e3da-9e85-4690-8ba9-ee7573619ec3":
|
||||
strat = resource.usage_strategies["m1.small"]
|
||||
strat = resource.usage_strategies["m1_small"]
|
||||
self.assertEqual(strat.volume, 1)
|
||||
if resource.id == "388b3939-8854-4a1b-a133-e738f1ffbb0a":
|
||||
strat = resource.usage_strategies["m1.micro"]
|
||||
strat = resource.usage_strategies["m1_micro"]
|
||||
self.assertEqual(strat.volume, 1)
|
||||
if resource.id == "de35c688-5a82-4ce5-a7e0-36245d2448bc":
|
||||
strat = resource.usage_strategies["m1.tiny"]
|
||||
strat = resource.usage_strategies["m1_tiny"]
|
||||
self.assertEqual(strat.volume, 1)
|
||||
if resource.id == "e404920f-cfc8-40ba-bc53-a5c610714bd":
|
||||
strat = resource.usage_strategies["m1.medium"]
|
||||
strat = resource.usage_strategies["m1_medium"]
|
||||
self.assertEqual(strat.volume, 0)
|
||||
|
||||
if resource.id == "3f7b702e4ca14cd99aebf4c4320e00ec":
|
||||
|
@ -11,7 +11,8 @@ Base = declarative_base()
|
||||
config = {
|
||||
"output_file": '%(tenant)s-%(start)s-%(end)s.csv',
|
||||
"output_path": "./invoices",
|
||||
"rates": {"file": "/home/adriant/Projects/openstack-artifice/examples/csv_rates.csv"}
|
||||
"rates": {"file":
|
||||
"/home/adriant/Projects/openstack-artifice/examples/csv_rates.csv"}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user