Search in sources :

Example 21 with DiscoveryException

use of com.cloud.exception.DiscoveryException in project cloudstack by apache.

the class OvmDiscoverer method find.

@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 {
    Connection conn = null;
    if (!url.getScheme().equals("http")) {
        String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
        s_logger.debug(msg);
        return null;
    }
    if (clusterId == null) {
        String msg = "must specify cluster Id when add host";
        s_logger.debug(msg);
        throw new CloudRuntimeException(msg);
    }
    if (podId == null) {
        String msg = "must specify pod Id when add host";
        s_logger.debug(msg);
        throw new CloudRuntimeException(msg);
    }
    ClusterVO cluster = _clusterDao.findById(clusterId);
    if (cluster == null || (cluster.getHypervisorType() != HypervisorType.Ovm)) {
        if (s_logger.isInfoEnabled())
            s_logger.info("invalid cluster id or cluster is not for Ovm hypervisors");
        return null;
    }
    String agentUsername = _params.get("agentusername");
    if (agentUsername == null) {
        throw new CloudRuntimeException("Agent user name must be specified");
    }
    String agentPassword = _params.get("agentpassword");
    if (agentPassword == null) {
        throw new CloudRuntimeException("Agent password must be specified");
    }
    try {
        String hostname = url.getHost();
        InetAddress ia = InetAddress.getByName(hostname);
        String hostIp = ia.getHostAddress();
        String guid = UUID.nameUUIDFromBytes(hostIp.getBytes()).toString();
        if (checkIfExisted(guid)) {
            throw new CloudRuntimeException("The host " + hostIp + " has been added before");
        }
        s_logger.debug("Ovm discover is going to disover host having guid " + guid);
        ClusterVO clu = _clusterDao.findById(clusterId);
        if (clu.getGuid() == null) {
            clu.setGuid(UUID.randomUUID().toString());
            _clusterDao.update(clusterId, clu);
        }
        com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(hostIp, 22);
        sshConnection.connect(null, 60000, 60000);
        sshConnection = SSHCmdHelper.acquireAuthorizedConnection(hostIp, username, password);
        if (sshConnection == null) {
            throw new DiscoveryException(String.format("Cannot connect to ovm host(IP=%1$s, username=%2$s, password=%3$s, discover failed", hostIp, username, password));
        }
        if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "[ -f '/etc/ovs-agent/agent.ini' ]")) {
            throw new DiscoveryException("Can not find /etc/ovs-agent/agent.ini " + hostIp);
        }
        Map<String, String> details = new HashMap<String, String>();
        OvmResourceBase ovmResource = new OvmResourceBase();
        details.put("ip", hostIp);
        details.put("username", username);
        details.put("password", password);
        details.put("zone", Long.toString(dcId));
        details.put("guid", guid);
        details.put("pod", Long.toString(podId));
        details.put("cluster", Long.toString(clusterId));
        details.put("agentusername", agentUsername);
        details.put("agentpassword", agentPassword);
        if (_publicNetworkDevice != null) {
            details.put("public.network.device", _publicNetworkDevice);
        }
        if (_privateNetworkDevice != null) {
            details.put("private.network.device", _privateNetworkDevice);
        }
        if (_guestNetworkDevice != null) {
            details.put("guest.network.device", _guestNetworkDevice);
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.putAll(details);
        ovmResource.configure("Ovm Server", params);
        ovmResource.start();
        conn = new Connection(hostIp, "oracle", agentPassword);
        /* After resource start, we are able to execute our agent api */
        OvmHost.Details d = OvmHost.getDetails(conn);
        details.put("agentVersion", d.agentVersion);
        details.put(HostInfo.HOST_OS_KERNEL_VERSION, d.dom0KernelVersion);
        details.put(HostInfo.HYPERVISOR_VERSION, d.hypervisorVersion);
        Map<OvmResourceBase, Map<String, String>> resources = new HashMap<OvmResourceBase, Map<String, String>>();
        resources.put(ovmResource, details);
        return resources;
    } catch (XmlRpcException e) {
        s_logger.debug("XmlRpc exception, Unable to discover OVM: " + url, e);
        return null;
    } catch (UnknownHostException e) {
        s_logger.debug("Host name resolve failed exception, Unable to discover OVM: " + url, e);
        return null;
    } catch (ConfigurationException e) {
        s_logger.debug("Configure resource failed, Unable to discover OVM: " + url, e);
        return null;
    } catch (Exception e) {
        s_logger.debug("Unable to discover OVM: " + url, e);
        return null;
    }
}
Also used : ClusterVO(com.cloud.dc.ClusterVO) OvmHost(com.cloud.ovm.object.OvmHost) UnknownHostException(java.net.UnknownHostException) HashMap(java.util.HashMap) Connection(com.cloud.ovm.object.Connection) DiscoveryException(com.cloud.exception.DiscoveryException) ConfigurationException(javax.naming.ConfigurationException) XmlRpcException(org.apache.xmlrpc.XmlRpcException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnknownHostException(java.net.UnknownHostException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) InetAddress(java.net.InetAddress) DiscoveryException(com.cloud.exception.DiscoveryException) HashMap(java.util.HashMap) Map(java.util.Map) XmlRpcException(org.apache.xmlrpc.XmlRpcException)

Example 22 with DiscoveryException

use of com.cloud.exception.DiscoveryException in project cloudstack by apache.

the class BareMetalDiscoverer method find.

@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 {
    /* Enable this after we decide to use addBaremetalHostCmd instead of addHostCmd
        String discoverName = _params.get(ApiConstants.BAREMETAL_DISCOVER_NAME);
        if (!this.getClass().getName().equals(discoverName)) {
            return null;
        } */
    Map<BareMetalResourceBase, Map<String, String>> resources = new HashMap<BareMetalResourceBase, Map<String, String>>();
    Map<String, String> details = new HashMap<String, String>();
    if (!url.getScheme().equals("http")) {
        String msg = "urlString is not http so we're not taking care of the discovery for this: " + url;
        s_logger.debug(msg);
        return null;
    }
    if (clusterId == null) {
        String msg = "must specify cluster Id when add host";
        s_logger.debug(msg);
        throw new RuntimeException(msg);
    }
    if (podId == null) {
        String msg = "must specify pod Id when add host";
        s_logger.debug(msg);
        throw new RuntimeException(msg);
    }
    ClusterVO cluster = _clusterDao.findById(clusterId);
    if (cluster == null || (cluster.getHypervisorType() != HypervisorType.BareMetal)) {
        if (s_logger.isInfoEnabled())
            s_logger.info("invalid cluster id or cluster is not for Bare Metal hosts");
        return null;
    }
    DataCenterVO zone = _dcDao.findById(dcId);
    if (zone == null) {
        throw new RuntimeException("Cannot find zone " + dcId);
    }
    try {
        String hostname = url.getHost();
        InetAddress ia = InetAddress.getByName(hostname);
        String ipmiIp = ia.getHostAddress();
        String guid = UUID.nameUUIDFromBytes(ipmiIp.getBytes()).toString();
        String injectScript = "scripts/util/ipmi.py";
        String scriptPath = Script.findScript("", injectScript);
        if (scriptPath == null) {
            throw new CloudRuntimeException("Unable to find key ipmi script " + injectScript);
        }
        final Script2 command = new Script2(scriptPath, s_logger);
        command.add("ping");
        command.add("hostname=" + ipmiIp);
        command.add("usrname=" + username);
        command.add("password=" + password, ParamType.PASSWORD);
        final String result = command.execute();
        if (result != null) {
            s_logger.warn(String.format("Can not set up ipmi connection(ip=%1$s, username=%2$s, password=%3$s, args) because %4$s", ipmiIp, username, "******", result));
            return null;
        }
        ClusterVO clu = _clusterDao.findById(clusterId);
        if (clu.getGuid() == null) {
            clu.setGuid(UUID.randomUUID().toString());
            _clusterDao.update(clusterId, clu);
        }
        Map<String, Object> params = new HashMap<String, Object>();
        params.putAll(_params);
        params.put("zone", Long.toString(dcId));
        params.put("pod", Long.toString(podId));
        params.put("cluster", Long.toString(clusterId));
        params.put("guid", guid);
        params.put(ApiConstants.PRIVATE_IP, ipmiIp);
        params.put(ApiConstants.USERNAME, username);
        params.put(ApiConstants.PASSWORD, password);
        params.put("vmDao", _vmDao);
        params.put("configDao", _configDao);
        String resourceClassName = _configDao.getValue(Config.ExternalBaremetalResourceClassName.key());
        BareMetalResourceBase resource = null;
        if (resourceClassName != null) {
            Class<?> clazz = Class.forName(resourceClassName);
            resource = (BareMetalResourceBase) clazz.newInstance();
            String externalUrl = _configDao.getValue(Config.ExternalBaremetalSystemUrl.key());
            if (externalUrl == null) {
                throw new IllegalArgumentException(String.format("You must specify ExternalBaremetalSystemUrl in global config page as ExternalBaremetalResourceClassName is not null"));
            }
            details.put(BaremetalManager.ExternalBaremetalSystemUrl, externalUrl);
        } else {
            resource = new BareMetalResourceBase();
        }
        resource.configure("Bare Metal Agent", params);
        String memCapacity = (String) params.get(ApiConstants.MEMORY);
        String cpuCapacity = (String) params.get(ApiConstants.CPU_SPEED);
        String cpuNum = (String) params.get(ApiConstants.CPU_NUMBER);
        String mac = (String) params.get(ApiConstants.HOST_MAC);
        if (hostTags != null && hostTags.size() != 0) {
            details.put("hostTag", hostTags.get(0));
        }
        details.put(ApiConstants.MEMORY, memCapacity);
        details.put(ApiConstants.CPU_SPEED, cpuCapacity);
        details.put(ApiConstants.CPU_NUMBER, cpuNum);
        details.put(ApiConstants.HOST_MAC, mac);
        details.put(ApiConstants.USERNAME, username);
        details.put(ApiConstants.PASSWORD, password);
        details.put(ApiConstants.PRIVATE_IP, ipmiIp);
        String vmIp = (String) params.get(ApiConstants.IP_ADDRESS);
        if (vmIp != null) {
            details.put(ApiConstants.IP_ADDRESS, vmIp);
        }
        String isEchoScAgent = _configDao.getValue(Config.EnableBaremetalSecurityGroupAgentEcho.key());
        details.put(BaremetalManager.EchoSecurityGroupAgent, isEchoScAgent);
        resources.put(resource, details);
        resource.start();
        zone.setGatewayProvider(Network.Provider.ExternalGateWay.getName());
        zone.setDnsProvider(Network.Provider.ExternalDhcpServer.getName());
        zone.setDhcpProvider(Network.Provider.ExternalDhcpServer.getName());
        _dcDao.update(zone.getId(), zone);
        s_logger.debug(String.format("Discover Bare Metal host successfully(ip=%1$s, username=%2$s, password=%3%s," + "cpuNum=%4$s, cpuCapacity-%5$s, memCapacity=%6$s)", ipmiIp, username, "******", cpuNum, cpuCapacity, memCapacity));
        return resources;
    } catch (Exception e) {
        s_logger.warn("Can not set up bare metal agent", e);
    }
    return null;
}
Also used : DataCenterVO(com.cloud.dc.DataCenterVO) ClusterVO(com.cloud.dc.ClusterVO) HashMap(java.util.HashMap) Script2(com.cloud.utils.script.Script2) DiscoveryException(com.cloud.exception.DiscoveryException) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) BareMetalResourceBase(com.cloud.baremetal.networkservice.BareMetalResourceBase) HashMap(java.util.HashMap) Map(java.util.Map) InetAddress(java.net.InetAddress)

Example 23 with DiscoveryException

use of com.cloud.exception.DiscoveryException in project cloudstack by apache.

the class HypervServerDiscoverer method find.

// End Listener implementation
// Returns server component used by server manager to operate the plugin.
// Server component is a ServerResource. If a connected agent is used, the
// ServerResource is
// ignored in favour of another created in response to
@Override
public final Map<? extends ServerResource, Map<String, String>> find(final long dcId, final Long podId, final Long clusterId, final URI uri, final String username, final String password, final List<String> hostTags) throws DiscoveryException {
    if (s_logger.isInfoEnabled()) {
        s_logger.info("Discover host. dc(zone): " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + uri.getHost());
    }
    // Assertions
    if (podId == null) {
        if (s_logger.isInfoEnabled()) {
            s_logger.info("No pod is assigned, skipping the discovery in" + " Hyperv discoverer");
        }
        return null;
    }
    // ClusterVO exists
    ClusterVO cluster = _clusterDao.findById(clusterId);
    // database
    if (cluster == null) {
        if (s_logger.isInfoEnabled()) {
            s_logger.info("No cluster in database for cluster id " + clusterId);
        }
        return null;
    }
    if (cluster.getHypervisorType() != HypervisorType.Hyperv) {
        if (s_logger.isInfoEnabled()) {
            s_logger.info("Cluster " + clusterId + "is not for Hyperv hypervisors");
        }
        return null;
    }
    if (!uri.getScheme().equals("http")) {
        String msg = "urlString is not http so we're not taking care of" + " the discovery for this: " + uri;
        s_logger.debug(msg);
        return null;
    }
    try {
        String hostname = uri.getHost();
        InetAddress ia = InetAddress.getByName(hostname);
        String agentIp = ia.getHostAddress();
        String uuidSeed = agentIp;
        String guidWithTail = calcServerResourceGuid(uuidSeed) + "-HypervResource";
        if (_resourceMgr.findHostByGuid(guidWithTail) != null) {
            s_logger.debug("Skipping " + agentIp + " because " + guidWithTail + " is already in the database.");
            return null;
        }
        s_logger.info("Creating" + HypervDirectConnectResource.class.getName() + " HypervDummyResourceBase for zone/pod/cluster " + dcId + "/" + podId + "/" + clusterId);
        // This GUID may change.
        if (cluster.getGuid() == null) {
            cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes(Charset.forName("UTF-8"))).toString());
            _clusterDao.update(clusterId, cluster);
        }
        // Settings required by all server resources managing a hypervisor
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("zone", Long.toString(dcId));
        params.put("pod", Long.toString(podId));
        params.put("cluster", Long.toString(clusterId));
        params.put("guid", guidWithTail);
        params.put("ipaddress", agentIp);
        // Hyper-V specific settings
        Map<String, String> details = new HashMap<String, String>();
        details.put("url", uri.getHost());
        details.put("username", username);
        details.put("password", password);
        details.put("cluster.guid", cluster.getGuid());
        params.putAll(details);
        params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
        HypervDirectConnectResource resource = new HypervDirectConnectResource();
        resource.configure(agentIp, params);
        // Assert
        // TODO: test by using bogus URL and bogus virtual path in URL
        ReadyCommand ping = new ReadyCommand();
        Answer pingAns = resource.executeRequest(ping);
        if (pingAns == null || !pingAns.getResult()) {
            String errMsg = "Agent not running, or no route to agent on at " + uri;
            s_logger.debug(errMsg);
            throw new DiscoveryException(errMsg);
        }
        Map<HypervDirectConnectResource, Map<String, String>> resources = new HashMap<HypervDirectConnectResource, Map<String, String>>();
        resources.put(resource, details);
        // TODO: does the resource have to create a connection?
        return resources;
    } catch (ConfigurationException e) {
        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage());
        s_logger.warn("Unable to instantiate " + uri.getHost(), e);
    } catch (UnknownHostException e) {
        _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + uri.getHost(), "Error is " + e.getMessage());
        s_logger.warn("Unable to instantiate " + uri.getHost(), e);
    } catch (Exception e) {
        String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage();
        s_logger.warn(msg);
    }
    return null;
}
Also used : ClusterVO(com.cloud.dc.ClusterVO) UnknownHostException(java.net.UnknownHostException) HashMap(java.util.HashMap) DiscoveryException(com.cloud.exception.DiscoveryException) ConfigurationException(javax.naming.ConfigurationException) ConnectionException(com.cloud.exception.ConnectionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) OperationTimedoutException(com.cloud.exception.OperationTimedoutException) UnknownHostException(java.net.UnknownHostException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) SetupAnswer(com.cloud.agent.api.SetupAnswer) AgentControlAnswer(com.cloud.agent.api.AgentControlAnswer) Answer(com.cloud.agent.api.Answer) ReadyCommand(com.cloud.agent.api.ReadyCommand) ConfigurationException(javax.naming.ConfigurationException) InetAddress(java.net.InetAddress) DiscoveryException(com.cloud.exception.DiscoveryException) HashMap(java.util.HashMap) Map(java.util.Map) HypervDirectConnectResource(com.cloud.hypervisor.hyperv.resource.HypervDirectConnectResource)

Example 24 with DiscoveryException

use of com.cloud.exception.DiscoveryException in project cloudstack by apache.

the class ResourceManagerImpl method discoverCluster.

@DB
@Override
public List<? extends Cluster> discoverCluster(final AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException {
    final long dcId = cmd.getZoneId();
    final long podId = cmd.getPodId();
    final String clusterName = cmd.getClusterName();
    String url = cmd.getUrl();
    final String username = cmd.getUsername();
    final String password = cmd.getPassword();
    if (url != null) {
        url = URLDecoder.decode(url);
    }
    URI uri = null;
    // Check if the zone exists in the system
    final DataCenterVO zone = _dcDao.findById(dcId);
    if (zone == null) {
        final InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified");
        ex.addProxyObject(String.valueOf(dcId), "dcId");
        throw ex;
    }
    final Account account = CallContext.current().getCallingAccount();
    if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getId())) {
        final PermissionDeniedException ex = new PermissionDeniedException("Cannot perform this operation, Zone with specified id is currently disabled");
        ex.addProxyObject(zone.getUuid(), "dcId");
        throw ex;
    }
    final HostPodVO pod = _podDao.findById(podId);
    if (pod == null) {
        throw new InvalidParameterValueException("Can't find pod with specified podId " + podId);
    }
    // Check if the pod exists in the system
    if (_podDao.findById(podId) == null) {
        throw new InvalidParameterValueException("Can't find pod by id " + podId);
    }
    // check if pod belongs to the zone
    if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) {
        final InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId);
        ex.addProxyObject(pod.getUuid(), "podId");
        ex.addProxyObject(zone.getUuid(), "dcId");
        throw ex;
    }
    // Verify cluster information and create a new cluster if needed
    if (clusterName == null || clusterName.isEmpty()) {
        throw new InvalidParameterValueException("Please specify cluster name");
    }
    if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) {
        throw new InvalidParameterValueException("Please specify a hypervisor");
    }
    final Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor());
    if (hypervisorType == null) {
        s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type");
        throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported ");
    }
    if (zone.isSecurityGroupEnabled() && zone.getNetworkType().equals(NetworkType.Advanced)) {
        if (hypervisorType != HypervisorType.KVM && hypervisorType != HypervisorType.XenServer && hypervisorType != HypervisorType.LXC && hypervisorType != HypervisorType.Simulator) {
            throw new InvalidParameterValueException("Don't support hypervisor type " + hypervisorType + " in advanced security enabled zone");
        }
    }
    Cluster.ClusterType clusterType = null;
    if (cmd.getClusterType() != null && !cmd.getClusterType().isEmpty()) {
        clusterType = Cluster.ClusterType.valueOf(cmd.getClusterType());
    }
    if (clusterType == null) {
        clusterType = Cluster.ClusterType.CloudManaged;
    }
    Grouping.AllocationState allocationState = null;
    if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) {
        try {
            allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState());
        } catch (final IllegalArgumentException ex) {
            throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state");
        }
    }
    if (allocationState == null) {
        allocationState = Grouping.AllocationState.Enabled;
    }
    final Discoverer discoverer = getMatchingDiscover(hypervisorType);
    if (discoverer == null) {
        throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor());
    }
    if (hypervisorType == HypervisorType.VMware) {
        final Map<String, String> allParams = cmd.getFullUrlParams();
        discoverer.putParam(allParams);
    }
    final List<ClusterVO> result = new ArrayList<ClusterVO>();
    ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
    cluster.setHypervisorType(hypervisorType.toString());
    cluster.setClusterType(clusterType);
    cluster.setAllocationState(allocationState);
    try {
        cluster = _clusterDao.persist(cluster);
    } catch (final Exception e) {
        // no longer tolerate exception during the cluster creation phase
        final CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + " in pod and data center with specified ids", e);
        // Get the pod VO object's table name.
        ex.addProxyObject(pod.getUuid(), "podId");
        ex.addProxyObject(zone.getUuid(), "dcId");
        throw ex;
    }
    result.add(cluster);
    if (clusterType == Cluster.ClusterType.CloudManaged) {
        final Map<String, String> details = new HashMap<String, String>();
        // should do this nicer perhaps ?
        if (hypervisorType == HypervisorType.Ovm3) {
            final Map<String, String> allParams = cmd.getFullUrlParams();
            details.put("ovm3vip", allParams.get("ovm3vip"));
            details.put("ovm3pool", allParams.get("ovm3pool"));
            details.put("ovm3cluster", allParams.get("ovm3cluster"));
        }
        details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
        details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
        _clusterDetailsDao.persist(cluster.getId(), details);
        return result;
    }
    // save cluster details for later cluster/host cross-checking
    final Map<String, String> details = new HashMap<String, String>();
    details.put("url", url);
    details.put("username", username);
    details.put("password", password);
    details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
    details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
    _clusterDetailsDao.persist(cluster.getId(), details);
    boolean success = false;
    try {
        try {
            uri = new URI(UriUtils.encodeURIComponent(url));
            if (uri.getScheme() == null) {
                throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix");
            } else if (uri.getScheme().equalsIgnoreCase("http")) {
                if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) {
                    throw new InvalidParameterValueException("Your host and/or path is wrong.  Make sure it's of the format http://hostname/path");
                }
            }
        } catch (final URISyntaxException e) {
            throw new InvalidParameterValueException(url + " is not a valid uri");
        }
        final List<HostVO> hosts = new ArrayList<HostVO>();
        Map<? extends ServerResource, Map<String, String>> resources = null;
        resources = discoverer.find(dcId, podId, cluster.getId(), uri, username, password, null);
        if (resources != null) {
            for (final Map.Entry<? extends ServerResource, Map<String, String>> entry : resources.entrySet()) {
                final ServerResource resource = entry.getKey();
                final HostVO host = (HostVO) createHostAndAgent(resource, entry.getValue(), true, null, false);
                if (host != null) {
                    hosts.add(host);
                }
                discoverer.postDiscovery(hosts, _nodeId);
            }
            s_logger.info("External cluster has been successfully discovered by " + discoverer.getName());
            success = true;
            return result;
        }
        s_logger.warn("Unable to find the server resources at " + url);
        throw new DiscoveryException("Unable to add the external cluster");
    } finally {
        if (!success) {
            _clusterDetailsDao.deleteDetails(cluster.getId());
            _clusterDao.remove(cluster.getId());
        }
    }
}
Also used : Account(com.cloud.user.Account) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) HostPodVO(com.cloud.dc.HostPodVO) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DiscoveryException(com.cloud.exception.DiscoveryException) DataCenterVO(com.cloud.dc.DataCenterVO) ClusterVO(com.cloud.dc.ClusterVO) Hypervisor(com.cloud.hypervisor.Hypervisor) PodCluster(com.cloud.dc.PodCluster) Cluster(com.cloud.org.Cluster) Grouping(com.cloud.org.Grouping) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) AgentUnavailableException(com.cloud.exception.AgentUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ResourceInUseException(com.cloud.exception.ResourceInUseException) URISyntaxException(java.net.URISyntaxException) DiscoveryException(com.cloud.exception.DiscoveryException) SshException(com.cloud.utils.ssh.SshException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) StoragePoolHostVO(com.cloud.storage.StoragePoolHostVO) HostVO(com.cloud.host.HostVO) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) Map(java.util.Map) HashMap(java.util.HashMap) DB(com.cloud.utils.db.DB)

Example 25 with DiscoveryException

use of com.cloud.exception.DiscoveryException in project cloudstack by apache.

the class VmwareServerDiscoverer method find.

@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;
    }
    boolean failureInClusterDiscovery = true;
    String vsmIp = "";
    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;
    }
    Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
    boolean legacyZone = _vmwareMgr.isLegacyZone(dcId);
    boolean usernameNotProvided = (username == null || username.isEmpty());
    boolean passwordNotProvided = (password == null || password.isEmpty());
    //Check if NOT a legacy zone.
    if (!legacyZone) {
        // Retrieve VMware DC associated with specified zone
        VmwareDatacenterVO vmwareDc = fetchVmwareDatacenterByZone(dcId);
        // If either or both not provided, try to retrieve & use the credentials from database, which are provided earlier while adding VMware DC to zone.
        if (usernameNotProvided || passwordNotProvided) {
            // Retrieve credentials associated with VMware DC
            s_logger.info("Username and/or Password not provided while adding cluster to cloudstack zone. " + "Hence using both username & password provided while adding VMware DC to CloudStack zone.");
            username = vmwareDc.getUser();
            password = vmwareDc.getPassword();
            clusterDetails.put("username", username);
            clusterDetails.put("password", password);
            _clusterDetailsDao.persist(clusterId, clusterDetails);
        }
        String updatedInventoryPath = validateCluster(url, vmwareDc);
        try {
            if (!URLDecoder.decode(url.getPath(), "UTF-8").equals(updatedInventoryPath)) {
                // If url from API doesn't specify DC then update url in database with DC associated with this zone.
                clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath);
                _clusterDetailsDao.persist(clusterId, clusterDetails);
            }
        } catch (UnsupportedEncodingException e) {
            throw new DiscoveredWithErrorException("Unable to decode URL path, URL path : " + url.getPath(), e);
        }
    } else {
        // For legacy zones insist on the old model of asking for credentials for each cluster being added.
        if (usernameNotProvided) {
            if (passwordNotProvided) {
                throw new InvalidParameterValueException("Please provide username & password to add this cluster to zone");
            } else {
                throw new InvalidParameterValueException("Please provide username to add this cluster to zone");
            }
        } else if (passwordNotProvided) {
            throw new InvalidParameterValueException("Please provide password to add this cluster to zone");
        }
    }
    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, current size: " + hosts.size() + ", max. 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);
    DataCenterVO zone = _dcDao.findById(dcId);
    NetworkType zoneType = zone.getNetworkType();
    _readGlobalConfigParameters();
    // 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);
            }
        }
    }
    privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware);
    if (privateTrafficLabel != null) {
        s_logger.info("Detected private network label : " + privateTrafficLabel);
    }
    Pair<Boolean, Long> vsmInfo = new Pair<Boolean, Long>(false, 0L);
    if (nexusDVS && (guestTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) || ((zoneType == NetworkType.Advanced) && (publicTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch))) {
        // 2) Atleast 1 traffic type uses Nexus distributed virtual switch as backend.
        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);
        }
        // Before proceeding with validation of Nexus 1000v VSM check if an instance of Nexus 1000v VSM is already associated with this cluster.
        boolean clusterHasVsm = _vmwareMgr.hasNexusVSM(clusterId);
        if (!clusterHasVsm) {
            vsmIp = _urlParams.get("vsmipaddress");
            String vsmUser = _urlParams.get("vsmusername");
            String vsmPassword = _urlParams.get("vsmpassword");
            String clusterName = cluster.getName();
            try {
                vsmInfo = _nexusElement.validateAndAddVsm(vsmIp, vsmUser, vsmPassword, clusterId, clusterName);
            } catch (ResourceInUseException ex) {
                DiscoveryException discEx = new DiscoveryException(ex.getLocalizedMessage() + ". The resource is " + ex.getResourceName());
                throw discEx;
            }
        }
        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(), "UTF-8"));
        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(), "UTF-8"));
            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(), "UTF-8"));
            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);
                if (clusterMo.isHAEnabled()) {
                    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);
            params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
            VmwareResource resource = new VmwareResource();
            try {
                resource.configure("VMware", params);
            } catch (ConfigurationException e) {
                _alertMgr.sendAlert(AlertManager.AlertType.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
        try {
            cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes("UTF-8")).toString());
        } catch (UnsupportedEncodingException e) {
            throw new DiscoveredWithErrorException("Unable to create UUID based on string " + String.valueOf(clusterId) + ". Bad clusterId or UTF-8 encoding error.");
        }
        _clusterDao.update(clusterId, cluster);
        // Flag cluster discovery success
        failureInClusterDiscovery = false;
        return resources;
    } catch (DiscoveredWithErrorException e) {
        throw e;
    } catch (Exception e) {
        s_logger.warn("Unable to connect to Vmware vSphere server. service address: " + url.getHost() + ". " + e);
        return null;
    } finally {
        if (context != null)
            context.close();
        if (failureInClusterDiscovery && vsmInfo.first()) {
            try {
                s_logger.debug("Deleting Nexus 1000v VSM " + vsmIp + " because cluster discovery and addition to zone has failed.");
                _nexusElement.deleteCiscoNexusVSM(vsmInfo.second().longValue());
            } catch (Exception e) {
                s_logger.warn("Deleting Nexus 1000v VSM " + vsmIp + " failed.");
            }
        }
    }
}
Also used : VmwareTrafficLabel(com.cloud.network.VmwareTrafficLabel) VmwareResource(com.cloud.hypervisor.vmware.resource.VmwareResource) HashMap(java.util.HashMap) HostMO(com.cloud.hypervisor.vmware.mo.HostMO) ClusterMO(com.cloud.hypervisor.vmware.mo.ClusterMO) URI(java.net.URI) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) NetworkType(com.cloud.dc.DataCenter.NetworkType) PhysicalNetwork(com.cloud.network.PhysicalNetwork) ResourceInUseException(com.cloud.exception.ResourceInUseException) DiscoveryException(com.cloud.exception.DiscoveryException) Pair(com.cloud.utils.Pair) DataCenterVO(com.cloud.dc.DataCenterVO) ClusterVO(com.cloud.dc.ClusterVO) UnsupportedEncodingException(java.io.UnsupportedEncodingException) DiscoveredWithErrorException(com.cloud.exception.DiscoveredWithErrorException) HostVO(com.cloud.host.HostVO) DiscoveredWithErrorException(com.cloud.exception.DiscoveredWithErrorException) DiscoveryException(com.cloud.exception.DiscoveryException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) ResourceInUseException(com.cloud.exception.ResourceInUseException) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VirtualSwitchType(com.cloud.hypervisor.vmware.mo.VirtualSwitchType) Map(java.util.Map) HashMap(java.util.HashMap) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Aggregations

DiscoveryException (com.cloud.exception.DiscoveryException)29 HashMap (java.util.HashMap)15 ConfigurationException (javax.naming.ConfigurationException)14 ClusterVO (com.cloud.dc.ClusterVO)12 Map (java.util.Map)12 ResourceInUseException (com.cloud.exception.ResourceInUseException)9 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)9 ServerApiException (org.apache.cloudstack.api.ServerApiException)9 DataCenterVO (com.cloud.dc.DataCenterVO)6 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)6 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)6 HostVO (com.cloud.host.HostVO)6 InetAddress (java.net.InetAddress)6 ArrayList (java.util.ArrayList)6 ConnectionException (com.cloud.exception.ConnectionException)5 DiscoveredWithErrorException (com.cloud.exception.DiscoveredWithErrorException)5 UnableDeleteHostException (com.cloud.resource.UnableDeleteHostException)5 URISyntaxException (java.net.URISyntaxException)5 UnknownHostException (java.net.UnknownHostException)5 ServerApiException (com.cloud.api.ServerApiException)4