117 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 | 
						|
 | 
						|
# Copyright (c) 2011 Openstack, LLC.
 | 
						|
# All Rights Reserved.
 | 
						|
#
 | 
						|
#    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.
 | 
						|
 | 
						|
"""Cron script to generate usage notifications for instances neither created
 | 
						|
   nor destroyed in a given time period.
 | 
						|
 | 
						|
   Together with the notifications generated by compute on instance
 | 
						|
   create/delete/resize, over that ime period, this allows an external
 | 
						|
   system consuming usage notification feeds to calculate instance usage
 | 
						|
   for each tenant.
 | 
						|
 | 
						|
   Time periods are specified like so:
 | 
						|
   <number>[mdy]
 | 
						|
 | 
						|
   1m = previous month. If the script is run April 1, it will generate usages
 | 
						|
        for March 1 thry March 31.
 | 
						|
   3m = 3 previous months.
 | 
						|
   90d = previous 90 days.
 | 
						|
   1y = previous year. If run on Jan 1, it generates usages for
 | 
						|
        Jan 1 thru Dec 31 of the previous year.
 | 
						|
"""
 | 
						|
 | 
						|
import datetime
 | 
						|
import gettext
 | 
						|
import os
 | 
						|
import sys
 | 
						|
import time
 | 
						|
 | 
						|
# If ../nova/__init__.py exists, add ../ to Python search path, so that
 | 
						|
# it will override what happens to be installed in /usr/(local/)lib/python...
 | 
						|
POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
 | 
						|
                                   os.pardir,
 | 
						|
                                   os.pardir))
 | 
						|
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
 | 
						|
    sys.path.insert(0, POSSIBLE_TOPDIR)
 | 
						|
 | 
						|
gettext.install('nova', unicode=1)
 | 
						|
 | 
						|
 | 
						|
from nova import context
 | 
						|
from nova import db
 | 
						|
from nova import exception
 | 
						|
from nova import flags
 | 
						|
from nova import log as logging
 | 
						|
from nova import utils
 | 
						|
 | 
						|
from nova.notifier import api as notifier_api
 | 
						|
 | 
						|
FLAGS = flags.FLAGS
 | 
						|
flags.DEFINE_string('instance_usage_audit_period', '1m',
 | 
						|
                    'time period to generate instance usages for.')
 | 
						|
 | 
						|
 | 
						|
def time_period(period):
 | 
						|
    today = datetime.date.today()
 | 
						|
    unit = period[-1]
 | 
						|
    if unit not in 'mdy':
 | 
						|
        raise ValueError('Time period must be m, d, or y')
 | 
						|
    n = int(period[:-1])
 | 
						|
    if unit == 'm':
 | 
						|
        year = today.year - (n // 12)
 | 
						|
        n = n % 12
 | 
						|
        if n >= today.month:
 | 
						|
            year -= 1
 | 
						|
            month = 12 + (today.month - n)
 | 
						|
        else:
 | 
						|
            month = today.month - n
 | 
						|
        begin = datetime.datetime(day=1, month=month, year=year)
 | 
						|
        end = datetime.datetime(day=1, month=today.month, year=today.year)
 | 
						|
 | 
						|
    elif unit == 'y':
 | 
						|
        begin = datetime.datetime(day=1, month=1, year=today.year - n)
 | 
						|
        end = datetime.datetime(day=1, month=1, year=today.year)
 | 
						|
 | 
						|
    elif unit == 'd':
 | 
						|
        b = today - datetime.timedelta(days=n)
 | 
						|
        begin = datetime.datetime(day=b.day, month=b.month, year=b.year)
 | 
						|
        end = datetime.datetime(day=today.day,
 | 
						|
                               month=today.month,
 | 
						|
                               year=today.year)
 | 
						|
 | 
						|
    return (begin, end)
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    utils.default_flagfile()
 | 
						|
    flags.FLAGS(sys.argv)
 | 
						|
    logging.setup()
 | 
						|
    begin, end = time_period(FLAGS.instance_usage_audit_period)
 | 
						|
    print "Creating usages for %s until %s" % (str(begin), str(end))
 | 
						|
    instances = db.instance_get_active_by_window(context.get_admin_context(),
 | 
						|
                                                 begin,
 | 
						|
                                                 end)
 | 
						|
    print "%s instances" % len(instances)
 | 
						|
    for instance_ref in instances:
 | 
						|
        usage_info = utils.usage_from_instance(instance_ref,
 | 
						|
                              audit_period_begining=str(begin),
 | 
						|
                              audit_period_ending=str(end))
 | 
						|
        notifier_api.notify('compute.%s' % FLAGS.host,
 | 
						|
                            'compute.instance.exists',
 | 
						|
                            notifier_api.INFO,
 | 
						|
                            usage_info)
 |