Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(manifests/helmfile): add helmfile templating engine #986

Merged

Conversation

thameezb
Copy link
Contributor

@thameezb thameezb commented May 23, 2023

Related to spinnaker/spinnaker#6837

Adds in support for helmfile as a "Render Engine" in the "Bake (Manifest)" stage.

This allows for existing helm configuration to still be used even when using helmfile (including additional value artifacts and explicit overrides) - fully debatable if this functionality should be allowed or not

Allows for usage with either helm2 or helm3 as the underlying templating engine - once again this is debatable if actually required

TODO:

  • add helmfile installation to docker files
  • add code to implement helmfile support
  • tests

@thameezb thameezb marked this pull request as draft May 23, 2023 15:16
@thameezb thameezb changed the title draft: feat(manifests/helmfile): add helmfile templating engine feat(manifests/helmfile): add helmfile templating engine May 23, 2023
@thameezb thameezb force-pushed the feat-6837/addHelmfileTemplatingEngine branch from bdc44b4 to 1ac6324 Compare May 24, 2023 13:40
@thameezb thameezb force-pushed the feat-6837/addHelmfileTemplatingEngine branch from 1ac6324 to 7eab89f Compare June 5, 2023 15:13
feat(manifests/helmfile): add tests
@thameezb thameezb force-pushed the feat-6837/addHelmfileTemplatingEngine branch from 7eab89f to 95ff86b Compare June 7, 2023 12:07
@thameezb thameezb marked this pull request as ready for review June 12, 2023 12:44
@@ -4,6 +4,7 @@ LABEL maintainer="sig-platform@spinnaker.io"
ENV KUSTOMIZE_VERSION=3.8.6
ENV KUSTOMIZE4_VERSION=4.5.5
ENV PACKER_VERSION=1.8.1
ENV HELMFILE_VERSION=0.153.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that 0.154.0 has now appeared. I'm OK to go ahead with 0.153.1 and update in a follow-up PR.

Copy link
Contributor

@mazzy89 mazzy89 Jul 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this PR, 0.155.0 has come out. Once this will be merged we are going to bump the version of helmfile.

@ConfigurationProperties("helmfile")
@Data
public class RoscoHelmfileConfigurationProperties {
private String ExecutablePath = "helmfile";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private String ExecutablePath = "helmfile";
private String executablePath = "helmfile";

return "Failed to fetch helmfile " + description + ": " + e.getMessage();
}

public String removeTestsDirectoryTemplates(String inputString) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's figure out a way to reduce the duplication / share the code in HelmTemplateUtils.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made a proposal for the this problem in here #986 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this method under an abstract class.

@@ -0,0 +1,18 @@
package com.netflix.spinnaker.rosco.manifests.helmfile;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

License header, here and elsewhere.

@@ -0,0 +1,674 @@
/*
* Copyright 2019 Google, LLC
Copy link
Contributor

@dbyron-sf dbyron-sf Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Copyright 2019 Google, LLC
* Copyright 2023 Grab Holdings, Inc.

@@ -0,0 +1,26 @@
/*
* Copyright 2020 Grab Holdings, Inc.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Copyright 2020 Grab Holdings, Inc.
* Copyright 2023 Grab Holdings, Inc.

import org.junit.runner.RunWith;
import org.springframework.http.HttpStatus;

@RunWith(JUnitPlatform.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this line. Once it's gone, the imports can go too.

private String environment;
private String namespace;

List<Artifact> inputArtifacts;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add javadoc for each member, but especially this one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return supportedTemplates.contains(type);
}

public Artifact bake(HelmfileBakeManifestRequest helmfileBakeManifestRequest) throws IOException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so close to HelmBakeManifestService. How can we share the code?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put this code within the new package suggested here com.netflix.spinnaker.rosco.manifests.utils.helm. what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code this is a function a bit hard to reduce in an OOP. I would need to create a separate class (abstract) to share only thing function. happy to hear here any proposals.

throw new SpinnakerHttpException(fetchFailureMessage("values file", e), e);
} catch (IOException | SpinnakerException e) {
throw new IllegalStateException(fetchFailureMessage("values file", e), e);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From here up, this basically dupilcates HelmTemplateUtils.buildBakeRecipe. How can we share the code?

Copy link
Contributor

@mazzy89 mazzy89 Jun 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. The HelmTemplateUtils is spread of duplications. What about to create a common utils class for both helm and helmfile baker? Not sure under which package to place though. Perhaps I would have to create a new package com.netflix.spinnaker.rosco.manifests.utils.helm. what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbyron-sf I've tried to make the HelmTemplateUtils and HelmfileTemplateUtils dryer reusing where I could the code. The only thing missing to reduce is https://github.com/thameezb/rosco/blob/7e1f5160aaa7459b22009484ea56c8b6dcd8aea9/rosco-manifests/src/main/java/com/netflix/spinnaker/rosco/manifests/helmfile/HelmfileTemplateUtils.java#L55-L97 but I cannot find a good way to reduce everything when there are in the middle POJOs. do you have any better ideas?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also reduce another bit the code in this commit 256756c

Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>

@ConfigurationProperties("helmfile")
@Data
public class RoscoHelmfileConfigurationProperties {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefix Rosco is unnecessary

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the other files have the Rosco prefix. we have just used the same conventions as the other files.


import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should avoid *

Comment on lines 55 to 84
BakeRecipe result = new BakeRecipe();
result.setName(request.getOutputName());

Path helmfileFilePath;
List<Path> valuePaths;

List<Artifact> inputArtifacts = request.getInputArtifacts();
if (inputArtifacts == null || inputArtifacts.isEmpty()) {
throw new IllegalArgumentException("At least one input artifact must be provided to bake");
}

log.info("helmfileFilePath: '{}'", request.getHelmfileFilePath());
Artifact helmfileTemplateArtifact = inputArtifacts.get(0);
String artifactType = Optional.ofNullable(helmfileTemplateArtifact.getType()).orElse("");
if ("git/repo".equals(artifactType)) {
env.downloadArtifactTarballAndExtract(super.getArtifactDownloader(), helmfileTemplateArtifact);

// If there's no helmfile path specified, assume it lives in the root of
// the git/repo artifact.
helmfileFilePath =
env.resolvePath(Optional.ofNullable(request.getHelmfileFilePath()).orElse(""));
} else {
try {
helmfileFilePath = downloadArtifactToTmpFile(env, helmfileTemplateArtifact);
} catch (SpinnakerHttpException e) {
throw new SpinnakerHttpException(fetchFailureMessage("template", e), e);
} catch (IOException | SpinnakerException e) {
throw new IllegalStateException(fetchFailureMessage("template", e), e);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this code is duplicated

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is duplicated but it is not easy to reuse. Please if you can recommend any ways to reuse this code I would appreciate it. Thanks

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to extract duplication either to a utilities class or similar in -core type projects. Possibly rewriting some of the inputs/outputs to be more "generic" on downloading to a tmp file. Note I'm PRETTY sure kustomize uses some of this same logic, so a generic "extract artifact to folder" utility that passes the resulting FS path.

I'd also argue for a chroot type setup where each one runs in isolation or you can hit some interesting concurrency issues (which we kinda already get with tmp file support.. but... I've been seeing more edge cases lately). Don't think THIS ask is doable, but moving to a "core" lib should be.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jasonmcintosh to provide some ideas. I'm going to check definitely whether the "core" lib way is a doable thing. I would like to avoid to introduce heavy refactors but certainly at this point it is too early to say that. I'll get back here once I have a more concrete idea.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this method(buildBakeRecipe) to HelmBakeTemplateUtils class and add an abstract method for the command(buildCommand, getCommand)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nemesisOsorio the whole buildBakeRecipe depends by request POJO which differs from Helm and Helmfile so moving buildBakeRecipe into HelmBakeTemplateUtils won't solve the problem.

Copy link
Contributor

@mazzy89 mazzy89 Jul 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the last changes, everything should result in more dry and favorite reuse.

jasonmcintosh and others added 3 commits July 5, 2023 09:21
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
@mazzy89
Copy link
Contributor

mazzy89 commented Jul 10, 2023

@jasonmcintosh @nemesisOsorio @dbyron-sf Everything has been addressed. now the code should look better.

@mazzy89
Copy link
Contributor

mazzy89 commented Jul 12, 2023

@thanks @nemesisOsorio for approving.
The build has run but there are some issues. going to address the errors

cc @dbyron-sf

mazzy89 and others added 3 commits July 13, 2023 09:57
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
Signed-off-by: Salvatore Mazzarino <salvatoremazz@double.cloud>
@mazzy89
Copy link
Contributor

mazzy89 commented Jul 13, 2023

@nemesisOsorio it's all green now. do you mind to start the merge process adding the proper label?

Copy link
Member

@jasonmcintosh jasonmcintosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, there are things I could see being improved, but as an initial feature I like this. Some cleanup and code reuse which is nice, overall, a solid new addition. I'd love to see the build command to be... redone but that can be a later thing.

@jasonmcintosh jasonmcintosh added the ready to merge Approved and ready for merge label Jul 14, 2023
@mergify mergify bot added the auto merged label Jul 14, 2023
@mergify mergify bot merged commit e5ea778 into spinnaker:master Jul 14, 2023
4 checks passed
@thameezb thameezb deleted the feat-6837/addHelmfileTemplatingEngine branch July 14, 2023 21:09
@thameezb
Copy link
Contributor Author

Big thanks to @mazzy89 and @jasonmcintosh for getting this to the finish line 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants