2023-08-22 22:23:54 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
2023-08-11 19:52:51 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
if res == nil {
|
|
|
|
return "", nil, errors.New("ID.Type not found")
|
|
|
|
}
|
|
|
|
|
2023-09-14 14:59:33 +00:00
|
|
|
resourceType := res.GetId().GetType()
|
|
|
|
if resourceType == nil {
|
|
|
|
return "", nil, errors.New("ID.Type is nil")
|
|
|
|
}
|
|
|
|
|
2023-08-11 19:52:51 +00:00
|
|
|
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
|
|
|
|
}
|