Skip to content

Commit

Permalink
orca-issue-2
Browse files Browse the repository at this point in the history
  • Loading branch information
yejingtao committed Mar 5, 2020
1 parent 62d4c19 commit a8f6529
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.netflix.spinnaker.orca.clouddriver.pipeline.image;

import com.netflix.spinnaker.orca.clouddriver.tasks.image.FindImageFromNameTask;
import com.netflix.spinnaker.orca.pipeline.StageDefinitionBuilder;
import com.netflix.spinnaker.orca.pipeline.TaskNode;
import com.netflix.spinnaker.orca.pipeline.model.Stage;
import org.springframework.stereotype.Component;

@Component
public class FindImageFromNameStage implements StageDefinitionBuilder {
@Override
public void taskGraph(Stage stage, TaskNode.Builder builder) {
builder.withTask("findImage", FindImageFromNameTask.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.netflix.spinnaker.orca.clouddriver.tasks.image;

import com.netflix.spinnaker.orca.ExecutionStatus;
import com.netflix.spinnaker.orca.RetryableTask;
import com.netflix.spinnaker.orca.TaskResult;
import com.netflix.spinnaker.orca.clouddriver.tasks.AbstractCloudProviderAwareTask;
import com.netflix.spinnaker.orca.pipeline.model.Stage;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class FindImageFromNameTask extends AbstractCloudProviderAwareTask implements RetryableTask {

@Autowired
ObjectMapper objectMapper;

@Autowired
List<ImageFinder> imageFinders;

@Value("${tasks.findImageFromNameTimeoutMillis:10000}")
private Long findImageFromNameTimeoutMillis;

@Override
public TaskResult execute(Stage stage) {
String cloudProvider = getCloudProvider(stage);
ImageFinder imageFinder = imageFinders.stream()
.filter(it -> it.getCloudProvider().equals(cloudProvider))
.findFirst()
.orElseThrow(() -> new IllegalStateException("ImageFinder not found for cloudProvider " + cloudProvider));
FindImageFromNameTask.StageData stageData = (FindImageFromNameTask.StageData) stage.mapTo(FindImageFromNameTask.StageData.class);
Collection<ImageFinder.ImageDetails> imageDetails = imageFinder.byName(stage, stageData.packageName, stageData.imageName);

if (imageDetails == null || imageDetails.isEmpty()) {
throw new IllegalStateException("Could not find named image for package: " + stageData.packageName + " and name: " + stageData.imageName);
}

List<Artifact> artifacts = new ArrayList<>();
imageDetails.forEach(imageDetail -> artifacts.add(generateArtifactFrom(imageDetail, cloudProvider)));

Map<String, Object> stageOutputs = new HashMap<>();
stageOutputs.put("amiDetails", imageDetails);
stageOutputs.put("artifacts", artifacts);

return new TaskResult(
ExecutionStatus.SUCCEEDED,
stageOutputs,
Collections.singletonMap("deploymentDetails", imageDetails)
);
}

private Artifact generateArtifactFrom(ImageFinder.ImageDetails imageDetails, String cloudProvider) {
Map<String, Object> metadata = new HashMap<>();
try {
ImageFinder.JenkinsDetails jenkinsDetails = imageDetails.getJenkins();
metadata.put("build_info_url", jenkinsDetails.get("host"));
metadata.put("build_number", jenkinsDetails.get("number"));
} catch (Exception e) {
// This is either all or nothing
}

Artifact artifact = new Artifact();
artifact.setName(imageDetails.getImageName());
artifact.setReference(imageDetails.getImageId());
artifact.setLocation(imageDetails.getRegion());
artifact.setType(cloudProvider + "/image");
artifact.setMetadata(metadata);
artifact.setUuid(UUID.randomUUID().toString());

return artifact;
}

@Override
public long getBackoffPeriod() {
return 10000;
}

@Override
public long getTimeout() {
return this.findImageFromNameTimeoutMillis;
}

static class StageData {
@JsonProperty
String packageName;

@JsonProperty
String imageName;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@
import java.util.Map;

public interface ImageFinder {

Collection<ImageDetails> byTags(Stage stage, String packageName, Map<String, String> tags);

default Collection<ImageDetails> byName(Stage stage, String packageName, String imageName) {
return null;
}

String getCloudProvider();

interface ImageDetails {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package com.netflix.spinnaker.orca.clouddriver.tasks.providers.tencent

import com.netflix.spinnaker.orca.clouddriver.OortService
import com.netflix.spinnaker.orca.clouddriver.tasks.image.ImageFinder
import com.netflix.spinnaker.orca.pipeline.model.Stage
import java.util.stream.Collectors
import org.springframework.stereotype.Component
import org.springframework.beans.factory.annotation.Autowired
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.annotation.JsonProperty


@Component
class TencentImageFinder implements ImageFinder {

final String cloudProvider = "tencent"

@Autowired
OortService oortService

@Autowired
ObjectMapper objectMapper

@Override
String getCloudProvider() {
return cloudProvider
}


@Override
Collection<ImageDetails> byTags(
Stage stage, String packageName, Map<String, String> tags) {
//TO-DO
return null
}

@Override
Collection<ImageDetails> byName(Stage stage, String packageName, String imageName) {
StageData stageData = (StageData) stage.mapTo(StageData.class)
List<TencentCloudImage> allMatchedImages =
oortService.findImage(getCloudProvider(), packageName, null, null, ['imageName':imageName])
.stream()
.map({ objectMapper.convertValue(it, TencentCloudImage.class)} )
.collect(Collectors.toList())

if (allMatchedImages.size() > 0) {
TencentCloudImage latestImage = allMatchedImages[0]
return Collections.singletonList(latestImage.toTencentCloudImageDetails())
} else {
return null
}
}

private static class TencentCloudImage {
@JsonProperty
String imageName

@JsonProperty
Map<String, Object> attributes

ImageDetails toTencentCloudImageDetails() {
JenkinsDetails jenkinsDetails = new JenkinsDetails("", "", "")
String imageId = attributes.get("imageId").toString()
return new TencentImageDetails(imageName, imageId, jenkinsDetails)
}

}

private static class TencentImageDetails extends HashMap<String, Object> implements ImageDetails{

TencentImageDetails (String imageName, String imageId, JenkinsDetails jenkinsDetails) {
put("imageName", imageName)
put("imageId", imageId)
put("ami", imageId)
put("amiId", imageName)
put("region", "global")
put("jenkins", jenkinsDetails)
}
@Override
String getImageId() {
return (String) super.get("imageId")
}

@Override
String getImageName() {
return (String) super.get("imageName")
}

@Override
String getRegion() {
return (String) super.get("region")
}

@Override
JenkinsDetails getJenkins() {
return (JenkinsDetails) super.get("jenkins")
}
}

static class StageData {
@JsonProperty
Collection<String> regions
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ public ExceptionHandler.Response handle(String taskName, Exception e) {
exceptionDetails.put("stackTrace", Throwables.getStackTraceAsString(e));
log.warn(format("Error occurred during task %s", taskName), e);
return new ExceptionHandler.Response(e.getClass().getSimpleName(), taskName, exceptionDetails, false);
}
}
}

0 comments on commit a8f6529

Please sign in to comment.