X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=plstackapi%2Fopenstack%2Fdriver.py;h=ce0f7c08906c1c2f39f8f31bb940d730b4e9af09;hb=d1cd5dfcc6df38e882a0d518d10b3856ffd432f9;hp=41a620830bbb8883167ff36676211912c53011a7;hpb=82a688d6240eed70fb3fbf72b4762a6a1ee33f75;p=plstackapi.git diff --git a/plstackapi/openstack/driver.py b/plstackapi/openstack/driver.py index 41a6208..ce0f7c0 100644 --- a/plstackapi/openstack/driver.py +++ b/plstackapi/openstack/driver.py @@ -9,6 +9,9 @@ class OpenStackDriver: else: self.config = Config() + self.admin_client = OpenStackClient() + self.admin_user = self.admin_client.keystone.users.find(name=self.admin_client.keystone.username) + if client: self.shell = client else: @@ -37,14 +40,20 @@ class OpenStackDriver: 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): - tenant = self.shell.keystone.tenants.find(id=id) - return self.shell.keystone.tenants.delete(tenant) + tenants = self.shell.keystone.tenants.findall(id=id) + for tenant in tenants: + self.shell.keystone.tenants.delete(tenant) + return 1 def create_user(self, name, email, password, enabled): users = self.shell.keystone.users.findall(email=email) @@ -56,106 +65,160 @@ class OpenStackDriver: user = users[0] return user + def delete_user(self, id): + users = self.shell.keystone.users.findall(id=id) + for user in users: + self.shell.keystone.users.delete(user) + return 1 + def add_user_role(self, user_id, tenant_id, role_name): user = self.shell.keystone.users.find(id=user_id) tenant = self.shell.keystone.tenants.find(id=tenant_id) - role = self.shell.keystone.roles.find(role_name) - return tenant.add_user(user, role) + 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, user_id, tenant_id, role_name): user = self.shell.keystone.users.find(id=user_id) tenant = self.shell.keystone.tenants.find(id=tenant_id) - role = self.shell.keystone.roles.find(role_name) - return tenant.delete_user(user, role) + 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, **kwds): return self.shell.keystone.users.update(id, **kwds) - def delete_user(self, id): - user = self.shell.keystone.users.find(id=id) - return self.shell.keystone.users.delete(user) - def create_router(self, name, set_gateway=True): - router = self.shell.quantum.create_router(name=name) + routers = self.shell.quantum.list_routers(name=name)['routers'] + if routers: + router = routers[0] + else: + router = self.shell.quantum.create_router({'router': {'name': name}})['router'] + # add router to external network if set_gateway: - nets = self.shell.quantum.list_networks() + nets = self.shell.quantum.list_networks()['networks'] for net in nets: if net['router:external'] == True: - self.shell.quantum.add_gateway_router(router, net) + self.shell.quantum.add_gateway_router(router['id'], + {'network_id': net['id']}) return router - def delete_router(self, name): - return self.shell.quantum.delete_router(name=name) + def delete_router(self, id): + routers = self.shell.quantum.list_routers(id=id)['routers'] + for router in routers: + self.shell.quantum.delete_router(router['id']) + # remove router form external network + #nets = self.shell.quantum.list_networks()['networks'] + #for net in nets: + # if net['router:external'] == True: + # self.shell.quantum.remove_gateway_router(router['id']) def add_router_interface(self, router_id, subnet_id): - router = None - subnet = None - for r in self.shell.quantum.list_routers(): - if r['id'] == router_id: - router = r - break - for s in self.shell.quantum.list_subnets(): - if s['id'] == subnet_id: - subnet = s - break - + router = self.shell.quantum.show_router(router_id)['router'] + subnet = self.shell.quantum.show_subnet(subnet_id)['subnet'] if router and subnet: - self.shell.quantum.router_add_interface(router, subnet) + self.shell.quantum.add_interface_router(router_id, {'subnet_id': subnet_id}) def delete_router_interface(self, router_id, subnet_id): - router = None - subnet = None - for r in self.shell.quantum.list_routers(): - if r['id'] == router_id: - router = r - break - for s in self.shell.quantum.list_subnets(): - if s['id'] == subnet_id: - subnet = s - break - + router = self.shell.quantum.show_router(router_id) + subnet = self.shell.quantum.show_subnet(subnet_id) if router and subnet: - self.shell.quantum.router_remove_interface(router, subnet) + self.shell.quantum.remove_interface_router(router_id, {'subnet_id': subnet_id}) def create_network(self, name): - nets = self.shell.quantum.list_networks(name=name) - if len(nets) > 0: + nets = self.shell.quantum.list_networks(name=name)['networks'] + if nets: net = nets[0] else: - net = self.shell.quantum.create_network(name, admin_state_up=True) + net = self.shell.quantum.create_network({'network': {'name': name}})['network'] return net - def delete_network(self, name): - nets = self.shell.quantum.list_networks(name=name) + def delete_network(self, id): + nets = self.shell.quantum.list_networks()['networks'] for net in nets: - # delete all subnets: - #subnets = self.api.client_shell.quantum.list_subnets(network_id=net['network_id'])['subnets'] - for subnet_id in net['subnets']: - self.delete_subnet(subnet_id) - self.shell.quantum.delete_network(net['id']) - - def create_subnet(self, network_name, cidr_ip, ip_version, start, end): - nets = self.shell.quantum.list_networks(name=network_name) - if not nets: - raise Exception, "No such network: %s" % network_name - nets = nets[0] - - subnets = self.shell.quantum.list_subnets(name=self.name) - allocation_pools = [{'start': start, 'end': end}] - subnet = self.shell.quantum.create_subnet(network_id=net['id'], - ip_version=ip_version, - cidr=cidr_ip, - dns_nameservers=['8.8.8.8', '8.8.8.4'], - allocation_pools=allocation_pools) + 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.quantum.delete_network(net['id']) + return 1 + + def delete_network_ports(self, network_id): + ports = self.shell.quantum.list_ports()['ports'] + for port in ports: + if port['network_id'] == network_id: + self.shell.quantum.delete_port(port['id']) + return 1 + + def delete_subnet_ports(self, subnet_id): + ports = self.shell.quantum.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.quantum.delete_port(port['id']) + return 1 + + def create_subnet(self, name, network_id, cidr_ip, ip_version, start, end): + #nets = self.shell.quantum.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.quantum.list_subnets()['subnets'] + for snet in subnets: + if snet['cidr'] == cidr_ip and snet['network_id'] == network_id: + subnet = snet + + if not subnet: + 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.8.4'], + 'allocation_pools': allocation_pools}} + subnet = self.shell.quantum.create_subnet(subnet)['subnet'] # TODO: Add route to external network # e.g. # route add -net 10.0.3.0/24 dev br-ex gw 10.100.0.5 return subnet + def update_subnet(self, id, fields): + return self.shell.quantum.update_subnet(id, fields) + def delete_subnet(self, id): - return self.shell.quantum.delete_subnet(id=id) - + #return self.shell.quantum.delete_subnet(id=id) + # inefficient but fault tolerant + subnets = self.shell.quantum.list_subnets()['subnets'] + for subnet in subnets: + if subnet['id'] == id: + self.delete_subnet_ports(subnet['id']) + self.shell.quantum.delete_subnet(id) + return def create_keypair(self, name, key): keys = self.shell.nova.keypairs.findall(name=name) @@ -165,46 +228,54 @@ class OpenStackDriver: key = self.shell.nova.keypairs.create(name=name, public_key=key) return key - def delete_keypair(self, name): - keys = self.shell.nova.keypairs.findall(name=name) + 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 spawn_instance(self, name, key_name=None, hostname=None, flavor=None, image=None, security_group=None, pubkeys=[]): - if not flavor: - flavor = self.config.nova_default_flavor - if not image: - image = self.config.nova_default_imave + def spawn_instance(self, name, key_name=None, hostname=None, image_id=None, security_group=None, pubkeys=[]): + flavor_name = self.config.nova_default_flavor + flavor = self.shell.nova.flavors.find(name=flavor_name) + #if not image: + # image = self.config.nova_default_imave if not security_group: security_group = self.config.nova_default_security_group - authorized_keys = "\n".join(pubkeys) - files = {'/root/.ssh/authorized_keys': authorized_keys} + #authorized_keys = "\n".join(pubkeys) + #files = {'/root/.ssh/authorized_keys': authorized_keys} + files = {} - flavor_id = self.shell.nova.flavors.find(name=flavor) - images = self.shell.glance.get_images(name=image) - if not images: - raise Exception, "Image not found: " + image - image_id = images[0]['id'] hints = {} + availability_zone = None if hostname: - hints['force_hosts']= hostname + availability_zone = 'nova:%s' % hostname server = self.shell.nova.servers.create( name=name, key_name = key_name, - flavor=flavor_id, + flavor=flavor.id, image=image_id, security_group = security_group, files=files, - scheduler_hints=hints) + scheduler_hints=hints, + availability_zone=availability_zone) return server - def destroy_instance(self, name, id=None): - args = {'name': name} - if id: - args['id'] = id - servers = self.shell.nova.servers.findall(**args) + def destroy_instance(self, id): + servers = self.shell.nova.servers.findall(id=id) + for server in servers: + 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: - if name == server.name: - if not id or id == server.id: - self.shell.nova.servers.delete(server) + 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) +