package com.telefonica.claudia.slm.paas;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import org.apache.log4j.Logger;
import org.dmtf.schemas.ovf.envelope._1.ContentType;
import org.dmtf.schemas.ovf.envelope._1.DiskSectionType;
import org.dmtf.schemas.ovf.envelope._1.EnvelopeType;
import org.dmtf.schemas.ovf.envelope._1.FileType;
import org.dmtf.schemas.ovf.envelope._1.ProductSectionType;
import org.dmtf.schemas.ovf.envelope._1.RASDType;
import org.dmtf.schemas.ovf.envelope._1.ReferencesType;
import org.dmtf.schemas.ovf.envelope._1.VirtualDiskDescType;
import org.dmtf.schemas.ovf.envelope._1.VirtualHardwareSectionType;
import org.dmtf.schemas.ovf.envelope._1.VirtualSystemCollectionType;
import org.dmtf.schemas.ovf.envelope._1.VirtualSystemType;
import org.dmtf.schemas.wbem.wscim._1.cim_schema._2.cim_resourceallocationsettingdata.ResourceType;
import org.dmtf.schemas.wbem.wscim._1.common.CimString;
import com.abiquo.ovf.OVFEnvelopeUtils;
import com.abiquo.ovf.OVFEnvironmentUtils;
import com.abiquo.ovf.exceptions.DNSServerNotFoundException;
import com.abiquo.ovf.exceptions.EmptyEnvelopeException;
import com.abiquo.ovf.exceptions.GatewayNotFoundException;
import com.abiquo.ovf.exceptions.IPNotFoundException;
import com.abiquo.ovf.exceptions.InvalidSectionException;
import com.abiquo.ovf.exceptions.NetmaskNotFoundException;
import com.abiquo.ovf.exceptions.NotEnoughIPsInPoolException;
import com.abiquo.ovf.exceptions.PoolNameNotFoundException;
import com.abiquo.ovf.exceptions.PrecedentTierEntryPointNotFoundException;
import com.abiquo.ovf.exceptions.SectionNotPresentException;
import com.abiquo.ovf.exceptions.XMLException;
import com.abiquo.ovf.section.OVFProductUtils;
import com.abiquo.ovf.xml.OVFSerializer;
import com.telefonica.claudia.slm.common.SMConfiguration;
import com.telefonica.claudia.slm.deployment.ServiceApplication;
import com.telefonica.claudia.slm.deployment.VEE;
import com.telefonica.claudia.slm.deployment.VEEReplica;
import com.telefonica.claudia.slm.deployment.hwItems.NIC;
import com.telefonica.claudia.slm.deployment.hwItems.NICConf;
import com.telefonica.claudia.slm.deployment.hwItems.Network;
import com.telefonica.claudia.slm.deployment.paas.Product;
import com.telefonica.claudia.slm.deployment.paas.Property;
import com.telefonica.claudia.slm.lifecyclemanager.FSM;
import com.telefonica.claudia.smi.URICreation;
public class OVFContextualization {
//
private static final String repositoryDir = "./repository";
private static final String customImagesDir = repositoryDir
+ SMConfiguration.getInstance().getImagesServerPath();
private static final String protocol = "http://";
private static Logger logger = Logger.getLogger("OVFContextualization");
public String getMacro (VEE vee, String macro)
{
if (macro.equals("@ServiceId"))
{
return getServiceId (vee);
}
else if (macro.equals("@MonitoringChannel"))
{
return getMonitoringChannel ();
}
else if (macro.equals("@Username"))
{
return vee.getUserName();
}
else if (macro.equals("@Password"))
{
return vee.getPassword();
}
else if (macro.equals("@IdServiceMonitoring"))
{
return getMd5FromFQN (vee);
}
else if (macro.startsWith("@Property"))
{
String product = macro.substring(macro.indexOf("(")+1,macro.indexOf(","));
String property = macro.substring(macro.indexOf(",")+1,macro.indexOf(")"));
return getPropertyFromOtherProduct (vee,product,property);
}
else if (macro.startsWith("@IP"))
{
if (macro.indexOf(",")!=-1)
{
return getIpVmName (vee, macro.substring(macro.indexOf("(")+1,macro.indexOf(","))
, macro.substring(macro.indexOf(",")+1,macro.indexOf(")")));
}
else
{
return getIpVm (vee,macro.substring(macro.indexOf("(")+1,macro.indexOf(")")));
}
}
return null;
}
public String getPropertyFromOtherProduct (VEE vee, String productname, String property)
{
Product product = null;
if ((product= vee.getProductByName (productname)) != null)
{
Property prop = null;
if ((prop = product.getPropertyByNameFinished(property))!= null)
{
return prop.getValue();
}
}
return null;
}
public String getMd5FromFQN (VEE vee)
{
String fqn = vee.getServiceApplication().getFQN().toString();
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
return null;
}
md.update(fqn.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
public String getServiceId (VEE vee)
{
//@ServiceId
return vee.getServiceApplication().getFQN().toString();
}
public String getMonitoringChannel ()
{
//@MonitoringChannel.
return SMConfiguration.getInstance().getMonitoringAddress();
}
//@id([n]),
//=�@IP(net1)�
public String getIpVm (VEE vee, String namenetwork)
{
// We chose the first one
for (VEEReplica replica: vee.getVEEReplicas())
{
for (NIC nic: replica.getNICs())
{
Network net = nic.getNICConf().getNetwork();
if (net.getName().equals(namenetwork))
{
return net.getNetworkAddresses()[0];
}
}
}
return null;
}
//@IP(sge_net,VIP)
public String getIpVmName (VEE vee, String namenetwork, String namevee)
{
// We chose the first one
VEE veerelated = null;
for (VEE vee2: vee.getServiceApplication().getVEEs())
{
if (vee2.getVEEName().equals(namevee))
veerelated = vee2;
}
return getIpVm (veerelated, namenetwork);
}
public String getOvfVEEwithContextualization (String ovf, String url) throws UnsupportedEncodingException, XMLException
{
OVFSerializer ovfSerializer = OVFSerializer.getInstance();
EnvelopeType envelope = ovfSerializer.readXMLEnvelope(new ByteArrayInputStream(ovf.getBytes("UTF-8")));
FileType file = new FileType ();
file.setHref(url);
file.setId("contextualization");
envelope.getReferences().getFile().add(file);
return ovfSerializer.writeXML(envelope);
}
public String generateOvfEnvironment (VEEReplica replica)
{
HashMap<String,ArrayList<String>> map = getIpsForMacros (replica);
HashMap<String, HashMap<String, String> > entry = getEntryPoints(replica);
OVFSerializer ovfSerializer = OVFSerializer.getInstance();
String xmlvs = replica.getVEE().getOvfRepresentation();
System.out.println (xmlvs);
VirtualSystemType vs = null;
try {
EnvelopeType envelope = ovfSerializer.readXMLEnvelope(new ByteArrayInputStream(xmlvs.getBytes("UTF-8")));
vs = (VirtualSystemType)OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envelope);
// vs = OVFEnvelopeUtils.getVirtualSystems ((VirtualSystemCollectionType)entityInstance);
} catch (UnsupportedEncodingException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (XMLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (EmptyEnvelopeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
OVFEnvironmentUtils.createOVFEnvironment( vs,
replica.getId(),
SMConfiguration.getInstance().getDomainName(),
URICreation.getFQN(SMConfiguration.getInstance().getSiteRoot(), replica.getVEE().getServiceApplication().getCustomer().getCustomerName(),
replica.getVEE().getServiceApplication().getSerAppName()),
URICreation.getFQN(SMConfiguration.getInstance().getSiteRoot(), replica.getVEE().getServiceApplication().getCustomer().getCustomerName(),
replica.getVEE().getServiceApplication().getSerAppName(), replica.getVEE().getVEEName()),
SMConfiguration.getInstance().getMonitoringAddress(),
map,
null,
null,
null,
entry,
output,
true);
} catch (IPNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DNSServerNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NetmaskNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GatewayNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PrecedentTierEntryPointNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotEnoughIPsInPoolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PoolNameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("OVF Environment file for VM [" + output.toString()+ "] ");
return output.toString();
}
public HashMap<String, String> getIpsNetwork (ServiceApplication sap, String network)
{
HashMap<String, String> aNetwork = new HashMap<String, String> ();
for (VEE vee: sap.getVEEs())
{
for (NICConf nicconf : vee.getNICsConf())
{
if (!nicconf.getNetwork().getName().equals(network))
{
continue;
}
else
{
for (VEEReplica replica: vee.getVEEReplicas())
{
String ip = getIpNetworkVEEReplica (network,replica);
if (ip!=null)
aNetwork.put(vee.getVEEName(), ip);
}
}
}
}
return aNetwork;
}
public List<String> getNetworksVEE (VEE vm)
{
List<String> networks = new ArrayList ();
for (VEE vee: vm.getServiceApplication().getVEEs())
{
for (NICConf nicconf : vee.getNICsConf())
{
if (!networks.contains(nicconf.getNetwork().getName()))
{
networks.add(nicconf.getNetwork().getName());
System.out.println("adding net " + nicconf.getNetwork().getName());
}
}
}
return networks;
}
public String getIpNetworkVEEReplica (String network, VEEReplica replica)
{
String ipstring = null;
for (NIC nic: replica.getNICs())
{
NICConf conf = nic.getNICConf();
String networkname = conf.getNetwork().getName();
if (!networkname.equals(network))
{
continue;
}
if (nic.getIPAddresses()==null || nic.getIPAddresses().size()==0 )
continue;
ipstring = nic.getIPAddresses().get(0);
}
return ipstring;
}
public String createCustomizationFile(VEEReplica veeReplica) {
String customizationDirName = customImagesDir + "/"
+ veeReplica.getFQN().toString();
File customizationDir = new File(customizationDirName);
customizationDir.mkdirs();
String customizationFileName = customizationDirName + "/ovf-env.xml";
File customizationFile = new File(customizationFileName);
logger.info("Creating customization file in "
+ customizationFile.getPath());
String customizationDirURLPath = SMConfiguration.getInstance()
.getImagesServerPath()
+ "/" + veeReplica.getFQN().toString();
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter(customizationFile));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(FSM.class.getName()).log(
java.util.logging.Level.SEVERE, null, ex);
return ex.getMessage();
}
out.write(generateOvfEnvironment(veeReplica));
out.close();
String urlToCustomFile = protocol
+ SMConfiguration.getInstance().getImagesServerHost() + ":"
+ SMConfiguration.getInstance().getImagesServerPort()
+ customizationDirURLPath + "/ovf-env.xml";
logger.info("URL to customization file: " + urlToCustomFile);
return urlToCustomFile;
}
public String updateOvfRepresentation (VEEReplica replica)
{
OVFSerializer ovfSerializer = OVFSerializer.getInstance();
String xmlvs = replica.getOvfRepresentation();
org.dmtf.schemas.ovf.envelope._1.ReferencesType referenceSection = null;
org.dmtf.schemas.ovf.envelope._1.DiskSectionType diskSection = null;
VirtualSystemType vs = null;
VirtualSystemCollectionType topVsc = null;
EnvelopeType envelope = null;
try {
envelope = ovfSerializer.readXMLEnvelope(new ByteArrayInputStream(xmlvs.getBytes("UTF-8")));
referenceSection = envelope.getReferences();
diskSection = OVFEnvelopeUtils.getSection(envelope, DiskSectionType.class);
vs = (VirtualSystemType)OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envelope);
// vs = OVFEnvelopeUtils.getVirtualSystems ((VirtualSystemCollectionType)entityInstance);
} catch (UnsupportedEncodingException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (XMLException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (SectionNotPresentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidSectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (EmptyEnvelopeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
org.dmtf.schemas.ovf.envelope._1.FileType file = new FileType ();
file.setHref(replica.getCustomizationFile());
file.setId("ovfcontext");
referenceSection.getFile().add(file);
VirtualDiskDescType disk = new VirtualDiskDescType();
String target = getPropertyFromVirtualSystem (vs,"TARGET_CONF" );
logger.info("target " + target);
disk.setTarget(target);
disk.setDiskId("ovfcontext");
disk.setCapacity("0");
disk.setFileRef("ovfcontext");
diskSection.getDisk().add(disk);
try {
VirtualHardwareSectionType vh = OVFEnvelopeUtils.getSection(vs, VirtualHardwareSectionType.class);
RASDType item = new RASDType ();
CimString elementName = new CimString();
elementName.setValue("ovfcontext");
item.setElementName(elementName);
ResourceType type = new ResourceType();
type.setValue("17");
item.setResourceType(type);
CimString id = new CimString ();
id.setValue(""+17);
item.setInstanceID(id);
CimString hostresource = new CimString();
hostresource.setValue("ovf://disk/ovfcontext");
item.getHostResource().add(hostresource);
vh.getItem().add(item);
} catch (SectionNotPresentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InvalidSectionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
return ovfSerializer.writeXML(envelope);
} catch (XMLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
private static String getPropertyFromVirtualSystem(VirtualSystemType virtualSystem, String property)
{
String propValue = null;
ProductSectionType productSection = null;
try
{
productSection = OVFEnvelopeUtils.getSection(virtualSystem, ProductSectionType.class);
org.dmtf.schemas.ovf.envelope._1.ProductSectionType.Property prop = OVFProductUtils.getProperty(productSection, property);
propValue = prop.getValue().toString();
}
catch (Exception e)
{
//TODO throw PropertyNotFoundException
logger.error(e);
}
return propValue;
}
public String macroReplacement (VEEReplica replica) throws IOException
{
HashMap<String,ArrayList<String>> map = getIpsForMacros (replica);
HashMap<String, HashMap<String, String> > entry = getEntryPoints(replica);
return inEnvolopeMacroReplacement(replica.getVEE().getOvfRepresentation(),
replica.getId(),
SMConfiguration.getInstance().getDomainName(),
URICreation.getFQN(SMConfiguration.getInstance().getSiteRoot(), replica.getVEE().getServiceApplication().getCustomer().getCustomerName(),
replica.getVEE().getServiceApplication().getSerAppName()),
URICreation.getFQN(SMConfiguration.getInstance().getSiteRoot(), replica.getVEE().getServiceApplication().getCustomer().getCustomerName(),
replica.getVEE().getServiceApplication().getSerAppName(), replica.getVEE().getVEEName()),
SMConfiguration.getInstance().getMonitoringAddress(),
map,
null,
null,
null,
entry) ;
}
public String inEnvolopeMacroReplacement(String ovf,
int instanceNumber,
String domain,
String serviceId,
String veeId,
String monitoringChannel,
HashMap<String,ArrayList<String>> ips,
HashMap<String, String> netmasks,
HashMap<String, String> dnsServers,
HashMap<String, String> gateways,
HashMap<String, HashMap<String, String> > entryPoints) throws IOException {
// Parse the ovf String
OVFSerializer ovfSerializer = OVFSerializer.getInstance();
try {
ovfSerializer.setValidateXML(false);
EnvelopeType envVee = ovfSerializer.readXMLEnvelope(new ByteArrayInputStream(ovf.getBytes()));
ContentType entityInstance = null;
entityInstance = OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envVee);
if (entityInstance instanceof VirtualSystemCollectionType) {
return "";
} else if (entityInstance instanceof VirtualSystemType) {
OVFEnvelopeUtils.inEnvolopeMacroReplacement(envVee, (VirtualSystemType) entityInstance, instanceNumber, domain, serviceId, veeId, monitoringChannel, ips,
netmasks, dnsServers, gateways, entryPoints);
// Serialize the ovf
ByteArrayOutputStream sob = new ByteArrayOutputStream();
OVFSerializer.getInstance().writeXML(envVee, sob);
return sob.toString(Charset.defaultCharset().toString());
} else {
throw new IllegalArgumentException("Virtual System not found.");
}
} catch (EmptyEnvelopeException e) {
logger.error("Empty envelope found: " + e);
throw new IOException("Empty envelope found: " + e.getMessage());
}catch (JAXBException e) {
logger.error("Unknown JAXB error");
throw new IOException("Unexpected errors in macro replacement." + e.getMessage());
} catch (XMLException e) {
logger.error("OVF could not be serialized: " + e.getMessage());
throw new IOException("Unexpected errors in macro replacement." + e.getMessage());
} catch (IPNotFoundException e) {
throw new IllegalArgumentException("No IP found: " + e.getMessage());
} catch (DNSServerNotFoundException e) {
e.printStackTrace();
throw new IllegalArgumentException("No DNS found: " + e.getMessage());
} catch (NetmaskNotFoundException e) {
e.printStackTrace();
throw new IllegalArgumentException("No Netmask found: " + e.getMessage());
} catch (GatewayNotFoundException e) {
e.printStackTrace();
throw new IllegalArgumentException("No Gateway found: " + e.getMessage());
} catch (PrecedentTierEntryPointNotFoundException e) {
e.printStackTrace();
throw new IllegalArgumentException("No Precedent Tier found: " + e.getMessage());
} catch (NotEnoughIPsInPoolException e) {
e.printStackTrace();
throw new IllegalArgumentException("Not enough IPs found: " + e.getMessage());
} catch (PoolNameNotFoundException e) {
e.printStackTrace();
throw new IllegalArgumentException("Pool Name not found: " + e.getMessage());
}
}
private HashMap<String,ArrayList<String>> getIpsForMacros (VEEReplica replica)
{
ArrayList<String> ipsvm = new ArrayList ();
HashMap<String,ArrayList<String>> map = new HashMap();
System.out.println ("getIpsForMacros for replica " + replica.getVEE().getVEEName() + " " + replica.getNICs().size());
for (NIC nic: replica.getNICs())
{
System.out.println ("NIC " + nic.getNICConf().getNetwork().getName());
if (nic.getIPAddresses() == null || nic.getIPAddresses().size()==0)
continue;
String ipstring = nic.getIPAddresses().get(0);
NICConf conf = nic.getNICConf();
String networkname = conf.getNetwork().getName();
System.out.println ("Nombre " + networkname+ " ips " + ipstring);
ipsvm.add(ipstring);
map.put(networkname, ipsvm);
}
return map;
}
private HashMap<String, HashMap<String, String> > getEntryPoints(VEEReplica replica)
{
HashMap<String, HashMap<String, String> > entry = new HashMap();
List<String> networks = getNetworksVEE (replica.getVEE());
HashMap<String, String> netwoksips = null;
for (String net: networks)
{
netwoksips = getIpsNetwork (replica.getVEE().getServiceApplication(), net);
entry.put(net, netwoksips);
System.out.println ("adding " + net + " " + netwoksips + " for replica" + replica.getVEE().getVEEName());
}
return entry;
}
}