def create(self, name, virttype=None, profile='', flavor=None, plan='kvirt', cpumodel='Westmere', cpuflags=[], cpupinning=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', image=None, disks=[{ 'size': 10 }], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags=[], storemetadata=False, sharedfolders=[], kernel=None, initrd=None, cmdline=None, cpuhotplug=False, memoryhotplug=False, numamode=None, numa=[], pcidevices=[], tpm=False, placement=[], autostart=False, rng=False, metadata={}, securitygroups=[]): """ :param name: :param virttype: :param profile: :param flavor: :param plan: :param cpumodel: :param cpuflags: :param cpupinning: :param numcpus: :param memory: :param guestid: :param pool: :param image: :param disks: :param disksize: :param diskthin: :param diskinterface: :param nets: :param iso: :param vnc: :param cloudinit: :param reserveip: :param reservedns: :param reservehost: :param start: :param keys: :param cmds: :param ips: :param netmasks: :param gateway: :param nested: :param dns: :param domain: :param tunnel: :param files: :param enableroot: :param alias: :param overrides: :param tags: :param cpuhotplug: :param memoryhotplug: :param numamode: :param numa: :param pcidevices: :param tpm: :return: """ reservation_id = overrides.get('hardware_reservation_id') if reservation_id is not None: reservations = self.conn.list_hardware_reservations(self.project) if not reservations: return { 'result': 'failure', 'reason': "No reserved hardware found" } elif reservation_id != 'next-available': matching_ids = [ r.id for r in reservations if r.id == reservation_id or r.short_id == reservation_id ] if not matching_ids: return { 'result': 'failure', 'reason': "Reserved hardware with id %s not found" % reservation_id } else: reservation_id = matching_ids[0] ipxe_script_url = None userdata = None networkid = None networkids = [] vlan = False for index, network in enumerate(nets): if index > 1: warning("Ignoring net higher than %s" % index) break if isinstance(network, str): networkname = network elif isinstance(network, dict) and 'name' in network: networkname = network['name'] if networkname != 'default': networks = [ n for n in self.conn.list_vlans(self.project) if n.id == networkname or (n.description is not None and n.description == networkname) ] if not networks: return { 'result': 'failure', 'reason': "Network %s not found" % networkname } else: vlan = True networkid = networks[0].id else: networkid = None networkids.append(networkid) if image is not None and not common.needs_ignition(image): if '_' not in image and image in [ 'rhel8', 'rhel7', 'centos7', 'centos8' ]: image = image[:-1] + '_' + image[-1:] pprint("Using image %s" % image) found = False for img in self.conn.list_operating_systems(): if img.slug == image: found = True if not found: msg = "image %s doesn't exist" % image return {'result': 'failure', 'reason': msg} elif image is None: ipxe_script_url = overrides.get('ipxe_script_url') if ipxe_script_url is None: return { 'result': 'failure', 'reason': 'You need to define ipxe_script_url as parameter' } image = 'custom_ipxe' else: ignition_url = overrides.get('ignition_url') if ignition_url is None: if self.tunnelhost is not None: ignition_url = "http://%s/%s.ign" % (self.tunnelhost, name) else: return { 'result': 'failure', 'reason': 'You need to define ignition_url as parameter' } url = IMAGES[image] if 'rhcos' in image: if 'commit_id' in overrides: kernel, initrd, metal = common.get_commit_rhcos_metal( overrides['commit_id']) else: kernel, initrd, metal = common.get_latest_rhcos_metal(url) elif 'fcos' in image: kernel, initrd, metal = common.get_latest_fcos_metal(url) interface = 'eth0' if 'fcos' in image else 'ens3f0' userdata = self._ipxe(kernel, initrd, metal, ignition_url, interface) version = common.ignition_version(image) ignitiondir = '/tmp' ipv6 = [] ignitiondata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, version=version, plan=plan, ipv6=ipv6, image=image) image = 'custom_ipxe' with open('%s/%s.ign' % (ignitiondir, name), 'w') as ignitionfile: ignitionfile.write(ignitiondata) if self.tunnelhost is not None: pprint("Copying ignition data to %s" % self.tunnelhost) scpcmd = "scp -qP %s /tmp/%s.ign %s@%s:%s/%s.ign" % ( self.tunnelport, name, self.tunneluser, self.tunnelhost, self.tunneldir, name) os.system(scpcmd) if flavor is None: # if f[1] >= numcpus and f[2] >= memory: minmemory = 512000 for f in self.conn.list_plans(): if not f.specs: continue flavorname = f.name # skip this flavor until we know where it can be launched if flavorname == 'c3.small.x86' or ( vlan and flavorname in ['t1.small.x86', 'c1.small.x86']): continue flavorcpus = int(f.specs['cpus'][0]['count']) flavormemory = int(f.specs['memory']['total'].replace( 'GB', '')) * 1024 if flavorcpus >= 1 and flavormemory >= memory and flavormemory < minmemory: flavor = flavorname minmemory = flavormemory validfacilities = f.available_in if flavor is None: return { 'result': 'failure', 'reason': 'Couldnt find flavor matching requirements' } pprint("Using flavor %s" % flavor) else: flavors = [f for f in self.conn.list_plans() if f.slug == flavor] if not flavors: return { 'result': 'failure', 'reason': 'Flavors %s not found' % flavor } else: validfacilities = flavors[0].available_in features = ['tpm'] if tpm else [] if cloudinit and userdata is None: userdata = common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, fqdn=True, storemetadata=storemetadata)[0] validfacilities = [ os.path.basename(e['href']) for e in validfacilities ] validfacilities = [ f.code for f in self.conn.list_facilities() if f.id in validfacilities ] if not validfacilities: return { 'result': 'failure', 'reason': 'no valid facility found for flavor %s' % flavor } facility = overrides.get('facility') if facility is not None: matchingfacilities = [ f for f in self.conn.list_facilities() if f.slug == facility ] if not matchingfacilities: return { 'result': 'failure', 'reason': 'Facility %s not found' % facility } if facility not in validfacilities: return { 'result': 'failure', 'reason': 'Facility %s not allowed. You should choose between %s' % (facility, ','.join(validfacilities)) } elif self.facility is not None: if self.facility not in validfacilities: return { 'result': 'failure', 'reason': 'Facility %s not allowed. You should choose between %s' % (self.facility, ','.join(validfacilities)) } facility = self.facility else: facility = validfacilities[0] tags = ['project_%s' % self.project] if userdata is not None and 'ignition' in userdata: tags.append("kernel_%s" % os.path.basename(kernel)) for entry in [field for field in metadata if field in METADATA_FIELDS]: tags.append("%s_%s" % (entry, metadata[entry])) # ip_addresses = [{"address_family": 4, "public": True}, {"address_family": 6, "public": False}] data = { 'project_id': self.project, 'hostname': name, 'plan': flavor, 'facility': facility, 'operating_system': image, 'userdata': userdata, 'features': features, 'tags': tags } if ipxe_script_url is not None: data['ipxe_script_url'] = ipxe_script_url if reservation_id is not None: data['hardware_reservation_id'] = reservation_id try: device = self.conn.create_device(**data) except Exception as e: return {'result': 'failure', 'reason': e} for networkid in networkids: if networkid is None: continue elif 'cluster' in overrides and name.startswith( "%s-" % overrides['cluster']): warning( "Not applying custom vlan to speed process for openshift..." ) warning("This will be applied manually later...") continue status = 'provisioning' while status != 'active': status = self.info(name).get('status') pprint("Waiting 5s for %s to be active..." % name) sleep(5) device_port_id = device["network_ports"][2]["id"] self.conn.disbond_ports(device_port_id, False) self.conn.assign_port(device_port_id, networkid) break return {'result': 'success'}
def create(self, name, virttype='kvm', profile='', plan='kvirt', flavor=None, cpumodel='Westmere', cpuflags=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', template=None, disks=[{ 'size': 10 }], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags=None): """ :param name: :param virttype: :param profile: :param plan: :param flavor: :param cpumodel: :param cpuflags: :param numcpus: :param memory: :param guestid: :param pool: :param template: :param disks: :param disksize: :param diskthin: :param diskinterface: :param nets: :param iso: :param vnc: :param cloudinit: :param reserveip: :param reservedns: :param reservehost: :param start: :param keys: :param cmds: :param ips: :param netmasks: :param gateway: :param nested: :param dns: :param domain: :param tunnel: :param files: :param enableroot: :param alias: :param overrides: :param tags: :return: """ glance = self.glance nova = self.nova neutron = self.neutron try: nova.servers.find(name=name) common.pprint("VM %s already exists" % name, color='red') return { 'result': 'failure', 'reason': "VM %s already exists" % name } except: pass allflavors = [f for f in nova.flavors.list()] allflavornames = [flavor.name for flavor in allflavors] if flavor is None: flavors = [ flavor for flavor in allflavors if flavor.ram >= memory and flavor.vcpus == numcpus ] flavor = flavors[0] if flavors else nova.flavors.find( name="m1.tiny") common.pprint("Using flavor %s" % flavor.name, color='green') elif flavor not in allflavornames: return { 'result': 'failure', 'reason': "Flavor %s not found" % flavor } else: flavor = nova.flavors.find(name=flavor) nics = [] for net in nets: if isinstance(net, str): netname = net elif isinstance(net, dict) and 'name' in net: netname = net['name'] try: net = nova.neutron.find_network(name=netname) except Exception as e: common.pprint(e, color='red') return { 'result': 'failure', 'reason': "Network %s not found" % netname } nics.append({'net-id': net.id}) image = None if template is not None: images = [ image for image in glance.images.list() if image.name == template ] if images: image = images[0] else: msg = "you don't have template %s" % template return {'result': 'failure', 'reason': msg} block_dev_mapping = {} for index, disk in enumerate(disks): imageref = None diskname = "%s-disk%s" % (name, index) letter = chr(index + ord('a')) if isinstance(disk, int): disksize = disk diskthin = True elif isinstance(disk, str) and disk.isdigit(): disksize = int(disk) diskthin = True elif isinstance(disk, dict): disksize = disk.get('size', '10') diskthin = disk.get('thin', True) if index == 0 and template is not None: if not diskthin: imageref = image.id else: continue newvol = self.cinder.volumes.create(name=diskname, size=disksize, imageRef=imageref) block_dev_mapping['vd%s' % letter] = newvol.id key_name = 'kvirt' keypairs = [k.name for k in nova.keypairs.list()] if key_name not in keypairs: homekey = None if not os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME']): print( "neither id_rsa.pub or id_dsa public keys found in your .ssh directory, you might have trouble " "accessing the vm") else: if os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_rsa.pub" % os.environ['HOME']).read() else: homekey = open("%s/.ssh/id_dsa.pub" % os.environ['HOME']).read() nova.keypairs.create(key_name, homekey) elif keypairs: key_name = keypairs[0] if key_name != 'kvirt': common.pprint('Using keypair %s' % key_name, color='green') else: common.pprint( 'Couldnt locate or create keypair for use. Leaving...', color='red') return {'result': 'failure', 'reason': "No usable keypair found"} meta = {'plan': plan, 'profile': profile} userdata = None if cloudinit: if template is not None and (template.startswith('coreos') or template.startswith('rhcos')): etcd = None userdata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, etcd=etcd) else: common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, iso=False) userdata = open('/tmp/user-data', 'r').read().strip() instance = nova.servers.create(name=name, image=image, flavor=flavor, key_name=key_name, nics=nics, meta=meta, userdata=userdata, block_device_mapping=block_dev_mapping) tenant_id = instance.tenant_id floating_ips = [ f['id'] for f in neutron.list_floatingips()['floatingips'] if f['port_id'] is None ] if not floating_ips: network_id = None networks = [ n for n in neutron.list_networks()['networks'] if n['router:external'] ] if networks: network_id = networks[0]['id'] if network_id is not None and tenant_id is not None: args = dict(floating_network_id=network_id, tenant_id=tenant_id) floating_ip = neutron.create_floatingip( body={'floatingip': args}) floatingip_id = floating_ip['floatingip']['id'] floatingip_ip = floating_ip['floatingip'][ 'floating_ip_address'] common.pprint('Assigning new floating ip %s for this vm' % floatingip_ip, color='green') else: floatingip_id = floating_ips[0] fixed_ip = None timeout = 0 while fixed_ip is None: common.pprint("Waiting 5 seconds for vm to get an ip", color='green') sleep(5) timeout += 5 if timeout >= 80: common.pprint("Time out waiting for vm to get an ip", color='red') break vm = nova.servers.get(instance.id) for key in list(vm.addresses): entry1 = vm.addresses[key] for entry2 in entry1: if entry2['OS-EXT-IPS:type'] == 'fixed': fixed_ip = entry2['addr'] break if fixed_ip is not None: fixedports = [ i['id'] for i in neutron.list_ports()['ports'] if i['fixed_ips'] and i['fixed_ips'][0]['ip_address'] == fixed_ip ] port_id = fixedports[0] neutron.update_floatingip(floatingip_id, {'floatingip': { 'port_id': port_id }}) securitygroups = [ s for s in neutron.list_security_groups()['security_groups'] if s['name'] == 'default' and s['tenant_id'] == tenant_id ] if securitygroups: securitygroup = securitygroups[0] securitygroupid = securitygroup['id'] sshrule = { 'security_group_rule': { 'direction': 'ingress', 'security_group_id': securitygroupid, 'port_range_min': '22', 'port_range_max': '22', 'protocol': 'tcp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0' } } icmprule = { 'security_group_rule': { 'direction': 'ingress', 'security_group_id': securitygroupid, 'protocol': 'icmp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0' } } try: neutron.create_security_group_rule(sshrule) neutron.create_security_group_rule(icmprule) except: pass return {'result': 'success'}
def create(self, name, virttype='kvm', profile='', flavor=None, plan='kvirt', cpumodel='Westmere', cpuflags=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', template=None, disks=[{'size': 10}], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags=None, dnshost=None, storemetadata=False): """ :param name: :param virttype: :param profile: :param flavor: :param plan: :param cpumodel: :param cpuflags: :param numcpus: :param memory: :param guestid: :param pool: :param template: :param disks: :param disksize: :param diskthin: :param diskinterface: :param nets: :param iso: :param vnc: :param cloudinit: :param reserveip: :param reservedns: :param reservehost: :param start: :param keys: :param cmds: :param ips: :param netmasks: :param gateway: :param nested: :param dns: :param domain: :param tunnel: :param files: :param enableroot: :param alias: :param overrides: :param tags: :return: """ template = self.__evaluate_template(template) keypair = self.keypair if template is not None and not template.startswith('ami-'): return {'result': 'failure', 'reason': 'Invalid template %s' % template} defaultsubnetid = None if flavor is None: matchingflavors = [f for f in static_flavors if static_flavors[f]['cpus'] >= numcpus and static_flavors[f]['memory'] >= memory] if matchingflavors: flavor = matchingflavors[0] common.pprint("Using instance type %s" % flavor, color='green') else: return {'result': 'failure', 'reason': 'Couldnt find instance type matching requirements'} conn = self.conn tags = [{'ResourceType': 'instance', 'Tags': [{'Key': 'Name', 'Value': name}, {'Key': 'plan', 'Value': plan}, {'Key': 'hostname', 'Value': name}, {'Key': 'profile', 'Value': profile}]}] if keypair is None: keypair = 'kvirt_%s' % self.access_key_id keypairs = [k for k in conn.describe_key_pairs()['KeyPairs'] if k['KeyName'] == keypair] if not keypairs: common.pprint("Importing your public key as %s" % keypair, color='green') if not os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.kcli/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.kcli/id_dsa.pub" % os.environ['HOME']): common.pprint("No public key found. Leaving", color='red') return {'result': 'failure', 'reason': 'No public key found'} elif os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_rsa.pub" % os.environ['HOME']).read() elif os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_dsa.pub" % os.environ['HOME']).read() elif os.path.exists("%s/.kcli/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.kcli/id_rsa.pub" % os.environ['HOME']).read() else: homekey = open("%s/.kcli/id_dsa.pub" % os.environ['HOME']).read() conn.import_key_pair(KeyName=keypair, PublicKeyMaterial=homekey) if cloudinit: if template is not None and (template.startswith('coreos') or template.startswith('rhcos')): etcd = None userdata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, etcd=etcd) else: common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, iso=False, fqdn=True, storemetadata=storemetadata) userdata = open('/tmp/user-data', 'r').read() else: userdata = '' networkinterfaces = [] blockdevicemappings = [] privateips = [] for index, net in enumerate(nets): networkinterface = {'DeleteOnTermination': True, 'Description': "eth%s" % index, 'DeviceIndex': index, 'Groups': ['string'], 'SubnetId': 'string'} ip = None if isinstance(net, str): netname = net netpublic = True elif isinstance(net, dict) and 'name' in net: netname = net['name'] ip = net.get('ip') alias = net.get('alias') netpublic = net.get('public', True) networkinterface['AssociatePublicIpAddress'] = netpublic if index == 0 else False if netname == 'default': if defaultsubnetid is not None: netname = defaultsubnetid else: # Filters = [{'Name': 'isDefault', 'Values': ['True']}] # vpcs = conn.describe_vpcs(Filters=Filters) vpcs = conn.describe_vpcs() vpcid = [vpc['VpcId'] for vpc in vpcs['Vpcs'] if vpc['IsDefault']][0] # Filters = [{'Name': 'vpc-id', 'Values': [vpcid]}, {'Name': 'default-for-az', 'Values': ['True']}] subnets = conn.describe_subnets() subnetid = [subnet['SubnetId'] for subnet in subnets['Subnets'] if subnet['DefaultForAz'] and subnet['VpcId'] == vpcid][0] netname = subnetid defaultsubnetid = netname common.pprint("Using subnet %s as default" % defaultsubnetid, color='green') if ips and len(ips) > index and ips[index] is not None: ip = ips[index] if index == 0: networkinterface['PrivateIpAddress'] = ip privateip = {'Primary': True, 'PrivateIpAddress': ip} else: privateip = {'Primary': False, 'PrivateIpAddress': ip} privateips = privateips.append(privateip) networkinterface['SubnetId'] = netname networkinterfaces.append(networkinterface) if len(privateips) > 1: networkinterface['PrivateIpAddresses'] = privateips for index, disk in enumerate(disks): letter = chr(index + ord('a')) devicename = '/dev/sd%s1' % letter if index == 0 else '/dev/sd%s' % letter blockdevicemapping = {'DeviceName': devicename, 'Ebs': {'DeleteOnTermination': True, 'VolumeType': 'standard'}} if isinstance(disk, int): disksize = disk elif isinstance(disk, str) and disk.isdigit(): disksize = str(disk) elif isinstance(disk, dict): disksize = disk.get('size', '10') blockdevicemapping['Ebs']['VolumeType'] = disk.get('type', 'standard') blockdevicemapping['Ebs']['VolumeSize'] = disksize blockdevicemappings.append(blockdevicemapping) if reservedns and domain is not None: tags[0]['Tags'].append({'Key': 'domain', 'Value': domain}) if dnshost is not None: tags[0]['Tags'].append({'Key': 'dnshost', 'Value': dnshost}) conn.run_instances(ImageId=template, MinCount=1, MaxCount=1, InstanceType=flavor, KeyName=keypair, BlockDeviceMappings=blockdevicemappings, UserData=userdata, TagSpecifications=tags) common.pprint("%s created on aws" % name, color='green') if reservedns and domain is not None: self.reserve_dns(name, nets=nets, domain=domain, alias=alias, instanceid=name) return {'result': 'success'}
def create(self, name, virttype='kvm', profile='', flavor=None, plan='kvirt', cpumodel='Westmere', cpuflags=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', image=None, disks=[{ 'size': 10 }], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags={}, dnsclient=None, storemetadata=False, sharedfolders=[], kernel=None, initrd=None, cmdline=None, placement=[], autostart=False): """ :param name: :param virttype: :param profile: :param flavor: :param plan: :param cpumodel: :param cpuflags: :param numcpus: :param memory: :param guestid: :param pool: :param image: :param disks: :param disksize: :param diskthin: :param diskinterface: :param nets: :param iso: :param vnc: :param cloudinit: :param reserveip: :param reservedns: :param reservehost: :param start: :param keys: :param cmds: :param ips: :param netmasks: :param gateway: :param nested: :param dns: :param domain: :param tunnel: :param files: :param enableroot: :param alias: :param overrides: :param tags: :return: """ plandir = "/tmp/%s" % plan namedir = "%s/%s" % (plandir, name) if not os.path.exists(plandir): common.pprint("Generating assets in %s" % plandir) os.mkdir(plandir) if os.path.exists(namedir): rmtree(namedir) os.mkdir(namedir) if cloudinit: if image is not None and ('coreos' in image or image.startswith('rhcos')): common.pprint("Data provided for a %s image" % image) version = '3.0.0' if image.startswith( 'fedora-coreos') else '2.2.0' etcd = None ignitiondata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, etcd=etcd, version=version, plan=plan) with open('%s/%s.ign' % (namedir, name), 'w') as ignitionfile: ignitionfile.write(ignitiondata) else: _files = yaml.safe_load( common.process_files(files=files, overrides=overrides)) cmds = common.process_cmds(cmds, overrides).replace('- ', '') if cmds != "": with open("%s/cmds.sh" % (namedir), "w") as f: f.write(cmds) copycmds = "" permissioncmds = "" if _files is not None: for entry in _files: owner = entry.get("owner", 'root') path = entry["path"] origin = os.path.basename(entry["path"]) permissions = entry.get("permissions") content = entry["content"] with open("%s/%s" % (namedir, os.path.basename(path)), "w") as f: f.write(content) copycmds += "scp %s $host:%s\n" % (origin, path) if owner != "root:root": permissioncmds += "chown %s %s\n" % (owner, path) if permissions is not None and permissions != '0600': permissioncmds += "chmod %s %s\n" % (permissions, path) with open("%s/launch.sh" % namedir, "w") as f: if 'host' in overrides: host = overrides["host"] else: common.pprint("Set host in launch.sh", color="blue") host = "" user = "******" % overrides[ "user"] if "user" in overrides else "root" f.write("#!/bin/bash\nhost=\"%s%s\"\n" % (user, host)) f.write(copycmds) f.write(permissioncmds) if cmds != "": f.write("scp cmds.sh $host:\n") f.write("ssh $host bash cmds.sh") return {'result': 'success'}
def create(self, name, virttype=None, profile='', plan='kvirt', flavor=None, cpumodel='Westmere', cpuflags=[], cpupinning=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', image=None, disks=[{ 'size': 10 }], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags=[], storemetadata=False, sharedfolders=[], kernel=None, initrd=None, cmdline=None, placement=[], autostart=False, cpuhotplug=False, memoryhotplug=False, numamode=None, numa=[], pcidevices=[], tpm=False, rng=False, metadata={}, securitygroups=[]): glance = self.glance nova = self.nova neutron = self.neutron try: nova.servers.find(name=name) return { 'result': 'failure', 'reason': "VM %s already exists" % name } except: pass allflavors = [f for f in nova.flavors.list()] allflavornames = [flavor.name for flavor in allflavors] if flavor is None: flavors = [ flavor for flavor in allflavors if flavor.ram >= memory and flavor.vcpus >= numcpus ] flavor = flavors[0] if flavors else nova.flavors.find( name="m1.tiny") pprint("Using flavor %s" % flavor.name) elif flavor not in allflavornames: return { 'result': 'failure', 'reason': "Flavor %s not found" % flavor } else: flavor = nova.flavors.find(name=flavor) nics = [] need_floating = True for net in nets: if isinstance(net, str): netname = net elif isinstance(net, dict) and 'name' in net: netname = net['name'] try: net = nova.neutron.find_network(name=netname) if net.to_dict()['router:external']: need_floating = False except Exception as e: error(e) return { 'result': 'failure', 'reason': "Network %s not found" % netname } nics.append({'net-id': net.id}) if image is not None: glanceimages = [ img for img in glance.images.list() if img.name == image ] if glanceimages: glanceimage = glanceimages[0] else: msg = "you don't have image %s" % image return {'result': 'failure', 'reason': msg} block_dev_mapping = {} for index, disk in enumerate(disks): imageref = None diskname = "%s-disk%s" % (name, index) letter = chr(index + ord('a')) if isinstance(disk, int): disksize = disk diskthin = True elif isinstance(disk, str) and disk.isdigit(): disksize = int(disk) diskthin = True elif isinstance(disk, dict): disksize = disk.get('size', '10') diskthin = disk.get('thin', True) if index == 0 and image is not None: if not diskthin: imageref = glanceimage.id else: continue newvol = self.cinder.volumes.create(name=diskname, size=disksize, imageRef=imageref) block_dev_mapping['vd%s' % letter] = newvol.id key_name = 'kvirt' keypairs = [k.name for k in nova.keypairs.list()] if key_name not in keypairs: homekey = None if not os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME']): print( "neither id_rsa.pub or id_dsa public keys found in your .ssh directory, you might have trouble " "accessing the vm") else: if os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_rsa.pub" % os.environ['HOME']).read() else: homekey = open("%s/.ssh/id_dsa.pub" % os.environ['HOME']).read() nova.keypairs.create(key_name, homekey) elif keypairs: key_name = keypairs[0] if key_name != 'kvirt': pprint('Using keypair %s' % key_name) else: error("Couldn't locate or create keypair for use. Leaving...") return {'result': 'failure', 'reason': "No usable keypair found"} userdata = None if cloudinit: if image is not None and common.needs_ignition(image): version = common.ignition_version(image) userdata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, version=version, plan=plan, image=image) else: userdata = common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, storemetadata=storemetadata)[0] meta = {x: metadata[x] for x in metadata if x in METADATA_FIELDS} instance = nova.servers.create(name=name, image=glanceimage, flavor=flavor, key_name=key_name, nics=nics, meta=meta, userdata=userdata, block_device_mapping=block_dev_mapping, security_groups=securitygroups) tenant_id = instance.tenant_id if need_floating: floating_ips = [ f['id'] for f in neutron.list_floatingips()['floatingips'] if f['port_id'] is None ] if not floating_ips: network_id = None if self.external_network is not None: networks = [ n for n in neutron.list_networks()['networks'] if n['router:external'] if n['name'] == self.external_network ] else: networks = [ n for n in neutron.list_networks()['networks'] if n['router:external'] ] if networks: network_id = networks[0]['id'] if network_id is not None and tenant_id is not None: args = dict(floating_network_id=network_id, tenant_id=tenant_id) floating_ip = neutron.create_floatingip( body={'floatingip': args}) floatingip_id = floating_ip['floatingip']['id'] floatingip_ip = floating_ip['floatingip'][ 'floating_ip_address'] pprint('Assigning new floating ip %s for this vm' % floatingip_ip) else: floatingip_id = floating_ips[0] fixed_ip = None timeout = 0 while fixed_ip is None: pprint("Waiting 5 seconds for vm to get an ip") sleep(5) timeout += 5 if timeout >= 240: error("Time out waiting for vm to get an ip") break vm = nova.servers.get(instance.id) if vm.status.lower() == 'error': msg = "Vm reports error status" return {'result': 'failure', 'reason': msg} for key in list(vm.addresses): entry1 = vm.addresses[key] for entry2 in entry1: if entry2['OS-EXT-IPS:type'] == 'fixed': fixed_ip = entry2['addr'] break if fixed_ip is not None: fixedports = [ i['id'] for i in neutron.list_ports()['ports'] if i['fixed_ips'] and i['fixed_ips'][0]['ip_address'] == fixed_ip ] port_id = fixedports[0] neutron.update_floatingip(floatingip_id, {'floatingip': { 'port_id': port_id }}) if not securitygroups: default_securitygroups = [ s for s in neutron.list_security_groups()['security_groups'] if s['name'] == 'default' and s['tenant_id'] == tenant_id ] if default_securitygroups: securitygroup = default_securitygroups[0] securitygroupid = securitygroup['id'] sshrule = { 'security_group_rule': { 'direction': 'ingress', 'security_group_id': securitygroupid, 'port_range_min': '22', 'port_range_max': '22', 'protocol': 'tcp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0' } } icmprule = { 'security_group_rule': { 'direction': 'ingress', 'security_group_id': securitygroupid, 'protocol': 'icmp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0' } } try: neutron.create_security_group_rule(sshrule) neutron.create_security_group_rule(icmprule) except: pass return {'result': 'success'}
def create(self, name, virttype=None, profile='', flavor=None, plan='kvirt', cpumodel='Westmere', cpuflags=[], cpupinning=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', image=None, disks=[{ 'size': 10 }], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags=[], storemetadata=False, sharedfolders=[], kernel=None, initrd=None, cmdline=None, placement=[], autostart=False, cpuhotplug=False, memoryhotplug=False, numamode=None, numa=[], pcidevices=[], tpm=False, rng=False, metadata={}, securitygroups=[]): conn = self.conn if self.exists(name): return { 'result': 'failure', 'reason': "VM %s already exists" % name } image = self.__evaluate_image(image) keypair = self.keypair if image is not None: Filters = [{'Name': 'name', 'Values': [image]}] images = conn.describe_images(Filters=Filters) if not image.startswith( 'ami-') and 'Images' in images and images['Images']: imageinfo = images['Images'][0] imageid = imageinfo['ImageId'] pprint("Using ami %s" % imageid) image = imageinfo['Name'] else: return { 'result': 'failure', 'reason': 'Invalid image %s' % image } else: return { 'result': 'failure', 'reason': 'An image (or amid) is required' } defaultsubnetid = None if flavor is None: matching = [ f for f in staticf if staticf[f]['cpus'] >= numcpus and staticf[f]['memory'] >= memory ] if matching: flavor = matching[0] pprint("Using instance type %s" % flavor) else: return { 'result': 'failure', 'reason': 'Couldnt find instance type matching requirements' } vmtags = [{ 'ResourceType': 'instance', 'Tags': [{ 'Key': 'Name', 'Value': name }, { 'Key': 'hostname', 'Value': name }] }] for entry in [field for field in metadata if field in METADATA_FIELDS]: vmtags[0]['Tags'].append({'Key': entry, 'Value': metadata[entry]}) if keypair is None: keypair = 'kvirt_%s' % self.access_key_id keypairs = [ k for k in conn.describe_key_pairs()['KeyPairs'] if k['KeyName'] == keypair ] if not keypairs: pprint("Importing your public key as %s" % keypair) if not os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.kcli/id_rsa.pub" % os.environ['HOME'])\ and not os.path.exists("%s/.kcli/id_dsa.pub" % os.environ['HOME']): error("No public key found. Leaving") return {'result': 'failure', 'reason': 'No public key found'} elif os.path.exists("%s/.ssh/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_rsa.pub" % os.environ['HOME']).read() elif os.path.exists("%s/.ssh/id_dsa.pub" % os.environ['HOME']): homekey = open("%s/.ssh/id_dsa.pub" % os.environ['HOME']).read() elif os.path.exists("%s/.kcli/id_rsa.pub" % os.environ['HOME']): homekey = open("%s/.kcli/id_rsa.pub" % os.environ['HOME']).read() else: homekey = open("%s/.kcli/id_dsa.pub" % os.environ['HOME']).read() conn.import_key_pair(KeyName=keypair, PublicKeyMaterial=homekey) if cloudinit: if image is not None and common.needs_ignition(image): version = common.ignition_version(image) userdata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, version=version, plan=plan, image=image) else: userdata = common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, fqdn=True, storemetadata=storemetadata)[0] else: userdata = '' networkinterfaces = [] blockdevicemappings = [] privateips = [] for index, net in enumerate(nets): networkinterface = { 'DeleteOnTermination': True, 'Description': "eth%s" % index, 'DeviceIndex': index, 'Groups': ['string'], 'SubnetId': 'string' } ip = None if isinstance(net, str): netname = net netpublic = True elif isinstance(net, dict) and 'name' in net: netname = net['name'] ip = net.get('ip') alias = net.get('alias') netpublic = net.get('public', True) networkinterface[ 'AssociatePublicIpAddress'] = netpublic if index == 0 else False if netname == 'default': if defaultsubnetid is not None: netname = defaultsubnetid else: vpcs = conn.describe_vpcs() vpcid = [ vpc['VpcId'] for vpc in vpcs['Vpcs'] if vpc['IsDefault'] ][0] subnets = conn.describe_subnets() subnetid = [ subnet['SubnetId'] for subnet in subnets['Subnets'] if subnet['DefaultForAz'] and subnet['VpcId'] == vpcid ][0] netname = subnetid defaultsubnetid = netname pprint("Using subnet %s as default" % defaultsubnetid) if ips and len(ips) > index and ips[index] is not None: ip = ips[index] if index == 0: networkinterface['PrivateIpAddress'] = ip privateip = {'Primary': True, 'PrivateIpAddress': ip} else: privateip = {'Primary': False, 'PrivateIpAddress': ip} privateips = privateips.append(privateip) networkinterface['SubnetId'] = netname networkinterfaces.append(networkinterface) if len(privateips) > 1: networkinterface['PrivateIpAddresses'] = privateips for index, disk in enumerate(disks): if image is not None and index == 0: continue letter = chr(index + ord('a')) # devicename = '/dev/sd%s1' % letter if index == 0 else '/dev/sd%s' % letter devicename = '/dev/xvd%s' % letter blockdevicemapping = { 'DeviceName': devicename, 'Ebs': { 'DeleteOnTermination': True, 'VolumeType': 'standard' } } if isinstance(disk, int): disksize = disk elif isinstance(disk, str) and disk.isdigit(): disksize = str(disk) elif isinstance(disk, dict): disksize = disk.get('size', '10') blockdevicemapping['Ebs']['VolumeType'] = disk.get( 'type', 'standard') blockdevicemapping['Ebs']['VolumeSize'] = disksize blockdevicemappings.append(blockdevicemapping) SecurityGroupIds = [] for sg in securitygroups: sgid = self.get_security_group_id(sg, vpcid) if sgid is not None: SecurityGroupIds.append(sgid) conn.run_instances(ImageId=imageid, MinCount=1, MaxCount=1, InstanceType=flavor, KeyName=keypair, BlockDeviceMappings=blockdevicemappings, UserData=userdata, TagSpecifications=vmtags, SecurityGroupIds=SecurityGroupIds) if reservedns and domain is not None: # eip = conn.allocate_address(Domain='vpc') # vmid = reservation.instances[0].id # conn.associate_address(InstanceId=vmid, AllocationId=eip["AllocationId"]) # self.reserve_dns(name, nets=nets, domain=domain, alias=alias, instanceid=name, ip=eip["PublicIp"]) self.reserve_dns(name, nets=nets, domain=domain, alias=alias, instanceid=name) return {'result': 'success'}
def create(self, name, virttype=None, profile='kvirt', flavor=None, plan='kvirt', cpumodel='host-model', cpuflags=[], cpupinning=[], numcpus=2, memory=512, guestid='centos7_64Guest', pool='default', image=None, disks=[{'size': 10}], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, overrides={}, tags=[], storemetadata=False, sharedfolders=[], kernel=None, initrd=None, cmdline=None, placement=[], autostart=False, cpuhotplug=False, memoryhotplug=False, numamode=None, numa=[], pcidevices=[], tpm=False, rng=False, metadata={}, securitygroups=[]): dc = self.dc vmFolder = dc.vmFolder distributed = self.distributed diskmode = 'persistent' default_diskinterface = diskinterface default_diskthin = diskthin default_disksize = disksize default_pool = pool memory = int(memory) numcpus = int(numcpus) si = self.si dc = self.dc rootFolder = self.rootFolder if plan != 'kvirt': createfolder(si, dc.vmFolder, plan) vmfolder = find(si, dc.vmFolder, vim.Folder, plan) else: vmfolder = dc.vmFolder si = self.si clu = find(si, rootFolder, vim.ComputeResource, self.clu) resourcepool = clu.resourcePool if image is not None: rootFolder = self.rootFolder imageobj = findvm(si, rootFolder, image) if imageobj is None: return {'result': 'failure', 'reason': "Image %s not found" % image} clonespec = createclonespec(resourcepool) confspec = vim.vm.ConfigSpec() confspec.annotation = name confspec.memoryMB = memory confspec.numCPUs = numcpus planopt = vim.option.OptionValue() planopt.key = 'plan' planopt.value = plan profileopt = vim.option.OptionValue() profileopt.key = 'profile' profileopt.value = profile imageopt = vim.option.OptionValue() imageopt.key = 'image' imageopt.value = image extraconfig = [imageopt, planopt, profileopt] clonespec.config = confspec clonespec.powerOn = False cloudinitiso = None if cloudinit: if image is not None and common.needs_ignition(image): version = common.ignition_version(image) ignitiondata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, version=version, plan=plan, image=image) ignitionopt = vim.option.OptionValue() ignitionopt.key = 'guestinfo.ignition.config.data' ignitionopt.value = base64.b64encode(ignitiondata.encode()).decode() encodingopt = vim.option.OptionValue() encodingopt.key = 'guestinfo.ignition.config.data.encoding' encodingopt.value = 'base64' extraconfig.extend([ignitionopt, encodingopt]) else: # customspec = makecuspec(name, nets=nets, gateway=gateway, dns=dns, domain=domain) # clonespec.customization = customspec cloudinitiso = "[%s]/%s/%s.ISO" % (default_pool, name, name) userdata, metadata, netdata = common.cloudinit(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, storemetadata=storemetadata) confspec.extraConfig = extraconfig t = imageobj.CloneVM_Task(folder=vmfolder, name=name, spec=clonespec) waitForMe(t) if cloudinitiso is not None: with TemporaryDirectory() as tmpdir: common.make_iso(name, tmpdir, userdata, metadata, netdata) cloudinitisofile = "%s/%s.ISO" % (tmpdir, name) self._uploadimage(default_pool, cloudinitisofile, name) vm = findvm(si, vmFolder, name) c = changecd(self.si, vm, cloudinitiso) waitForMe(c) datastores = {} confspec = vim.vm.ConfigSpec() confspec.name = name confspec.annotation = name confspec.memoryMB = memory confspec.numCPUs = numcpus confspec.extraConfig = [] for entry in [field for field in metadata if field in METADATA_FIELDS]: opt = vim.option.OptionValue() opt.key = entry opt.value = metadata[entry] confspec.extraConfig.append(opt) if nested: confspec.nestedHVEnabled = True confspec.guestId = 'centos7_64Guest' vmfi = vim.vm.FileInfo() filename = "[" + default_pool + "]" vmfi.vmPathName = filename confspec.files = vmfi if vnc: vncport = random.randint(5900, 7000) opt1 = vim.option.OptionValue() opt1.key = 'RemoteDisplay.vnc.port' opt1.value = vncport opt2 = vim.option.OptionValue() opt2.key = 'RemoteDisplay.vnc.enabled' opt2.value = "TRUE" confspec.extraConfig = [opt1, opt2] if image is None: t = vmfolder.CreateVM_Task(confspec, resourcepool) waitForMe(t) vm = find(si, dc.vmFolder, vim.VirtualMachine, name) currentdevices = vm.config.hardware.device currentdisks = [d for d in currentdevices if isinstance(d, vim.vm.device.VirtualDisk)] currentnics = [d for d in currentdevices if isinstance(d, vim.vm.device.VirtualEthernetCard)] confspec = vim.vm.ConfigSpec() devconfspec = [] for index, disk in enumerate(disks): if disk is None: disksize = default_disksize diskthin = default_diskthin diskinterface = default_diskinterface diskpool = default_pool elif isinstance(disk, int): disksize = disk diskthin = default_diskthin diskinterface = default_diskinterface diskpool = default_pool elif isinstance(disk, str) and disk.isdigit(): disksize = int(disk) diskthin = default_diskthin diskinterface = default_diskinterface diskpool = default_pool elif isinstance(disk, dict): disksize = disk.get('size', default_disksize) diskthin = disk.get('thin', default_diskthin) diskinterface = disk.get('interface', default_diskinterface) diskpool = disk.get('pool', default_pool) if index < len(currentdisks) and image is not None: currentdisk = currentdisks[index] currentsize = convert(1000 * currentdisk.capacityInKB, GB=False) if int(currentsize) < disksize: pprint("Waiting for image disk %s to be resized" % index) currentdisk.capacityInKB = disksize * 1048576 diskspec = vim.vm.ConfigSpec() diskspec = vim.vm.device.VirtualDeviceSpec(device=currentdisk, operation="edit") devconfspec.append(diskspec) continue disksize = disksize * 1048576 if diskpool not in datastores: datastore = find(si, rootFolder, vim.Datastore, diskpool) if not datastore: return {'result': 'failure', 'reason': "Pool %s not found" % diskpool} else: datastores[diskpool] = datastore if index == 0: scsispec = createscsispec() devconfspec.append(scsispec) diskspec = creatediskspec(index, disksize, datastore, diskmode, diskthin) devconfspec.append(diskspec) # NICSPEC for index, net in enumerate(nets): if index < len(currentnics): continue nicname = 'Network Adapter %d' % (index + 1) if net == 'default': net = 'VM Network' nicspec = createnicspec(nicname, net) devconfspec.append(nicspec) if iso: if '/' not in iso: matchingisos = [i for i in self._getisos() if i.endswith(iso)] if matchingisos: iso = matchingisos[0] else: return {'result': 'failure', 'reason': "Iso %s not found" % iso} cdspec = createisospec(iso) devconfspec.append(cdspec) # bootoptions = vim.option.OptionValue(key='bios.bootDeviceClasses',value='allow:hd,cd,fd,net') # confspec.bootOptions = vim.vm.BootOptions(bootOrder=[vim.vm.BootOptions.BootableCdromDevice()]) confspec.deviceChange = devconfspec t = vm.Reconfigure(confspec) waitForMe(t) # HANDLE DVS if distributed: # 2-GETMAC vm = findvm(si, vmfolder, name) if vm is None: return "%s not found" % (name) devices = vm.config.hardware.device macaddr = [] for dev in devices: if "addressType" in dir(dev): macaddr.append(dev.macAddress) portgs = {} o = si.content.viewManager.CreateContainerView(rootFolder, [vim.DistributedVirtualSwitch], True) dvnetworks = o.view o.Destroy() for dvnetw in dvnetworks: uuid = dvnetw.uuid for portg in dvnetw.portgroup: portgs[portg.name] = [uuid, portg.key] for k in range(len(nets)): net = nets[k] mactochange = macaddr[k] if net in portgs.keys(): confspec = vim.vm.VirtualMachineSpec() nicspec = vim.vm.device.VirtualDeviceSpec() nicspec.operation = vim.ConfigSpecOperation.edit nic = vim.vm.device.VirtualPCNet32() dnicbacking = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo() dvconnection = vim.dvs.DistributedVirtualSwitchPortConnection() dvconnection.switchUuid = portgs[net][0] dvconnection.portgroupKey = portgs[net][1] dnicbacking.port = dvconnection nic.backing = dnicbacking nicspec.device = nic # 2-GETMAC vm = findvm(si, vmfolder, name) if vm is None: return "%s not found" % (name) devices = vm.config.hardware.device for dev in devices: if "addressType" in dir(dev): mac = dev.macAddress if mac == mactochange: dev.backing = dnicbacking nicspec.device = dev devconfspec = [nicspec] confspec.deviceChange = devconfspec t = vm.reconfigVM_Task(confspec) waitForMe(t) t = vm.PowerOnVM_Task(None) waitForMe(t) if start: t = vm.PowerOnVM_Task(None) waitForMe(t) return {'result': 'success'}
def create(self, name, virttype='kvm', profile='', flavor=None, plan='kvirt', cpumodel='Westmere', cpuflags=[], numcpus=2, memory=512, guestid='guestrhel764', pool='default', template=None, disks=[{'size': 10}], disksize=10, diskthin=True, diskinterface='virtio', nets=['default'], iso=None, vnc=False, cloudinit=True, reserveip=False, reservedns=False, reservehost=False, start=True, keys=None, cmds=[], ips=None, netmasks=None, gateway=None, nested=True, dns=None, domain=None, tunnel=False, files=[], enableroot=True, alias=[], overrides={}, tags={}): """ :param name: :param virttype: :param profile: :param flavor: :param plan: :param cpumodel: :param cpuflags: :param numcpus: :param memory: :param guestid: :param pool: :param template: :param disks: :param disksize: :param diskthin: :param diskinterface: :param nets: :param iso: :param vnc: :param cloudinit: :param reserveip: :param reservedns: :param reservehost: :param start: :param keys: :param cmds: :param ips: :param netmasks: :param gateway: :param nested: :param dns: :param domain: :param tunnel: :param files: :param enableroot: :param alias: :param overrides: :param tags: :return: """ conn = self.conn project = self.project zone = self.zone region = self.region if flavor is None: if numcpus != 1 and numcpus % 2 != 0: return {'result': 'failure', 'reason': "Number of cpus is not even"} if memory != 512 and memory % 1024 != 0: return {'result': 'failure', 'reason': "Memory is not multiple of 1024"} if numcpus > 1 and memory < 2048: common.pprint("Rounding memory to 2048Mb as more than one cpu is used", color='blue') memory = 2048 machine_type = 'custom-%s-%s' % (numcpus, memory) if memory < 921.6: common.pprint("Rounding memory to 1024Mb", color='blue') machine_type = 'f1-micro' else: machine_type = flavor machine_type = "zones/%s/machineTypes/%s" % (zone, machine_type) body = {'name': name, 'machineType': machine_type, 'networkInterfaces': []} foundnets = [] for index, net in enumerate(nets): ip = None if isinstance(net, str): netname = net elif isinstance(net, dict) and 'name' in net: netname = net['name'] if 'ip' in net: ip = net['ip'] if 'alias' in net: alias = net['alias'] if ips and len(ips) > index and ips[index] is not None: ip = ips[index] if netname in foundnets: continue else: foundnets.append(netname) newnet = {'network': 'global/networks/%s' % netname} if netname == 'default': newnet['accessConfigs'] = [{'type': 'ONE_TO_ONE_NAT', 'name': 'External NAT'}] else: newnet['subnetwork'] = 'projects/%s/regions/%s/subnetworks/%s' % (project, region, netname) if ip is not None: newnet['networkIP'] = ip body['networkInterfaces'].append(newnet) body['disks'] = [] for index, disk in enumerate(disks): if isinstance(disk, int): disksize = disk elif isinstance(disk, str) and disk.isdigit(): disksize = int(disk) elif isinstance(disk, dict): disksize = disk.get('size', '10') newdisk = {'boot': False, 'autoDelete': True} if index == 0 and template is not None: template = self.__evaluate_template(template) templateproject = self.__get_template_project(template) if templateproject is not None: image_response = conn.images().getFromFamily(project=templateproject, family=template).execute() else: try: image_response = conn.images().get(project=self.project, image=template).execute() except: return {'result': 'failure', 'reason': 'Issue with template %s' % template} src = image_response['selfLink'] newdisk['initializeParams'] = {'sourceImage': src, 'diskSizeGb': disksize} newdisk['boot'] = True else: diskname = "%s-disk%s" % (name, index) diskpath = '/compute/v1/projects/%s/zones/%s/disks/%s' % (project, zone, diskname) info = {'sizeGb': disksize, 'sourceDisk': 'zones/%s/diskTypes/pd-standard' % zone, 'name': diskname} conn.disks().insert(zone=zone, project=project, body=info).execute() timeout = 0 while True: if timeout > 60: return {'result': 'failure', 'reason': 'timeout waiting for disk %s to be ready' % diskname} newstatus = conn.disks().get(zone=zone, project=project, disk=diskname).execute() if newstatus['status'] == 'READY': break else: timeout += 5 time.sleep(5) common.pprint("Waiting for disk %s to be ready" % diskname, color='green') newdisk['source'] = diskpath body['disks'].append(newdisk) body['serviceAccounts'] = [{'email': 'default', 'scopes': ['https://www.googleapis.com/auth/devstorage.read_write', 'https://www.googleapis.com/auth/logging.write']}] body['metadata'] = {'items': []} startup_script = '' for fil in files: if not isinstance(fil, dict): continue origin = fil.get('origin') path = fil.get('path') content = fil.get('content') if origin is not None: origin = os.path.expanduser(origin) if not os.path.exists(origin): print("Skipping file %s as not found" % origin) continue binary = True if '.' in origin and origin.split('.')[-1].lower() in binary_types else False if binary: with open(origin, "rb") as f: content = f.read().encode("base64") elif overrides: basedir = os.path.dirname(origin) if os.path.dirname(origin) != '' else '.' env = Environment(block_start_string='[%', block_end_string='%]', variable_start_string='[[', variable_end_string=']]', loader=FileSystemLoader(basedir)) templ = env.get_template(os.path.basename(origin)) newfile = templ.render(overrides) startup_script += "cat <<'EOF' >%s\n%s\nEOF\n" % (path, newfile) else: newfile = open(origin, 'r').read() startup_script += "cat <<'EOF' >%s\n%s\nEOF\n" % (path, newfile) elif content is None: continue if cmds: for cmd in cmds: if cmd.startswith('#'): continue else: newcmd = Environment(block_start_string='[%', block_end_string='%]', variable_start_string='[[', variable_end_string=']]').from_string(cmd).render(overrides) startup_script += '%s\n' % newcmd if startup_script != '': beginningcmd = 'test -f /root/.kcli_startup && exit 0\n' endcmd = 'touch /root/.kcli_startup\n' newval = {'key': 'startup-script', 'value': beginningcmd + startup_script + endcmd} body['metadata']['items'].append(newval) if not os.path.exists(os.path.expanduser("~/.ssh/id_rsa.pub"))\ and not os.path.exists(os.path.expanduser("~/.ssh/id_dsa.pub"))\ and not os.path.exists(os.path.expanduser("~/.kcli/id_rsa.pub"))\ and not os.path.exists(os.path.expanduser("~/.kcli/id_dsa.pub")): print("neither id_rsa.pub or id_dsa public keys found in your .ssh or .kcli directory, you might have " "trouble accessing the vm") homekey = None elif os.path.exists(os.path.expanduser("~/.ssh/id_rsa.pub")): homekey = open(os.path.expanduser("~/.ssh/id_rsa.pub")).read() elif os.path.exists(os.path.expanduser("~/.ssh/id_dsa.pub")): homekey = open(os.path.expanduser("~/.ssh/id_dsa.pub")).read() elif os.path.exists(os.path.expanduser("~/.kcli/id_rsa.pub")): homekey = open(os.path.expanduser("~/.kcli/id_rsa.pub")).read() else: homekey = open(os.path.expanduser("~/.kcli/id_dsa.pub")).read() if homekey is not None: keys = [homekey] + keys if keys is not None else [homekey] if keys is not None: keys = ["%s: %s" % (self.user, x) for x in keys] keys = ''.join(keys) newval = {'key': 'ssh-keys', 'value': keys} body['metadata']['items'].append(newval) newval = {'key': 'plan', 'value': plan} body['metadata']['items'].append(newval) newval = {'key': 'profile', 'value': profile} body['metadata']['items'].append(newval) if tags: body['tags'] = {'items': tags} if reservedns: newval = {'key': 'domain', 'value': domain} body['metadata']['items'].append(newval) if template is not None and (template.startswith('coreos') or template.startswith('rhcos')): etcd = None userdata = common.ignition(name=name, keys=keys, cmds=cmds, nets=nets, gateway=gateway, dns=dns, domain=domain, reserveip=reserveip, files=files, enableroot=enableroot, overrides=overrides, etcd=etcd) newval = {'key': 'user-data', 'value': userdata} body['metadata']['items'].append(newval) if self.debug: print(body) conn.instances().insert(project=project, zone=zone, body=body).execute() if reservedns: self.reserve_dns(name, nets=nets, domain=domain, alias=alias) return {'result': 'success'}