""" Generates billing sample data """ import datetime import os import operator import pytz import json import random import sys import time # The granularity at which the charge collection system collects charges. Once # per hour makes for a very slow UI, so I upped it to once per 8 hours. CHARGE_HOURS = 8 MINUTE_SECONDS = 60 HOUR_SECONDS = MINUTE_SECONDS * 60 DAY_SECONDS = HOUR_SECONDS * 24 MONTH_SECONDS = DAY_SECONDS * 30 sys.path.append("/opt/planetstack") #sys.path.append("/home/smbaker/projects/vicci/plstackapi/planetstack") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings") #from openstack.manager import OpenStackManager from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice from core.models import Invoice, Charge, Account, UsableObject, Payment def delete_all(model): for item in model.objects.all(): item.delete() def get_usable_object(name): objs = UsableObject.objects.filter(name=name) if objs: return objs[0] obj = UsableObject(name=name) obj.save() return obj def generate_invoice(account, batch): invoice = Invoice(date=batch[-1].date, account=account) invoice.save() for charge in batch: charge.invoice = invoice charge.state = "invoiced" charge.save() def generate_invoices(account): invoices = sorted(Invoice.objects.filter(account=account), key=operator.attrgetter('date')) charges = sorted(Charge.objects.filter(account=account, state="pending"), key=operator.attrgetter('date')) if invoices: latest_invoice_date = invoices[-1].date() else: latest_invoice_date = None batch = [] last_week = 0 for charge in charges: # check to see if we crossed a week boundary. If we did, then generate # an invoice for the last week's batch of charges week = charge.date.isocalendar()[1] if (week != last_week) and (batch): generate_invoice(account, batch) batch = [] last_week = week batch.append(charge) # we might still have last week's data batched up, and no data for this week # if so, invoice the batch this_week = datetime.datetime.now().isocalendar()[1] if (this_week != last_week) and (batch): generate_invoice(account, batch) def generate_payments(account): invoices = Invoice.objects.filter(account=account) for invoice in invoices: # let's be optomistic and assume everyone pays exactly two weeks after # receiving an invoice payment_time = int(invoice.date.strftime("%s")) + 14 * DAY_SECONDS if payment_time < time.time(): payment_time = datetime.datetime.utcfromtimestamp(payment_time).replace(tzinfo=pytz.utc) payment = Payment(account=account, amount=invoice.amount, date=payment_time) payment.save() print "deleting old stuff" delete_all(Invoice) delete_all(Charge) delete_all(Payment) delete_all(Account) delete_all(UsableObject) print "creating accounts" for site in Site.objects.all(): # only create accounts for sites where some slices exist if len(site.slices.all()) > 0: account = Account(site=site) account.save() print "generating charges" for slice in Slice.objects.all(): site = slice.site account = site.accounts.all()[0] serviceClass =slice.serviceClass if not (slice.name in ["DnsRedir", "DnsDemux", "HyperCache", "Hadoop", "Owl", "Stork", "Syndicate", "test-slice-1", "test-slice-2", "test", "test2"]): continue print " generating charges for", slice.name now = int(time.time())/HOUR_SECONDS*HOUR_SECONDS charge_kind=None for resource in slice.serviceClass.serviceresources.all(): if resource.name == "numberCores": charge_kind = "reservation" cost = resource.cost elif (charge_kind==None) and (resource.name == "cycles") or (resource.name == "Cycles"): charge_kind = "besteffort" cost = resource.cost if not charge_kind: print "failed to find resource for", slice.serviceClass continue for sliver in slice.slivers.all()[:4]: # only do up to 4 slivers; it's way too much data otherwise hostname = sliver.node.name for i in range(now-MONTH_SECONDS, now, CHARGE_HOURS*HOUR_SECONDS): if charge_kind == "besteffort": core_hours = random.randint(20,60)/100.0 else: core_hours = 1 core_hours = core_hours * CHARGE_HOURS amount = float(core_hours * cost) / 100.0 object = get_usable_object(hostname) date = datetime.datetime.utcfromtimestamp(i).replace(tzinfo=pytz.utc) charge = Charge(account=account, slice=slice, kind=charge_kind, state="pending", date=date, object=object, coreHours=core_hours, amount=amount) charge.save() print "doing invoices and payments" for account in Account.objects.all(): generate_invoices(account) generate_payments(account)