/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.hyperic.plugin.vrealize.automation;
import static com.vmware.hyperic.model.relations.RelationType.PARENT;
import static com.vmware.hyperic.model.relations.RelationType.SIBLING;
import static com.vmware.hyperic.model.relations.ResourceTier.SERVER;
import static org.hyperic.plugin.vrealize.automation.VRAUtils.executeXMLQuery;
import static org.hyperic.plugin.vrealize.automation.VraConstants.CREATE_IF_NOT_EXIST;
import static org.hyperic.plugin.vrealize.automation.VraConstants.KEY_APPLICATION_NAME;
import static org.hyperic.plugin.vrealize.automation.VraConstants.PROP_EXTENDED_REL_MODEL;
import static org.hyperic.plugin.vrealize.automation.VraConstants.PROP_INSTALL_PATH;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_FAKE_DISCOVERY_SERVICE_NAME;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_LOAD_BALANCER_TAG;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VCO_TAG;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_APPLICATION;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_IAAS_WEB;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_IAAS_WEB_LOAD_BALANCER;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_IAAS_WEB_LOAD_BALANCER_TAG;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_IAAS_WEB_TAG;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_SERVER;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_SERVER_LOAD_BALANCER;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_SERVER_TAG;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_VCO;
import static org.hyperic.plugin.vrealize.automation.VraConstants.TYPE_VRA_VCO_LOAD_BALANCER;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.params.AuthPNames;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.AuthPolicy;
import org.hyperic.hq.agent.AgentKeystoreConfig;
import org.hyperic.hq.product.PluginException;
import org.hyperic.hq.product.ServerResource;
import org.hyperic.hq.product.ServiceResource;
import org.hyperic.sigar.SigarException;
import org.hyperic.util.config.ConfigResponse;
import org.hyperic.util.http.HQHttpClient;
import org.hyperic.util.http.HttpConfig;
import org.w3c.dom.Document;
import com.vmware.hyperic.model.relations.CommonModelUtils;
import com.vmware.hyperic.model.relations.ObjectFactory;
import com.vmware.hyperic.model.relations.Property;
import com.vmware.hyperic.model.relations.Resource;
/**
* @author glaullon
*/
public class DiscoveryVRAIaasWeb extends Discovery {
private static final Log log = LogFactory.getLog(DiscoveryVRAIaasWeb.class);
@Override
protected ServerResource newServerResource(
long pid,
String exe) {
ServerResource server = super.newServerResource(pid, exe);
log.debug("[newServerResource] pid=" + pid);
File configFile = null;
try {
String[] args = getSigar().getProcArgs(pid);
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equalsIgnoreCase("-h")) {
configFile = new File(args[i + 1]);
}
}
} catch (SigarException ex) {
log.debug(ex, ex);
}
log.debug("[newServerResource] configFile=" + configFile);
if (configFile != null) {
String mmwebPath =
executeXMLQuery(
"//application[@applicationPool='RepositoryAppPool']/virtualDirectory[@path='/']/@physicalPath",
configFile);
if (mmwebPath != null) {
File installPath = new File(mmwebPath, "../..");
log.debug("[newServerResource] installPath=" + getCanonicalPath(installPath));
server.setInstallPath(getCanonicalPath(installPath));
server.setIdentifier(server.getIdentifier().replace("%installpath%", server.getInstallPath()));
server.getProductConfig().setValue(PROP_INSTALL_PATH, getCanonicalPath(installPath));
server.getProductConfig().setValue("process.query", getTypeProperty("PROC_QUERY"));
// do not remove, why? please don't ask.
setProductConfig(server, server.getProductConfig());
server.setProductConfig(server.getProductConfig());
}
}
return server;
}
@Override
protected List<ServiceResource> discoverServices(ConfigResponse config)
throws PluginException {
log.debug("[discoverServices] config=" + config);
List<ServiceResource> res = new ArrayList<ServiceResource>();
String installPath = config.getValue(PROP_INSTALL_PATH, "");
final String platformFqdn = config.getValue("platform.fqdn");
VRAUtils.setLocalFqdn(platformFqdn);
final String iaasWebServerFqdn = platformFqdn;
final String vcoFqdn = getVCO(config);
log.debug("[discoverServices] iaasWebServerFqdn=" + iaasWebServerFqdn);
log.debug("[discoverServices] vcoFqdn=" + vcoFqdn);
ServiceResource service = createServiceResource(TYPE_FAKE_DISCOVERY_SERVICE_NAME);
String type = getTypeInfo().getName();
String platformName = getPlatformName();
service.setName(String.format("%s %s %s", platformName, type, TYPE_FAKE_DISCOVERY_SERVICE_NAME));
File dataCfg = new File(installPath, "Server/Model Manager Data/Repoutil.exe.config");
log.debug("[discoverServices] dataCfg=" + getCanonicalPath(dataCfg));
String vRAIaaSWebLoadBalancer = executeXMLQuery("//add[@key='repositoryAddress']/@value", dataCfg);
vRAIaaSWebLoadBalancer = VRAUtils.getFqdn(vRAIaaSWebLoadBalancer);
log.debug("[discoverServices] vRAIaaSWebLoadBalancer=" + vRAIaaSWebLoadBalancer);
VRAUtils.VraVersion vraVersion = VRAUtils.getVraVersion(isWin32());
String vRAServer;
if (vraVersion.getMajor() <= 6 && vraVersion.getMinor() <= 1) {
File webCfg = new File(installPath, "Server/Model Manager Web/Web.config");
log.debug("[discoverServices] webCfg=" + getCanonicalPath(webCfg));
vRAServer = executeXMLQuery("//repository/@store", webCfg.toString());
vRAServer = VRAUtils.getFqdn(vRAServer);
log.debug("[discoverServices] vRAServer=" + vRAServer);
} else {
vRAServer = CommonModelUtils.getParametrizedName(VraConstants.KEY_APPLICATION_NAME);
}
String model = VRAUtils.marshallResource(
getIaaSWebServerRelationsModel(vRAServer, iaasWebServerFqdn, vRAIaaSWebLoadBalancer, vcoFqdn));
ConfigResponse c = new ConfigResponse();
c.setValue(PROP_EXTENDED_REL_MODEL, new String(Base64.encodeBase64(model.getBytes())));
setProductConfig(service, c);
setMeasurementConfig(service, new ConfigResponse());
res.add(service);
return res;
}
public static Resource getIaaSWebServerRelationsModel(
String vRaApplicationFqdn,
String iaasWebServerFqdn,
String vRAIaaSWebLoadBalancerFqdn,
String vcoFqdn) {
log.debug("[getIaaSWebServerRelationsModel] vRaApplicationFqdn=" + vRaApplicationFqdn);
log.debug("[getIaaSWebServerRelationsModel] iaasWebServerFqdn=" + iaasWebServerFqdn);
log.debug("[getIaaSWebServerRelationsModel] vRAIaaSWebLoadBalancerFqdn=" + vRAIaaSWebLoadBalancerFqdn);
log.debug("[getIaaSWebServerRelationsModel] vcoFqdn=" + vcoFqdn);
ObjectFactory factory = new ObjectFactory();
Resource iaasWebServer =
factory.createResource(!CREATE_IF_NOT_EXIST, TYPE_VRA_IAAS_WEB, iaasWebServerFqdn, SERVER);
Resource iaasWebServerTag = factory.createLogicalResource(TYPE_VRA_IAAS_WEB_TAG, vRaApplicationFqdn);
iaasWebServer.addRelations(factory.createRelation(iaasWebServerTag, PARENT));
Resource vraAppTagResource = getVraApp(factory, vRaApplicationFqdn, TYPE_VRA_APPLICATION);
iaasWebServerTag.addRelations(factory.createRelation(vraAppTagResource, PARENT));
createRelationIaasWebLoadBalancer(vRaApplicationFqdn, iaasWebServerFqdn, vRAIaaSWebLoadBalancerFqdn, factory,
iaasWebServer, iaasWebServerTag);
createRelationVcoOrLoadBalancer(vRaApplicationFqdn, vcoFqdn, factory, iaasWebServer, vraAppTagResource);
/**
* Adding both vRAVA directly and the vRAVA load balancer because we won't to which the FQDN we have points.
*/
Resource vraServer = factory.createResource(!CREATE_IF_NOT_EXIST, TYPE_VRA_SERVER, vRaApplicationFqdn, SERVER);
iaasWebServer.addRelations(factory.createRelation(vraServer, SIBLING));
final String vraServerLoadBalancerName = vRaApplicationFqdn;
Resource vraServerPossibleLoadBalancer =
factory.createResource(!CREATE_IF_NOT_EXIST, TYPE_VRA_SERVER_LOAD_BALANCER,
vraServerLoadBalancerName, SERVER);
iaasWebServer.addRelations(
factory.createRelation(vraServerPossibleLoadBalancer, SIBLING, !CREATE_IF_NOT_EXIST));
Resource vraServerTag = factory.createLogicalResource(TYPE_VRA_SERVER_TAG, vRaApplicationFqdn);
vraServer.addRelations(factory.createRelation(vraServerTag, PARENT, CREATE_IF_NOT_EXIST));
vraServerTag.addRelations(factory.createRelation(vraAppTagResource, PARENT));
return iaasWebServer;
}
private static void createRelationVcoOrLoadBalancer(
String vRaApplicationFqdn,
String vcoFqdn,
ObjectFactory factory,
Resource iaasWebServer,
Resource vraAppTagResource) {
// Relation to VCO component might me of two types:
// 1. Direct reference to VCO server
// 2. Reference to a Load Balancer of VCO servers cluster
// Therefore, the code below creates two kinds of relationship - only one of them suppose to be working
if (StringUtils.isBlank(vcoFqdn)) {
return;
}
Resource vcoServer = factory.createResource(!CREATE_IF_NOT_EXIST, TYPE_VRA_VCO, vcoFqdn, SERVER);
iaasWebServer.addRelations(factory.createRelation(vcoServer, SIBLING));
Resource vcoTag = factory.createLogicalResource(TYPE_VCO_TAG, vRaApplicationFqdn);
vcoTag.addRelations(factory.createRelation(vraAppTagResource, PARENT));
vcoServer.addRelations(factory.createRelation(vcoTag, PARENT, CREATE_IF_NOT_EXIST));
Resource loadBalancerSuperTag =
factory.createLogicalResource(VraConstants.TYPE_LOAD_BALANCER_TAG, vRaApplicationFqdn);
loadBalancerSuperTag.addRelations(factory.createRelation(vraAppTagResource, PARENT));
Resource vcoLoadBalancerTag =
factory.createLogicalResource(VraConstants.TYPE_VRA_VCO_LOAD_BALANCER_TAG, vRaApplicationFqdn);
vcoLoadBalancerTag.addRelations(factory.createRelation(loadBalancerSuperTag, PARENT, CREATE_IF_NOT_EXIST));
Resource vcoLoadBalancer =
factory.createResource(!CREATE_IF_NOT_EXIST, TYPE_VRA_VCO_LOAD_BALANCER, vcoFqdn, SERVER);
vcoLoadBalancer.addRelations(factory.createRelation(vcoLoadBalancerTag, PARENT, CREATE_IF_NOT_EXIST),
factory.createRelation(vcoTag, PARENT, CREATE_IF_NOT_EXIST));
iaasWebServer.addRelations(factory.createRelation(vcoLoadBalancer, SIBLING));
}
private static void createRelationIaasWebLoadBalancer(
String vRaApplicationFqdn,
String iaasWebServerFqdn,
String vRAIaaSWebLoadBalancerFqdn,
ObjectFactory factory,
Resource iaasWebServer,
Resource iaasWebServerTag) {
// TODO change equals to equivalent from VRAUtils.
if (StringUtils.isBlank(vRAIaaSWebLoadBalancerFqdn) || iaasWebServerFqdn.equals(vRAIaaSWebLoadBalancerFqdn)) {
return;
}
// Cluster - has load balancer
// This is only if there is a load balancer. If not then nothing load balancer related should be created.
Resource iaasWebLoadBalancer = factory.createResource(Boolean.FALSE, TYPE_VRA_IAAS_WEB_LOAD_BALANCER,
vRAIaaSWebLoadBalancerFqdn, SERVER);
iaasWebServer.addRelations(factory.createRelation(iaasWebLoadBalancer, SIBLING));
Resource iaasWebLoadBalancerTag =
factory.createLogicalResource(TYPE_VRA_IAAS_WEB_LOAD_BALANCER_TAG, vRaApplicationFqdn);
iaasWebLoadBalancer.addRelations(factory.createRelation(iaasWebLoadBalancerTag, PARENT),
factory.createRelation(iaasWebServerTag, PARENT));
// iaasWebLoadBalancerTag.addRelations(factory.createRelation(vraAppTagResource, PARENT));
Resource loadBalancerSuperTag = factory.createLogicalResource(TYPE_LOAD_BALANCER_TAG, vRaApplicationFqdn);
iaasWebLoadBalancerTag.addRelations(factory.createRelation(loadBalancerSuperTag, PARENT));
}
private static Resource getVraApp(
ObjectFactory factory,
String vRaApplicationName,
String vraAppTagType) {
Property vraApplicationName = factory.createProperty(KEY_APPLICATION_NAME, vRaApplicationName);
Resource vraAppTagResource = factory.createApplicationResource(vraAppTagType, vRaApplicationName);
if (!CommonModelUtils.containsVariable(vRaApplicationName)) {
vraAppTagResource.addProperty(vraApplicationName);
}
return vraAppTagResource;
}
/*
* Use parameter instead of trying to discover VCO details
* Assume that VCO has an Hyperic agent that performs discovery of VCO server and it's components/services
*/
private static String getVCO(ConfigResponse config) {
String vcoFNQ = null;
String xml = null;
String user = config.getValue("iaas.http.user", "");
String pass = config.getValue("iaas.http.pass", "");
String domain = config.getValue("iaas.http.domain", "");
try {
AgentKeystoreConfig ksCFG = new AgentKeystoreConfig();
HQHttpClient client =
new HQHttpClient(ksCFG, new HttpConfig(5000, 5000, null, 0), ksCFG.isAcceptUnverifiedCert());
List<String> authpref = new ArrayList<String>();
authpref.add(AuthPolicy.NTLM);
authpref.add(AuthPolicy.BASIC);
client.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref);
client.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthPolicy.NTLM),
new NTCredentials(user, pass, "localhost", domain));
HttpGet get =
new HttpGet("https://localhost/Repository/Data/ManagementModelEntities.svc/ManagementEndpoints");
HttpResponse response = client.execute(get);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
xml = readInputString(response.getEntity().getContent());
} else {
log.debug("[getVCOx] GET failed: " + response.getStatusLine().getReasonPhrase());
}
} catch (IOException ex) {
log.debug("[getVCOx] " + ex, ex);
}
if (xml != null) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = (Document) builder.parse(new ByteArrayInputStream(xml.getBytes()));
log.debug("[getVCOx] xml:" + xml);
XPathFactory xFactory = XPathFactory.newInstance();
XPath xpath = xFactory.newXPath();
String xPath = "//properties[InterfaceType[text()='vCO']]/ManagementEndpointName/text()";
log.debug("[getVCOx] evaluating XPath:" + xPath);
vcoFNQ = xpath.evaluate(xPath, doc);
log.debug("[getVCOx] vcoFNQ:" + vcoFNQ);
} catch (Exception ex) {
log.debug("[getVCOx] " + ex, ex);
}
}
return VRAUtils.getFqdn(vcoFNQ);
}
private String getCanonicalPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException ex) {
log.debug("[getCanonicalPath] " + ex, ex);
return file.getAbsolutePath();
}
}
public static String readInputString(InputStream in)
throws IOException {
StringBuilder out = new StringBuilder();
byte[] b = new byte[4096];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
return out.toString();
}
}