# HG changeset patch # User Florent Aide <florent.aide@gmail.com> # Date 1697627078 -7200 # Wed Oct 18 13:04:38 2023 +0200 # Node ID 3d9d30f69999e66becbf9e0bff94e57f473208c9 # Parent ac27a21a752d0019cb108f683ad38bb9aea3e2aa add test coverage for beaver namespaces as variables diff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -155,8 +155,7 @@ ## Beaver variables -`beaver` variables can be used inside your value files, and **only** inside value -files, using the following syntax: +`beaver` variables can be used inside your value files, using the following syntax: ``` <[variable_name]> @@ -199,6 +198,67 @@ here `pg_tag` value will be `13.7-alpine` if you run `beaver build environments/demo`. +### Beaver variables in the beaver namespace itself + +You can set some variables in the 'namespace' keyword of a beaver file. + +```yaml +# example/base/beaver.yml +namespace: <[myns]> +charts: + demoytt: + type: ytt + path: demoytt.tmpl.yaml +``` + +in this case this means this base is not useable by itself but can now be adapted by the caller by setting a beaver +variable to fill the slot + +```yaml +# example/ns1/beaver.yml +namespace: ns1 +inherit: ../base +variables: +- name: myns + value: ns1yo +``` + +This is a somewhat warped example but in this case the resulting ouput dir (namespace for beaver) will be example/build/ns1yo + +### variables inside the charts.disabled flag + +imagine a base with a chart that is disabled by default + +```yaml +# example/base/beaver.yml +namespace: example +charts: + demoytt: + type: ytt + path: demoytt.tmpl.yaml + disabled: <[configmapDisabled]> +variables: +- name: configmapDisabled + value: true +``` + +and another file that inherits from this base and want to have this chart enabled + +```yaml +# example/configmapenabled/beaver.yml +namespace: ns1 +inherit: ../base +variables: +- name: configmapDisabled + value: false +``` + +This can be used to allow for options in some inheritance cases where you want to enable/disable a certain backend like +a Redis server, a Postgresql server. +Your base provides the diverse options and your inheritance will pick the ones they need. + + + ## Output files `beaver` output files have the following format: @@ -209,7 +269,7 @@ all `apiVersion` slashes (`/`) are replaced by underscores (`_`). -This convention will help you reviewing merge requests. +This convention will help you review merge requests. By default `beaver` will store those files inside `${PWD}/build/<namespace>`, you can use `-o` or `--output` to specify an output directory. @@ -247,7 +307,7 @@ [ytt overlays](https://carvel.dev/ytt/docs/v0.39.0/ytt-overlays/) by providing `ytt.yaml` or `ytt.yml` files or a `ytt` folder inside your `beaver` project(s). -You can use `beaver` variables inside ytt files (outside of ytt folder), because +You can use `beaver` variables inside ytt files (outside ytt folder), because `beaver` considers those as value files. ## Create resources using kubectl create diff --git a/runner/config_test.go b/runner/config_test.go --- a/runner/config_test.go +++ b/runner/config_test.go @@ -21,6 +21,7 @@ shaFixtures = "fixtures/f2" helmNamespaceFixtures = "fixtures/f3" disabledAsVar = "fixtures/fDisabledAsVar" + namespaceAsVar = "fixtures/fNamespaceAsVar" ) func TestConfig(t *testing.T) { @@ -292,7 +293,70 @@ if !tCase.FilePresent { _, err = os.Stat(outPutConfigMapName) require.Error(t, err) - // file should not exist since it is disabled by a variable in the noconfigmap/beaver.yaml + // file should not exist since it is disabled by a variable in the ns2/beaver.yaml + require.True(t, errors.Is(err, os.ErrNotExist)) + } else { + _, err = os.Stat(outPutConfigMapName) + // file should exist + require.NoError(t, err) + } +} + +type namespaceTCase struct { + Name string + TestPath string + ExpectedBuildDir string + FilePresent bool +} + +func TestNamaspaceAsVariable(t *testing.T) { + tCases := []namespaceTCase{ + { + Name: "ns1yo", + TestPath: "ns1", + ExpectedBuildDir: filepath.Join(namespaceAsVar, "build", "ns1yo"), + FilePresent: true, + }, + { + Name: "ns2yo", + TestPath: "ns2", + ExpectedBuildDir: filepath.Join(namespaceAsVar, "build", "ns2yo"), + FilePresent: true, + }, + } + for _, tCase := range tCases { + t.Run(tCase.Name, func(t *testing.T) { + runTestBeaverNamespaceAsVariable(t, tCase) + }) + } +} + +func runTestBeaverNamespaceAsVariable(t *testing.T, tCase namespaceTCase) { + t.Helper() + defer func() { + require.NoError(t, runner.CleanDir(tCase.ExpectedBuildDir)) + require.NoError(t, os.RemoveAll(tCase.ExpectedBuildDir)) + }() + + tl := testutils.NewTestLogger(t) + absRootDir, err := filepath.Abs(namespaceAsVar) + require.NoError(t, err) + c := runner.NewCmdConfig(tl.Logger(), absRootDir, tCase.TestPath, false, "", "") + tmpDir, err := os.MkdirTemp(os.TempDir(), "beaver-") + require.NoError(t, err) + defer func() { + assert.NoError(t, os.RemoveAll(tmpDir)) + }() + require.NoError(t, c.Initialize(tmpDir)) + r := runner.NewRunner(c) + require.NoError(t, r.Build(tmpDir)) + + // the output file should be in a directory that matches the variable namespace + outPutConfigMapName := filepath.Join(tCase.ExpectedBuildDir, "ConfigMap.v1.demo.yaml") + if !tCase.FilePresent { + _, err = os.Stat(outPutConfigMapName) + require.Error(t, err) + // file should not exist since it is disabled by a variable in the ns2/beaver.yaml require.True(t, errors.Is(err, os.ErrNotExist)) } else { _, err = os.Stat(outPutConfigMapName) diff --git a/runner/fixtures/fDisabledAsVar/base/beaver.yaml b/runner/fixtures/fDisabledAsVar/base/beaver.yaml --- a/runner/fixtures/fDisabledAsVar/base/beaver.yaml +++ b/runner/fixtures/fDisabledAsVar/base/beaver.yaml @@ -4,3 +4,6 @@ type: ytt path: demoytt.tmpl.yaml disabled: <[configmapDisabled]> +variables: +- name: configmapDisabled + value: true diff --git a/runner/fixtures/fDisabledAsVar/base/beaver.yaml b/runner/fixtures/fNamespaceAsVar/base/beaver.yaml copy from runner/fixtures/fDisabledAsVar/base/beaver.yaml copy to runner/fixtures/fNamespaceAsVar/base/beaver.yaml --- a/runner/fixtures/fDisabledAsVar/base/beaver.yaml +++ b/runner/fixtures/fNamespaceAsVar/base/beaver.yaml @@ -1,6 +1,5 @@ -namespace: example +namespace: <[myns]> charts: demoytt: type: ytt path: demoytt.tmpl.yaml - disabled: <[configmapDisabled]> diff --git a/runner/fixtures/fDisabledAsVar/base/demoytt.tmpl.yaml b/runner/fixtures/fNamespaceAsVar/base/demoytt.tmpl.yaml copy from runner/fixtures/fDisabledAsVar/base/demoytt.tmpl.yaml copy to runner/fixtures/fNamespaceAsVar/base/demoytt.tmpl.yaml diff --git a/runner/fixtures/fDisabledAsVar/base/demoytt.yaml b/runner/fixtures/fNamespaceAsVar/base/demoytt.yaml copy from runner/fixtures/fDisabledAsVar/base/demoytt.yaml copy to runner/fixtures/fNamespaceAsVar/base/demoytt.yaml diff --git a/runner/fixtures/fDisabledAsVar/configmapenabled/beaver.yml b/runner/fixtures/fNamespaceAsVar/ns1/beaver.yml copy from runner/fixtures/fDisabledAsVar/configmapenabled/beaver.yml copy to runner/fixtures/fNamespaceAsVar/ns1/beaver.yml --- a/runner/fixtures/fDisabledAsVar/configmapenabled/beaver.yml +++ b/runner/fixtures/fNamespaceAsVar/ns1/beaver.yml @@ -1,5 +1,5 @@ namespace: ns1 inherit: ../base variables: -- name: configmapDisabled - value: false +- name: myns + value: ns1yo diff --git a/runner/fixtures/fDisabledAsVar/noconfigmap/beaver.yml b/runner/fixtures/fNamespaceAsVar/ns2/beaver.yml copy from runner/fixtures/fDisabledAsVar/noconfigmap/beaver.yml copy to runner/fixtures/fNamespaceAsVar/ns2/beaver.yml --- a/runner/fixtures/fDisabledAsVar/noconfigmap/beaver.yml +++ b/runner/fixtures/fNamespaceAsVar/ns2/beaver.yml @@ -1,5 +1,5 @@ -namespace: ns1 +namespace: ns2 inherit: ../base variables: -- name: configmapDisabled - value: true +- name: myns + value: ns2yo