Poonam Jadhav 559c61e6b6
Net-2712/resource hcl parsing (#18250)
* Initial protohcl implementation

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Daniel Upton <daniel@floppy.co>

* resourcehcl: implement resource decoding on top of protohcl

Co-authored-by: Daniel Upton <daniel@floppy.co>

* fix: resolve ci failures

* test: add additional unmarshalling tests

* refactor: update function test to clean protohcl package imports

---------

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Daniel Upton <daniel@floppy.co>
2023-08-11 15:52:51 -04:00

47 lines
1.2 KiB
Go

package resourcehcl
import (
"errors"
"fmt"
"google.golang.org/protobuf/reflect/protoreflect"
"github.com/hashicorp/consul/internal/protohcl"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/proto-public/pbresource"
)
// anyProvider implements protohcl.AnyTypeProvider to infer the `Data` block
// type from `ID.Type`.
type anyProvider struct {
base protohcl.AnyTypeProvider
reg resource.Registry
}
func (p anyProvider) AnyType(ctx *protohcl.UnmarshalContext, decoder protohcl.MessageDecoder) (protoreflect.FullName, protohcl.MessageDecoder, error) {
if ctx.Name != "Data" {
return p.base.AnyType(ctx, decoder)
}
if ctx.Parent == nil || ctx.Parent.Message == nil {
return p.base.AnyType(ctx, decoder)
}
res, isResource := ctx.Parent.Message.Interface().(*pbresource.Resource)
if !isResource {
return p.base.AnyType(ctx, decoder)
}
resourceType := res.GetId().GetType()
if res == nil {
return "", nil, errors.New("ID.Type not found")
}
reg, ok := p.reg.Resolve(resourceType)
if !ok {
return "", nil, fmt.Errorf("unknown resource type: %s", resource.ToGVK(resourceType))
}
return reg.Proto.ProtoReflect().Descriptor().FullName(), decoder, nil
}