mirror of https://github.com/hashicorp/consul
57 lines
1.3 KiB
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
|
||
|
}
|