Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
Conflicts:
	dough/api.py
  • Loading branch information
pengyuwei committed Jun 15, 2012
2 parents 0cd745e + 90d3e78 commit 7523869
Show file tree
Hide file tree
Showing 9 changed files with 465 additions and 1 deletion.
8 changes: 7 additions & 1 deletion bin/dough-api
Expand Up @@ -6,9 +6,9 @@ import sys

import zmq

from nova import utils
from nova import flags
from nova import log as logging
from nova import utils

from dough import api
from dough import context as dough_context
Expand All @@ -25,6 +25,7 @@ if __name__ == '__main__':
# Socket to receive messages on
handler = zmq_context.socket(zmq.REP)
handler.bind("tcp://%s:%s" % (FLAGS.api_listen, FLAGS.api_listen_port))
print "listen:", FLAGS.api_listen, FLAGS.api_listen_port

poller = zmq.Poller()
poller.register(handler, zmq.POLLIN)
Expand All @@ -40,8 +41,13 @@ if __name__ == '__main__':
method = msg_body['method']
args = msg_body['args']
context = dough_context.get_context(**args)
print "-"*60
print "\033[0;31m" + method + "\033[0m:"
print args
method_func = getattr(api, method)
response = method_func(context, **args)
print "response:"
print response
except Exception, e:
print traceback.format_exc()
cli_msg['code'] = 500
Expand Down
101 changes: 101 additions & 0 deletions bin/dough-client
@@ -0,0 +1,101 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 Sina Corporation
# All Rights Reserved.
# Author: YuWei Peng <pengyuwei@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import sys
import time
import ConfigParser
import json
import zmq
from collections import OrderedDict
from dough.client.dough_client import *

def show_usage():
print "usage:"
print "\tdough_client"
print "\tdough_client <param> <tenant_id> <time_from> [time_to] [period_hours]"
print "param:"
print "\t -m : query_monthly_report"
print "\t -d : query_report"
print "./dough-client -d 1adfb274fee24dbd96ea89b57d110fc5 2012-06-01T00:00:00 2012-07-01T00:00:00 days network resource_name"

def show_result(data):
print data

def show_report(data):
# print "ID=", data['data']['id']
data = data['data']['default']
line_total_sum = 0
quantity_sum = 0
count = 0

rs = OrderedDict(sorted(data.items(), key=lambda t: t[0]))
for k, i in rs.iteritems():
count += 1
print '-' * 60, count
print k
for kk, ii in i.iteritems():
print "\t", kk, ii
if kk == 'line_total':
line_total_sum += ii
elif kk == 'quantity':
quantity_sum += ii
print "total[", count, "] = ", line_total_sum

def main():
if len(sys.argv) == 2:
show_usage()
return
if len(sys.argv) == 3:
if sys.argv[2] in ['--help', "-h", "?"]:
show_usage()
return

data = None
client = DoughClient()

if len(sys.argv) > 8:
tenant_id = sys.argv[3]
time_from = sys.argv[4]
time_to = sys.argv[5]
period = sys.argv[6]
item_name = sys.argv[7]
resource_name = sys.argv[8]
if sys.argv[2] == '-d':
data = client.query_report(tenant_id, time_from, time_to, period,
item_name, resource_name)
else:
pass

show_report(data)
elif len(sys.argv) > 6:
return
elif len(sys.argv) > 5:
tenant_id = sys.argv[3]
time_from = sys.argv[4]
time_to = sys.argv[5]
if sys.argv[2] == '-m':
data = client.query_monthly_report(tenant_id, time_from, time_to)
else:
pass
show_result(data)
else:
pass

if __name__ == '__main__':
main()
1 change: 1 addition & 0 deletions bin/dough-farmer
Expand Up @@ -29,6 +29,7 @@ if __name__ == '__main__':
context = dough_context.get_admin_context()
while True:
current_time = utils.utcnow()
print "-" * 50, str(current_time)
subscriptions = list()
_subscriptions = db.subscription_get_all(context)
for sub in _subscriptions:
Expand Down
134 changes: 134 additions & 0 deletions bin/dough-manager
@@ -0,0 +1,134 @@
#!/usr/bin/env python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 Sina Corporation
# All Rights Reserved.
# Author: YuWei Peng <pengyuwei@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import datetime
import sys
import time
import traceback

#from dateutil.relativedelta import relativedelta
#import zmq

from nova import flags
from nova import log as logging
from nova import utils

#from dough import billing
# from dough.billing import api
from dough import context as dough_context
from dough import db
from dough import api
from nova.openstack.common import cfg
#from dough import exception

utils.default_flagfile(filename='/etc/dough/dough.conf')
FLAGS = flags.FLAGS
#logging.setup()

manager_opts = [
cfg.StrOpt('resource_name',
short='r',
default='name1',
help='resource_name.'),
cfg.StrOpt('purchase',
short='p',
default='name1',
help='purchase.'),
cfg.StrOpt('help',
short='?',
default='',
help='help'),
]

FLAGS.register_cli_opts(manager_opts)
flags.FLAGS(sys.argv)

def show_usage():
print "dough-mansger -n <resource_name>"

def get_subs(context, param):
print "filter: resource_name=", param
try:
sub = db.subscription_get_byname(context, resource_name=param)
subscription_id = sub['id']
status = sub['status']
tenant_id = sub['project_id']
resource_uuid = sub['resource_uuid']
created_at = sub['created_at']
updated_at = sub['updated_at']
expires_at = sub['expires_at']
order_unit = sub['product']['order_unit']
order_size = sub['product']['order_size']
price = sub['product']['price']
currency = sub['product']['currency']

region_name = sub['product']['region']['name']
item_name = sub['product']['item']['name']
pay_type = sub['product']['payment_type']
interval_unit = pay_type['interval_unit']
interval_size = pay_type['interval_size']
is_prepaid = pay_type['is_prepaid']
print '-'*60
print "%24s : %s" % ("subscription_id", str(subscription_id))
print "%24s : %s" % ("tenant_id", str(tenant_id))
print "%24s : %s" % ("expires_at", str(expires_at))
print "%24s : %s" % ("price", str(price))
print "%24s : %s" % ("region_name", str(region_name))
print "%24s : %s" % ("item_name", str(item_name))
# print "%24s : %s" % ("pay_type", str(pay_type))
print "%24s : %s" % ("created_at", str(created_at))
except Exception, e:
print Exception, e

def query_report(tenant_id, timestamp_from, timestamp_to):
datetime_from = iso8601.parse_date(timestamp_from)
datetime_to = iso8601.parse_date(timestamp_to)
context = dough_context.get_context(tenant_id=self.tenant_id)
data = api.query_report(self.context,
timestamp_from,
timestamp_to)
return data

"""
select id, subscription_id, created_at, quantity from purchases where subscription_id =151 and created_at>"2012-06-03 00:00:00";
"""

def main():
baselen = 2
context = dough_context.get_admin_context()
if len(sys.argv) == baselen:
get_subs(context, sys.argv)
return
if len(sys.argv) == baselen:
if sys.argv[baselen-1] in ['--help', "-h", "?"]:
show_usage()
return

if len(sys.argv) == baselen + 2:
param = sys.argv[baselen + 1]
if sys.argv[baselen][:2] == '-r':
get_subs(context, param)
elif len(sys.argv) == baselen + 4:
tenant_id = sys.argv[baselen + 1]
timestamp_from = sys.argv[baselen + 2]
timestamp_to = sys.argv[baselen + 3]
print query_report(tenant_id, timestamp_from, timestamp_to)


if __name__ == '__main__':
main()
96 changes: 96 additions & 0 deletions dough/api.py
Expand Up @@ -182,12 +182,14 @@ def find_timeframe(start_time, end_time, target):
current_frame = start_time
month_cnt = 1
while current_frame < end_time:
# 2012-05-10 00:00:00+00:00-->2012-06-10 00:00:00+00:00
next_frame = start_time + relativedelta(months=month_cnt)
if current_frame <= target_utc < next_frame:
break
month_cnt += 1
current_frame = next_frame
assert(current_frame < end_time)

return current_frame.isoformat()

monthly_report = dict()
Expand Down Expand Up @@ -218,3 +220,97 @@ def find_timeframe(start_time, end_time, target):
monthly_usage.setdefault(item_name, 0)
monthly_usage[item_name] += line_total
return {'data': monthly_report}

def query_report(context, timestamp_from=None, timestamp_to=None,
period=None, item_name=None, resource_name=None, **kwargs):
"""period='days' or 'hours'"""
print "query_report", timestamp_from, timestamp_to, item_name, resource_name
# period = int(period)

if not period in ['days', 'hours', 'months']:
return {'data': None}

def find_timeframe(start_time, end_time, target):
target_utc = target.replace(tzinfo=UTC_TIMEZONE)
current_frame = start_time
cnt = 1
while current_frame < end_time:
foo = {period: cnt}
next_frame = start_time + relativedelta(**foo)
if current_frame <= target_utc < next_frame:
break
cnt += 1
current_frame = next_frame
assert(current_frame < end_time)
return current_frame.isoformat()

monthly_report = dict()
usage_report = dict()
datetime_from = iso8601.parse_date(timestamp_from)
datetime_to = iso8601.parse_date(timestamp_to)
subscriptions = list()
_subscriptions = list()

__subscriptions = db.subscription_get_all_by_project(context,
context.project_id)
if not __subscriptions:
return {'data': None}
# print "context.project_id", context.project_id
for subscription in __subscriptions:
# print subscription['id'], subscription['resource_name'], subscription['product']['item']['name']
if subscription['resource_name'] != resource_name:
continue
elif subscription['product']['item']['name'] != item_name:
continue
_subscriptions.append(subscription)

for subscription in _subscriptions:
subscription_id = subscription['id']
resource_uuid = subscription['resource_uuid']
resource_name = subscription['resource_name']
created_at = subscription['created_at']
expires_at = subscription['expires_at']
region_name = subscription['product']['region']['name']
item_name = subscription['product']['item']['name']
item_type_name = subscription['product']['item_type']['name']
order_unit = subscription['product']['order_unit']
order_size = subscription['product']['order_size']
price = subscription['product']['price']
currency = subscription['product']['currency']
subscriptions.append([subscription_id, resource_uuid, resource_name,
created_at, expires_at,
region_name, item_name, item_type_name,
order_unit, order_size, price, currency])
for (subscription_id, resource_uuid, resource_name, created_at, expires_at,
region_name, item_name, item_type_name,
order_unit, order_size, price, currency) in subscriptions:
purchases = db.purchase_get_all_by_subscription_and_timeframe(context,
subscription_id,
datetime_from,
datetime_to)
if not purchases:
continue
i = 0
for purchase in purchases:
line_total = purchase['line_total']
quantity = purchase['quantity']
timeframe = find_timeframe(datetime_from,
datetime_to,
purchase['created_at'])
# print timeframe
i += 1
usage_datum = (resource_uuid, resource_name, item_type_name,
order_unit, order_size, price,
currency, quantity, line_total,
created_at.isoformat(), expires_at.isoformat())
region_usage = monthly_report.setdefault(region_name, dict())
monthly_usage = region_usage.setdefault(timeframe, dict())
item = monthly_usage.setdefault(item_name, 0)
monthly_usage[item_name] = usage_datum
item = monthly_usage.setdefault("quantity", 0)
monthly_usage.setdefault("line_total", 0)
monthly_usage["quantity"] += quantity
monthly_usage["line_total"] += line_total
print "total:", i
return {'data': monthly_report}

0 comments on commit 7523869

Please sign in to comment.