/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.service.vmware;
import static com.emc.sa.service.ServiceParams.DATACENTER;
import static com.emc.sa.service.ServiceParams.HOST;
import static com.emc.sa.service.ServiceParams.VCENTER;
import java.net.URI;
import java.util.List;
import java.util.Set;
import com.emc.sa.engine.ExecutionUtils;
import com.emc.sa.engine.bind.Param;
import com.emc.sa.service.vipr.ViPRService;
import com.emc.sa.service.vipr.block.BlockStorageUtils;
import com.emc.storageos.db.client.model.Cluster;
import com.emc.storageos.db.client.model.DiscoveredDataObject;
import com.emc.storageos.db.client.model.Host;
import com.emc.storageos.db.client.model.VcenterDataCenter;
import com.google.common.collect.Sets;
import com.vmware.vim25.mo.ClusterComputeResource;
import com.vmware.vim25.mo.HostSystem;
public abstract class VMwareHostService extends ViPRService {
@Param(VCENTER)
protected URI vcenterId;
@Param(DATACENTER)
protected URI datacenterId;
@Param(HOST)
protected URI hostId;
protected VMwareSupport vmware = new VMwareSupport();
protected VcenterDataCenter datacenter;
protected Host esxHost;
protected Cluster hostCluster;
protected HostSystem host;
protected ClusterComputeResource cluster;
public boolean checkClusterConnectivity() {
return true;
}
private void initHost() {
datacenter = vmware.getDatacenter(datacenterId);
if (BlockStorageUtils.isHost(hostId)) {
esxHost = getModelClient().hosts().findById(hostId);
if (esxHost == null) {
throw new IllegalArgumentException("Host " + hostId + " not found");
}
logInfo("vmware.service.target.host", esxHost.getLabel());
} else {
hostCluster = getModelClient().clusters().findById(hostId);
if (hostCluster == null) {
throw new IllegalArgumentException("Cluster " + hostId + " not found");
}
List<Host> hosts = getModelClient().hosts().findByCluster(hostId);
if (hosts.isEmpty()) {
throw new IllegalArgumentException("Cluster '" + hostCluster.getLabel() + "' [" + hostId
+ "] contains no hosts");
}
cluster = vmware.getCluster(datacenter.getLabel(), hostCluster.getLabel(), checkClusterConnectivity());
esxHost = getConnectedHost(hosts, datacenter);
if (esxHost == null) {
throw new IllegalArgumentException("Cluster '" + hostCluster.getLabel() + "' [" + hostId
+ "] does not contain any connected hosts");
}
logInfo("vmware.service.target.cluster", hostCluster.getLabel(), hosts.size());
}
host = vmware.getHostSystem(datacenter.getLabel(), esxHost.getLabel(), true);
}
/**
* Get the first connected host from the given set of hosts
*
* @param hosts list of hosts
* @param datacenter the datacenter the hosts belong to
* @return connected host or null if no hosts are connected
*/
protected Host getConnectedHost(List<Host> hosts, VcenterDataCenter datacenter) {
for (Host host : hosts) {
HostSystem esxHost = null;
esxHost = vmware.getHostSystem(datacenter.getLabel(), host.getLabel(), false);
if (VMwareSupport.isHostConnected(esxHost)) {
return host;
}
}
return null;
}
protected void connectAndInitializeHost() {
vmware.connect(vcenterId);
initHost();
}
@Override
public void precheck() throws Exception {
super.precheck();
connectAndInitializeHost();
validateClusterHosts();
}
@Override
public void destroy() {
super.destroy();
vmware.disconnect();
}
protected void acquireHostLock() {
acquireHostLock(esxHost, hostCluster);
}
/**
* Validates the vCenter cluster hosts match the same hosts we have in our database for the cluster. If there is a mismatch the check
* will fail the order.
*/
protected void validateClusterHosts() {
if (hostCluster != null) {
VcenterDataCenter datacenter = getModelClient().datacenters().findById(datacenterId);
Cluster cluster = getModelClient().clusters().findById(hostCluster.getId());
ClusterComputeResource vcenterCluster = vmware.getCluster(datacenter.getLabel(), cluster.getLabel(),
checkClusterConnectivity());
if (vcenterCluster == null) {
ExecutionUtils.fail("failTask.vmware.cluster.notfound", args(), args(cluster.getLabel()));
}
Set<String> vCenterHostUuids = Sets.newHashSet();
for (HostSystem hostSystem : vcenterCluster.getHosts()) {
if (hostSystem.getHardware() != null && hostSystem.getHardware().systemInfo != null) {
vCenterHostUuids.add(hostSystem.getHardware().systemInfo.uuid);
}
}
List<Host> dbHosts = getModelClient().hosts().findByCluster(hostCluster.getId());
Set<String> dbHostUuids = Sets.newHashSet();
for (Host host : dbHosts) {
// Validate the hosts within the cluster all have good discovery status
if (!DiscoveredDataObject.CompatibilityStatus.COMPATIBLE.toString().equalsIgnoreCase(host.getCompatibilityStatus())) {
ExecutionUtils.fail("failTask.vmware.cluster.hostincompatible", args(), args(cluster.getLabel(), host.getLabel()));
} else if (DiscoveredDataObject.DataCollectionJobStatus.ERROR.toString().equalsIgnoreCase(host.getDiscoveryStatus())) {
ExecutionUtils.fail("failTask.vmware.cluster.hostsdiscoveryfailed", args(), args(cluster.getLabel(), host.getLabel()));
}
dbHostUuids.add(host.getUuid());
}
if (!vCenterHostUuids.equals(dbHostUuids)) {
ExecutionUtils.fail("failTask.vmware.cluster.mismatch", args(), args(cluster.getLabel()));
} else {
info("Hosts in cluster %s matches correctly", cluster.getLabel());
}
}
}
}