class csresources: def __init__(self): tempdict = {} path = os.path.dirname(os.path.abspath(__file__)) # Read config try: f = open(path + "/../cloudstack.config", "r") config = f.readlines() except: print("Somethings wrong with your config file") sys.exit(2) for entry in config: entry = entry.replace("\n", "") temarray = entry.split("=") tempdict[temarray[0]] = temarray[1] if tempdict['verify'] is None: tempdict['verify'] = False self.cs = CloudStack(endpoint=tempdict['endpoint'], key=tempdict['key'], secret=tempdict['secret'], verify=False) def list_virtual_routers(self): routerList = [] domains = self.cs.listDomains() for domain in domains['domain']: projects = self.cs.listProjects(domainid=domain["id"]) if "project" in projects: for project in projects["project"]: routers = self.cs.listRouters(projectid=project["id"]) if "router" in routers: for router in routers["router"]: routerList.append(router) routers = self.cs.listRouters(domainid=domain["id"]) if "router" in routers: for router in routers["router"]: routerList.append(router) return routerList def list_system_vms(self): return self.cs.listSystemVms()['systemvm'] def list_capacity(self): return self.cs.listCapacity()['capacity'] def list_projects(self, domainfilter=None, projectfilter=None): projects = [] domains = self.cs.listDomains(id=domainfilter)['domain'] if projectfilter is not None and domainfilter is not None: temp = self.cs.listProjects(domainid=domainfilter, id=projectfilter) if 'project' in temp: projects += temp['project'] else: for domain in domains: temp = self.cs.listProjects(domainid=domain['id']) if 'project' in temp: for project in temp['project']: projects.append(project) return projects def list_domains(self, domainfilter=None): return self.cs.listDomains(id=domainfilter)['domain'] def list_clusters(self): return self.cs.listClusters()['cluster'] def list_offerings(self): return self.cs.listServiceOfferings()['serviceoffering'] def list_hvs(self): return self.cs.listHosts(type="Routing")['host'] def get_hvstructure(self, cluster, withvm=1): hvstatus = [] domains = self.cs.listDomains() vmdict = [] if 'cluster.memory.allocated.capacity.disablethreshold' in cluster[ 'resourcedetails']: memthreshold = cluster['resourcedetails'][ 'cluster.memory.allocated.capacity.disablethreshold'] else: memthreshold = 1 if 'cluster.cpu.allocated.capacity.disablethreshold' in cluster[ 'resourcedetails']: cputhreshold = cluster['resourcedetails'][ 'cluster.cpu.allocated.capacity.disablethreshold'] else: cputhreshold = 1 memovercommit = cluster['resourcedetails']['memoryOvercommitRatio'] cpuovercommit = cluster['resourcedetails']['cpuOvercommitRatio'] clusterid = cluster['id'] hosts = self.cs.listHosts(clusterid=clusterid) #Get Host list for host in hosts['host']: if host['type'] == "Routing": hvstatus.append({ 'name': host['name'], 'cpu': (float(host['cpunumber'] * host['cpuspeed']) * float(cpuovercommit)) * float(cputhreshold), 'mem': ((host['memorytotal'] * float(memovercommit)) * float(memthreshold)) / 1024, 'memfree': ((host['memorytotal'] * float(memthreshold)) - host['memoryused']) / 1024, 'cpufree': ((float(host['cpunumber'] * host['cpuspeed']) * float(cpuovercommit)) * float(cputhreshold)) - (float(host['cpuallocated'].replace("%", "")) * ((host['cpunumber'] * host['cpuspeed']) / 100)), 'ratio': None, 'vms': [], }) ##Split this as an extra function!!!!!! if withvm == 1: # Get VM list for domain in domains['domain']: projects = self.cs.listProjects(domainid=domain['id']) if "project" in projects.keys(): for project in projects['project']: vms = self.cs.listVirtualMachines( projectid=project['id']) if "virtualmachine" in vms: for vm in vms['virtualmachine']: vmdict.append(vm) #Add VMs to their Hypervisors for vm in vmdict: for hv in hvstatus: if "hostname" in vm: if vm['hostname'] == hv['name']: hv['vms'].append({ 'name': vm['name'], 'cpu': vm['cpunumber'] * vm['cpuspeed'], 'mem': vm['memory'] * 1024, 'instance': vm['instancename'], }) return hvstatus
import json from cs import CloudStack, read_config import argparse import os import base64 def print_pretty(json_data): print(json.dumps(json_data, indent=4, sort_keys=True)) cs = CloudStack(**read_config()) OFFERINGS = { o["name"].lower(): o["id"] for o in cs.listServiceOfferings()["serviceoffering"] } ZONES = {z["name"].lower(): z["id"] for z in cs.listZones()["zone"]} SSH_KEY_PAIRS = [kp["name"] for kp in cs.listSSHKeyPairs()["sshkeypair"]] RAIN_VERSION = "v0.1.1" VIRTUAL_MACHINES = cs.listVirtualMachines() TEMPLATE_OFFERINGS = cs.listTemplates(templatefilter="executable") NETWORK_OFFERINGS = cs.listNetworkOfferings() SECURITY_GROUPS = cs.listSecurityGroups() INIT_SCRIPT_TEMPLATE = """ #cloud-config runcmd: - cd /tmp - wget https://github.com/substantic/rain/releases/download/{version}/rain-{version}-linux-x64.tar.xz - tar xf rain-{version}-linux-x64.tar.xz
class CloudStackApiClient: _INSTANCE = None @classmethod def get_instance(cls): if cls._INSTANCE is None: cls._INSTANCE = cls() return cls._INSTANCE def __init__(self, key=None, secret=None, endpoint=None): if key is None or secret is None or endpoint is None: self._config = read_config() self._cs = CloudStack(**self._config) else: self._cs = CloudStack(key=key, secret=secret, endpoint=endpoint) self.vms = [] self.zones = [] self.lbs = [] self.tps = [] self.nws = [] self.svs = [] def listVirtualMachines(self, force=False): if force or len(self.vms) == 0: vms = self._cs.listVirtualMachines() self.vms = [ (vm['id'], vm['name']) for vm in vms['virtualmachine'] ] return self.vms def listZones(self, force=False): if force or len(self.zones) == 0: zones = self._cs.listZones() self.zones = [ (zone['id'], zone['name']) for zone in zones['zone'] ] return self.zones def listLoadBalancerRules(self, force=False): if force or len(self.lbs) == 0: lbs = self._cs.listLoadBalancerRules() self.lbs = [] if 'loadbalancerrule' in lbs: self.lbs = [ (lb['id'], lb['name']) for lb in lbs['loadbalancerrule'] ] return self.lbs def listTemplates(self, force=False): if force or len(self.tps) == 0: tps = self._cs.listTemplates(templatefilter="self") self.tps = [] if 'template' in tps: self.tps = [ (tp['id'], tp['name']) for tp in tps['template'] ] return self.tps def listNetworks(self, force=False): if force or len(self.nws) == 0: nws = self._cs.listNetworks() self.nws = [ (nw['id'], nw['name']) for nw in nws['network'] ] return self.nws def listServiceOfferings(self, force=False): if force or len(self.svs) == 0: svs = self._cs.listServiceOfferings() self.svs = [ (sv['id'], sv['name']) for sv in svs['serviceoffering'] ] return self.svs def _get_name(self, data, uuid): for x in data: if uuid == x[0]: return x[1] return None def get_vm_name(self, uuid): name = self._get_name(self.vms, uuid) if name is None: self.listVirtualMachines(force=True) name = self._get_name(self.vms, uuid) return name def get_zone_name(self, uuid): name = self._get_name(self.zones, uuid) if name is None: self.listZones(force=True) name = self._get_name(self.zones, uuid) return name def get_lb_name(self, uuid): name = self._get_name(self.lbs, uuid) if name is None: self.listLoadBalancerRules(force=True) name = self._get_name(self.lbs, uuid) return name def get_tp_name(self, uuid): name = self._get_name(self.tps, uuid) if name is None: self.listTemplates(force=True) name = self._get_name(self.tps, uuid) return name def get_nw_name(self, uuid): name = self._get_name(self.nws, uuid) if name is None: self.listNetworks(force=True) name = self._get_name(self.nws, uuid) return name def get_sv_name(self, uuid): name = self._get_name(self.svs, uuid) if name is None: self.listServiceOfferings(force=True) name = self._get_name(self.svs, uuid) return name
class CloudstackCloudAdapter(CloudAdapter): def __init__(self): super().__init__() self.cs = CloudStack( endpoint=os.getenv("CLOUDSTACK_API_ENDPOINT"), key=os.getenv("CLOUDSTACK_API_KEY"), secret=os.getenv("CLOUDSTACK_API_SECRET"), ) def get_service_offering(self, name) -> dict: res = self.cs.listServiceOfferings(name=name) if not res: raise Exception(f"Error: Service offering not found: {name}") return res["serviceoffering"][0] def get_zone(self, name) -> dict: res = self.cs.listZones(name=name) if not res: raise Exception(f"Error: Zone not found: {name}") return res["zone"][0] def get_template(self, name) -> dict: for tf in ["community", "self"]: res = self.cs.listTemplates(name=name, templatefilter=tf) if res: break else: raise Exception(f"Error: Template not found: {name}") return res["template"][0] def get_params(self, name: str) -> dict: user_data = self.launch.get("user_data") if user_data: user_data = base64.b64encode(user_data.encode("utf-8")) return { "displayname": name, "serviceofferingid": self.get_service_offering( name=self.launch["service_offering"] ).get("id"), "affinitygroupnames": self.launch.get("affinity_groups"), "securitygroupnames": self.launch.get("security_groups"), "templateid": self.get_template(name=self.launch["template"]).get("id"), "zoneid": self.get_zone(name=self.launch["zone"]).get("id"), "userdata": user_data, "keypair": self.launch.get("ssh_key"), "group": self.launch.get("group"), "rootdisksize": self.launch.get("root_disk_size"), } def get_current_instances(self) -> List[GenericCloudInstance]: filter_tag = f"scalr={self.filter}" log.info(f"cloudstack: Querying with filter_tag: {filter_tag}") servers = self.cs.listVirtualMachines( tags=[ { "key": "scalr", "value": self.filter, } ], fetch_list=True, ) return [ GenericCloudInstance( id=server["id"], name=server["name"], status=server["state"].lower(), ) for server in sorted(servers, key=lambda i: i["created"]) ] def ensure_instances_running(self): for server in self.get_current_instances(): log.info(f"cloudstack: Server {server.name} status {server.status}") if server.status in ["stopping", "stopped"]: self.cs.startVirtualMachine(id=server.id) log.info(f"cloudstack: Server {server.name} started") def deploy_instance(self, name: str): params = self.get_params(name=name) tags = self.launch.get("tags", {}) tags = [ { "key": "scalr", "value": self.filter, } ] server = self.cs.deployVirtualMachine(**params) self.cs.createTags( resourceids=[ server["id"], ], resourcetype="UserVm", tags=tags, ) def destroy_instance(self, instance: GenericCloudInstance): log.info(f"cloudstack: Destroying instance {instance}") self.cs.destroyVirtualMachine(id=instance.id)
import os import paramiko import base64 import multiprocessing from collections import OrderedDict from scp import SCPClient import time def print_pretty(json_data): print(json.dumps(json_data, indent=4, sort_keys=True)) cs = CloudStack(**read_config()) OFFERINGS = {o["name"].lower(): o["id"] for o in cs.listServiceOfferings()["serviceoffering"]} ZONES = {z["name"].lower(): z["id"] for z in cs.listZones()["zone"]} SSH_KEY_PAIRS = [kp["name"] for kp in cs.listSSHKeyPairs()["sshkeypair"]] VIRTUAL_MACHINES = cs.listVirtualMachines() TEMPLATE_OFFERINGS = cs.listTemplates(templatefilter="executable") NETWORK_OFFERINGS = cs.listNetworkOfferings() SECURITY_GROUPS = cs.listSecurityGroups() INIT_SCRIPT = """ #cloud-config runcmd: - apt-get update - apt-get install -y python3-pip - touch /ready """ # noqa SSH_CMD = "ssh -o StrictHostKeyChecking=no"