@Override public List<ManagedObjectReference> addHostToPodCluster( VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath) throws Exception { ManagedObjectReference mor = null; if (serviceContext != null) { mor = serviceContext.getHostMorByPath(hostInventoryPath); } String privateTrafficLabel = null; privateTrafficLabel = serviceContext.getStockObject("privateTrafficLabel"); if (privateTrafficLabel == null) { privateTrafficLabel = _privateNetworkVSwitchName; } if (mor != null) { List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>(); if (mor.getType().equals("ComputeResource")) { List<ManagedObjectReference> hosts = (List<ManagedObjectReference>) serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (hosts != null && hosts.size() > 0); // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, hosts.get(0)); prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(hosts.get(0)); return returnedHostList; } else if (mor.getType().equals("ClusterComputeResource")) { List<ManagedObjectReference> hosts = (List<ManagedObjectReference>) serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert (hosts != null); if (hosts.size() > 0) { AboutInfo about = (AboutInfo) (serviceContext .getVimClient() .getDynamicProperty(hosts.get(0), "config.product")); String version = about.getApiVersion(); int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(HypervisorType.VMware, version); if (hosts.size() > maxHostsPerCluster) { String msg = "Failed to add VMware cluster as size is too big, current size: " + hosts.size() + ", max. size: " + maxHostsPerCluster; s_logger.error(msg); throw new DiscoveredWithErrorException(msg); } } for (ManagedObjectReference morHost : hosts) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, morHost); prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(morHost); } return returnedHostList; } else if (mor.getType().equals("HostSystem")) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, mor); prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(mor); return returnedHostList; } else { s_logger.error( "Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); return null; } } s_logger.error("Unable to find host from inventory path: " + hostInventoryPath); return null; }
@Override public Map<? extends ServerResource, Map<String, String>> find( long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException { if (s_logger.isInfoEnabled()) s_logger.info( "Discover host. dc: " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + url.getHost()); if (podId == null) { if (s_logger.isInfoEnabled()) s_logger.info( "No pod is assigned, assuming that it is not for vmware and skip it to next discoverer"); return null; } ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null || cluster.getHypervisorType() != HypervisorType.VMware) { if (s_logger.isInfoEnabled()) s_logger.info("invalid cluster id or cluster is not for VMware hypervisors"); return null; } List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId); if (hosts != null && hosts.size() > 0) { int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster( hosts.get(0).getHypervisorType(), hosts.get(0).getHypervisorVersion()); if (hosts.size() > maxHostsPerCluster) { String msg = "VMware cluster " + cluster.getName() + " is too big to add new host now. (current configured cluster size: " + maxHostsPerCluster + ")"; s_logger.error(msg); throw new DiscoveredWithErrorException(msg); } } String privateTrafficLabel = null; String publicTrafficLabel = null; String guestTrafficLabel = null; Map<String, String> vsmCredentials = null; VirtualSwitchType defaultVirtualSwitchType = VirtualSwitchType.StandardVirtualSwitch; String paramGuestVswitchType = null; String paramGuestVswitchName = null; String paramPublicVswitchType = null; String paramPublicVswitchName = null; VmwareTrafficLabel guestTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Guest); VmwareTrafficLabel publicTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Public); Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId); DataCenterVO zone = _dcDao.findById(dcId); NetworkType zoneType = zone.getNetworkType(); _readGlobalConfigParameters(); // Set default physical network end points for public and guest traffic // Private traffic will be only on standard vSwitch for now. if (useDVS) { // Parse url parameters for type of vswitch and name of vswitch specified at cluster level paramGuestVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC); paramGuestVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC); paramPublicVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC); paramPublicVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC); defaultVirtualSwitchType = getDefaultVirtualSwitchType(); } // Zone level vSwitch Type depends on zone level traffic labels // // User can override Zone wide vswitch type (for public and guest) by providing following // optional parameters in addClusterCmd // param "guestvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs // param "publicvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs // // Format of label is <VSWITCH>,<VLANID>,<VSWITCHTYPE> // If a field <VLANID> OR <VSWITCHTYPE> is not present leave it empty. // Ex: 1) vswitch0 // 2) dvswitch0,200,vmwaredvs // 3) nexusepp0,300,nexusdvs // 4) vswitch1,400,vmwaresvs // 5) vswitch0 // default vswitchtype is 'vmwaresvs'. // <VSWITCHTYPE> 'vmwaresvs' is for vmware standard vswitch // <VSWITCHTYPE> 'vmwaredvs' is for vmware distributed virtual switch // <VSWITCHTYPE> 'nexusdvs' is for cisco nexus distributed virtual switch // Get zone wide traffic labels for Guest traffic and Public traffic guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware); // Process traffic label information provided at zone level and cluster level guestTrafficLabelObj = getTrafficInfo( TrafficType.Guest, guestTrafficLabel, defaultVirtualSwitchType, paramGuestVswitchType, paramGuestVswitchName, clusterId); if (zoneType == NetworkType.Advanced) { // Get zone wide traffic label for Public traffic publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware); // Process traffic label information provided at zone level and cluster level publicTrafficLabelObj = getTrafficInfo( TrafficType.Public, publicTrafficLabel, defaultVirtualSwitchType, paramPublicVswitchType, paramPublicVswitchName, clusterId); // Configuration Check: A physical network cannot be shared by different types of virtual // switches. // // Check if different vswitch types are chosen for same physical network // 1. Get physical network for guest traffic - multiple networks // 2. Get physical network for public traffic - single network // See if 2 is in 1 // if no - pass // if yes - compare publicTrafficLabelObj.getVirtualSwitchType() == // guestTrafficLabelObj.getVirtualSwitchType() // true - pass // false - throw exception - fail cluster add operation List<? extends PhysicalNetwork> pNetworkListGuestTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Guest); List<? extends PhysicalNetwork> pNetworkListPublicTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Public); // Public network would be on single physical network hence getting first object of the list // would suffice. PhysicalNetwork pNetworkPublic = pNetworkListPublicTraffic.get(0); if (pNetworkListGuestTraffic.contains(pNetworkPublic)) { if (publicTrafficLabelObj.getVirtualSwitchType() != guestTrafficLabelObj.getVirtualSwitchType()) { String msg = "Both public traffic and guest traffic is over same physical network " + pNetworkPublic + ". And virtual switch type chosen for each traffic is different" + ". A physical network cannot be shared by different types of virtual switches."; s_logger.error(msg); throw new InvalidParameterValueException(msg); } } } else { // Distributed virtual switch is not supported in Basic zone for now. // Private / Management network traffic is not yet supported over distributed virtual switch. if (guestTrafficLabelObj.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) { String msg = "Detected that Guest traffic is over Distributed virtual switch in Basic zone. Only Standard vSwitch is supported in Basic zone."; s_logger.error(msg); throw new DiscoveredWithErrorException(msg); } } privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware); if (privateTrafficLabel != null) { s_logger.info("Detected private network label : " + privateTrafficLabel); } if (nexusDVS) { if (zoneType != NetworkType.Basic) { publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware); if (publicTrafficLabel != null) { s_logger.info("Detected public network label : " + publicTrafficLabel); } } // Get physical network label guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware); if (guestTrafficLabel != null) { s_logger.info("Detected guest network label : " + guestTrafficLabel); } vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId); } VmwareContext context = null; try { context = VmwareContextFactory.create(url.getHost(), username, password); if (privateTrafficLabel != null) context.registerStockObject("privateTrafficLabel", privateTrafficLabel); if (nexusDVS) { if (vsmCredentials != null) { s_logger.info("Stocking credentials of Nexus VSM"); context.registerStockObject("vsmcredentials", vsmCredentials); } } List<ManagedObjectReference> morHosts = _vmwareMgr.addHostToPodCluster( context, dcId, podId, clusterId, URLDecoder.decode(url.getPath())); if (morHosts == null) s_logger.info("Found 0 hosts."); if (privateTrafficLabel != null) context.uregisterStockObject("privateTrafficLabel"); if (morHosts == null) { s_logger.error( "Unable to find host or cluster based on url: " + URLDecoder.decode(url.getPath())); return null; } ManagedObjectReference morCluster = null; clusterDetails = _clusterDetailsDao.findDetails(clusterId); if (clusterDetails.get("url") != null) { URI uriFromCluster = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url"))); morCluster = context.getHostMorByPath(URLDecoder.decode(uriFromCluster.getPath())); if (morCluster == null || !morCluster.getType().equalsIgnoreCase("ClusterComputeResource")) { s_logger.warn( "Cluster url does not point to a valid vSphere cluster, url: " + clusterDetails.get("url")); return null; } else { ClusterMO clusterMo = new ClusterMO(context, morCluster); ClusterDasConfigInfo dasConfig = clusterMo.getDasConfig(); if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) { clusterDetails.put("NativeHA", "true"); _clusterDetailsDao.persist(clusterId, clusterDetails); } } } if (!validateDiscoveredHosts(context, morCluster, morHosts)) { if (morCluster == null) s_logger.warn( "The discovered host is not standalone host, can not be added to a standalone cluster"); else s_logger.warn("The discovered host does not belong to the cluster"); return null; } Map<VmwareResource, Map<String, String>> resources = new HashMap<VmwareResource, Map<String, String>>(); for (ManagedObjectReference morHost : morHosts) { Map<String, String> details = new HashMap<String, String>(); Map<String, Object> params = new HashMap<String, Object>(); HostMO hostMo = new HostMO(context, morHost); details.put("url", hostMo.getHostName()); details.put("username", username); details.put("password", password); String guid = morHost.getType() + ":" + morHost.getValue() + "@" + url.getHost(); details.put("guid", guid); params.put("url", hostMo.getHostName()); params.put("username", username); params.put("password", password); params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); params.put("cluster", Long.toString(clusterId)); params.put("guid", guid); if (privateTrafficLabel != null) { params.put("private.network.vswitch.name", privateTrafficLabel); } params.put("guestTrafficInfo", guestTrafficLabelObj); params.put("publicTrafficInfo", publicTrafficLabelObj); VmwareResource resource = new VmwareResource(); try { resource.configure("VMware", params); } catch (ConfigurationException e) { _alertMgr.sendAlert( AlertManager.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage()); s_logger.warn("Unable to instantiate " + url.getHost(), e); } resource.start(); resources.put(resource, details); } // place a place holder guid derived from cluster ID cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes()).toString()); _clusterDao.update(clusterId, cluster); return resources; } catch (DiscoveredWithErrorException e) { throw e; } catch (Exception e) { s_logger.warn( "Unable to connect to Vmware vSphere server. service address: " + url.getHost()); return null; } finally { if (context != null) context.close(); } }
@Override public List<ManagedObjectReference> addHostToPodCluster( VmwareContext serviceContext, long dcId, Long podId, Long clusterId, String hostInventoryPath) throws Exception { ManagedObjectReference mor = serviceContext.getHostMorByPath(hostInventoryPath); if (mor != null) { List<ManagedObjectReference> returnedHostList = new ArrayList<ManagedObjectReference>(); if (mor.getType().equals("ComputeResource")) { ManagedObjectReference[] hosts = (ManagedObjectReference[]) serviceContext.getServiceUtil().getDynamicProperty(mor, "host"); assert (hosts != null); // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, hosts[0]); HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO(); if (firewallMo != null) { firewallMo.enableRuleset("vncServer"); firewallMo.refreshFirewall(); } // prepare at least one network on the vswitch to enable OVF importing String managementPortGroupName = hostMo.getPortGroupNameByNicType(HostVirtualNicType.management); assert (managementPortGroupName != null); HostPortGroupSpec spec = hostMo.getPortGroupSpec(managementPortGroupName); Integer vlanId = null; if (spec.getVlanId() != 0) { vlanId = spec.getVlanId(); } HypervisorHostHelper.preparePrivateNetwork( _privateNetworkVSwitchName, hostMo, vlanId, 180000); returnedHostList.add(hosts[0]); return returnedHostList; } else if (mor.getType().equals("ClusterComputeResource")) { ManagedObjectReference[] hosts = (ManagedObjectReference[]) serviceContext.getServiceUtil().getDynamicProperty(mor, "host"); assert (hosts != null); if (hosts.length > _maxHostsPerCluster) { String msg = "vCenter cluster size is too big (current configured cluster size: " + _maxHostsPerCluster + ")"; s_logger.error(msg); throw new DiscoveredWithErrorException(msg); } for (ManagedObjectReference morHost : hosts) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, morHost); HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO(); if (firewallMo != null) { firewallMo.enableRuleset("vncServer"); firewallMo.refreshFirewall(); } String managementPortGroupName = hostMo.getPortGroupNameByNicType(HostVirtualNicType.management); assert (managementPortGroupName != null); HostPortGroupSpec spec = hostMo.getPortGroupSpec(managementPortGroupName); Integer vlanId = null; if (spec.getVlanId() != 0) { vlanId = spec.getVlanId(); } // prepare at least one network on the vswitch to enable OVF importing HypervisorHostHelper.preparePrivateNetwork( _privateNetworkVSwitchName, hostMo, vlanId, 180000); returnedHostList.add(morHost); } return returnedHostList; } else if (mor.getType().equals("HostSystem")) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, mor); HostFirewallSystemMO firewallMo = hostMo.getHostFirewallSystemMO(); if (firewallMo != null) { firewallMo.enableRuleset("vncServer"); firewallMo.refreshFirewall(); } String managementPortGroupName = hostMo.getPortGroupNameByNicType(HostVirtualNicType.management); assert (managementPortGroupName != null); HostPortGroupSpec spec = hostMo.getPortGroupSpec(managementPortGroupName); Integer vlanId = null; if (spec.getVlanId() != 0) { vlanId = spec.getVlanId(); } // prepare at least one network on the vswitch to enable OVF importing HypervisorHostHelper.preparePrivateNetwork( _privateNetworkVSwitchName, hostMo, vlanId, 180000); returnedHostList.add(mor); return returnedHostList; } else { s_logger.error( "Unsupport host type " + mor.getType() + ":" + mor.get_value() + " from inventory path: " + hostInventoryPath); return null; } } s_logger.error("Unable to find host from inventory path: " + hostInventoryPath); return null; }