2 Generates billing sample data
14 # The granularity at which the charge collection system collects charges. Once
15 # per hour makes for a very slow UI, so I upped it to once per 8 hours.
19 HOUR_SECONDS = MINUTE_SECONDS * 60
20 DAY_SECONDS = HOUR_SECONDS * 24
21 MONTH_SECONDS = DAY_SECONDS * 30
24 sys.path.append("/opt/planetstack")
25 #sys.path.append("/home/smbaker/projects/vicci/plstackapi/planetstack")
27 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "planetstack.settings")
28 #from openstack.manager import OpenStackManager
29 from core.models import Slice, Sliver, ServiceClass, Reservation, Tag, Network, User, Node, Image, Deployment, Site, NetworkTemplate, NetworkSlice
30 from core.models import Invoice, Charge, Account, UsableObject, Payment
32 def delete_all(model):
33 for item in model.objects.all():
36 def get_usable_object(name):
37 objs = UsableObject.objects.filter(name=name)
40 obj = UsableObject(name=name)
44 def generate_invoice(account, batch):
45 invoice = Invoice(date=batch[-1].date, account=account)
48 charge.invoice = invoice
49 charge.state = "invoiced"
52 def generate_invoices(account):
53 invoices = sorted(Invoice.objects.filter(account=account), key=operator.attrgetter('date'))
54 charges = sorted(Charge.objects.filter(account=account, state="pending"), key=operator.attrgetter('date'))
57 latest_invoice_date = invoices[-1].date()
59 latest_invoice_date = None
63 for charge in charges:
64 # check to see if we crossed a week boundary. If we did, then generate
65 # an invoice for the last week's batch of charges
66 week = charge.date.isocalendar()[1]
67 if (week != last_week) and (batch):
68 generate_invoice(account, batch)
73 # we might still have last week's data batched up, and no data for this week
74 # if so, invoice the batch
75 this_week = datetime.datetime.now().isocalendar()[1]
76 if (this_week != last_week) and (batch):
77 generate_invoice(account, batch)
79 def generate_payments(account):
80 invoices = Invoice.objects.filter(account=account)
81 for invoice in invoices:
82 # let's be optomistic and assume everyone pays exactly two weeks after
83 # receiving an invoice
84 payment_time = int(invoice.date.strftime("%s")) + 14 * DAY_SECONDS
85 if payment_time < time.time():
86 payment_time = datetime.datetime.utcfromtimestamp(payment_time).replace(tzinfo=pytz.utc)
87 payment = Payment(account=account, amount=invoice.amount, date=payment_time)
90 print "deleting old stuff"
96 delete_all(UsableObject)
98 print "creating accounts"
100 for site in Site.objects.all():
101 # only create accounts for sites where some slices exist
102 if len(site.slices.all()) > 0:
103 account = Account(site=site)
106 print "generating charges"
108 for slice in Slice.objects.all():
110 account = site.accounts.all()[0]
111 serviceClass =slice.serviceClass
113 if not (slice.name in ["DnsRedir", "DnsDemux", "HyperCache", "Hadoop", "Owl", "Stork", "Syndicate", "test-slice-1", "test-slice-2", "test", "test2"]):
116 print " generating charges for", slice.name
118 now = int(time.time())/HOUR_SECONDS*HOUR_SECONDS
121 for resource in slice.serviceClass.serviceresources.all():
122 if resource.name == "numberCores":
123 charge_kind = "reservation"
125 elif (charge_kind==None) and (resource.name == "cycles") or (resource.name == "Cycles"):
126 charge_kind = "besteffort"
130 print "failed to find resource for", slice.serviceClass
133 for sliver in slice.slivers.all()[:4]: # only do up to 4 slivers; it's way too much data otherwise
134 hostname = sliver.node.name
135 for i in range(now-MONTH_SECONDS, now, CHARGE_HOURS*HOUR_SECONDS):
136 if charge_kind == "besteffort":
137 core_hours = random.randint(20,60)/100.0
141 core_hours = core_hours * CHARGE_HOURS
143 amount = float(core_hours * cost) / 100.0
145 object = get_usable_object(hostname)
147 date = datetime.datetime.utcfromtimestamp(i).replace(tzinfo=pytz.utc)
149 charge = Charge(account=account, slice=slice, kind=charge_kind, state="pending", date=date, object=object, coreHours=core_hours, amount=amount)
152 print "doing invoices and payments"
154 for account in Account.objects.all():
155 generate_invoices(account)
156 generate_payments(account)