drop openstack driver from xos core

Change-Id: Id49560b65590b527c3e8088fc585c6f84626d61d
diff --git a/xos/openstack_xos/__init__.py b/xos/openstack_xos/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/xos/openstack_xos/__init__.py
+++ /dev/null
diff --git a/xos/openstack_xos/client.py b/xos/openstack_xos/client.py
deleted file mode 100644
index d1383f4..0000000
--- a/xos/openstack_xos/client.py
+++ /dev/null
@@ -1,210 +0,0 @@
-import urlparse
-try:
-    from keystoneauth1.identity import v2 as keystoneauth_v2
-    from keystoneauth1 import session as keystone_session
-    from keystoneclient.v2_0 import client as keystone_client
-    #from glance import client as glance_client
-    import glanceclient
-    from novaclient.v2 import client as nova_client
-    from neutronclient.v2_0 import client as neutron_client 
-    has_openstack = True
-except:
-    has_openstack = False
-
-from xos.config import Config
-
-def require_enabled(callable):
-    def wrapper(*args, **kwds):
-        if has_openstack:
-            return callable(*args, **kwds)
-        else:
-            return None
-    return wrapper
-
-def parse_novarc(filename):
-    opts = {}
-    f = open(filename, 'r')
-    for line in f:
-        try:
-            line = line.replace('export', '').strip()
-            parts = line.split('=')
-            if len(parts) > 1:
-                value = parts[1].replace("\'", "")
-                value = value.replace('\"', '')
-                opts[parts[0]] = value
-        except:
-            pass
-    f.close()
-    return opts
-
-class Client:
-    def __init__(self, username=None, password=None, tenant=None, url=None, token=None, endpoint=None, controller=None, cacert=None, admin=True, *args, **kwds):
-       
-        self.has_openstack = has_openstack
-        self.url = controller.auth_url
-        if admin:
-            self.username = controller.admin_user
-            self.password = controller.admin_password
-            self.tenant = controller.admin_tenant
-        else:
-            self.username = None
-            self.password = None
-            self.tenant = None
-
-        if username:
-            self.username = username
-        if password:
-            self.password = password
-        if tenant:
-            self.tenant = tenant
-        if url:
-            self.url = url
-        if token:
-            self.token = token    
-        if endpoint:
-            self.endpoint = endpoint
-
-        if cacert:
-            self.cacert = cacert
-        else:
-            self.cacert = getattr(Config(), "nova_ca_ssl_cert", "None")
-
-        #if '@' in self.username:
-        #    self.username = self.username[:self.username.index('@')]
-
-class KeystoneClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            auth = keystoneauth_v2.Password(username=self.username,
-                                            password=self.password,
-                                            tenant_name=self.tenant,
-                                            auth_url=self.url,
-                                            )
-            sess = keystone_session.Session(auth=auth, verify=self.cacert, )
-            self.client = keystone_client.Client(session=sess)
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-
-class Glance(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = glanceclient.get_client(host='0.0.0.0',
-                                                   username=self.username,
-                                                   password=self.password,
-                                                   tenant=self.tenant,
-                                                   auth_url=self.url,
-                                                   cacert=self.cacert
-                                                   )
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class GlanceClient(Client):
-    def __init__(self, version, endpoint, token, cacert=None, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = glanceclient.Client(version, 
-                endpoint=endpoint, 
-                token=token,
-                cacert=cacert
-            )
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)        
-
-class NovaClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = nova_client.client.Client(
-                    "2",
-                    username=self.username,
-                    api_key=self.password,
-                    project_id=self.tenant,
-                    auth_url=self.url,
-                    region_name='',
-                    extensions=[],
-                    service_type='compute',
-                    service_name='',
-                    cacert=self.cacert
-                    )
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class NovaDB(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.ctx = get_admin_context()
-            nova_db_api.FLAGS(default_config_files=['/etc/nova/nova.conf'])
-            self.client = nova_db_api
-
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class NeutronClient(Client):
-    def __init__(self, *args, **kwds):
-        Client.__init__(self, *args, **kwds)
-        if has_openstack:
-            self.client = neutron_client.Client(username=self.username,
-                                                password=self.password,
-                                                tenant_name=self.tenant,
-                                                auth_url=self.url,
-                                                ca_cert=self.cacert
-                                                )
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def __getattr__(self, name):
-        return getattr(self.client, name)
-
-class OpenStackClient:
-    """
-    A simple native shell to the openstack backend services.
-    This class can receive all nova calls to the underlying testbed
-    """
-
-    def __init__ ( self, *args, **kwds) :
-        # instantiate managers
-        self.keystone = KeystoneClient(*args, **kwds)
-        url_parsed = urlparse.urlparse(self.keystone.url)
-        hostname = url_parsed.netloc.split(':')[0]
-        token = self.keystone.client.tokens.authenticate(username=self.keystone.username, password=self.keystone.password, tenant_name=self.keystone.tenant)
-#        glance_endpoint = self.keystone.client.service_catalog.url_for(service_type='image', endpoint_type='publicURL')
-#        self.glanceclient = GlanceClient('1', endpoint=glance_endpoint, token=token.id, **kwds)
-        self.nova = NovaClient(*args, **kwds)
-        # self.nova_db = NovaDB(*args, **kwds)
-        self.neutron = NeutronClient(*args, **kwds)
-    
-
-    @require_enabled
-    def connect(self, *args, **kwds):
-        self.__init__(*args, **kwds)
-
-    @require_enabled
-    def authenticate(self):
-        return self.keystone.authenticate()
diff --git a/xos/openstack_xos/driver.py b/xos/openstack_xos/driver.py
deleted file mode 100644
index 3064eb2..0000000
--- a/xos/openstack_xos/driver.py
+++ /dev/null
@@ -1,488 +0,0 @@
-import commands
-import hashlib
-from xos.config import Config
-from core.models import Controller
-
-try:
-    from openstack_xos.client import OpenStackClient
-    has_openstack = True
-except:
-    has_openstack = False
-
-manager_enabled = Config().api_nova_enabled
-
-class OpenStackDriver:
-
-    def __init__(self, config = None, client=None):
-        if config:
-            self.config = Config(config)
-        else:
-            self.config = Config()
-
-        if client:
-            self.shell = client
-
-        self.enabled = manager_enabled
-        self.has_openstack = has_openstack
-        self.controller = None
-        self.admin_user = None
-
-    def client_driver(self, caller=None, tenant=None, controller=None):
-        if caller:
-            auth = {'username': caller.email,
-                    'password': hashlib.md5(caller.password).hexdigest()[:6],
-                    'tenant': tenant}
-            client = OpenStackClient(controller=controller, cacert=self.config.nova_ca_ssl_cert, **auth)
-        else:
-            admin_driver = self.admin_driver(tenant=tenant, controller=controller)
-            client = OpenStackClient(tenant=tenant, controller=admin_driver.controller)
-
-        driver = OpenStackDriver(client=client)
-        #driver.admin_user = admin_driver.admin_user
-        #driver.controller = admin_driver.controller
-        return driver
-
-    def admin_driver(self, tenant=None, controller=None):
-        if isinstance(controller, int):
-            controller = Controller.objects.get(id=controller.id)
-        if not tenant:
-            tenant = controller.admin_tenant
-        client = OpenStackClient(tenant=tenant, controller=controller, cacert=self.config.nova_ca_ssl_cert)
-        driver = OpenStackDriver(client=client)
-        driver.admin_user = client.keystone.users.find(name=controller.admin_user)
-        driver.controller = controller
-        return driver
-
-    def create_role(self, name):
-        roles = self.shell.keystone.roles.findall(name=name)
-        roles_title = self.shell.keystone.roles.findall(name=name.title())
-        roles_found = roles + roles_title
-        if not roles_found:
-            role = self.shell.keystone.roles.create(name)
-        else:
-            role = roles_found[0]
-        return role
-
-    def delete_role(self, filter):
-        roles = self.shell.keystone.roles.findall(**filter)
-        for role in roles:
-            self.shell.keystone.roles.delete(role)
-        return 1
-
-    def create_tenant(self, tenant_name, enabled, description):
-        """Create keystone tenant. Suggested fields: name, description, enabled"""
-        tenants = self.shell.keystone.tenants.findall(name=tenant_name)
-        if not tenants:
-            fields = {'tenant_name': tenant_name, 'enabled': enabled,
-                      'description': description}
-            tenant = self.shell.keystone.tenants.create(**fields)
-        else:
-            tenant = tenants[0]
-
-        # always give the admin user the admin role to any tenant created
-        # by the driver.
-        self.add_user_role(self.admin_user.id, tenant.id, 'admin')
-        return tenant
-
-    def update_tenant(self, id, **kwds):
-        return self.shell.keystone.tenants.update(id, **kwds)
-
-    def delete_tenant(self, id):
-        # FIXME: nova_db is commented out in clients.py, throws errors.
-        # Commenting this out for the time being until actually fixed
-
-        #ctx = self.shell.nova_db.ctx
-        tenants = self.shell.keystone.tenants.findall(id=id)
-        for tenant in tenants:
-            # nova does not automatically delete the tenant's instances
-            # so we manually delete instances before deleting the tenant
-            #instances = self.shell.nova_db.instance_get_all_by_filters(ctx,
-            #          {'project_id': tenant.id}, 'id', 'asc')
-            #client = OpenStackClient(tenant=tenant.name)
-            #driver = OpenStackDriver(client=client)
-            #for instance in instances:
-            #    driver.destroy_instance(instance.id)
-            self.shell.keystone.tenants.delete(tenant)
-        return 1
-
-    def create_user(self, name, email, password, enabled):
-        users = self.shell.keystone.users.findall(email=email)
-        if not users:
-            fields = {'name': name, 'email': email, 'password': password,
-                      'enabled': enabled}
-            user = self.shell.keystone.users.create(**fields)
-        else:
-            user = users[0]
-        return user
-
-    def delete_user(self, id):
-        users = self.shell.keystone.users.findall(id=id)
-        for user in users:
-            # delete users keys
-            keys = self.shell.nova.keypairs.findall()
-            for key in keys:
-                self.shell.nova.keypairs.delete(key)
-            self.shell.keystone.users.delete(user)
-        return 1
-
-    def get_admin_role(self):
-        role = None
-        for admin_role_name in ['admin', 'Admin']:
-            roles = self.shell.keystone.roles.findall(name=admin_role_name)
-            if roles:
-                role = roles[0]
-                break
-        return role
-
-    def add_user_role(self, kuser_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=kuser_id)
-        tenant = self.shell.keystone.tenants.find(id=tenant_id)
-        # admin role can be lowercase or title. Look for both
-        role = None
-        if role_name.lower() == 'admin':
-            role = self.get_admin_role()
-        else:
-            # look up non admin role or force exception when admin role isnt found
-            role = self.shell.keystone.roles.find(name=role_name)
-
-        role_found = False
-        user_roles = user.list_roles(tenant.id)
-        for user_role in user_roles:
-            if user_role.name == role.name:
-                role_found = True
-        if not role_found:
-            tenant.add_user(user, role)
-
-        return 1
-
-    def delete_user_role(self, kuser_id, tenant_id, role_name):
-        user = self.shell.keystone.users.find(id=kuser_id)
-        tenant = self.shell.keystone.tenants.find(id=tenant_id)
-        # admin role can be lowercase or title. Look for both
-        role = None
-        if role_name.lower() == 'admin':
-            role = self.get_admin_role()
-        else:
-            # look up non admin role or force exception when admin role isnt found
-            role = self.shell.keystone.roles.find(name=role_name)
-
-        role_found = False
-        user_roles = user.list_roles(tenant.id)
-        for user_role in user_roles:
-            if user_role.name == role.name:
-                role_found = True
-        if role_found:
-            tenant.remove_user(user, role)
-
-        return 1
-
-    def update_user(self, id, fields):
-        if 'password' in fields:
-            self.shell.keystone.users.update_password(id, fields['password'])
-        if 'enabled' in fields:
-            self.shell.keystone.users.update_enabled(id, fields['enabled'])
-        return 1
-
-    def create_router(self, name, set_gateway=True):
-        routers = self.shell.neutron.list_routers(name=name)['routers']
-        if routers:
-            router = routers[0]
-        else:
-            router = self.shell.neutron.create_router({'router': {'name': name}})['router']
-        # add router to external network
-        if set_gateway:
-            nets = self.shell.neutron.list_networks()['networks']
-            for net in nets:
-                if net['router:external'] == True:
-                    self.shell.neutron.add_gateway_router(router['id'],
-                                                          {'network_id': net['id']})
-
-        return router
-
-    def delete_router(self, id):
-        routers = self.shell.neutron.list_routers(id=id)['routers']
-        for router in routers:
-            self.shell.neutron.delete_router(router['id'])
-            # remove router form external network
-            #nets = self.shell.neutron.list_networks()['networks']
-            #for net in nets:
-            #    if net['router:external'] == True:
-            #        self.shell.neutron.remove_gateway_router(router['id'])
-
-    def add_router_interface(self, router_id, subnet_id):
-        router = self.shell.neutron.show_router(router_id)['router']
-        subnet = self.shell.neutron.show_subnet(subnet_id)['subnet']
-        if router and subnet:
-            self.shell.neutron.add_interface_router(router_id, {'subnet_id': subnet_id})
-
-    def delete_router_interface(self, router_id, subnet_id):
-        router = self.shell.neutron.show_router(router_id)
-        subnet = self.shell.neutron.show_subnet(subnet_id)
-        if router and subnet:
-            self.shell.neutron.remove_interface_router(router_id, {'subnet_id': subnet_id})
-
-    def create_network(self, name, shared=False):
-        nets = self.shell.neutron.list_networks(name=name)['networks']
-        if nets:
-            net = nets[0]
-        else:
-            net = self.shell.neutron.create_network({'network': {'name': name, 'shared': shared}})['network']
-        return net
-
-    def delete_network(self, id):
-        nets = self.shell.neutron.list_networks()['networks']
-        for net in nets:
-            if net['id'] == id:
-                # delete_all ports
-                self.delete_network_ports(net['id'])
-                # delete all subnets:
-                for subnet_id in net['subnets']:
-                    self.delete_subnet(subnet_id)
-                self.shell.neutron.delete_network(net['id'])
-        return 1
-
-    def delete_network_ports(self, network_id):
-        ports = self.shell.neutron.list_ports()['ports']
-        for port in ports:
-            if port['network_id'] == network_id:
-                self.shell.neutron.delete_port(port['id'])
-        return 1
-
-    def delete_subnet_ports(self, subnet_id):
-        ports = self.shell.neutron.list_ports()['ports']
-        for port in ports:
-            delete = False
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id:
-                    delete=True
-                    break
-            if delete:
-                self.shell.neutron.delete_port(port['id'])
-        return 1
-
-    def create_subnet(self, name, network_id, cidr_ip, ip_version, start, end):
-        #nets = self.shell.neutron.list_networks(name=network_name)['networks']
-        #if not nets:
-        #    raise Exception, "No such network: %s" % network_name
-        #net = nets[0]
-
-        subnet = None
-        subnets = self.shell.neutron.list_subnets()['subnets']
-        for snet in subnets:
-            if snet['cidr'] == cidr_ip and snet['network_id'] == network_id:
-                subnet = snet
-
-        if not subnet:
-            # HACK: Add metadata route -- Neutron does not reliably supply this
-            metadata_ip = cidr_ip.replace("0/24", "3")
-
-            allocation_pools = [{'start': start, 'end': end}]
-            subnet = {'subnet': {'name': name,
-                                 'network_id': network_id,
-                                 'ip_version': ip_version,
-                                 'cidr': cidr_ip,
-                                 #'dns_nameservers': ['8.8.8.8', '8.8.4.4'],
-                                 'host_routes': [{'destination':'169.254.169.254/32','nexthop':metadata_ip}],
-                                 'gateway_ip': None,
-                                 'allocation_pools': allocation_pools}}
-            subnet = self.shell.neutron.create_subnet(subnet)['subnet']
-            # self.add_external_route(subnet)
-
-        return subnet
-
-    def update_subnet(self, id, fields):
-        return self.shell.neutron.update_subnet(id, fields)
-
-    def delete_subnet(self, id):
-        #return self.shell.neutron.delete_subnet(id=id)
-        # inefficient but fault tolerant
-        subnets = self.shell.neutron.list_subnets()['subnets']
-        for subnet in subnets:
-            if subnet['id'] == id:
-                self.delete_subnet_ports(subnet['id'])
-                self.shell.neutron.delete_subnet(id)
-                self.delete_external_route(subnet)
-        return 1
-
-    def get_external_routes(self):
-        status, output = commands.getstatusoutput('route')
-        routes = output.split('\n')[3:]
-        return routes
-
-    def add_external_route(self, subnet, routes=[]):
-        if not routes:
-            routes = self.get_external_routes()
-
-        ports = self.shell.neutron.list_ports()['ports']
-
-        gw_ip = subnet['gateway_ip']
-        subnet_id = subnet['id']
-
-        # 1. Find the port associated with the subnet's gateway
-        # 2. Find the router associated with that port
-        # 3. Find the port associated with this router and on the external net
-        # 4. Set up route to the subnet through the port from step 3
-        ip_address = None
-        for port in ports:
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
-                    gw_port = port
-                    router_id = gw_port['device_id']
-                    router = self.shell.neutron.show_router(router_id)['router']
-                    if router and router.get('external_gateway_info'):
-                        ext_net = router['external_gateway_info']['network_id']
-                        for port in ports:
-                            if port['device_id'] == router_id and port['network_id'] == ext_net:
-                                ip_address = port['fixed_ips'][0]['ip_address']
-
-        if ip_address:
-            # check if external route already exists
-            route_exists = False
-            if routes:
-                for route in routes:
-                    if subnet['cidr'] in route and ip_address in route:
-                        route_exists = True
-            if not route_exists:
-                cmd = "route add -net %s dev br-ex gw %s" % (subnet['cidr'], ip_address)
-                s, o = commands.getstatusoutput(cmd)
-                #print cmd, "\n", s, o
-
-        return 1
-
-    def delete_external_route(self, subnet):
-        ports = self.shell.neutron.list_ports()['ports']
-
-        gw_ip = subnet['gateway_ip']
-        subnet_id = subnet['id']
-
-        # 1. Find the port associated with the subnet's gateway
-        # 2. Find the router associated with that port
-        # 3. Find the port associated with this router and on the external net
-        # 4. Set up route to the subnet through the port from step 3
-        ip_address = None
-        for port in ports:
-            for fixed_ip in port['fixed_ips']:
-                if fixed_ip['subnet_id'] == subnet_id and fixed_ip['ip_address'] == gw_ip:
-                    gw_port = port
-                    router_id = gw_port['device_id']
-                    router = self.shell.neutron.show_router(router_id)['router']
-                    ext_net = router['external_gateway_info']['network_id']
-                    for port in ports:
-                        if port['device_id'] == router_id and port['network_id'] == ext_net:
-                            ip_address = port['fixed_ips'][0]['ip_address']
-
-        if ip_address:
-            cmd = "route delete -net %s" % (subnet['cidr'])
-            commands.getstatusoutput(cmd)
-
-        return 1
-
-    def create_keypair(self, name, public_key):
-        keys = self.shell.nova.keypairs.findall(name=name)
-        if keys:
-            key = keys[0]
-            # update key
-            if key.public_key != public_key:
-                self.delete_keypair(key.id)
-                key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
-        else:
-            key = self.shell.nova.keypairs.create(name=name, public_key=public_key)
-        return key
-
-    def delete_keypair(self, id):
-        keys = self.shell.nova.keypairs.findall(id=id)
-        for key in keys:
-            self.shell.nova.keypairs.delete(key)
-        return 1
-
-    def get_private_networks(self, tenant=None):
-        if not tenant:
-            tenant = self.shell.nova.tenant
-        tenant = self.shell.keystone.tenants.find(name=tenant)
-        search_opts = {"tenant_id": tenant.id, "shared": False}
-        private_networks = self.shell.neutron.list_networks(**search_opts)
-        return private_networks
-
-    def get_shared_networks(self):
-        search_opts = {"shared": True}
-        shared_networks = self.shell.neutron.list_networks(**search_opts)
-        return shared_networks
-
-    def get_network_subnet(self, network_id):
-        subnet_id = None
-        subnet = None
-        if network_id:
-            os_networks = self.shell.neutron.list_networks(id=network_id)["networks"]
-            if os_networks:
-                os_network = os_networks[0]
-                if os_network['subnets']:
-                    subnet_id = os_network['subnets'][0]
-                    os_subnets = self.shell.neutron.list_subnets(id=subnet_id)['subnets']
-                    if os_subnets:
-                        subnet = os_subnets[0]['cidr']
-
-        return (subnet_id, subnet)
-
-    def spawn_instance(self, name, key_name=None, availability_zone=None, hostname=None, image_id=None, security_group=None, pubkeys=[], nics=None, metadata=None, userdata=None, flavor_name=None):
-        if not flavor_name:
-            flavor_name = self.config.nova_default_flavor
-
-        flavor = self.shell.nova.flavors.find(name=flavor_name)
-
-        if not security_group:
-            security_group = self.config.nova_default_security_group
-
-        files = {}
-        #if pubkeys:
-        #    files["/root/.ssh/authorized_keys"] = "\n".join(pubkeys).encode('base64')
-        hints = {}
-
-        # determine availability zone and compute host
-        availability_zone_filter = None
-        if availability_zone is None or not availability_zone:
-            availability_zone_filter = 'nova'
-        else:
-            availability_zone_filter = availability_zone
-        if hostname:
-            availability_zone_filter += ':%s' % hostname
-
-        server = self.shell.nova.servers.create(
-                                            name=name,
-                                            key_name = key_name,
-                                            flavor=flavor.id,
-                                            image=image_id,
-                                            security_group = security_group,
-                                            #files = files,
-                                            scheduler_hints=hints,
-                                            availability_zone=availability_zone_filter,
-                                            nics=nics,
-                                            networks=nics,
-                                            meta=metadata,
-                                            userdata=userdata)
-        return server
-
-    def destroy_instance(self, id):
-        if (self.shell.nova.tenant=="admin"):
-            # findall() is implemented as a list() followed by a python search of the
-            # list. Since findall() doesn't accept "all_tenants", we do this using
-            # list() ourselves. This allows us to delete an instance as admin.
-            servers = self.shell.nova.servers.list(search_opts={"all_tenants": True})
-        else:
-            servers = self.shell.nova.servers.list()
-        for server in servers:
-            if server.id == id:
-                result=self.shell.nova.servers.delete(server)
-
-    def update_instance_metadata(self, id, metadata):
-        servers = self.shell.nova.servers.findall(id=id)
-        for server in servers:
-            self.shell.nova.servers.set_meta(server, metadata)
-            # note: set_meta() returns a broken Server() object. Don't try to
-            # print it in the shell or it will fail in __repr__.
-
-    def delete_instance_metadata(self, id, metadata):
-        # note: metadata is a dict. Only the keys matter, not the values.
-        servers = self.shell.nova.servers.findall(id=id)
-        for server in servers:
-            self.shell.nova.servers.delete_meta(server, metadata)
-