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

Handle multiple backends for the TypeInstance #657

Merged
merged 13 commits into from
Mar 24, 2022
2 changes: 2 additions & 0 deletions hack/images/jinja2/jinja2-cli/jinja2cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ def cli(opts, args, config): # noqa: C901

if config.get("prefix") is not None and len(parsed_data) != 0:
parsed_data = {config["prefix"]: parsed_data}
if config.get("strip-value") is True and len(parsed_data) != 0 and "value" in parsed_data:
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
mszostok marked this conversation as resolved.
Show resolved Hide resolved
parsed_data = parsed_data.get("value", {})

template_path = os.path.abspath(template_path)
out.write(render(template_path, parsed_data, extensions, opts.filters, opts.strict))
Expand Down
8 changes: 7 additions & 1 deletion hack/images/merger/merger.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
SRC=${SRC:-"/yamls"}
OUT=${OUT:-"/merged.yaml"}

# prefix each file with its filename
for filename in "${SRC}"/*; do
filename=$(basename -- "$filename")
prefix="${filename%.*}"

# remove value key if exists
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

For consistency reason, it would be good to also have unpackValue conf option here. When I went through our manifests, it was hard to understand why it works in this way, as this is a "hidden" functionality.

But let's do that on a new follow-up PR. It's not a blocker for merging this one 👍

if [[ $(yq e 'has("value")' "${SRC}"/"${filename}") == "true" ]]; then
yq e '.value' -i "${SRC}"/"${filename}"
fi

# prefix each file with its filename
yq e -i "{\"${prefix}\": . }" "${SRC}"/"${filename}"
done

Expand Down
16 changes: 12 additions & 4 deletions internal/installation/capact_register.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,22 @@ func (i *CapactRegister) produceHelmReleaseTypeInstance(helmRelease *release.Rel
return nil, errors.Wrap(err, "while producing Helm release definition")
}

var unmarshalled interface{}
var unmarshalled map[string]interface{}
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
err = yaml.Unmarshal(releaseOut, &unmarshalled)
if err != nil {
return nil, errors.Wrap(err, "while unmarshaling bytes")
}
if _, ok := unmarshalled["value"]; !ok {
return nil, errors.Wrap(err, "while getting value from unmarshalled additional output")
}

return &gqllocalapi.CreateTypeInstanceInput{
Alias: ptr.String(helmRelease.Name),
TypeRef: &gqllocalapi.TypeInstanceTypeReferenceInput{
Path: helmReleaseTypeRefPath,
Revision: "0.1.0",
},
Value: unmarshalled,
Value: unmarshalled["value"],
}, nil
}

Expand All @@ -207,17 +210,22 @@ func (i *CapactRegister) produceConfigTypeInstance(ownerName string, helmRelease
return nil, errors.Wrap(err, "while producing additional info")
}

var unmarshalled interface{}
var unmarshalled map[string]interface{}
err = yaml.Unmarshal(data, &unmarshalled)
if err != nil {
return nil, errors.Wrap(err, "while unmarshaling bytes")
}

if _, ok := unmarshalled["value"]; !ok {
return nil, errors.Wrap(err, "while getting value from unmarshalled additional output")
}

return &gqllocalapi.CreateTypeInstanceInput{
Alias: ptr.String(ownerName),
TypeRef: &gqllocalapi.TypeInstanceTypeReferenceInput{
Path: capactTypeRefPath,
Revision: "0.1.0",
},
Value: unmarshalled,
Value: unmarshalled["value"],
}, nil
}
5 changes: 5 additions & 0 deletions pkg/argo-actions/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ func ErrMissingTypeInstanceValue(typeInstanceName string) error {
func ErrMissingResourceVersion() error {
return errors.Errorf("resourceVersion is missing")
}

// ErrTypeConversion returns an error indicating incorrect type conversion.
func ErrTypeConversion(field string, targetType string, typeInstanceName string) error {
return errors.Errorf("%s cannot be converted to %s for TypeInstances %s", field, targetType, typeInstanceName)
}
27 changes: 26 additions & 1 deletion pkg/argo-actions/upload_type_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,32 @@ func (u *Upload) render(payload *graphqllocal.CreateTypeInstancesInput, values m
return ErrMissingTypeInstanceValue(*typeInstance.Alias)
}

typeInstance.Value = value
// render value
if _, ok = value["value"]; ok {
typeInstanceValue, ok := value["value"].(map[string]interface{})
if !ok {
return ErrTypeConversion("value", "map[string]interface{}", *typeInstance.Alias)
}
typeInstance.Value = typeInstanceValue
} else {
// for backward compatibility, if there is an artifact without value/backend syntax,
// treat it as a value for TypeInstance
Copy link
Author

Choose a reason for hiding this comment

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

it is mainly for the case like here

typeInstance.Value = value
continue
}

// render backend
if _, ok := value["backend"]; ok {
typeInstanceBackend, ok := value["backend"].(map[string]interface{})
if !ok {
return ErrTypeConversion("backend", "map[string]interface{}", *typeInstance.Alias)
}
backendContext, ok := typeInstanceBackend["context"].(map[string]interface{})
if !ok {
return ErrTypeConversion("backend.context", "map[string]interface{}", *typeInstance.Alias)
}
typeInstance.Backend.Context = backendContext
}
}
return nil
}
Expand Down
19 changes: 19 additions & 0 deletions pkg/runner/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"io/ioutil"

"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)

// DefaultFilePermissions are the default file permissions
Expand All @@ -18,3 +19,21 @@ func SaveToFile(path string, bytes []byte) error {
}
return nil
}

// NestingOutputUnderValue write output to "value" key in YAML.
func NestingOutputUnderValue(output []byte) ([]byte, error) {
unmarshalled := map[string]interface{}{}
err := yaml.Unmarshal([]byte(output), &unmarshalled)
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, errors.Wrap(err, "while unmarshalling output to map[string]interface{}")
}

nestingOutputValue := map[string]interface{}{
"value": unmarshalled,
}
result, err := yaml.Marshal(&nestingOutputValue)
if err != nil {
return nil, errors.Wrap(err, "while marshaling output under a value key")
}
return result, nil
}
12 changes: 11 additions & 1 deletion pkg/runner/helm/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package helm
import (
"strings"

"capact.io/capact/pkg/runner"
"github.com/pkg/errors"
"go.uber.org/zap"
"helm.sh/helm/v3/pkg/chart"
Expand Down Expand Up @@ -39,7 +40,11 @@ func (o *Outputter) ProduceHelmRelease(repository string, helmRelease *release.R
},
}

bytes, err := yaml.Marshal(&releaseData)
nestingValue := map[string]interface{}{
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
"value": releaseData,
}

bytes, err := yaml.Marshal(&nestingValue)
if err != nil {
return nil, errors.Wrap(err, "while marshaling yaml")
}
Expand All @@ -60,5 +65,10 @@ func (o *Outputter) ProduceAdditional(args OutputArgs, chrt *chart.Chart, rel *r
return nil, errors.Wrap(err, "while rendering additional output")
}

bytes, err = runner.NestingOutputUnderValue(bytes)
if err != nil {
return nil, errors.Wrap(err, "while nesting output under a value key")
}

return bytes, nil
}
21 changes: 18 additions & 3 deletions pkg/runner/terraform/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,25 @@ func (r *terraformRunner) mergeInputVariables(variables string) error {
func (r *terraformRunner) saveOutput(out Output) error {
if out.Release != nil {
r.log.Debug("Saving terraform release output", zap.String("path", r.cfg.Output.TerraformReleaseFilePath))
err := runner.SaveToFile(r.cfg.Output.TerraformReleaseFilePath, out.Release)
bytesRelease, err := runner.NestingOutputUnderValue(out.Release)
if err != nil {
return errors.Wrap(err, "while nesting Terrafrom release under value")
}

err = runner.SaveToFile(r.cfg.Output.TerraformReleaseFilePath, bytesRelease)
if err != nil {
return errors.Wrap(err, "while saving terraform release output")
}
}

if out.Additional != nil {
r.log.Debug("Saving additional output", zap.String("path", r.cfg.Output.AdditionalFilePath))
err := runner.SaveToFile(r.cfg.Output.AdditionalFilePath, out.Additional)
bytesAdditional, err := runner.NestingOutputUnderValue(out.Additional)
if err != nil {
return errors.Wrap(err, "while nesting Terrafrom additional under value")
}

err = runner.SaveToFile(r.cfg.Output.AdditionalFilePath, bytesAdditional)
if err != nil {
return errors.Wrap(err, "while saving default output")
}
Expand All @@ -243,7 +253,12 @@ func (r *terraformRunner) saveOutput(out Output) error {
return errors.Wrap(err, "while marshaling state")
}

err = runner.SaveToFile(r.cfg.Output.TfstateFilePath, stateData)
nestingStateData, err := runner.NestingOutputUnderValue(stateData)
if err != nil {
return errors.Wrap(err, "while nesting Terrafrom state data under value")
}

err = runner.SaveToFile(r.cfg.Output.TfstateFilePath, nestingStateData)
if err != nil {
return errors.Wrap(err, "while saving tfstate output")
}
Expand Down
Loading