Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

123 lines
3.1 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package resource
import (
"context"
"fmt"
"google.golang.org/grpc/metadata"
"github.com/hashicorp/consul/command/resource/client"
"github.com/hashicorp/consul/proto-public/pbresource"
)
const (
HeaderConsulToken = "x-consul-token"
)
type ResourceGRPC struct {
C *client.GRPCClient
}
func (resource *ResourceGRPC) Apply(parsedResource *pbresource.Resource) (*pbresource.Resource, error) {
token, err := resource.C.Config.GetToken()
if err != nil {
return nil, err
}
ctx := context.Background()
if token != "" {
ctx = metadata.AppendToOutgoingContext(context.Background(), HeaderConsulToken, token)
}
defer resource.C.Conn.Close()
writeRsp, err := resource.C.Client.Write(ctx, &pbresource.WriteRequest{Resource: parsedResource})
if err != nil {
return nil, fmt.Errorf("error writing resource: %+v", err)
}
return writeRsp.Resource, err
}
func (resource *ResourceGRPC) Read(resourceType *pbresource.Type, resourceTenancy *pbresource.Tenancy, resourceName string, stale bool) (*pbresource.Resource, error) {
token, err := resource.C.Config.GetToken()
if err != nil {
return nil, err
}
ctx := context.Background()
if !stale {
ctx = metadata.AppendToOutgoingContext(ctx, "x-consul-consistency-mode", "consistent")
}
if token != "" {
ctx = metadata.AppendToOutgoingContext(context.Background(), HeaderConsulToken, token)
}
defer resource.C.Conn.Close()
readRsp, err := resource.C.Client.Read(ctx, &pbresource.ReadRequest{
Id: &pbresource.ID{
Type: resourceType,
Tenancy: resourceTenancy,
Name: resourceName,
},
})
if err != nil {
return nil, fmt.Errorf("error reading resource: %+v", err)
}
return readRsp.Resource, err
}
func (resource *ResourceGRPC) List(resourceType *pbresource.Type, resourceTenancy *pbresource.Tenancy, prefix string, stale bool) ([]*pbresource.Resource, error) {
token, err := resource.C.Config.GetToken()
if err != nil {
return nil, err
}
ctx := context.Background()
if !stale {
ctx = metadata.AppendToOutgoingContext(ctx, "x-consul-consistency-mode", "consistent")
}
if token != "" {
ctx = metadata.AppendToOutgoingContext(context.Background(), HeaderConsulToken, token)
}
defer resource.C.Conn.Close()
listRsp, err := resource.C.Client.List(ctx, &pbresource.ListRequest{
Type: resourceType,
Tenancy: resourceTenancy,
NamePrefix: prefix,
})
if err != nil {
return nil, fmt.Errorf("error listing resource: %+v", err)
}
return listRsp.Resources, err
}
func (resource *ResourceGRPC) Delete(resourceType *pbresource.Type, resourceTenancy *pbresource.Tenancy, resourceName string) error {
token, err := resource.C.Config.GetToken()
if err != nil {
return err
}
ctx := context.Background()
if token != "" {
ctx = metadata.AppendToOutgoingContext(context.Background(), HeaderConsulToken, token)
}
defer resource.C.Conn.Close()
_, err = resource.C.Client.Delete(ctx, &pbresource.DeleteRequest{
Id: &pbresource.ID{
Type: resourceType,
Tenancy: resourceTenancy,
Name: resourceName,
},
})
if err != nil {
return fmt.Errorf("error deleting resource: %+v", err)
}
return nil
}