Skip to content

Commit

Permalink
wip: configure helmfile promotion per env
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronbraid committed Jan 27, 2021
1 parent ba547aa commit 21f1177
Show file tree
Hide file tree
Showing 26 changed files with 72 additions and 195 deletions.
6 changes: 3 additions & 3 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,13 @@ same cluster using the same git repository URL as the dev environment</p>
</tr>
<tr>
<td>
<code>keepOldReleases</code></br>
<code>KeepOldVersions</code></br>
<em>
bool
[]string
</em>
</td>
<td>
<p>KeepOldReleases if specified will cause the old releases to be retailed in the helfile</p>
<p>KeepOldVersions if specified will cause the named repo/release releases to be retailed in the helmfile</p>
</td>
</tr>
</tbody>
Expand Down
4 changes: 0 additions & 4 deletions pkg/apis/promote/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ type HelmfileRule struct {
// same cluster using the same git repository URL as the dev environment
Namespace string `json:"namespace"`

// KeepOldReleases if specified will cause the old releases to be retailed in the helfile
// Deprecated : use KeepOldVersions
KeepOldReleases bool `json:"keepOldReleases"`

// KeepOldVersions if specified is a list of release names and if the release name is in this list then the old versions are kept
KeepOldVersions []string `json:"keepOldVersions"`
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/promoteconfig/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func Discover(dir, promoteNamespace string) (*v1alpha1.Promote, string, error) {
if err != nil {
return nil, "", errors.Wrapf(err, "failed to find helmfile")
}

config = &v1alpha1.Promote{
ObjectMeta: metav1.ObjectMeta{
Name: "generated",
Expand All @@ -59,6 +60,7 @@ func Discover(dir, promoteNamespace string) (*v1alpha1.Promote, string, error) {
},
},
}

return config, "", nil
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/rules/factory/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func TestRuleFactory(t *testing.T) {
if name == "jenkins-x-versions" {
continue
}
if name != "helmfile-per-env-keep-old-version" {
continue
}

dir := filepath.Join(tmpDir, name)

Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: promote.jenkins-x.io/v1alpha1
kind: HelmfilePromote
spec:
keepOldVersions:
- dev/myapp
70 changes: 59 additions & 11 deletions pkg/rules/helmfile/helmfile_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package helmfile

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

Expand All @@ -12,9 +13,11 @@ import (
"github.com/jenkins-x/jx-promote/pkg/rules"
"github.com/pkg/errors"
"github.com/roboll/helmfile/pkg/state"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kyaml "sigs.k8s.io/yaml"
)

// HelmfileRule uses a jx-apps.yml file
// Rule uses a helmfile.yaml file
func Rule(r *rules.PromoteRule) error {
config := r.Config
if config.Spec.HelmfileRule == nil {
Expand All @@ -25,7 +28,21 @@ func Rule(r *rules.PromoteRule) error {
rule.Path = "helmfile.yaml"
}

err := modifyHelmfile(r, rule, filepath.Join(r.Dir, rule.Path), rule.Namespace)
envHelmfileRulePath := filepath.Join(r.Dir, "helmfiles", rule.Namespace, "promote.yaml")
exists, err := files.FileExists(envHelmfileRulePath)
if err != nil {
return errors.Wrapf(err, "failed to check if file exists %s", envHelmfileRulePath)
}
if exists {
// environment specific HelmfileRule
envHemlfileRule, err := LoadHelmfilePromote(envHelmfileRulePath)
if err != nil {
return errors.Wrapf(err, "failed load %s", envHelmfileRulePath)
}
config.Spec.HelmfileRule.KeepOldVersions = envHemlfileRule.Spec.KeepOldVersions
}

err = modifyHelmfile(r, rule, filepath.Join(r.Dir, rule.Path), rule.Namespace)
if err != nil {
return errors.Wrapf(err, "failed to modify chart files in dir %s", r.Dir)
}
Expand Down Expand Up @@ -118,16 +135,20 @@ func modifyHelmfileApps(r *rules.PromoteRule, helmfile *state.HelmState, promote

isRemoteEnv := r.DevEnvContext.DevEnv.Spec.RemoteCluster

keepOldReleases := r.Config.Spec.HelmfileRule.KeepOldReleases || contains(r.Config.Spec.HelmfileRule.KeepOldVersions, details.Name)
keepOldVersions := contains(r.Config.Spec.HelmfileRule.KeepOldVersions, details.Name)

if nestedHelmfile {
// for nested helmfiles we assume we don't need to specify a namespace on each chart
// as all the charts will use the same namespace
if promoteNs != "" && helmfile.OverrideNamespace == "" {
helmfile.OverrideNamespace = promoteNs
if len(helmfile.Releases) == 0 {
// for nested helmfiles when adding the first release, set it up as the override
// then when future releases are added they can omit the namespace if their namespace matches this override
// if different namespaces are required for releases, manual edits should be done to
// set the namespace of EVERY release and make OverrideNamespace blank
if promoteNs != "" && helmfile.OverrideNamespace == "" {
helmfile.OverrideNamespace = promoteNs
}
}
found := false
if !keepOldReleases {
if !keepOldVersions {
for i := range helmfile.Releases {
release := &helmfile.Releases[i]
if release.Name == app || release.Name == details.Name {
Expand All @@ -143,7 +164,7 @@ func modifyHelmfileApps(r *rules.PromoteRule, helmfile *state.HelmState, promote
ns = promoteNs
}
newReleaseName := details.LocalName
if keepOldReleases {
if keepOldVersions {
newReleaseName = fmt.Sprintf("%s-%s", details.LocalName, version)
}
helmfile.Releases = append(helmfile.Releases, state.ReleaseSpec{
Expand All @@ -156,7 +177,7 @@ func modifyHelmfileApps(r *rules.PromoteRule, helmfile *state.HelmState, promote
return nil
}
found := false
if !keepOldReleases {
if !keepOldVersions {
for i := range helmfile.Releases {
release := &helmfile.Releases[i]
if (release.Name == app || release.Name == details.Name) && (release.Namespace == promoteNs || isRemoteEnv) {
Expand All @@ -169,7 +190,7 @@ func modifyHelmfileApps(r *rules.PromoteRule, helmfile *state.HelmState, promote

if !found {
newReleaseName := details.LocalName
if keepOldReleases {
if keepOldVersions {
newReleaseName = fmt.Sprintf("%s-%s", details.LocalName, version)
}
helmfile.Releases = append(helmfile.Releases, state.ReleaseSpec{
Expand Down Expand Up @@ -237,3 +258,30 @@ func contains(arr []string, str string) bool {
}
return false
}

// HelmfilePromote is for configuring promotion for an environment
type HelmfilePromote struct {
metav1.TypeMeta `json:",inline"`

Spec HelmfilePromoteSpec `json:"spec"`
}

// HelmfilePromoteSpec defines the configuration for an environment
type HelmfilePromoteSpec struct {
// keepOldVersions if specified is a list of release names and if the release name is in this list then the old versions are kept
KeepOldVersions []string `json:"keepOldVersions,omitempty"`
}

// LoadHelmfilePromote loads a HelmfilePromote from a specific YAML file
func LoadHelmfilePromote(fileName string) (*HelmfilePromote, error) {
data, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, errors.Wrapf(err, "failed to read file %s", fileName)
}
config := &HelmfilePromote{}
err = kyaml.Unmarshal(data, config)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal YAML file %s due to %s", fileName, err)
}
return config, nil
}

0 comments on commit 21f1177

Please sign in to comment.