Permalink
Browse files

Nova Server Group anti-affinity policy validation tool

This script checks a given Nova Server Group for any instances that fall
foul of invalid anti-affinity rules, i.e there are multiple instances
running on the same hypervisor in a Server Group where the anti-affinity
policy has been set.

Example usage:

./antiaffinitycheck.py --check c353197c-5fbb-410f-a7b3-843452a55276

Anti-affinity rules violated in Server Group: c353197c-5fbb-410f-a7b3-843452a55276
+--------------------------------------+-----------+--------------+
| Instance ID                          | Instance  | Hypervisor   |
+--------------------------------------+-----------+--------------+
| 4c38cf7f-2073-4d96-b377-d2bd29595d8a | app-db-12 | compute2.dev |
| 5c40b1e9-8b38-4978-98b2-391e53e65418 | app-db-11 | compute2.dev |
+--------------------------------------+-----------+--------------+

Change-Id: I2fee4c5eaa1aa0b511c6912f6d7cc35f736621a8
  • Loading branch information...
yankcrime committed Apr 9, 2016
1 parent d2dce9c commit e3b5bc9634c1437ef9538c0a6e7d89c18289b1bb
Showing with 97 additions and 0 deletions.
  1. +97 −0 nova/antiaffinitycheck.py
View
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+""" Utility to check validity of anti-affinity rules """
+
+import os
+import sys
+import argparse
+from collections import defaultdict, Counter
+from keystoneclient import session
+from keystoneclient.auth.identity import v2
+from keystoneclient.v2_0 import client as ksclient
+from novaclient import client as nclient
+import prettytable
+
+def get_credentials():
+ """ Build dictionary of Keystone credentials from environment """
+ keystone_credentials = {}
+ keystone_credentials['auth_url'] = os.environ['OS_AUTH_URL']
+ keystone_credentials['username'] = os.environ['OS_USERNAME']
+ keystone_credentials['password'] = os.environ['OS_PASSWORD']
+ keystone_credentials['tenant_name'] = os.environ['OS_TENANT_NAME']
+ return keystone_credentials
+
+def get_args():
+ """ Get commandline arguments """
+ parser = argparse.ArgumentParser(description='Nova Server Group anti-affinity rule checker')
+ parser.add_argument('--check', type=str, help='Validate the specified Server Group')
+ parser.add_argument('--list', type=str, help='List instances and their hypervisors for a given Server Group')
+ return parser.parse_args()
+
+def get_server(serverid):
+ """ Return Server object """
+ return nova.servers.get(serverid)
+
+def get_group_members(server_group_id):
+ """ Return list of instance UUIDs present in a Server Group """
+ server_group = nova.server_groups.get(server_group_id)
+ if 'anti-affinity' in server_group.policies:
+ return server_group.members
+ else:
+ return False
+
+def create_table(fields):
+ """ Boilerplate for PrettyTable """
+ table = prettytable.PrettyTable(fields, caching=False)
+ table.align = 'l'
+ return table
+
+def print_group_members(server_group_id):
+ """ Print a table detailing Server Group instances and their hypervisors """
+ group_members = get_group_members(server_group_id)
+ if group_members:
+ table = create_table(['Instance ID', 'Instance', 'Hypervisor'])
+ for server in get_group_members(server_group_id):
+ instance = get_server(server)
+ hypervisor = getattr(instance, 'OS-EXT-SRV-ATTR:hypervisor_hostname'.split('.')[0])
+ table.add_row([instance.id, instance.name, hypervisor])
+ print table
+ else:
+ print "Server Group", server_group_id, "empty or does not have an anti-affinity policy set."
+
+def print_group_duplicates(server_group_id):
+ """ Evaluate whether any instances in a SG have been scheduled to the same hypervisor """
+ group_members = get_group_members(server_group_id)
+ if group_members:
+ hypervisors = []
+ instances = defaultdict(list)
+ for instance in get_group_members(server_group_id):
+ i = get_server(instance)
+ hypervisor = getattr(i, 'OS-EXT-SRV-ATTR:hypervisor_hostname')
+ instances[instance].append(i.name)
+ instances[instance].append(hypervisor)
+ hypervisors.append(hypervisor)
+ dupes = [k for k, v in Counter(hypervisors).items() if v > 1]
+ if dupes:
+ print "Anti-affinity rules violated in Server Group:", server_group_id
+ table = create_table(['Instance ID', 'Instance', 'Hypervisor'])
+ [table.add_row([instance_id, instance_name, hypervisor])
+ for instance_id, [instance_name, hypervisor] in instances.items()
+ if hypervisor in dupes]
+ print table
+ else:
+ print "No anti-affinity rules violated for Server Group:", server_group_id
+ else:
+ print "Server Group", server_group_id, "empty or does not have an anti-affinity policy set."
+
+if __name__ == '__main__':
+ credentials = get_credentials()
+ keystone = ksclient.Client(**credentials)
+ auth = v2.Password(**credentials)
+ sess = session.Session(auth=auth)
+ nova = nclient.Client(2, session=sess)
+ args = get_args()
+ group = sys.argv[2]
+ if args.check:
+ print_group_duplicates(group)
+ if args.list:
+ print_group_members(group)

0 comments on commit e3b5bc9

Please sign in to comment.