def action_list(): nc = utils.get_client(Nova, options, logger, region) gc = utils.get_client(Glance, options, logger, region) instances = utils.load_file('/tmp/q35-{}.txt'.format(region)) images = dict() for i, line in enumerate(instances): if 'osl-compute-' in line: continue if options.limit and i > options.limit: break instance = nc.get_by_id('server', line.split(' ')[-1]) if instance.image and hasattr(instance.image, 'id'): image = gc.get_image_by_id(instance.image['id']) image_names = image.tags if 'gold' in image_names: image_names.remove('gold') # pick one, for gold this is the official name tag image_name = next(iter(image_names), None) else: image_name = 'unknown' output = { '1': instance.id, '2': instance.name, '3': instance.created, '4': image_name } printer.output_dict(output, sort=False, one_line=True) images[image_name] = images.get(image_name, 0) + 1 printer.output_dict(images)
def action_volume(): projects = ksclient.get_all_projects() for region in regions: cc = himutils.get_client(Cinder, options, logger, region) nc = himutils.get_client(Nova, options, logger, region) # vms pool vms_pool = dict({'in_use_gb': 0}) for aggregate in nc.get_aggregates(True): if aggregate in local_aggregates: continue hosts = nc.get_aggregate_hosts(aggregate, True) for host in hosts: vms_pool['in_use_gb'] += int(host.local_gb_used) printer.output_dict({'header': 'Nova OS-disk: %s pool vms (max usage)' % region}) printer.output_dict(vms_pool) # cinder quotas and volume usages quotas = dict({'in_use': 0, 'quota': 0}) for project in projects: if not hasattr(project, "type"): # unknown project type logger.debug('=> unknow project type %s', project.name) continue # Filter demo if not options.demo and project.type == 'demo': continue quota = cc.get_quota(project_id=project.id, usage=True) quotas['in_use'] += quota['gigabytes']['in_use'] quotas['quota'] += quota['gigabytes']['limit'] # cinder volume usage volumes = cc.get_volumes(True) volume_usage = {'count': 0, 'size': 0} for volume in volumes: volume_usage['size'] += volume.size volume_usage['count'] += 1 # cinder pools pools = cc.get_pools(detail=True) tmp = pools.to_dict() for pool in pools.pools: name = pool['capabilities']['volume_backend_name'] #print pool out_pool = dict() out_pool['total_capacity_gb'] = pool['capabilities']['total_capacity_gb'] out_pool['free_capacity_gb'] = pool['capabilities']['free_capacity_gb'] printer.output_dict({'header': 'Cinder pool: %s pool %s' % (region, name)}) printer.output_dict(out_pool) out_pools = dict() out_pools['number_of_volumes'] = volume_usage['count'] out_pools['total_quota_gb'] = float(quotas['quota']) out_pools['total_in_volume_gb'] = volume_usage['size'] out_pools['used_in_volume_gb'] = float(quotas['in_use']) printer.output_dict({'header': '%s openstack volume service' % region}) printer.output_dict(out_pools)
def action_expired(): max_days = 90 projects = kc.get_projects(type='demo') subject = '[NREC] Your demo instance is due for deletion' logfile = 'logs/demo-logs/expired_instances/demo-notify-expired-instances-{}.log'.format( date.today().isoformat()) mail = utils.get_client(Mail, options, logger) fromaddr = mail.get_config('mail', 'from_addr') cc = '*****@*****.**' inputday = options.day question = 'Send mail to instances that have been running for {} days?'.format( inputday) if not options.force and not utils.confirm_action(question): return template = options.template if not utils.file_exists(template, logger): utils.sys_error('Could not find template file {}'.format(template)) if not options.template: utils.sys_error( 'Specify a template file. E.g. -t notify/demo-notify-expired-instances.txt' ) if not options.day: utils.sys_error( 'Specify the number of days for running demo instances. E.g. -d 30' ) for region in regions: nc = utils.get_client(Nova, options, logger, region) for project in projects: instances = nc.get_project_instances(project_id=project.id) for instance in instances: created = utils.get_date(instance.created, None, '%Y-%m-%dT%H:%M:%SZ') active_days = (date.today() - created).days kc.debug_log('{} running for {} days'.format( instance.id, active_days)) if (int(active_days) == int(inputday)): mapping = dict(project=project.name, enddate=int((max_days) - int(inputday)), activity=int(active_days), region=region.upper(), instance=instance.name) body_content = utils.load_template(inputfile=template, mapping=mapping, log=logger) msg = mail.get_mime_text(subject, body_content, fromaddr, cc) kc.debug_log( 'Sending mail to {} that has been active for {} days'. format(instance.id, active_days)) mail.send_mail(project.admin, msg, fromaddr) utils.append_to_logfile(logfile, date.today(), region, project.admin, instance.name, active_days) print('Mail sendt to {}'.format(project.admin))
def action_start_instance(): state = utils.get_client(State, options, logger) for region in regions: nova = utils.get_client(Nova, options, logger, region) instances = state.get_all(Instance, region=region, aggregate=options.aggregate) for i in instances: if i.status == 'ACTIVE': instance = nova.get_by_id('server', i.instance_id) nova.start_instance(instance) state.close()
def action_dualstack(): for region in regions: nc = himutils.get_client(Nova, options, logger, region) instances = nc.get_all_instances() printer.output_dict( {'header': 'Instance list (id, name, status, updated)'}) status = dict({'total': 0}) for i in instances: # Filter for project type if options.type: project = kc.get_by_id('project', i.tenant_id) if hasattr(project, 'type') and project.type != options.type: status['type'] = options.type continue network = i.addresses.keys()[0] if len( i.addresses.keys()) > 0 else 'unknown' if network != 'dualStack': continue output = { '1': i.id, '3': i.name, '4': i.status, #'2': i.updated, #'6'': getattr(i, 'OS-EXT-SRV-ATTR:instance_name'), #'5': i.flavor['original_name'] '7': network } printer.output_dict(output, sort=True, one_line=True) status['total'] += 1 status[str( i.status).lower()] = status.get(str(i.status).lower(), 0) + 1 printer.output_dict({'header': 'Counts'}) printer.output_dict(status)
def action_project(): mail = Mail(options.config, debug=options.debug) search_filter = dict() projects = ksclient.get_projects(domain=options.domain, **search_filter) if options.template: content = options.template email_content = open(content, 'r') body_content = email_content.read() if options.dry_run: print body_content else: with open(content, 'r') as email_content: body_content = email_content.read() if options.filter and options.filter != 'all': search_filter['type'] = options.filter if options.type: search_filter['type'] = options.type for region in regions: for project in projects: project_type = project.type if hasattr(project, 'type') else '(unknown)' novaclient = himutils.get_client(Nova, options, logger, region) instances = novaclient.get_project_instances(project.id) mail.set_keystone_client(ksclient) users = mail.mail_instance_owner(instances=instances, body=body_content, subject=subject, admin=True) mail.close()
def action_notify(): projects = kc.get_projects() subject = '[NREC] Your project has expired' logfile = 'logs/expired-notify-{}.log'.format(date.today().isoformat()) mail = utils.get_client(Mail, options, logger) fromaddr = mail.get_config('mail', 'from_addr') if options.template: template = options.template else: template = 'notify/notify_expired_first.txt' for project in projects: project = expired_project(project) if not project or hasattr(project, 'notified'): continue mapping = dict(project=project.name, enddate=project.enddate) body_content = utils.load_template(inputfile=template, mapping=mapping, log=logger) msg = mail.get_mime_text(subject, body_content, fromaddr) mail.send_mail(project.admin, msg, fromaddr) print "mail sendt to {}".format(project.admin) if not options.dry_run: utils.append_to_file(logfile, project.admin) # Add metadata to project for the time of notification kc.update_project(project_id=project.id, notified=str(date.today()))
def vendorapi_list(): from himlarcli.nova import Nova data_instance = dict() data_project = dict() projects = ksclient.get_projects() # Loop through projects for project in projects: contact = project.contact if hasattr(project, 'contact') else None admin = project.admin if hasattr(project, 'admin') else None data_project[project.id] = { "project_name": project.name, "project_admin": admin, "project_contact": contact } # Get Instances for region in regions: instances = dict() # Initiate Nova object nc = utils.get_client(Nova, options, logger, region) # Get a list of instances in project instances[region] = nc.get_project_instances(project_id=project.id) for instance in instances[region]: contact = project.contact if hasattr(project, 'contact') else None data_instance[instance.id] = { "region": region, } return data_project, data_instance
def action_instances(): for region in regions: nc = himutils.get_client(Nova, options, logger, region) flavors = nc.get_flavors(class_filter=options.flavor) printer.output_dict( {'header': 'Instance list %s (id, name, flavor)' % region}) status = dict({'total': 0}) for flavor in flavors: search_opts = dict(all_tenants=1, flavor=flavor.id) instances = nc.get_all_instances(search_opts=search_opts) for i in instances: output = { '1': i.id, '3': i.name, '4': i.status, #'2': i.updated, #'6'': getattr(i, 'OS-EXT-SRV-ATTR:instance_name'), '5': i.flavor['original_name'] } printer.output_dict(output, sort=True, one_line=True) status['total'] += 1 status[str(i.status).lower()] = status.get( str(i.status).lower(), 0) + 1 printer.output_dict({'header': 'Counts'}) printer.output_dict(status)
def action_instances(): for region in regions: nova = utils.get_client(Nova, options, logger, region) #neutron = utils.get_client(Neutron, options, logger) #network = neutron.list_networks() instances = nova.get_instances(options.aggregate) printer.output_dict( {'header': 'Instance list (id, host, status, flavor)'}) status = dict({'total': 0}) for i in instances: output = { '1': i.id, '2': nova.get_compute_host(i), #'3': i.name, '4': i.status, #'2': i.updated, #'6'': getattr(i, 'OS-EXT-SRV-ATTR:instance_name'), '5': i.flavor['original_name'] } printer.output_dict(output, sort=True, one_line=True) status['total'] += 1 status[str( i.status).lower()] = status.get(str(i.status).lower(), 0) + 1 printer.output_dict({'header': 'Counts'}) printer.output_dict(status)
def action_revoke(): for region in regions: nc = himutils.get_client(Nova, options, logger, region) result = update_access(nc, 'revoke', region) if result: printer.output_msg("Revoke access to {} for {} in {}".format( options.flavor, options.project, region))
def action_count(): projects = kc.get_projects(type='demo') count_all = count_60 = 0 for project in projects: for region in regions: nc = utils.get_client(Nova, options, logger, region) instances = nc.get_project_instances(project_id=project.id) if not instances: continue for i in instances: count_all += 1 created_at = utils.get_date(i.created, None, '%Y-%m-%dT%H:%M:%SZ') if (date.today() - created_at) >= timedelta(60): count_60 += 1 with open('/opt/himlarcli/logs/dryrun-logs/dryrun-logs.log' ) as f: if i.id in f.read(): printer.output_dict({ 'instance name': i.name, 'instance id': i.id, 'notify?': 'yes' }) f.close() else: print created_at printer.output_dict({'header': 'count', 'all': count_all, '>60': count_60})
def _count_project_zones(project, options, logger): # Initiate Designate object dc = utils.get_client(Designate, options, logger) # Get Zones zones = dc.list_project_zones(project.id) return len(zones)
def action_show(): for region in regions: nova = utils.get_client(Nova, options, logger, region) aggregate = nova.get_aggregate(options.aggregate) if not aggregate: continue printer.output_dict({'header': 'Host aggregate in {}'.format(region)}) printer.output_dict(aggregate.to_dict())
def action_compare(): if options.resource == 'quota': projects = kc.get_all_projects() for region in regions: printer.output_dict({'header': 'quota miss match found in %s' % region}) nova = himutils.get_client(Nova, options, logger, region) cinder = himutils.get_client(Cinder, options, logger, region) neutron = himutils.get_client(Neutron, options, logger, region) for project in projects: quotas = nova.get_quota(project.id).copy() quotas.update(cinder.get_quota(project.id)) quotas.update(neutron.get_quota(project.id)) quotas['project_id'] = project.id quotas['region'] = region q = state.get_first(Quota, project_id=project.id, region=region) if q is None: print 'could not find saved quota for %s' % project.name continue miss_match = q.compare(quotas) if miss_match: output = { '1': project.name, '2': miss_match } printer.output_dict(output, one_line=True) elif options.resource == 'keypair': users = kc.get_users() for region in regions: printer.output_dict({'header': 'ssh keys miss match found in %s' % region}) nova = himutils.get_client(Nova, options, logger, region) for user in users: keypairs = list() temp = nova.get_keypairs(user_id=user.id) for k in temp: keypairs.append(k) saved_keys = state.get_all(Keypair, user_id=user.id) if len(keypairs) != len(saved_keys): output = { '1': user.name, '2': len(keypairs), '3': len(saved_keys) } printer.output_dict(output, one_line=True)
def action_disable(): projects = kc.get_projects() subject = '[NREC] Your project is due for deletion' logfile = 'logs/expired-disabled-{}.log'.format(date.today().isoformat()) if options.template: template = options.template else: template = 'notify/notify_expired_last.txt' mail = utils.get_client(Mail, options, logger) fromaddr = mail.get_config('mail', 'from_addr') for project in projects: project = expired_project(project) if not project: continue # Allow 30 days gracetime before we disable disabled_date = utils.get_date(project.notified, None, '%Y-%m-%d') gracetime = timedelta(30) if date.today() - disabled_date < gracetime: continue # stop instances for region in regions: nc = utils.get_client(Nova, options, logger, region) instances = nc.get_project_instances(project_id=project.id) for i in instances: if i.status == 'ACTIVE': i.stop() mapping = dict(project=project.name, enddate=project.enddate) body_content = utils.load_template(inputfile=template, mapping=mapping, log=logger) msg = mail.get_mime_text(subject, body_content, fromaddr) mail.send_mail(project.admin, msg, fromaddr) print "mail sendt to {}".format(project.admin) if not options.dry_run: utils.append_to_file(logfile, project.admin) # Add metadata to project for the time of project disable kc.update_project(project_id=project.id, enabled=False, disabled=str(date.today()))
def action_list(): for region in regions: nc = himutils.get_client(Nova, options, logger, region) flavors = nc.get_flavors(class_filter=options.flavor) outputs = ['name', 'vcpus', 'ram', 'disk'] header = 'flavors in %s (%s)' % (region, ', '.join(outputs)) printer.output_dict({'header': header}) for flavor in flavors: output = OrderedDict() for out in outputs: output[out] = getattr(flavor, out) printer.output_dict(objects=output, one_line=True, sort=False)
def action_save(): if options.resource == 'quota': projects = kc.get_all_projects() for region in regions: nova = himutils.get_client(Nova, options, logger, region) cinder = himutils.get_client(Cinder, options, logger, region) neutron = himutils.get_client(Neutron, options, logger, region) for project in projects: quotas = nova.get_quota(project.id).copy() quotas.update(cinder.get_quota(project.id)) quotas.update(neutron.get_quota(project.id)) quotas['project_id'] = project.id quotas['region'] = region q = state.get_first(Quota, project_id=project.id, region=region) if q is not None: state.update(q, quotas) else: quota = Quota.create(quotas) # pylint: disable=E1101 state.add(quota) elif options.resource == 'keypair': users = kc.get_users() for region in regions: nova = himutils.get_client(Nova, options, logger, region) for user in users: keypairs = nova.get_keypairs(user_id=user.id) for key in keypairs: keypair = { 'user_id': user.id, 'name': key.name, 'public_key': key.public_key, 'region': region, 'type': key.type } k = state.get_first(Keypair, region=region, user_id=user.id, name=key.name) logger.debug('=> key %s for user %s', key.name, user.name) if k is not None: state.update(k, keypair) else: state.add(Keypair.create(keypair)) # pylint: disable=E1101
def _count_project_instances(project, options, logger, regions): instances = dict() # Get Instances for region in regions: # Initiate Nova object nc = utils.get_client(Nova, options, logger, region) # Get a list of instances in project instances[region] = len( nc.get_project_instances(project_id=project.id)) return instances
def _count_project_images(project, options, logger, regions): images = dict() # Get Images for region in regions: # Initiate Glance object gc = utils.get_client(Glance, options, logger, region) # Get a list of volumes in project filters = {'owner': project.id, 'visibility': 'private'} images[region] = len(gc.find_image(filters=filters)) return images
def _count_project_volumes(project, options, logger, regions): volumes = dict() # Get Volumes for region in regions: # Initiate Cinder object cc = utils.get_client(Cinder, options, logger, region) # Get a count of volumes in project volumes[region] = len( cc.get_volumes(search_opts={'project_id': project.id})) return volumes
def action_list(): printer.output_dict({'header': 'Host aggregate (#hosts, name, az)'}) for region in regions: nova = utils.get_client(Nova, options, logger, region) aggregates = nova.get_aggregates(simple=False) for aggr in aggregates: output = { '2': aggr.name, '3': aggr.metadata['availability_zone'], '1': len(aggr.hosts) } printer.output_dict(output, one_line=True)
def action_list(): projects = kc.get_projects(type='demo') printer.output_dict( {'header': 'Demo project (instances, vcpus, volumes, gb, name)'}) count = {'size': 0, 'vcpus': 0, 'instances': 0} for project in projects: ins_data = {'count': 0, 'vcpu': 0} vol_data = dict({'count': 0, 'size': 0}) for region in regions: nc = utils.get_client(Nova, options, logger, region) cc = utils.get_client(Cinder, options, logger, region) instances = nc.get_project_instances(project_id=project.id) ins_data = {'count': 0, 'vcpus': 0} for i in instances: ins_data['vcpus'] += i.flavor['vcpus'] ins_data['count'] += 1 volumes = cc.get_volumes(detailed=True, search_opts={'project_id': project.id}) for volume in volumes: vol_data['size'] += volume.size vol_data['count'] += 1 output = { '5': project.name, '1': ins_data['count'], '2': ins_data['vcpus'], '3': vol_data['count'], '4': vol_data['size'] } printer.output_dict(output, one_line=True) count['size'] += vol_data['size'] count['vcpus'] += ins_data['vcpus'] count['instances'] += ins_data['count'] printer.output_dict({ 'header': 'Count', 'instances': count['instances'], 'volume_gb': count['size'], 'vcpus': count['vcpus'] })
def action_stop_instance(): msg = 'Remember to purge db with state.py first! Continue?' if not options.dry_run and not utils.confirm_action(msg): return state = utils.get_client(State, options, logger) for region in regions: nova = utils.get_client(Nova, options, logger, region) instances = nova.get_instances(options.aggregate) for i in instances: instance_data = i.to_dict().copy() instance_data['region'] = region instance_data['aggregate'] = options.aggregate instance_data['instance_id'] = i.id instance_data.pop('created', None) # not instance created, but db instance = state.get_first(Instance, instance_id=i.id) if instance is None: # add to db if not found instance = Instance.create(instance_data) #pylint: disable=E1101 state.add(instance) nova.stop_instance(i) state.close()
def action_list(): # pylint: disable=W0612 blacklist, whitelist, notify = load_config() for region in regions: nova = utils.get_client(Nova, options, logger, region) neutron = utils.get_client(Neutron, options, logger, region) rules = neutron.get_security_group_rules(1000) question = ( "Are you sure you will check {} security group rules in {}?". format(len(rules), region)) if not options.assume_yes and not utils.confirm_action(question): return printer.output_dict( {'header': 'Rules in {} (project, port, ip)'.format(region)}) for rule in rules: if is_whitelist(rule, whitelist): continue if is_blacklist(rule, blacklist): continue sec_group = neutron.get_security_group(rule['security_group_id']) if not rule_in_use(sec_group, nova): continue # check if project exists project = kc.get_by_id('project', rule['project_id']) if not project: kc.debug_log('could not find project {}'.format( rule['project_id'])) continue output = { '0': project.name, '1': "{}-{}".format(rule['port_range_min'], rule['port_range_max']), '2': rule['remote_ip_prefix'] } printer.output_dict(output, one_line=True)
def prettyprint_project_images(project, options, logger, regions): out_str = '' images_total = 0 images = dict() # Get Images for region in regions: # Initiate Glance object gc = utils.get_client(Glance, options, logger, region) # Get a list of volumes in project filters = {'owner': project.id, 'visibility': 'private'} images[region] = gc.find_image(filters=filters) for i in images[region]: images_total += 1 # Print Images table if images_total > 0: table_images = PrettyTable() table_images.field_names = [ 'id', 'name', 'created', 'size', 'type', 'owner', 'status', 'region' ] table_images.align['id'] = 'l' table_images.align['name'] = 'l' table_images.align['created'] = 'l' table_images.align['size'] = 'r' table_images.align['type'] = 'l' table_images.align['owner'] = 'l' table_images.align['status'] = 'l' table_images.align['region'] = 'l' for region in regions: for image in images[region]: image_type = image.image_type if hasattr( image, 'image_type') else 'n/a' image_owner = image.owner_user_name if hasattr( image, 'owner_user_name') else 'n/a' image_size = "%d KiB" % (int(image.size) / 1024) if isinstance( image.size, int) else 'n/a' table_images.add_row([ image.id, image.name, image.created_at, image_size, image_type, image_owner, image.status, region ]) out_str += "\n Images (%d): \n" % images_total out_str += table_images.get_string() + "\n" return out_str.encode('utf-8')
def action_list(): for region in regions: nc = himutils.get_client(Neutron, options, logger, region) networks = nc.list_networks() printer.output_dict( {'header': 'networks (name, shared, IPv4 addresses)'}) for net in networks: output = { '0': net['name'], '1': net['shared'], '2': nc.get_allocation_pool_size(network_id=net['id'], ip_version=4) } printer.output_dict(output, sort=True, one_line=True)
def action_delete(): q = 'Delete flavor class {} in region(s) {}'.format( options.flavor, ','.join(regions)) if not himutils.confirm_action(q): return for region in regions: nc = himutils.get_client(Nova, options, logger, region) nc.debug_log('Start delete all {} from region {}'.format( options.flavor, region)) result = nc.delete_flavors(class_filter=options.flavor) if result: printer.output_msg('Deleted all {} from region {}'.format( options.flavor, region)) else: printer.output_msg( 'Nothing to delete from region {}'.format(region))
def action_purge(): q = 'Purge flavors from class {} in region(s) {}'.format( options.flavor, ','.join(regions)) if not himutils.confirm_action(q): return for region in regions: flavors = get_flavor_config(region) nc = himutils.get_client(Nova, options, logger, region) nc.debug_log('Start purge of flavor class {} from region {}'.format( options.flavor, region)) result = nc.purge_flavors(class_filter=options.flavor, flavors=flavors) if result: printer.output_msg( 'Purged flavors of class {} from region {}'.format( options.flavor, region)) else: printer.output_msg( 'Nothing to purge from region {}'.format(region))
def action_list_access(): for region in regions: nc = himutils.get_client(Nova, options, logger, region) access = nc.get_flavor_access(filters=options.flavor) header = 'access to %s flavor in %s' % (options.flavor, region) printer.output_dict({'header': header}) output = dict() for name, projects in access.iteritems(): output[name] = list() for project_id in projects: project = kc.get_by_id('project', project_id.tenant_id) if project: output[name].append(project.name) else: himutils.sys_error( 'project not found %s' % project_id.tenant_id, 0) continue printer.output_dict(output)
def action_orphan(): question = "This will also purge all orphan volumes. Are you sure?" if options.purge and not utils.confirm_action(question): return cc = utils.get_client(Cinder, options, logger, region) volumes = cc.get_volumes(detailed=True) printer.output_dict({'header': 'Volumes (id, name, type)'}) count = {'count': 0, 'size': 0} for volume in volumes: project = kc.get_by_id('project', getattr(volume, 'os-vol-tenant-attr:tenant_id')) if project: # not orphan volume continue count = print_and_count(volume, count) if options.purge: cc.delete_volume(volume.id, True) printer.output_dict({ 'header': 'Count', 'volumes': count['count'], 'size': count['size']})
def action_instance(): if options.template: content = options.template email_content = open(content, 'r') body_content = email_content.read() if options.dry_run: print body_content else: with open(content, 'r') as email_content: body_content = email_content.read() for region in regions: novaclient = himutils.get_client(Nova, options, logger, region) instances = novaclient.get_instances() mail = Mail(options.config, debug=options.debug) mail.set_keystone_client(ksclient) users = mail.mail_instance_owner(instances=instances, body=body_content, subject=subject, admin=True) mail.close()