/*
* Copyright (c) 2012-2015 iWave Software LLC
* All Rights Reserved
*/
package com.emc.sa.machinetags;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.emc.sa.machinetags.vmware.DatastoreMachineTag;
import com.emc.sa.machinetags.vmware.VMwareDatastoreTagger;
import com.emc.sa.util.ResourceType;
import com.emc.storageos.db.client.URIUtil;
import com.emc.storageos.model.DataObjectRestRep;
import com.emc.storageos.model.block.BlockObjectRestRep;
import com.emc.storageos.model.file.FileShareRestRep;
import com.emc.storageos.model.file.MountInfo;
import com.emc.vipr.client.ViPRCoreClient;
import com.emc.vipr.client.core.ProjectResources;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class MachineTagUtils {
@SuppressWarnings("unused")
private static final Logger log = Logger.getLogger(MachineTagUtils.class);
private static Pattern MACHINE_TAG_REGEX = Pattern.compile("([^W]*\\:[^W]*)=(.*)");
public static String getTaskTag(DataObjectRestRep dataObject, String tagName) {
if (dataObject.getTags() == null) {
return null;
}
Map<String, String> currentMachineTags = parseMachineTags(dataObject.getTags());
return currentMachineTags.get(tagName);
}
public static String getTaskTag(ViPRCoreClient client, URI taskId, String tagName) {
Set<String> currentTags = getTaskTags(client, taskId);
Map<String, String> currentMachineTags = parseMachineTags(currentTags);
return currentMachineTags.get(tagName);
}
public static void setTaskTag(ViPRCoreClient client, URI taskId, String tagName, String tagValue) {
removeTaskTag(client, taskId, tagName);
client.tasks().addTags(taskId, Sets.newHashSet(machineTag(tagName, tagValue)));
}
public static void setTaskOrderIdTag(ViPRCoreClient client, URI taskId, String tagValue) {
setTaskTag(client, taskId, KnownMachineTags.getOrderIdTagName(), tagValue);
}
public static void setTaskOrderNumberTag(ViPRCoreClient client, URI taskId, String tagValue) {
setTaskTag(client, taskId, KnownMachineTags.getOrderNumberTagName(), tagValue);
}
public static void removeTaskTag(ViPRCoreClient client, URI taskId, String tagName) {
Set<String> currentTags = getTaskTags(client, taskId);
Map<String, String> currentMachineTags = parseMachineTags(currentTags);
if (currentMachineTags.containsKey(tagName)) {
String currentTagValue = currentMachineTags.get(tagName);
client.tasks().removeTags(taskId, Sets.newHashSet(machineTag(tagName, currentTagValue)));
}
}
protected static Set<String> getTaskTags(ViPRCoreClient client, URI taskId) {
return client.tasks().getTags(taskId);
}
public static String getBlockVolumeTag(BlockObjectRestRep blockObject, String tagName) {
if (blockObject.getTags() == null) {
return null;
}
Map<String, String> currentMachineTags = parseMachineTags(blockObject.getTags());
return currentMachineTags.get(tagName);
}
/**
* @return The current value of the Block Volume machine tag, or NULL if the
* tag doesn't exist
*/
public static String getBlockVolumeTag(ViPRCoreClient client, URI volumeId, String tagName) {
Set<String> currentTags = getBlockResourceTags(client, volumeId);
Map<String, String> currentMachineTags = parseMachineTags(currentTags);
return currentMachineTags.get(tagName);
}
/**
* Sets the value of a Machine Tag on the Volume. If the machine tag already
* exists, its value is replaced with @{link #tagValue}
*/
public static void setBlockVolumeTag(ViPRCoreClient client, URI volumeId, String tagName, String tagValue) {
removeBlockVolumeTag(client, volumeId, tagName);
getClientResource(client, volumeId).addTags(volumeId, Sets.newHashSet(machineTag(tagName, tagValue)));
}
protected static ProjectResources<? extends BlockObjectRestRep> getClientResource(ViPRCoreClient client,
URI volumeId) {
ProjectResources<? extends BlockObjectRestRep> resource = null;
if (ResourceType.fromResourceId(volumeId.toString()).equals(ResourceType.VOLUME)) {
resource = client.blockVolumes();
} else if (ResourceType.fromResourceId(volumeId.toString()).equals(ResourceType.BLOCK_SNAPSHOT)) {
resource = client.blockSnapshots();
} else {
throw new IllegalStateException("Unable to find block resource with id " + volumeId);
}
return resource;
}
/** Removes the Machine Tag with the specified name from the block volume */
public static void removeBlockVolumeTag(ViPRCoreClient client, URI volumeId, String tagName) {
Set<String> currentTags = getBlockResourceTags(client, volumeId);
Map<String, String> currentMachineTags = parseMachineTags(currentTags);
if (currentMachineTags.containsKey(tagName)) {
String currentTagValue = currentMachineTags.get(tagName);
getClientResource(client, volumeId).removeTags(volumeId,
Sets.newHashSet(machineTag(tagName, currentTagValue)));
}
}
protected static Set<String> getBlockResourceTags(ViPRCoreClient client, URI resourceId) {
return getClientResource(client, resourceId).getTags(resourceId);
}
public static Map<String, String> getDatastoresOnFilesystem(FileShareRestRep fileSystem) {
return getDatastoresOnFilesystemsOld(Collections.singleton(fileSystem));
}
public static Map<String, String> getDatastoresOnFilesystemsOld(Collection<FileShareRestRep> filesystems) {
Map<String, String> datastoreTags = Maps.newHashMap();
for (FileShareRestRep filesystem : filesystems) {
MachineTagsCollection tags = VMwareDatastoreTagger.getFileSystemTags(filesystem);
for (MachineTag tag : tags.findAll(DatastoreMachineTag.NAMESPACE, DatastoreMachineTag.DATASTORE)) {
datastoreTags.put(tag.getUniqueKey(), tag.value);
}
}
return datastoreTags;
}
public static boolean hasDatastores(FileShareRestRep filesystem) {
MachineTagsCollection tags = VMwareDatastoreTagger.getFileSystemTags(filesystem);
MachineTagsCollection datastoreTags = tags
.findAll(DatastoreMachineTag.NAMESPACE, DatastoreMachineTag.DATASTORE);
return datastoreTags.size() > 0;
}
public static List<String> getDatastores(ViPRCoreClient client, URI projectId, URI vcenterId, URI datacenterId) {
final VMwareDatastoreTagger tagger = new VMwareDatastoreTagger(client);
return tagger.getDatastoreNames(projectId, vcenterId, datacenterId);
}
public static Map<String, String> parseMachineTags(Collection<String> tags) {
Map<String, String> machineTags = Maps.newHashMap();
for (String tag : tags) {
Matcher matcher = MACHINE_TAG_REGEX.matcher(tag);
if (matcher.matches()) {
machineTags.put(matcher.group(1), matcher.group(2));
}
}
return machineTags;
}
private static String machineTag(String name, String value) {
return name + "=" + value;
}
public static String generateMountTag(URI hostId, String destinationPath, String subDirectory, String securityType) {
return "mountNfs;" + hostId.toString() + ";" + destinationPath + ";" + subDirectory + ";" + securityType;
}
public static void setFileSystemTag(ViPRCoreClient client, URI fsId, String tag) {
Set<String> tags = new HashSet<String>();
tags.add(tag);
client.fileSystems().addTags(fsId, tags);
}
public static void removeFileSystemTag(ViPRCoreClient client, URI fsId, String tag) {
Set<String> removeTags = new HashSet<String>();
removeTags.add(tag);
client.fileSystems().removeTags(fsId, removeTags);
}
public static Set<String> getFileSystemTags(ViPRCoreClient client, URI fsId) {
return client.fileSystems().getTags(fsId);
}
public static MountInfo getMountInfo(String strMountInfo) {
if (strMountInfo != null && !strMountInfo.isEmpty()) {
MountInfo mountInfo = new MountInfo();
String[] mountAttrs = strMountInfo.split(";");
if (mountAttrs.length > 0) {
mountInfo.setHostId(URIUtil.uri(mountAttrs[0]));
}
if (mountAttrs.length > 1) {
mountInfo.setFsId(URIUtil.uri(mountAttrs[1]));
}
if (mountAttrs.length > 2) {
mountInfo.setSecurityType(mountAttrs[2]);
}
if (mountAttrs.length > 3) {
mountInfo.setMountPath(mountAttrs[3]);
}
if (mountAttrs.length > 4) {
mountInfo.setSubDirectory(mountAttrs[4]);
if (StringUtils.isEmpty(mountAttrs[4])) {
mountInfo.setSubDirectory(null);
}
}
return mountInfo;
}
return null;
}
public static List<MountInfo> convertMountStringToMounts(List<String> mountTags) {
List<MountInfo> mountList = new ArrayList<MountInfo>();
for (String strMount : mountTags) {
mountList.add(getMountInfo(strMount));
}
return mountList;
}
}