def main(argv=None): script = 'clean-old-aggregates' slack = Slackbot(args.slack, script_name=script) if args.slack else None try: term_leases = [ lease for lease in leases.values() if is_terminated(lease) ] old_aggregates = [ aggs for aggs in (aggregates_for_lease(lease) for lease in term_leases) if aggs != None ] aggregate_list = list(itertools.chain(*old_aggregates)) errors, reports = clear_aggregates(aggregate_list) orphan_list = orphan_find(aggregates) for orphan in orphan_list: destiny = has_active_allocation(orphan) host = osrest.blazar.host(auth, orphan) if destiny is None: reports.append( "Error identifying allocation for orphan host {}.".format( orphan)) elif destiny is False: reports.append( "Returning orphan host {} to freepool.".format(orphan) + "\n") osrest.nova.aggregate_add_host(auth, 1, host['hypervisor_hostname']) else: destination_agg = [ aggr['id'] for aggr in aggregates.values() if aggr['name'] == destiny ][0] reports.append( "Moving orphan host {} to destined aggregate {}.".format( orphan, destination_agg)) osrest.nova.aggregate_add_host(auth, destination_agg, host['hypervisor_hostname']) old_allocations = query.blazar_find_old_host_alloc(conn) for alloc in old_allocations: hostname, lease_id = del_expired_alloc(conn, alloc) reports.append( "Deleted host_allocation for host {} matching expired lease {}." .format(hostname, lease_id)) conn.db.commit() if reports: str_report = '\n'.join(reports) if slack: if errors: slack.error(str_report) else: slack.message(str_report) except: if slack: slack.exception() raise
def main(argv=None): if argv is None: argv = sys.argv parser = base_parser('Fixes issues with orphaned resource providers.') mysqlargs = MySqlArgs({ 'user': '******', 'password': '', 'host': 'localhost', 'port': 3306, }) mysqlargs.inject(parser) parser.add_argument( '-q', '--quiet', action='store_true', help='Quiet mode. No output if there was nothing to do.') parser.add_argument('action', choices=['info', 'update'], help='Just display info or actually update them?') args = parser.parse_args(argv[1:]) mysqlargs.extract(args) slack = Slackbot( args.slack, script_name='orphan-resource-providers') if args.slack else None try: db = mysqlargs.connect() update_count = resource_providers_fixer(db=db, describe=args.action == 'info', quiet=args.quiet) if args.action == 'update': if update_count > 0: message = ('Commanded update of *{} resource providers*'. format(update_count)) print(message) slack.message(message) elif not args.quiet: print('No resource providers to delete') except: if slack: slack.exception() raise
def main(argv=None): if argv is None: argv = sys.argv parser = base_parser('Floating IP and port reclaimer.') mysqlargs = MySqlArgs({ 'user': '******', 'password': '', 'host': 'localhost', 'port': 3306, }) mysqlargs.inject(parser) parser.add_argument('-w', '--whitelist', type=str, help='File of project/tenant IDs/names to ignore, one per line. ' 'Ignores case and dashes.') parser.add_argument('action', choices=['info', 'delete'], help='Just display info or actually delete them?') parser.add_argument('type', choices=list(RESOURCE_QUERY), help='Grab floating IPs or ports?') parser.add_argument('idle_days', type=float, help='Number of days since last active instance in project was ' 'deleted to consider it idle.') args = parser.parse_args(argv[1:]) mysqlargs.extract(args) auth = osapi.Authv2.from_env_or_args(args=args) slack = Slackbot(args.slack, script_name='neutron-reaper') if args.slack else None whitelist = set() if args.whitelist: with open(args.whitelist) as f: whitelist = {line for line in f} db = mysqlargs.connect() db.version = query.ROCKY try: to_delete = find_reapable_resources(db=db, auth=auth, type_=args.type, idle_days=args.idle_days, whitelist=whitelist) thing = '{}{}'.format( {'ip': 'floating IP', 'port': 'port'}[args.type], ('' if len(to_delete) == 1 else 's'), ) if to_delete: if args.action == 'delete': for resource_id in to_delete: RESOURCE_DELETE_COMMAND[args.type](auth, resource_id) message = ( 'Commanded deletion of *{} {}* ({:.0f} day grace-period)' .format(len(to_delete), thing, args.idle_days) ) print(message) if slack: slack.message(message) else: print(( 'Found *{} {}* to delete ({:.0f} day grace-period):\n{}' .format(len(to_delete), thing, args.idle_days, to_delete) )) else: print('No {} to delete ({:.0f} day grace-period)'.format(thing, args.idle_days)) except: if slack: slack.exception() raise
def main(argv=None): if argv is None: argv = sys.argv parser = base_parser('Reserve nodes for maintenance') append_global_identity_args(parser, argv) mysqlargs = MySqlArgs({ 'user': '******', 'password': '', 'host': 'localhost', 'port': 3306, }) mysqlargs.inject(parser) parser.add_argument('--operator', type=str, required=True, help='Chameleon account username of the operator') parser.add_argument('--nodes', type=str, required=True, help='node ids or node names; comma separated') parser.add_argument('--reason', type=str, required=True, help='maintenance reasons') parser.add_argument('--dry-run', action="store_true", help='perform a trial run without making reservations') parser.add_argument( '--start-time', type=valid_date, default=None, help= 'lease start time (YYYY-mm-DD HH:MM:SS); if not given, start at the earliest possible datetime' ) parser.add_argument( '--estimate-hours', type=int, default=168, help= 'estimated hours required for maintenance; default is 168 hours (1 week)' ) args = parser.parse_args(argv[1:]) slack = Slackbot( args.slack, script_name='maintenance-reservation') if args.slack else None # connect to database mysqlargs.extract(args) db = mysqlargs.connect() # keystone authentication auth_args = { 'auth_url': args.os_auth_url, 'username': args.os_username, 'password': args.os_password, 'project_name': args.os_project_name, 'region_name': args.os_region_name, 'interface': 'public' } if args.os_user_domain_name: auth_args['user_domain_name'] = args.os_user_domain_name if args.os_project_domain_name: auth_args['project_domain_name'] = args.os_project_domain_name # get admin session for node information admin_sess = get_session(**auth_args) # get maint session for creating lease auth_args['project_name'] = 'maintenance' maint_sess = get_session(**auth_args) try: # get node details nodes = get_nodes(admin_sess, args.nodes.split(',')) report_info = {} for node in nodes: lease_start_time = args.start_time if not lease_start_time: # find the earliest reservation time for the node lease_start_time = get_node_earliest_reserve_time( db, node.uuid, args.estimate_hours) else: # convert to utc lease_start_time = lease_start_time.replace( tzinfo=tz.tzlocal()).astimezone(tz.gettz('UTC')) # reserve reserve_args = { 'sess': maint_sess, 'node': node, 'start_time': lease_start_time, 'requested_hours': args.estimate_hours, 'reason': args.reason, 'operator': args.operator, 'dryrun': args.dry_run } start_time_str, end_time_str = reserve(**reserve_args) report_info[node.name] = (start_time_str, end_time_str) # summary report_lines = [('Node {node_name} at {region} is under maintenance ' 'from {start_time} to {end_time}').format( node_name=key, region=args.os_region_name, start_time=value[0], end_time=value[1]) for key, value in report_info.items()] if report_lines: report = '\n'.join(report_lines) print(report) if slack: slack.message(report) else: print('nothing reserved!') except: if slack: slack.exception() raise
def main(argv=None): if argv is None: argv = sys.argv parser = base_parser('floating IP reaper') mysqlargs = MySqlArgs({ 'user': '******', 'password': '', 'host': 'localhost', 'port': 3306, }) mysqlargs.inject(parser) parser.add_argument( '-w', '--whitelist', type=str, help='File of project/tenant IDs to ignore, one per line.') parser.add_argument( '--grace-days', type=int, required=True, help='Number of days since last used to consider to be idle') parser.add_argument('--dryrun', help='dryrun mode', action='store_true') args = parser.parse_args(argv[1:]) mysqlargs.extract(args) auth = osapi.Auth.from_env_or_args(args=args) slack = Slackbot(args.slack, script_name='floatingip-reaper') if args.slack else None whitelist = set() if args.whitelist: with open(args.whitelist) as f: whitelist = {line.rstrip('\n') for line in f} db = mysqlargs.connect() db.version = query.ROCKY try: result = reaper(db=db, auth=auth, grace_days=args.grace_days, whitelist=whitelist, dryrun=args.dryrun) if result and not args.dryrun: message_lines = [] for proj, ips in result.items(): message_lines.append( 'Reclaimed *{} floating ips* from project {} ({:.0f} day grace-period)' .format(str(len(ips)), proj, args.grace_days)) message = '\n'.join(message_lines) print(message) if slack: slack.message(message) except: if slack: slack.exception() raise
def main(argv=None): if argv is None: argv = sys.argv parser = base_parser('Unutilized Lease Reaper') parser.add_argument('-w', '--warn-hours', type=int, help='Number of hours after which to warn user.', default=DEFAULT_WARN_HOURS) parser.add_argument('-r', '--grace-hours', type=int, help='Number of hours after which to remove lease.', default=DEFAULT_GRACE_HOURS) parser.add_argument('action', choices=['info', 'delete'], help='Just display info or actually delete them?') parser.add_argument('--sender', type=str, help='Email address of sender.', default='*****@*****.**') args = parser.parse_args(argv[1:]) auth = osapi.Auth.from_env_or_args(args=args) assert args.grace_hours > args.warn_hours, ( "Grace hours must be greater than warning period.") if args.slack: slack = Slackbot(args.slack, script_name='unutilized-leases-reaper') else: slack = None try: sender = args.sender warn_period = args.warn_hours grace_period = args.grace_hours warn, terminate = find_leases_in_violation(auth, warn_period, grace_period) if (len(warn) + len(terminate) > 0): if args.action == 'delete': for lease in warn: if lease not in terminate: send_notification( auth, lease, sender, warn_period, grace_period, "Your lease {} is idle and may be terminated.". format(lease['name']), _email.IDLE_LEASE_WARNING_EMAIL_BODY) for lease in terminate: blazar.lease_delete(auth, lease['id']) send_notification( auth, lease, sender, warn_period, grace_period, "Your lease {} has been terminated.".format( lease['name']), _email.IDLE_LEASE_TERMINATION_EMAIL_BODY) message = ('Warned deletion of *{} idle leases* ' 'Commanded deletion of *{} idle leases* ' '(Unutilized lease violation)'.format( len(warn), len(terminate))) print(message) if slack: slack.message(message) else: pprint( dict(warn=[ dict(lease_id=l['id'], nodes=[n['uuid'] for n in l['nodes']]) for l in warn ], terminate=[ dict(lease_id=l['id'], nodes=[n['uuid'] for n in l['nodes']]) for l in terminate ])) else: print('No leases to warn or delete.') except Exception: if slack: slack.exception() raise