consul/agent/dns/context.go

57 lines
1.3 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package dns
import (
"context"
"fmt"
"github.com/mitchellh/mapstructure"
"google.golang.org/grpc/metadata"
)
// Context is used augment a DNS message with Consul-specific metadata.
type Context struct {
Token string `mapstructure:"x-consul-token,omitempty"`
DefaultNamespace string `mapstructure:"x-consul-namespace,omitempty"`
DefaultPartition string `mapstructure:"x-consul-partition,omitempty"`
}
// NewContextFromGRPCContext returns the request context using the gRPC metadata attached to the
// given context. If there is no gRPC metadata, it returns an empty context.
func NewContextFromGRPCContext(ctx context.Context) (Context, error) {
if ctx == nil {
return Context{}, nil
}
reqCtx := Context{}
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return reqCtx, nil
}
m := map[string]string{}
for k, v := range md {
m[k] = v[0]
}
decoderConfig := &mapstructure.DecoderConfig{
Metadata: nil,
Result: &reqCtx,
WeaklyTypedInput: true,
}
decoder, err := mapstructure.NewDecoder(decoderConfig)
if err != nil {
return Context{}, fmt.Errorf("error creating mapstructure decoder: %w", err)
}
err = decoder.Decode(m)
if err != nil {
return Context{}, fmt.Errorf("error decoding metadata: %w", err)
}
return reqCtx, nil
}