Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion function/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ require (
github.com/google/uuid v1.6.0
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/hcl/v2 v2.24.0
github.com/pkg/errors v0.9.1
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
github.com/zclconf/go-cty v1.17.0
Expand Down Expand Up @@ -75,6 +74,7 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.4 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
Expand Down
17 changes: 8 additions & 9 deletions function/internal/composition/composition.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/crossplane-contrib/function-hcl/function/internal/evaluator"
"github.com/ghodss/yaml"
"github.com/hashicorp/hcl/v2"
"github.com/pkg/errors"
"golang.org/x/tools/txtar"
)

Expand Down Expand Up @@ -91,10 +90,10 @@ func (l *loader) loadArchive(dir string) (*txtar.Archive, []evaluator.File, erro
func (l *loader) checkDir(dir string) (string, error) {
st, err := l.fs.Stat(dir)
if err != nil {
return "", errors.Wrapf(err, "stat %s", dir)
return "", fmt.Errorf("stat %s: %w", dir, err)
}
if !st.IsDir() {
return "", errors.Errorf("%s is not a directory", dir)
return "", fmt.Errorf("%s is not a directory", dir)
}
return dir, nil
}
Expand All @@ -110,15 +109,15 @@ func (l *loader) loadConfig(dir string) (*Config, error) {
return nil, err
}
if st.IsDir() {
return nil, errors.Errorf("%s is a directory", file)
return nil, fmt.Errorf("%s is a directory", file)
}
b, err := l.fs.ReadFile(file)
if err != nil {
return nil, err
}
err = yaml.Unmarshal(b, &cfg)
if err != nil {
return nil, errors.Wrapf(err, "unmarshal contents of %s", file)
return nil, fmt.Errorf("unmarshal contents of %s: %w", file, err)
}
return &cfg, nil
}
Expand All @@ -138,7 +137,7 @@ func (l *loader) fileList(dir string, cfg *Config) ([]string, error) {
file := filepath.Join(dir, entry.Name())
s, err := l.fs.Stat(file)
if err != nil {
return nil, errors.Wrapf(err, "stat %s", file)
return nil, fmt.Errorf("stat %s: %w", file, err)
}
if s.IsDir() {
continue
Expand All @@ -153,7 +152,7 @@ func (l *loader) fileList(dir string, cfg *Config) ([]string, error) {
log.Println(errMsg)
continue
}
return nil, errors.New(errMsg)
return nil, fmt.Errorf("%s", errMsg)
}
file = filepath.Clean(filepath.Join(dir, file))
s, err := l.fs.Stat(file)
Expand All @@ -163,15 +162,15 @@ func (l *loader) fileList(dir string, cfg *Config) ([]string, error) {
log.Println(errMsg)
continue
}
return nil, errors.New(errMsg)
return nil, fmt.Errorf("%s", errMsg)
}
if s.IsDir() {
errMsg := fmt.Sprintf("library file %s cannot be a directory", file)
if l.ignoreMetadataErrors {
log.Println(errMsg)
continue
}
return nil, errors.New(errMsg)
return nil, fmt.Errorf("%s", errMsg)
}
files = append(files, file)
}
Expand Down
21 changes: 10 additions & 11 deletions function/internal/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
fnv1 "github.com/crossplane/function-sdk-go/proto/v1"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"google.golang.org/protobuf/encoding/protojson"
)

Expand Down Expand Up @@ -158,7 +157,7 @@ func pavedStr(p *fieldpath.Paved, path string) string {
func setLabelOrAnnotation(p *fieldpath.Paved, elem, name, value string) error {
m, err := p.GetValue("metadata")
if err != nil {
return errors.Wrap(err, "get metadata")
return fmt.Errorf("get metadata: %w", err)
}
if _, ok := m.(object); !ok {
return fmt.Errorf("metadata was not an object")
Expand Down Expand Up @@ -278,31 +277,31 @@ func (p *Printer) Response(req *fnv1.RunFunctionRequest, res *fnv1.RunFunctionRe

err := pavedComp.GetValueInto("spec.claimRef", &cr)
if err != nil && !fieldpath.IsNotFound(err) {
return errors.Wrap(err, "get claimRef")
return fmt.Errorf("get claimRef: %w", err)
}

for name, o := range res.GetDesired().GetResources() {
r := o.Resource.AsMap()
// mimic what crossplane does after calling the function successfully
paved := fieldpath.Pave(r)
if err = paved.SetValue("metadata.generateName", compName+"-"); err != nil {
return errors.Wrap(err, "set metadata.generateName")
return fmt.Errorf("set metadata.generateName: %w", err)
}
if err = paved.SetValue("metadata.ownerReferences", ownerRefs); err != nil {
return errors.Wrap(err, "set owner references")
return fmt.Errorf("set owner references: %w", err)
}
if err = setAnnotation(paved, "crossplane.io/composition-resource-name", name); err != nil {
return errors.Wrap(err, "set crossplane.io/composition-resource-name annotation")
return fmt.Errorf("set crossplane.io/composition-resource-name annotation: %w", err)
}
if err = setLabel(paved, "crossplane.io/composite", compName); err != nil {
return errors.Wrap(err, "set crossplane.io/composite annotation")
return fmt.Errorf("set crossplane.io/composite annotation: %w", err)
}
if cr.name != "" {
if err = setLabel(paved, "crossplane.io/claim-name", cr.name); err != nil {
return errors.Wrap(err, "set crossplane.io/claim-name annotation")
return fmt.Errorf("set crossplane.io/claim-name annotation: %w", err)
}
if err = setLabel(paved, "crossplane.io/claim-namespace", cr.namespace); err != nil {
return errors.Wrap(err, "set crossplane.io/claim-namespace annotation")
return fmt.Errorf("set crossplane.io/claim-namespace annotation: %w", err)
}
}
w.yamlDoc(r, "desired object: "+name)
Expand Down Expand Up @@ -341,12 +340,12 @@ func (p *Printer) Response(req *fnv1.RunFunctionRequest, res *fnv1.RunFunctionRe
// do this in two steps because of the weird Match interface that needs protobuf
b, err := protojson.Marshal(res.GetRequirements())
if err != nil {
return errors.Wrap(err, "marshal requirements")
return fmt.Errorf("marshal requirements: %w", err)
}
var er object
err = json.Unmarshal(b, &er)
if err != nil {
return errors.Wrap(err, "unmarshal requirements")
return fmt.Errorf("unmarshal requirements: %w", err)
}
w.yamlDoc(er, "")
}
Expand Down
17 changes: 11 additions & 6 deletions function/internal/evaluator/eval.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package evaluator

import (
"errors"
"fmt"
"sort"
"strings"
Expand All @@ -11,7 +12,6 @@ import (
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclparse"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/pkg/errors"
"github.com/zclconf/go-cty/cty"
"google.golang.org/protobuf/types/known/structpb"
)
Expand All @@ -28,6 +28,11 @@ func (e *Evaluator) doEval(in *fnv1.RunFunctionRequest, files ...File) (_ *fnv1.
diags, ok := finalErr.(hcl.Diagnostics)
if ok {
finalErr = sortDiagsBySeverity(diags)
var errs []error
for _, diag := range diags {
errs = append(errs, diag)
}
finalErr = errors.Join(errs...)
Comment on lines +34 to +35

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

L30 is now a dead assignment: sortDiagsBySeverity(diags) result is discarded before use. It's harmless today (sort mutates in place) but confusing and fragile. A future refactor that changes sortDiagsBySeverity to return a copy (a very natural change for a function named sortX, which normally implies non-mutating) would silently break ordering with no signal at the call site.

Proposed change

if finalErr != nil {
    diags, ok := finalErr.(hcl.Diagnostics)
    if ok {
        sortDiagsBySeverity(diags)
        var errs []error
        for _, diag := range diags {
            errs = append(errs, diag)
        }
        finalErr = errors.Join(errs...)
    }
}

}
}
}()
Expand Down Expand Up @@ -174,14 +179,14 @@ func (e *Evaluator) toResponse(diags hcl.Diagnostics) (*fnv1.RunFunctionResponse
if len(e.compositeStatuses) > 0 {
st, err := unify(e.compositeStatuses...)
if err != nil {
return nil, errors.Wrap(err, "unify composite status")
return nil, fmt.Errorf("unify composite status: %w", err)
}
obj := Object{
"status": st,
}
s, err := structpb.NewStruct(obj)
if err != nil {
return nil, fmt.Errorf("unexpected error converting composite status: %v", err)
return nil, fmt.Errorf("unexpected error converting composite status: %w", err)
}
ensureDesiredComposite()
ret.Desired.Composite.Resource = s
Expand All @@ -191,19 +196,19 @@ func (e *Evaluator) toResponse(diags hcl.Diagnostics) (*fnv1.RunFunctionResponse
ensureDesiredComposite()
u, err := unifyBytes(e.compositeConnections...)
if err != nil {
return nil, errors.Wrap(err, "unify composite connection")
return nil, fmt.Errorf("unify composite connection: %w", err)
}
ret.Desired.Composite.ConnectionDetails = u
}

if len(e.contexts) > 0 {
ctx, err := unify(e.contexts...)
if err != nil {
return nil, errors.Wrap(err, "unify context")
return nil, fmt.Errorf("unify context: %w", err)
}
s, err := structpb.NewStruct(ctx)
if err != nil {
return nil, fmt.Errorf("unexpected error converting context: %v", err)
return nil, fmt.Errorf("unexpected error converting context: %w", err)
}
ret.Context = s
}
Expand Down
6 changes: 3 additions & 3 deletions function/internal/evaluator/functions/internal/funcs/cidr.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var CidrHostFunc = function.New(&function.Spec{
}
_, network, err := ipaddr.ParseCIDR(args[0].AsString())
if err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %w", err)
}

ip, err := cidr.HostBig(network, hostNum)
Expand All @@ -60,7 +60,7 @@ var CidrNetmaskFunc = function.New(&function.Spec{
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
_, network, err := ipaddr.ParseCIDR(args[0].AsString())
if err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %w", err)
}

if network.IP.To4() == nil {
Expand Down Expand Up @@ -101,7 +101,7 @@ var CidrSubnetFunc = function.New(&function.Spec{

_, network, err := ipaddr.ParseCIDR(args[0].AsString())
if err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %w", err)
}

newNetwork, err := cidr.SubnetBig(network, newbits, netnum)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ var OneFunc = function.New(&function.Spec{
// It would be very strange to get here, because that would
// suggest that the length is either not a number or isn't
// an integer, which would suggest a bug in cty.
return cty.NilVal, fmt.Errorf("invalid collection length: %s", err)
return cty.NilVal, fmt.Errorf("invalid collection length: %w", err)
}
switch l {
case 0:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ var UUIDV5Func = function.New(&function.Spec{
namespace = uuidv5.NameSpaceX500
default:
if namespace, err = uuidv5.Parse(args[0].AsString()); err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("uuidv5() doesn't support namespace %s (%v)", args[0].AsString(), err)
return cty.UnknownVal(cty.String), fmt.Errorf("uuidv5() doesn't support namespace %s: %w", args[0].AsString(), err)
}
}
val := args[1].AsString()
Expand Down Expand Up @@ -110,7 +110,7 @@ var BcryptFunc = function.New(&function.Spec{
input := args[0].AsString()
out, err := bcrypt.GenerateFromPassword([]byte(input), defaultCost)
if err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("error occurred generating password %s", err.Error())
return cty.UnknownVal(cty.String), fmt.Errorf("error occurred generating password %w", err)
}

return cty.StringVal(string(out)), nil
Expand Down Expand Up @@ -162,7 +162,7 @@ var RsaDecryptFunc = function.New(&function.Spec{

out, err := rsa.DecryptPKCS1v15(nil, privateKey, b)
if err != nil {
return cty.UnknownVal(cty.String), fmt.Errorf("failed to decrypt: %s", err)
return cty.UnknownVal(cty.String), fmt.Errorf("failed to decrypt: %w", err)
}

return cty.StringVal(string(out)), nil
Expand Down
10 changes: 5 additions & 5 deletions function/internal/evaluator/functions/internal/funcs/datetime.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func parseTimestamp(ts string) (time.Time, error) {
if err.LayoutElem == "" && err.ValueElem == "" && err.Message != "" {
// For some reason err.Message is populated with a ": " prefix
// by the time package.
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp%s", err.Message)
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: %w", err)
}
var what string
switch err.LayoutElem {
Expand All @@ -178,9 +178,9 @@ func parseTimestamp(ts string) (time.Time, error) {
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: missing required time introducer 'T'")
case ":", "-":
if err.ValueElem == "" {
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string where %q is expected", err.LayoutElem)
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string where %q is expected: %w", err.LayoutElem, err)
} else {
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: found %q where %q is expected", err.ValueElem, err.LayoutElem)
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: found %q where %q is expected: %w", err.ValueElem, err.LayoutElem, err)
}
default:
// Should never get here, because time.RFC3339 includes only the
Expand All @@ -189,9 +189,9 @@ func parseTimestamp(ts string) (time.Time, error) {
what = "timestamp segment"
}
if err.ValueElem == "" {
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string before %s", what)
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: end of string before %s: %w", what, err)
} else {
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: cannot use %q as %s", err.ValueElem, what)
return time.Time{}, fmt.Errorf("not a valid RFC3339 timestamp: cannot use %q as %s: %w", err.ValueElem, what, err)
}
}
return time.Time{}, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func TestTimeCmp(t *testing.T) {
cty.StringVal("2017-11-22T00:00:00Z"),
cty.StringVal("bloop"),
cty.UnknownVal(cty.String),
`not a valid RFC3339 timestamp: cannot use "bloop" as year`,
`not a valid RFC3339 timestamp: cannot use "bloop" as year: parsing time "bloop" as "2006-01-02T15:04:05Z07:00": cannot parse "bloop" as "2006"`,
},
{
cty.StringVal("2017-11-22 00:00:00Z"),
Expand Down
7 changes: 3 additions & 4 deletions function/internal/evaluator/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/hashicorp/hcl/v2"
"github.com/pkg/errors"
"github.com/zclconf/go-cty/cty"
ctyjson "github.com/zclconf/go-cty/cty/json"
"google.golang.org/protobuf/encoding/protojson"
Expand Down Expand Up @@ -99,12 +98,12 @@ func valueToStructWithAnnotations(val cty.Value, a map[string]string) (*structpb

jsonBytes, err := ctyjson.Marshal(val, val.Type())
if err != nil {
return nil, errors.Wrap(err, "marshal cty to json")
return nil, fmt.Errorf("marshal cty to json: %w", err)
}

var result map[string]any
if err = json.Unmarshal(jsonBytes, &result); err != nil {
return nil, errors.Wrap(err, "unmarshal cty to json")
return nil, fmt.Errorf("unmarshal cty to json: %w", err)
}

meta, ok := result["metadata"]
Expand Down Expand Up @@ -132,7 +131,7 @@ func valueToStructWithAnnotations(val cty.Value, a map[string]string) (*structpb
}
ret, err := structpb.NewStruct(result)
if err != nil {
return nil, errors.Wrapf(err, "convert result to struct")
return nil, fmt.Errorf("convert result to struct: %w", err)
}
return ret, nil
}
Expand Down
Loading
Loading