diff --git a/build.gradle b/build.gradle index 90c80af1b4..d77d76121a 100644 --- a/build.gradle +++ b/build.gradle @@ -34,7 +34,7 @@ allprojects { group = "com.netflix.spinnaker.orca" ext { - spinnakerDependenciesVersion = project.hasProperty('spinnakerDependenciesVersion') ? project.property('spinnakerDependenciesVersion') : '0.125.0' + spinnakerDependenciesVersion = project.hasProperty('spinnakerDependenciesVersion') ? project.property('spinnakerDependenciesVersion') : '0.127.0' } def checkLocalVersions = [spinnakerDependenciesVersion: spinnakerDependenciesVersion] diff --git a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/manifest/DeployManifestTask.java b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/manifest/DeployManifestTask.java index 81668d8d8e..bc2844b8a0 100644 --- a/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/manifest/DeployManifestTask.java +++ b/orca-clouddriver/src/main/groovy/com/netflix/spinnaker/orca/clouddriver/tasks/manifest/DeployManifestTask.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableMap; import com.netflix.spinnaker.kork.artifacts.model.Artifact; +import com.netflix.spinnaker.kork.artifacts.model.ExpectedArtifact; import com.netflix.spinnaker.orca.ExecutionStatus; import com.netflix.spinnaker.orca.Task; import com.netflix.spinnaker.orca.TaskResult; @@ -26,18 +27,17 @@ import com.netflix.spinnaker.orca.clouddriver.model.TaskId; import com.netflix.spinnaker.orca.clouddriver.tasks.AbstractCloudProviderAwareTask; import com.netflix.spinnaker.orca.pipeline.model.Stage; -import com.netflix.spinnaker.orca.pipeline.model.StageContext; +import com.netflix.spinnaker.orca.pipeline.util.ArtifactResolver; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.Nonnull; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; @Component @Slf4j @@ -45,6 +45,9 @@ public class DeployManifestTask extends AbstractCloudProviderAwareTask implement @Autowired KatoService kato; + @Autowired + ArtifactResolver artifactResolver; + public static final String TASK_NAME = "deployManifest"; @Nonnull @@ -53,24 +56,20 @@ public TaskResult execute(@Nonnull Stage stage) { String credentials = getCredentials(stage); String cloudProvider = getCloudProvider(stage); - List artifacts = new ArrayList<>(); - if (stage.getContext() instanceof StageContext) { - artifacts = (List) ((StageContext) stage.getContext()).getAll("artifacts") - .stream() - .filter(a -> a instanceof List) - .flatMap(x -> ((List) x).stream()) - .collect(Collectors.toList()); - } else { - log.warn("Unable to read artifacts from unknown context type: {} ({})", stage.getContext().getClass(), stage.getExecution().getId()); + List artifacts = artifactResolver.getArtifacts(stage); + Map task = new HashMap(stage.getContext()); + String artifactSource = (String) task.get("source"); + if (StringUtils.isNotEmpty(artifactSource) && artifactSource.equals("artifact")) { + Artifact manifestArtifact = artifactResolver.getBoundArtifactForId(stage, task.get("manifestArtifactId").toString()); + task.put("manifestArtifact", manifestArtifact); + log.info("Using {} as the manifest to be deployed", manifestArtifact); } - Map task = new HashMap(stage.getContext()); task.put("artifacts", artifacts); Map operation = new ImmutableMap.Builder() .put(TASK_NAME, task) .build(); - System.out.println("op = " + operation.keySet()); TaskId taskId = kato.requestOperations(cloudProvider, Collections.singletonList(operation)).toBlocking().first(); Map outputs = new ImmutableMap.Builder() diff --git a/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ArtifactResolver.groovy b/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ArtifactResolver.groovy index 1dc45d4c7b..1a8bf230f6 100644 --- a/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ArtifactResolver.groovy +++ b/orca-core/src/main/groovy/com/netflix/spinnaker/orca/pipeline/util/ArtifactResolver.groovy @@ -19,17 +19,51 @@ package com.netflix.spinnaker.orca.pipeline.util import com.fasterxml.jackson.databind.ObjectMapper import com.netflix.spinnaker.kork.artifacts.model.Artifact import com.netflix.spinnaker.kork.artifacts.model.ExpectedArtifact +import com.netflix.spinnaker.orca.pipeline.model.Stage +import com.netflix.spinnaker.orca.pipeline.model.StageContext import com.netflix.spinnaker.orca.pipeline.persistence.ExecutionRepository +import groovy.util.logging.Slf4j import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component import rx.schedulers.Schedulers @Component +@Slf4j class ArtifactResolver { @Autowired private ObjectMapper objectMapper + List getArtifacts(Stage stage) { + List artifacts = new ArrayList<>() + if (stage.getContext() instanceof StageContext) { + artifacts = (List) ((StageContext) stage.getContext()).getAll("artifacts") + .collect { s -> (List) ((List) s).collect { a -> (Artifact) a }} + .flatten() + } else { + log.warn("Unable to read artifacts from unknown context type: {} ({})", stage.getContext().getClass(), stage.getExecution().getId()); + } + + return artifacts + } + + Artifact getBoundArtifactForId(Stage stage, String id) { + if (!id) { + return null + } + + List expectedArtifacts = new ArrayList<>() + if (stage.getContext() instanceof StageContext) { + expectedArtifacts = (List) ((StageContext) stage.getContext()).getAll("resolvedExpectedArtifacts") + .collect { s -> (List) ((List) s).collect { a -> (ExpectedArtifact) a }} + .flatten() + } else { + log.warn("Unable to read resolved expected artifacts from unknown context type: {} ({})", stage.getContext().getClass(), stage.getExecution().getId()); + } + + return expectedArtifacts.find { e -> e.getId() == id }?.boundArtifact + } + void resolveArtifacts(ExecutionRepository repository, Map pipeline) { List expectedArtifacts = pipeline.expectedArtifacts?.collect { objectMapper.convertValue(it, ExpectedArtifact.class) } ?: [] List receivedArtifacts = pipeline.receivedArtifacts?.collect { objectMapper.convertValue(it, Artifact.class) } ?: [] @@ -67,6 +101,7 @@ class ArtifactResolver { if (!resolved) { throw new IllegalStateException("Unmatched expected artifact ${expectedArtifact} could not be resolved.") } else { + expectedArtifact.boundArtifact = resolved resolvedArtifacts.add(resolved) } } @@ -93,6 +128,7 @@ class ArtifactResolver { for (ExpectedArtifact expectedArtifact : expectedArtifacts) { Artifact resolved = resolveSingleArtifact(expectedArtifact, receivedArtifacts) if (resolved) { + expectedArtifact.boundArtifact = resolved result.resolvedArtifacts.add(resolved) } else { result.unresolvedExpectedArtifacts.add(expectedArtifact)