Skip to content

Commit

Permalink
feat(artifact): logic to handle reference URIs in overrides
Browse files Browse the repository at this point in the history
This commit updates the Helm util helpers that we have to include the
artifact store. This will allow us to inspect the raw strings and check
to see if we need to expand them.

Further, I opted to not utilize the deserializer this time, since this
problem seemed very specific to Helm. If that changes, we can always
just use the deserializer

Signed-off-by: benjamin-j-powell <bjp@apple.com>
  • Loading branch information
benjamin-j-powell committed Feb 3, 2024
1 parent 845c8f5 commit ad5f0c0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,42 @@

package com.netflix.spinnaker.rosco.manifests;

import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import com.netflix.spinnaker.kork.exceptions.SpinnakerException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactReferenceURI;
import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStore;
import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStoreConfigurationProperties;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import com.netflix.spinnaker.kork.exceptions.SpinnakerException;
import com.netflix.spinnaker.kork.retrofit.exceptions.SpinnakerHttpException;

import lombok.Getter;

public abstract class HelmBakeTemplateUtils<T extends BakeManifestRequest> {
private static final String MANIFEST_SEPARATOR = "---\n";
private static final Pattern REGEX_TESTS_MANIFESTS =
Pattern.compile("# Source: .*/templates/tests/.*");

private final ArtifactDownloader artifactDownloader;
@Getter private final ArtifactDownloader artifactDownloader;
private final ArtifactStore artifactStore;
private final ArtifactStoreConfigurationProperties.HelmConfig helmConfig;

protected HelmBakeTemplateUtils(ArtifactDownloader artifactDownloader) {
protected HelmBakeTemplateUtils(
ArtifactDownloader artifactDownloader,
Optional<ArtifactStore> artifactStore,
ArtifactStoreConfigurationProperties.HelmConfig helmConfig) {
this.artifactDownloader = artifactDownloader;
}

public ArtifactDownloader getArtifactDownloader() {
return artifactDownloader;
this.artifactStore = artifactStore.orElse(null);
this.helmConfig = helmConfig;
}

public abstract String fetchFailureMessage(String description, Exception e);
Expand Down Expand Up @@ -103,4 +113,32 @@ protected Path getHelmTypePathFromArtifact(

return helmTypeFilePath;
}

/**
* This is a helper method to build the appropriate overrides in the event that an
* ArtifactReferenceURI was passed in an override
*/
protected List<String> buildOverrideList(Map<String, Object> overrides) {
return overrides.entrySet().stream()
.map(entry -> entry.getKey() + "=" + expandArtifactReferenceURIs(entry.getValue()).toString())
.collect(Collectors.toList());
}

/**
* In the event that we encounter and ArtifactReferenceURI, we want to pull
* down that artifact instead of using the raw URI as a value for helm.
*/
private Object expandArtifactReferenceURIs(Object value) {
if (artifactStore == null || !(helmConfig.isExpandOverrides() && value instanceof String)) {
return value;
}

String ref = (String) value;
if (ArtifactReferenceURI.is(ref)) {
Artifact artifact = artifactStore.get(ArtifactReferenceURI.parse(ref));
return artifact.getReference();
}

return ref;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.netflix.spinnaker.rosco.manifests.helm;

import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStore;
import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStoreConfigurationProperties;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import com.netflix.spinnaker.rosco.jobs.BakeRecipe;
import com.netflix.spinnaker.rosco.manifests.ArtifactDownloader;
Expand All @@ -12,20 +14,25 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
@Slf4j
@ConfigurationPropertiesScan("com.netflix.spinnaker.kork.artifacts.artifactstore")
public class HelmTemplateUtils extends HelmBakeTemplateUtils<HelmBakeManifestRequest> {
private final RoscoHelmConfigurationProperties helmConfigurationProperties;

public HelmTemplateUtils(
ArtifactDownloader artifactDownloader,
Optional<ArtifactStore> artifactStore,
ArtifactStoreConfigurationProperties artifactStoreProperties,
RoscoHelmConfigurationProperties helmConfigurationProperties) {
super(artifactDownloader);
super(artifactDownloader, artifactStore, artifactStoreProperties.getHelm());
this.helmConfigurationProperties = helmConfigurationProperties;
}

Expand Down Expand Up @@ -103,10 +110,7 @@ public BakeRecipe buildCommand(

Map<String, Object> overrides = request.getOverrides();
if (overrides != null && !overrides.isEmpty()) {
List<String> overrideList = new ArrayList<>();
for (Map.Entry<String, Object> entry : overrides.entrySet()) {
overrideList.add(entry.getKey() + "=" + entry.getValue().toString());
}
List<String> overrideList = buildOverrideList(overrides);
String overrideOption = request.isRawOverrides() ? "--set" : "--set-string";
command.add(overrideOption);
command.add(String.join(",", overrideList));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.netflix.spinnaker.rosco.manifests.helmfile;

import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStore;
import com.netflix.spinnaker.kork.artifacts.artifactstore.ArtifactStoreConfigurationProperties;
import com.netflix.spinnaker.kork.artifacts.model.Artifact;
import com.netflix.spinnaker.rosco.jobs.BakeRecipe;
import com.netflix.spinnaker.rosco.manifests.ArtifactDownloader;
Expand All @@ -28,6 +30,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
Expand All @@ -41,8 +44,10 @@ public class HelmfileTemplateUtils extends HelmBakeTemplateUtils<HelmfileBakeMan

public HelmfileTemplateUtils(
ArtifactDownloader artifactDownloader,
Optional<ArtifactStore> artifactStore,
ArtifactStoreConfigurationProperties artifactStoreConfig,
RoscoHelmfileConfigurationProperties helmfileConfigurationProperties) {
super(artifactDownloader);
super(artifactDownloader, artifactStore, artifactStoreConfig.getHelm());
this.helmfileConfigurationProperties = helmfileConfigurationProperties;
}

Expand Down Expand Up @@ -105,10 +110,7 @@ public BakeRecipe buildCommand(

Map<String, Object> overrides = request.getOverrides();
if (!overrides.isEmpty()) {
List<String> overrideList = new ArrayList<>();
for (Map.Entry<String, Object> entry : overrides.entrySet()) {
overrideList.add(entry.getKey() + "=" + entry.getValue().toString());
}
List<String> overrideList = buildOverrideList(overrides);
command.add("--set");
command.add(String.join(",", overrideList));
}
Expand Down

0 comments on commit ad5f0c0

Please sign in to comment.