예제 #1
0
def _find_dvswitch(server, vlan, datacenter):
    """Try to find a dvSwitch named as a network."""
    netfolder = datacenter.networkFolder._obj
    dvswitch_resources = server._retrieve_properties_traversal(
        property_names=['uuid', 'portgroup'],
        from_node=netfolder,
        obj_type='DistributedVirtualSwitch')

    if not dvswitch_resources:
        return None

    # Count number of uplinks we can use to make sure that we're not trying to
    # use an un-initialized DVS
    for dvswitch in dvswitch_resources:
        if pysphere.VIProperty(server, dvswitch._obj).summary.numPorts > 0:
            break
    else:
        return None

    # Find the dvPortgroup that contains a portgroup with the correct VLAN
    portgroup_key, portgroup_name = _vlan_to_dvs_portgroup_key(
        server, vlan, datacenter)

    # Now get the associated dvswitch
    dvswitch = _portgroup_to_dvswitch(server, dvswitch_resources,
                                      portgroup_key)
    dvswitch_uuid = next(p.Val for p in dvswitch.PropSet if p.Name == 'uuid')
    dvswitch_name = pysphere.VIProperty(server, dvswitch._obj).summary.name
    print 'Using VLAN %s on PG %s on DVS %s' % (vlan, portgroup_name,
                                                dvswitch_name)
    return DistributedSwitchPort(dvswitch_uuid, portgroup_key)
예제 #2
0
def create_dvswitch(vcenter, datacenter, name, uplinks=2):
    """Create a new DVS."""
    switch_folder = pysphere.VIProperty(vcenter, datacenter).networkFolder._obj
    request = VI.CreateDVS_TaskRequestMsg()
    _this = request.new__this(switch_folder)
    _this.set_attribute_type(switch_folder.get_attribute_type())
    request.set_element__this(_this)

    spec = request.new_spec()
    config = spec.new_configSpec()
    config.Name = name

    uplink_policy = (
        VI.ns0.DVSNameArrayUplinkPortPolicy_Def('uplink_policy').pyclass())
    uplink_policy.UplinkPortName = [
        'Uplink%d' % x for x in range(1, uplinks + 1)
    ]
    config.set_element_uplinkPortPolicy(uplink_policy)

    spec.set_element_configSpec(config)
    request.set_element_spec(spec)
    task = vcenter._proxy.CreateDVS_Task(request)._returnval
    vi_task = pysphere.VITask(task, vcenter)
    status = vi_task.wait_for_state(
        [vi_task.STATE_SUCCESS, vi_task.STATE_ERROR])
    if status == vi_task.STATE_ERROR:
        raise CreateDvSwitchError(vi_task.get_error_message())
예제 #3
0
def provision_vm(server, vm, vlan, datacenter):
    # Set VMs first NIC to the correct label
    hardware = pysphere.VIProperty(server, vm).config.hardware
    nic = next(
        (x._obj for x in hardware.device if x._type in NET_DEVICE_TYPES), None)
    if not nic:
        raise NicNotFoundError('No NIC found')

    # Only vCenter has the correct notion of a datacenter, so if talking to
    # an ESXi assume it is called ha-datacenter instead.
    dc = datacenter if 'vCenter' in server.get_server_type(
    ) else 'ha-datacenter'
    datacenter_props = _get_datacenter_props(server, dc)
    nic.set_element_backing(create_nic_backing(server, vlan, datacenter_props))

    # Submit reconfig request
    # Copy/paste from pysphere mailinglist
    request = VI.ReconfigVM_TaskRequestMsg()
    _this = request.new__this(vm)
    _this.set_attribute_type(vm.get_attribute_type())
    request.set_element__this(_this)
    spec = request.new_spec()
    dev_change = spec.new_deviceChange()
    dev_change.set_element_device(nic)
    dev_change.set_element_operation('edit')
    spec.set_element_deviceChange([dev_change])
    request.set_element_spec(spec)

    ret = server._proxy.ReconfigVM_Task(request)._returnval
    task = pysphere.VITask(ret, server)
    status = task.wait_for_state([task.STATE_SUCCESS, task.STATE_ERROR])
    if task.get_state() == task.STATE_ERROR:
        raise ProvisionVmError(task.get_error_message())
예제 #4
0
def _vlan_to_network(server, vlan, datacenter):
    """Given a numeric VLAN, resolve to network name."""
    # Fetch VLAN -> network label map
    hosts = server._retrieve_properties_traversal(
        property_names=('name', ),
        obj_type='HostSystem',
        from_node=datacenter.hostFolder._obj)
    if not hosts:
        raise NoHostsInClusterError('Datacenter %s has no hosts' %
                                    datacenter.name)
    prop = pysphere.VIProperty(server, hosts[0].Obj)

    network_info = prop.configManager.networkSystem.networkInfo

    # This doesn't work if we have the same VLAN in multiple switches
    vlan_map = {
        pg.spec.vlanId: pg.spec.name
        for pg in network_info.portgroup
        if pg.spec.name != 'Management Network'
    }

    if vlan not in vlan_map:
        raise UnknownVlanError('VLAN %d not found in any networks' % vlan)

    return vlan_map[vlan]
예제 #5
0
def get_server_fqdn(server):
    """Extract server's configured fqdn."""
    host = next(server.get_hosts().iterkeys())
    prop = pysphere.VIProperty(server, host)
    # Prop is a "HostSystem"
    # http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/vim.HostSystem.html
    dnsconfig = prop.config.network.dnsConfig
    return dnsconfig.hostName + '.' + dnsconfig.domainName
예제 #6
0
def _get_datacenter_props(server, datacenter):
    if datacenter is None:
        datacenter = server.get_datacenters().values()[0]
    for k, v in server.get_datacenters().iteritems():
        if v == datacenter:
            return pysphere.VIProperty(server, k)
    raise DatacenterNotFoundError('Found no datacenter named "%s"' %
                                  datacenter)
예제 #7
0
def get_server_ip(server):
    """Extract server's configured IP."""
    host = next(server.get_hosts().iterkeys())
    prop = pysphere.VIProperty(server, host)
    # Prop is a "HostSystem"
    # http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/vim.HostSystem.html
    # TODO soundgoof quick and dirty fix for edgecase for esxi00 mgmt
    if prop.config.network.vnic[0].spec.ip.ipAddress.startswith('169'):
        return prop.config.network.vnic[1].spec.ip.ipAddress
    return prop.config.network.vnic[0].spec.ip.ipAddress
예제 #8
0
def _get_first_active_cluster(server, datacenter):
    """Given a server, return the first active cluster."""
    compute_resources = server._retrieve_properties_traversal(
        property_names=('name', 'host'),
        obj_type='ComputeResource',
        from_node=datacenter.hostFolder._obj)
    for compute_resource in compute_resources:
        compute_resource_props = pysphere.VIProperty(server,
                                                     compute_resource.Obj)
        if compute_resource_props.summary.numEffectiveHosts > 0:
            break
    else:
        raise NoHostsInClusterError(
            'Tried to create VM, but no available clusters could be found')
    return compute_resource_props
예제 #9
0
def add_host_to_dvs(server, host, datacenter, switch, interface):
    """Add given interface on a host to a dvSwitch."""
    host_mor = next(m for m, h in server.get_hosts().iteritems() if h == host)

    netfolder = pysphere.VIProperty(server, datacenter).networkFolder._obj
    dvswitch_resources = server._retrieve_properties_traversal(
        property_names=['config', 'name'],
        from_node=netfolder,
        obj_type='DistributedVirtualSwitch')

    version = None
    for dvswitch in dvswitch_resources:
        name = next(p.Val for p in dvswitch.PropSet if p.Name == 'name')
        config = next(p.Val for p in dvswitch.PropSet if p.Name == 'config')
        if name == switch:
            version = config.get_element_configVersion()
            break
    else:
        raise CreateDvSwitchError('Switch %s not found' % switch)

    request = VI.ReconfigureDvs_TaskRequestMsg()
    _this = request.new__this(dvswitch._obj)
    _this.set_attribute_type(dvswitch._obj.get_attribute_type())
    request.set_element__this(_this)

    spec = VI.ns0.VMwareDVSConfigSpec_Def('spec').pyclass()
    spec.ConfigVersion = version
    host_spec = spec.new_host()

    backing = VI.ns0.DistributedVirtualSwitchHostMemberPnicBacking_Def(
        'backing').pyclass()
    pnic_spec = backing.new_pnicSpec()
    pnic_spec.PnicDevice = interface
    backing.set_element_pnicSpec([pnic_spec])

    host_spec.Backing = backing
    host_spec.Host = host_mor
    host_spec.Operation = 'add'

    spec.set_element_host([host_spec])
    request.set_element_spec(spec)
    task = server._proxy.ReconfigureDvs_Task(request)._returnval
    vi_task = pysphere.VITask(task, server)
    status = vi_task.wait_for_state(
        [vi_task.STATE_SUCCESS, vi_task.STATE_ERROR])
    if status == vi_task.STATE_ERROR:
        raise CreateDvSwitchError(vi_task.get_error_message())
예제 #10
0
def get_or_create_cluster(vcenter, datacenter, cluster):
    """Retrieve (or create) a given cluster."""
    for folder, name in vcenter.get_clusters().iteritems():
        if name == cluster:
            return folder
    cluster_folder = pysphere.VIProperty(vcenter, datacenter).hostFolder._obj
    request = VI.CreateClusterRequestMsg()
    _this = request.new__this(cluster_folder)
    _this.set_attribute_type(cluster_folder.get_attribute_type())
    request.set_element__this(_this)
    request.set_element_name(cluster)
    spec = request.new_spec()
    drsConfig = spec.new_drsConfig()
    drsConfig.Enabled = True
    drsConfig.DefaultVmBehavior = 'fullyAutomated'
    spec.set_element_drsConfig(drsConfig)
    request.set_element_spec(spec)
    return vcenter._proxy.CreateCluster(request)._returnval
예제 #11
0
def get_ssl_thumbprint(server):
    """Calculate the SSL thumbprint for a given server."""
    # Source: https://groups.google.com/forum/#!topic/pysphere/rio7h8nWDcw
    host = next(server.get_hosts().iterkeys())
    prop = pysphere.VIProperty(server, host)
    # Prop is a "HostSystem"
    # http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.wssdk.apiref.doc/vim.HostSystem.html
    cert = ''.join(chr(x) for x in prop.config.certificate)
    # Remove --BEGIN CERTIFICATE-- and --END CERTIFICATE--
    cert = ''.join(x for x in cert.split('\n')
                   if not x.startswith('--')).strip()
    cert_decode = base64.decodestring(cert)
    cert_digest = hashlib.sha1(cert_decode).hexdigest()

    # SSL Thumbprint MUST be uppercase for VMware use
    ssl_thumbprint = ':'.join(cert_digest[i:i + 2]
                              for i in range(0, len(cert_digest), 2))
    return ssl_thumbprint.upper()
예제 #12
0
def create_dvs_portgroup(server, datacenter, switch, name_vlan_map):
    """Create a new DVS."""
    netfolder = pysphere.VIProperty(server, datacenter).networkFolder._obj
    dvswitch_resources = server._retrieve_properties_traversal(
        property_names=['name'],
        from_node=netfolder,
        obj_type='DistributedVirtualSwitch')

    for dvswitch in dvswitch_resources:
        name = next(p.Val for p in dvswitch.PropSet if p.Name == 'name')
        if name == switch:
            break
    else:
        raise CreateDvSwitchError('Switch %s not found' % switch)

    request = VI.AddDVPortgroup_TaskRequestMsg()
    _this = request.new__this(dvswitch._obj)
    _this.set_attribute_type(dvswitch._obj.get_attribute_type())
    request.set_element__this(_this)

    specs = []
    for name, vlan_id in name_vlan_map.iteritems():
        if vlan_id is None:
            continue
        spec = request.new_spec()
        spec.Name = name
        spec.Type = 'earlyBinding'
        spec.NumPorts = 0
        vlan = VI.ns0.VmwareDistributedVirtualSwitchVlanIdSpec_Def(
            'vlan').pyclass()
        vlan.Inherited = False
        vlan.VlanId = vlan_id
        port_config = VI.ns0.VMwareDVSPortSetting_Def('port_config').pyclass()
        port_config.Vlan = vlan
        spec.DefaultPortConfig = port_config
        specs.append(spec)

    request.set_element_spec(specs)
    task = server._proxy.AddDVPortgroup_Task(request)._returnval
    vi_task = pysphere.VITask(task, server)
    status = vi_task.wait_for_state(
        [vi_task.STATE_SUCCESS, vi_task.STATE_ERROR])
    if status == vi_task.STATE_ERROR:
        raise CreateDvPortgroupError(vi_task.get_error_message())