use of com.netflix.simianarmy.Resource in project SimianArmy by Netflix.
the class EddaImageJanitorCrawler method updateReferenceTimeByInstance.
private void updateReferenceTimeByInstance(String region, List<Resource> batch, long since) {
LOGGER.info(String.format("Getting the last reference time by instance for batch of size %d", batch.size()));
String batchUrl = getInstanceBatchUrl(region, batch, since);
JsonNode batchResult = null;
Map<String, Resource> idToResource = Maps.newHashMap();
for (Resource resource : batch) {
idToResource.put(resource.getId(), resource);
}
try {
batchResult = eddaClient.getJsonNodeFromUrl(batchUrl);
} catch (IOException e) {
LOGGER.error("Failed to get response for the batch.", e);
}
if (batchResult == null || !batchResult.isArray()) {
throw new RuntimeException(String.format("Failed to get valid document from %s, got: %s", batchUrl, batchResult));
}
for (Iterator<JsonNode> it = batchResult.getElements(); it.hasNext(); ) {
JsonNode elem = it.next();
JsonNode data = elem.get("data");
String imageId = data.get("imageId").getTextValue();
String instanceId = data.get("instanceId").getTextValue();
JsonNode ltimeNode = elem.get("ltime");
if (ltimeNode != null && !ltimeNode.isNull()) {
long ltime = ltimeNode.asLong();
Resource ami = idToResource.get(imageId);
String lastRefTimeByInstance = ami.getAdditionalField(AMI_FIELD_LAST_INSTANCE_REF_TIME);
if (lastRefTimeByInstance == null || Long.parseLong(lastRefTimeByInstance) < ltime) {
LOGGER.info(String.format("The last time that the image %s was referenced by instance %s is %d", imageId, instanceId, ltime));
ami.setAdditionalField(AMI_FIELD_LAST_INSTANCE_REF_TIME, String.valueOf(ltime));
}
}
}
}
use of com.netflix.simianarmy.Resource in project SimianArmy by Netflix.
the class EddaImageJanitorCrawler method getImageIdsString.
private String getImageIdsString(List<Resource> resources) {
StringBuilder sb = new StringBuilder();
boolean isFirst = true;
for (Resource resource : resources) {
if (!isFirst) {
sb.append(',');
} else {
isFirst = false;
}
sb.append(resource.getId());
}
return sb.toString();
}
use of com.netflix.simianarmy.Resource in project SimianArmy by Netflix.
the class EddaImageJanitorCrawler method getAMIResourcesInRegion.
private List<Resource> getAMIResourcesInRegion(String region, Collection<String> excludedImageIds, String... imageIds) {
JsonNode jsonNode = getImagesInJson(region, imageIds);
List<Resource> resources = Lists.newArrayList();
for (Iterator<JsonNode> it = jsonNode.getElements(); it.hasNext(); ) {
JsonNode ami = it.next();
String imageId = ami.get("imageId").getTextValue();
Resource resource = parseJsonElementToresource(region, ami);
String name = ami.get("name").getTextValue();
if (excludedImageIds.contains(imageId)) {
LOGGER.info(String.format("Image %s is excluded from being managed by Janitor Monkey, ignore.", imageId));
continue;
}
if (usedByInstance.contains(imageId) || usedByLaunchConfig.contains(imageId)) {
LOGGER.info(String.format("AMI %s is referenced by existing instance or launch configuration.", imageId));
} else {
LOGGER.info(String.format("AMI %s is not referenced by existing instance or launch configuration.", imageId));
if (usedNames.contains(name)) {
LOGGER.info(String.format("The same AMI name %s is used in another region", name));
} else {
resources.add(resource);
}
}
}
long since = DateTime.now().minusDays(daysBack).getMillis();
addLastReferenceInfo(resources, since);
// Mark the base AMIs that are used as the ancestor of other images
for (Resource resource : resources) {
if (ancestorImageIds.contains(resource.getId())) {
resource.setAdditionalField(AMI_FIELD_BASE_IMAGE, "true");
}
}
return resources;
}
use of com.netflix.simianarmy.Resource in project SimianArmy by Netflix.
the class EddaLaunchConfigJanitorCrawler method getLaunchConfigResourcesInRegion.
private List<Resource> getLaunchConfigResourcesInRegion(String region, String... launchConfigNames) {
String url = eddaClient.getBaseUrl(region) + "/aws/launchConfigurations;";
if (launchConfigNames != null && launchConfigNames.length != 0) {
url += StringUtils.join(launchConfigNames, ',');
LOGGER.info(String.format("Getting launch configurations in region %s for %d ids", region, launchConfigNames.length));
} else {
LOGGER.info(String.format("Getting all launch configurations in region %s", region));
}
url += ";_expand:(launchConfigurationName,createdTime)";
JsonNode jsonNode = null;
try {
jsonNode = eddaClient.getJsonNodeFromUrl(url);
} catch (Exception e) {
LOGGER.error(String.format("Failed to get Jason node from edda for instances in region %s.", region), e);
}
if (jsonNode == null || !jsonNode.isArray()) {
throw new RuntimeException(String.format("Failed to get valid document from %s, got: %s", url, jsonNode));
}
List<Resource> resources = Lists.newArrayList();
Set<String> usedLCs = getLaunchConfigsInUse(region);
for (Iterator<JsonNode> it = jsonNode.getElements(); it.hasNext(); ) {
JsonNode launchConfiguration = it.next();
String lcName = launchConfiguration.get("launchConfigurationName").getTextValue();
Resource lcResource = new AWSResource().withId(lcName).withRegion(region).withResourceType(AWSResourceType.LAUNCH_CONFIG).withLaunchTime(new Date(launchConfiguration.get("createdTime").getLongValue()));
lcResource.setOwnerEmail(getOwnerEmailForResource(lcResource));
lcResource.setAdditionalField(LAUNCH_CONFIG_FIELD_USED_BY_ASG, String.valueOf(usedLCs.contains(lcName)));
resources.add(lcResource);
}
return resources;
}
use of com.netflix.simianarmy.Resource in project SimianArmy by Netflix.
the class BasicJanitorRuleEngine method isValid.
/**
* Decides whether the resource should be a candidate of cleanup based on the underlying rules. If any rule in the
* rule set thinks the resource should be a candidate of cleanup, the method returns false which indicates that the
* resource should be marked for cleanup. If multiple rules think the resource should be cleaned up, the rule with
* the nearest expected termination time fills the termination reason and expected termination time.
*
* @param resource
* The resource
* @return true if the resource is valid and should not be a candidate of cleanup based on the underlying rules,
* false otherwise.
*/
@Override
public boolean isValid(Resource resource) {
LOGGER.debug(String.format("Checking if resource %s of type %s is a cleanup candidate against %d rules and %d exclusion rules.", resource.getId(), resource.getResourceType(), rules.size(), exclusionRules.size()));
for (Rule exclusionRule : exclusionRules) {
if (exclusionRule.isValid(resource)) {
LOGGER.info(String.format("Resource %s is not marked as a cleanup candidate because of an exclusion rule.", resource.getId()));
return true;
}
}
// We create a clone of the resource each time when we try the rule. In the first iteration of the rules
// we identify the rule with the nearest termination date if there is any rule considers the resource
// as a cleanup candidate. Then the rule is applied to the original resource.
Rule nearestRule = null;
if (rules.size() == 1) {
nearestRule = rules.get(0);
} else {
Date nearestTerminationTime = null;
for (Rule rule : rules) {
Resource clone = resource.cloneResource();
if (!rule.isValid(clone)) {
if (clone.getExpectedTerminationTime() != null) {
if (nearestTerminationTime == null || nearestTerminationTime.after(clone.getExpectedTerminationTime())) {
nearestRule = rule;
nearestTerminationTime = clone.getExpectedTerminationTime();
}
}
}
}
}
if (nearestRule != null && !nearestRule.isValid(resource)) {
LOGGER.info(String.format("Resource %s is marked as a cleanup candidate.", resource.getId()));
return false;
} else {
LOGGER.info(String.format("Resource %s is not marked as a cleanup candidate.", resource.getId()));
return true;
}
}
Aggregations