class OpenstackDriver(): def __init__(self, cloud_config=None): cloud_config = OPENSTACK_CONFIGUE self.auth_url = cloud_config['os_auth_url'] self.project_name = cloud_config['os_project_name'] self.username = cloud_config['os_username'] self.password = cloud_config['os_password'] self.user_domain_name = \ cloud_config['os_project_domain_name'] self.project_domain_name = \ cloud_config['os_user_domain_name'] self.client_version = \ cloud_config['os_novaclient_version'] self._setup() def _setup(self): auth = v3.Password(auth_url=self.auth_url, user_domain_name=self.user_domain_name, username=self.username, password=self.password, project_domain_name=self.project_domain_name, project_name=self.project_name) sess = session.Session(auth=auth) self.client = Client(self.client_version, session=sess) self.neutron_client = Neutron_Client(session=sess) def show(self, instance_id): server = self.client.servers.get( instance_id ) return server def list(self): servers = self.client.servers.list() return servers def reboot(self, instance_id): """Soft reboot""" self.client.servers.reboot(instance_id) return True def list_nic(self, instance_id): """List all Network Interface Controller """ # NOTE: interfaces a list of novaclient.v2.servers.Server interfaces = self.client.servers.interface_list(instance_id) return interfaces def list_ip(self, instance_id): """Add all IPs""" return dict(self.client.servers.ips(instance_id)) def add_nic(self, instance_id, net_id): """Add a Network Interface Controller""" # TODO: upgrade with port_id and fixed_ip in future self.client.servers.interface_attach( instance_id, None, net_id, None) return True def shutdown(self, instance_id): self.client.servers.stop(instance_id) return True def start(self, instance_id): self.client.servers.start(instance_id) return True def net_list(self): list_net = self.neutron_client.list_networks() return list_net def choice_network(self, instance_id): network_choice = '' workload = self.show(instance_id=instance_id) network_name_list = [] for key, value in workload.networks.items(): network_name_list.append(key) list_net_obj = self.neutron_client.list_networks() list_network = list_net_obj['networks'] for network in list_network: if network['name'] not in network_name_list: network_choice = network['id'] break return network_choice
class OSClient(object): def __init__(self, testbed_name, testbed, tenant_name=None, project_id=None): self.testbed_name = testbed_name self.tenant_name = None self.project_id = None self.testbed = testbed self.project_domain_name = self.testbed.get('project_domain_name') or 'Default' self.user_domain_name = self.testbed.get('user_domain_name') or 'Default' self.api_version = self.testbed.get('api_version') self.username = self.testbed.get('username') self.password = self.testbed.get('password') self.auth_url = self.testbed.get("auth_url") if self.auth_url.endswith('/'): self.auth_url = self.auth_url[:-1] self.admin_tenant_name = self.testbed.get("admin_tenant_name") self.admin_project_id = self.testbed.get("admin_project_id") if not self.admin_tenant_name and not self.admin_project_id: raise OpenstackClientError("Missing both admin project id and admin tenant name") if self.api_version == 2 and not self.admin_tenant_name: raise OpenstackClientError("Missing tenant name required if using v2") if self.api_version == 3 and not self.admin_project_id: raise OpenstackClientError("Missing project id required if using v3") self.neutron = None self.nova = None self.glance = None self.keypair = None self.sec_group = None self.os_tenant_id = None # logger.debug("Log level is: %s and DEBUG is %s" % (logger.getEffectiveLevel(), logging.DEBUG)) # if logger.getEffectiveLevel() == logging.DEBUG: # logging.basicConfig(level=logging.DEBUG) if not tenant_name and not project_id: self.keystone = self._create_keystone_client() logger.debug("Created Keystone client %s" % self.keystone) else: self.tenant_name = tenant_name self.project_id = project_id if self.api_version == 2 and not self.tenant_name: raise OpenstackClientError("Missing tenant name required if using v2") if self.api_version == 3 and not self.project_id: raise OpenstackClientError("Missing project id required if using v3") logger.debug("Creating keystone client") if self.api_version == 3: self.keystone = self._create_keystone_client(project_id) self.os_tenant_id = project_id else: self.keystone = self._create_keystone_client(tenant_name) self.os_tenant_id = self.project_id = self._get_tenant_id_from_name(tenant_name) logger.debug("Created Keystone client %s" % self.keystone) self.set_nova(self.os_tenant_id) self.set_neutron(self.os_tenant_id) self.set_glance(self.os_tenant_id) def _create_keystone_client(self, project_id=None): if self.api_version == 3: return keystoneclient.v3.client.Client(session=self._get_session(project_id)) elif self.api_version == 2: if not project_id: project_id = self.tenant_name or self.admin_tenant_name return keystoneclient.v2_0.client.Client(username=self.username, password=self.password, tenant_name=project_id, auth_url=self.auth_url) def set_nova(self, os_tenant_id): self.nova = Nova('2.1', session=self._get_session(os_tenant_id)) def _get_session(self, tenant_id=None): if self.api_version == 2: tenant_name = self.tenant_name or self.admin_tenant_name auth = v2.Password(auth_url=self.auth_url, username=self.username, password=self.password, tenant_name=tenant_name) elif self.api_version == 3: p_id = tenant_id or self.project_id or self.admin_project_id auth = v3.Password(auth_url=self.auth_url, username=self.username, password=self.password, project_id=p_id, project_domain_name=self.project_domain_name, user_domain_name=self.user_domain_name) else: msg = "Wrong api version: %s" % self.api_version logger.error(msg) raise OpenstackClientError(msg) return session.Session(auth=auth) def set_neutron(self, os_tenant_id): # self.os_tenant_id = os_tenant_id if not self.neutron: self.neutron = Neutron(session=self._get_session(os_tenant_id)) def get_user(self, username=None): users = self.list_users() if username: un = username else: un = self.username for user in users: if user.name == un: return user def get_role(self, role_to_find): roles = self.list_roles() for role in roles: if role.name == role_to_find: return role def list_roles(self): return self.keystone.roles.list() def list_tenants(self): if self.api_version == 3: return self.keystone.projects.list() else: return self.keystone.tenants.list() def create_tenant(self, tenant_name, description): self.tenant_name = tenant_name if self.api_version == 2: return self.keystone.tenants.create(tenant_name=tenant_name, description=description) else: return self.keystone.projects.create(name=tenant_name, description=description, domain=self.user_domain_name.lower()) def add_user_role(self, user, role, tenant): if self.api_version == 2: try: return self.keystone.roles.add_user_role(user=user, role=role, tenant=tenant) except Conflict as c: if c.http_status == 409: # role already assigned to user return raise c else: return self.keystone.roles.grant(user=user, role=role, project=tenant) def import_keypair(self, key_file, os_tenant_id=None): if not self.nova and not os_tenant_id: raise OpenstackClientError("Both os_tenant_id and nova obj are None") if not self.nova: self.set_nova(os_tenant_id=os_tenant_id) keypair_name = "softfire-key" self.keypair = keypair_name for keypair in self.list_keypairs(os_tenant_id): if keypair.name == keypair_name: return keypair if os.path.isfile(key_file): with open(key_file, "r") as sosftfire_ssh_pub_key: kargs = {"name": keypair_name, "public_key": sosftfire_ssh_pub_key.read()} return self.nova.keypairs.create(**kargs) else: kargs = {"name": keypair_name, "public_key": key_file} return self.nova.keypairs.create(**kargs) def get_ext_net(self, ext_net_name='softfire-network'): return [ext_net for ext_net in self.neutron.list_networks()['networks'] if ext_net['router:external'] and ext_net['name'] == ext_net_name][0] def allocate_floating_ips(self, ext_net, fip_num=0): body = { "floatingip": { "floating_network_id": ext_net['id'] } } for i in range(fip_num): try: self.neutron.create_floatingip(body=body) except IpAddressGenerationFailureClient as e: logger.error("Not able to allocate floatingips :(") raise OpenstackClientError("Not able to allocate floatingips :(") def create_networks_and_subnets(self, ext_net, router_name='ob_router'): networks = [] subnets = [] ports = [] router_id = None exist_net = [network for network in self.neutron.list_networks()['networks']] exist_net_names = [network['name'] for network in exist_net] net_name_to_create = [net for net in NETWORKS if net not in exist_net_names] networks.extend(network for network in exist_net if network['name'] in NETWORKS) index = 1 for net in net_name_to_create: kwargs = {'network': { 'name': net, 'shared': False, 'admin_state_up': True }} logger.debug("Creating net %s" % net) network_ = self.neutron.create_network(body=kwargs)['network'] networks.append(network_) kwargs = { 'subnets': [ { 'name': "subnet_%s" % net, 'cidr': "192.%s.%s.0/24" % ((get_username_hash(self.username) % 254) + 1, index), 'gateway_ip': '192.%s.%s.1' % ((get_username_hash(self.username) % 254) + 1, index), 'ip_version': '4', 'enable_dhcp': True, 'dns_nameservers': ['8.8.8.8'], 'network_id': network_['id'] } ] } logger.debug("Creating subnet subnet_%s" % net) subnet = self.neutron.create_subnet(body=kwargs) subnets.append(subnet) router = self.get_router_from_name(router_name, ext_net) router_id = router['router']['id'] body_value = { 'subnet_id': subnet['subnets'][0]['id'], } try: ports.append(self.neutron.add_interface_router(router=router_id, body=body_value)) except Exception as e: pass index += 1 return networks, subnets, router_id def get_router_from_name(self, router_name, ext_net): for router in self.neutron.list_routers()['routers']: if router['name'] == router_name: return self.neutron.show_router(router['id']) request = {'router': {'name': router_name, 'admin_state_up': True}} router = self.neutron.create_router(request) body_value = {"network_id": ext_net['id']} self.neutron.add_gateway_router(router=router['router']['id'], body=body_value) return router def create_rule(self, sec_group, protocol): body = {"security_group_rule": { "direction": "ingress", "port_range_min": "1", "port_range_max": "65535", # "name": sec_group['security_group']['name'], "security_group_id": sec_group['security_group']['id'], "remote_ip_prefix": "0.0.0.0/0", "protocol": protocol, }} if protocol == 'icmp': body['security_group_rule'].pop('port_range_min', None) body['security_group_rule'].pop('port_range_max', None) try: self.neutron.create_security_group_rule(body=body) except neutronclient.common.exceptions.Conflict as e: logger.error("error while creating a rule: %s" % e.message) pass def create_security_group(self, project_id, sec_g_name=None): if not sec_g_name: sec_g_name = sec_group_name sec_group = {} for sg in self.list_sec_group(project_id): if sg['name'] == sec_g_name: sec_group['security_group'] = sg break if len(sec_group) == 0: body = dict(security_group=dict(name=sec_g_name, description="openbaton security group"), project_id=project_id, tenant_id=project_id) sec_group = self.neutron.create_security_group(body=body) self.create_rule(sec_group, 'tcp') self.create_rule(sec_group, 'udp') self.create_rule(sec_group, 'icmp') self.sec_group = sec_group['security_group'] return self.sec_group def list_sec_group(self, os_project_id): if not self.neutron: self.set_neutron(os_project_id) return [sec for sec in self.neutron.list_security_groups()['security_groups'] if (sec.get('tenant_id') is not None and sec.get('tenant_id') == os_project_id) or ( sec.get('project_id') is not None and sec.get('project_id') == os_project_id)] def get_vim_instance(self, tenant_name, username=None, password=None): if username: un = username else: un = self.username if password: pwd = password else: pwd = self.password logger.debug("Using tenant id: %s " % tenant_name) return { "name": "vim-instance-%s" % self.testbed_name, "authUrl": self.auth_url, "tenant": tenant_name, "username": un, "password": pwd, "securityGroups": [ 'default', sec_group_name ], "type": "openstack", "location": { "name": "Berlin", "latitude": "52.525876", "longitude": "13.314400" } } def upload_image(self, name, path, container_format="bare", disk_format="qcow2", visibility="public"): # image = self.glance.images.create(name=name) # self.glance.images.upload(image.id, open(path, 'rb')) with open(path, 'rb') as fimage: img = self.glance.images.create(name=name, # is_public="True", # public="True", visibility=visibility, disk_format=disk_format, container_format=container_format, data=path) # print(dir(self.glance.images)) self.glance.images.upload(img.id, fimage) def list_images(self, tenant_id=None): if not self.nova: if not tenant_id: logger.error("Missing tenant_id!") raise OpenstackClientError('Missing tenant_id!') self.set_nova(tenant_id) try: imgs = self.nova.images.list() return imgs except: self.set_glance(tenant_id) return self.glance.images.list() def _get_tenant_id_from_name(self, tenant_name): if self.api_version == 2: tenants_list = self.keystone.tenants.list() else: tenants_list = self.keystone.projects.list() for tenant in tenants_list: if tenant.name == tenant_name: return tenant.id def set_glance(self, os_tenant_id): self.os_tenant_id = os_tenant_id self.glance = Glance('2', session=self._get_session(os_tenant_id)) def _get_tenant_name_from_id(self, os_tenant_id): for t in self.list_tenants(): if t.id == os_tenant_id: return t.name def create_user(self, username, password=None, tenant_id=None): for u in self.list_users(): if hasattr(u, 'username'): u_username = u.username else: u_username = u.name if u_username == username: return u if not password: raise OpenstackClientError("Paswsord is needed to create user") if self.api_version == 2: return self.keystone.users.create(username, password, tenant_id=tenant_id) else: return self.keystone.users.create(name=username, password=password, project=self.get_project_from_id(tenant_id)) def list_users(self): return self.keystone.users.list() def list_networks(self, project_id=None): if not self.neutron: if not project_id: raise OpenstackClientError("Missing project_id!") self.set_neutron(project_id) return self.neutron.list_networks(tenant_id=project_id) def list_subnets(self, project_id): if not self.neutron: if not project_id: raise OpenstackClientError("Missing project_id!") self.set_neutron(project_id) return self.neutron.list_subnets(tenant_id=project_id) def list_floatingips(self, project_id): if not self.neutron: if not project_id: raise OpenstackClientError("Missing project_id!") self.set_neutron(project_id) return self.neutron.list_floatingips(tenant_id=project_id) def list_routers(self, project_id): if not self.neutron: if not project_id: raise OpenstackClientError("Missing project_id!") self.set_neutron(project_id) return self.neutron.list_routers(tenant_id=project_id) def list_ports(self, project_id): if not self.neutron: if not project_id: raise OpenstackClientError("Missing project_id!") self.set_neutron(project_id) return self.neutron.list_ports(tenant_id=project_id) def list_keypairs(self, os_project_id=None): if not self.nova: if not os_project_id: raise OpenstackClientError("Missing project_id!") self.set_nova(os_project_id) return self.nova.keypairs.list() def list_domains(self): return self.keystone.domains.list() def get_project_from_id(self, tenant_id): for p in self.list_tenants(): if p.id == tenant_id: return p raise OpenstackClientError("Project with id %s not found") def delete_user(self, username): try: self.keystone.users.delete(self.create_user(username=username)) except: traceback.print_exc() logger.error("Not Able to delete user %s" % username) def delete_project(self, project_id): try: if self.api_version == 2: self.keystone.tenants.delete(project_id) else: self.keystone.projects.delete(project_id) except: traceback.print_exc() logger.error("Not Able to delete project %s" % project_id) def release_floating_ips(self, project_id, keep_fip_id_list=list()): fips = self.list_floatingips(project_id).get('floatingips') for fip in fips: if fip.get('id') in keep_fip_id_list: logger.debug("Not relasing floating ip: %s" % fip) else: self.neutron.delete_floatingip(fip.get('id')) def delete_ports(self, project_id): ports = self.list_ports(project_id).get('ports') for port in ports: try: self.neutron.delete_port(port.get('id')) except Exception as e: pass def remove_gateway_routers(self, project_id): routers = self.list_routers(project_id).get('routers') for router in routers: self.neutron.remove_gateway_router(router.get('id')) def remove_interface_routers(self, project_id): routers = self.list_routers(project_id).get('routers') subnets = self.list_subnets(project_id).get('subnets') for router in routers: for subnet in subnets: body_value = { 'subnet_id': subnet.get('id'), } try: self.neutron.remove_interface_router(router.get('id'), body_value) break except Exception as e: pass else: logger.warning('No subnet found that is associated to router {}'.format(router.get('id'))) def delete_routers(self, project_id): routers = self.list_routers(project_id).get('routers') for router in routers: self.neutron.delete_router(router.get('id')) def delete_networks(self, project_id): networks = self.list_networks(project_id).get('networks') for nw in networks: self.neutron.delete_network(nw.get('id')) def delete_security_groups(self, project_id): sec_groups = self.list_sec_group(project_id) for sec_group in sec_groups: self.neutron.delete_security_group(sec_group.get('id'))
cirros_image = image break if cirros_image is None: raise Exception("no cirros image found!") nova_client = NovaClient("2", session=os_session) flavors = nova_client.flavors.list() compute_hosts = nova_client.hosts.list("nova") neutron_client = NeutronClient(session=os_session) public_network = neutron_client.list_networks(**{"router:external": True})["networks"][0] config = ConfigParser() # DEFAULT section config.set(DEFAULTSECT, "debug", "False") config.set(DEFAULTSECT, "verbose", "False") # alarming section alarming_section_name = "alarming" config.add_section(alarming_section_name) # no option for alarming service # auth section