Skip to content

Commit

Permalink
Handle experiment tag and pointers in reflect
Browse files Browse the repository at this point in the history
See chainguard-dev/apko#1453

Since GID is optional and 0 is a valid value, we needed a way to
distinguish between unset and 0, so GID became a pointer.

This broke the reflect code (labeled HACK) that punted on pointers.

I've updated that code to handle pointers but also to ignore any fields
marked with `apko:"experimental"` because I don't want to pollute the
schema with them.

Signed-off-by: Jon Johnson <[email protected]>
  • Loading branch information
jonjohnsonjr committed Dec 30, 2024
1 parent 66212a8 commit b2ead03
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 30 deletions.
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/chainguard-dev/terraform-provider-apko
go 1.23.4

require (
chainguard.dev/apko v0.22.3
chainguard.dev/apko v0.22.4
github.com/chainguard-dev/clog v1.5.1
github.com/chainguard-dev/terraform-provider-oci v0.0.18
github.com/google/go-cmp v0.6.0
Expand Down Expand Up @@ -183,25 +183,25 @@ require (
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.step.sm/crypto v0.55.0 // indirect
go.step.sm/crypto v0.56.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.8.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/api v0.213.0 // indirect
google.golang.org/api v0.214.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.2 // indirect
google.golang.org/grpc v1.69.0 // indirect
google.golang.org/protobuf v1.36.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
30 changes: 16 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
chainguard.dev/apko v0.22.3 h1:av2SnPryS5YhR4rqjCv2gIRmrgitnsV9l3l9+sTp0m4=
chainguard.dev/apko v0.22.3/go.mod h1:r5NlHbveP9V6v6wk0j6SsQ4lLohNT4ypzpsSiml9ZHA=
chainguard.dev/apko v0.22.4 h1:DqLeqVijEMhFH6PhYYEry+3vPcd2DwHbV89MK3tw4e0=
chainguard.dev/apko v0.22.4/go.mod h1:QA+Bl4DgHNlDqpPUt9J2+JT+CaGtp2v1VyYNmwNgRq4=
chainguard.dev/go-grpc-kit v0.17.6 h1:lwIs9LmSnm8jwrH1QmigCwMP6MYkIBENq/0xGduYZss=
chainguard.dev/go-grpc-kit v0.17.6/go.mod h1:ZNaXn2KEO++2u2WveHs65krYiHmAEGjYLeEtfaQaOWU=
chainguard.dev/sdk v0.1.28 h1:xLQv0JxiGhqVKOL059DmTReTjrKFhUsP5U1W6cgr+jQ=
Expand Down Expand Up @@ -477,14 +477,16 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo=
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.step.sm/crypto v0.55.0 h1:575Q7NahuM/ZRxUVN1GkO2e1aDYQJqIIg+nbfOajQJk=
go.step.sm/crypto v0.55.0/go.mod h1:MgEmD1lgwsuzZwTgI0GwKapHjKVEQLVggSvHuf3bYnU=
go.step.sm/crypto v0.56.0 h1:KcFfV76cI9Xaw8bdSc9x55skyuSdcHcTdL37vvVZnvY=
go.step.sm/crypto v0.56.0/go.mod h1:snWNloxY9s1W+HsFqcviq55nvzbqqX6LxVt0Vktv5mw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
Expand Down Expand Up @@ -530,8 +532,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
Expand Down Expand Up @@ -608,8 +610,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.213.0 h1:KmF6KaDyFqB417T68tMPbVmmwtIXs2VB60OJKIHB0xQ=
google.golang.org/api v0.213.0/go.mod h1:V0T5ZhNUUNpYAlL306gFZPFt5F5D/IeyLoktduYYnvQ=
google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA=
google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
Expand All @@ -627,12 +629,12 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/grpc v1.69.0 h1:quSiOM1GJPmPH5XtU+BCoVXcDVJJAzNcoyfC2cCjGkI=
google.golang.org/grpc v1.69.0/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ=
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
79 changes: 69 additions & 10 deletions internal/provider/reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package provider

import (
"fmt"
"log"
"reflect"
"strings"

Expand Down Expand Up @@ -58,14 +57,11 @@ func generateTypeReflect(t reflect.Type) (attr.Type, error) {
if tag == nil {
continue
}

// HACK: Handle this field.
if sf.Type.Kind() == reflect.Pointer {
log.Println("skipping pointer field", sf.Name)
if experimental(sf) {
continue
}

ft, err := generateTypeReflect(sf.Type)
ft, err := generateTypeReflect(maybeDeref(sf.Type))
if err != nil {
return nil, fmt.Errorf("struct %w", err)
}
Expand All @@ -78,10 +74,46 @@ func generateTypeReflect(t reflect.Type) (attr.Type, error) {
}
}

func maybeDeref(t reflect.Type) reflect.Type {
if t.Kind() == reflect.Pointer {
// For pointers we want the element's type, not Pointer.
return t.Elem()
}

return t
}

func generateValue(v any) (attr.Value, diag.Diagnostics) {
return generateValueReflect(reflect.ValueOf(v))
}

func generateNull(t reflect.Type, at attr.Type) (attr.Value, diag.Diagnostics) {
switch t.Kind() {
case reflect.String:
return basetypes.NewStringNull(), nil
case reflect.Bool:
return basetypes.NewBoolNull(), nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return basetypes.NewInt64Null(), nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
return basetypes.NewInt64Null(), nil
case reflect.Float32, reflect.Float64:
return basetypes.NewFloat64Null(), nil
case reflect.Array, reflect.Slice:
return basetypes.NewListNull(at), nil
case reflect.Map:
return basetypes.NewMapNull(at), nil
case reflect.Struct:
attrTyp, ok := at.(basetypes.ObjectType)
if !ok {
return nil, []diag.Diagnostic{diag.NewErrorDiagnostic("expected object type", "")}
}
return basetypes.NewObjectNull(attrTyp.AttrTypes), nil
default:
return nil, []diag.Diagnostic{diag.NewErrorDiagnostic("unexpected null type", t.Kind().String())}
}
}

func generateValueReflect(v reflect.Value) (attr.Value, diag.Diagnostics) {
t := v.Type()
switch t.Kind() {
Expand Down Expand Up @@ -142,10 +174,20 @@ func generateValueReflect(v reflect.Value) (attr.Value, diag.Diagnostics) {
if tag == nil {
continue
}
if experimental(sf) {
continue
}

// HACK: Handle this field.
if sf.Type.Kind() == reflect.Pointer {
log.Println("skipping pointer field", sf.Name)
if sf.Type.Kind() == reflect.Pointer && v.Field(i).IsNil() {
at, err := generateTypeReflect(sf.Type)
if err != nil {
return nil, []diag.Diagnostic{diag.NewErrorDiagnostic(err.Error(), "")}
}
ft, diags := generateNull(sf.Type.Elem(), at)
if diags.HasError() {
return nil, diags
}
fv[*tag] = ft
continue
}

Expand Down Expand Up @@ -298,11 +340,15 @@ func assignValueReflect(in attr.Value, out reflect.Value) diag.Diagnostics {
if tag == nil {
continue
}
if experimental(sf) {
continue
}
val, ok := fl[*tag]
if !ok {
continue
}
diags := assignValueReflect(val, out.Field(i))

diags := assignValueReflect(val, indirect(out.Field(i)))
if diags.HasError() {
return diags
}
Expand Down Expand Up @@ -336,6 +382,19 @@ func yamlName(field reflect.StructField) *string {
return &fn
}

func experimental(field reflect.StructField) bool {
tag := field.Tag.Get("apko")
if tag == "" {
return false
}
for _, field := range strings.Split(tag, ",") {
if field == "experimental" {
return true
}
}
return false
}

// indirect walks down v allocating pointers as needed,
// until it gets to a non-pointer.
// If it encounters an Unmarshaler, indirect stops and returns that.
Expand Down

0 comments on commit b2ead03

Please sign in to comment.