// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package discovery
import (
"context"
"net"
"sync/atomic"
"time"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/consul/agent/config"
"github.com/hashicorp/consul/agent/structs"
)
const (
// TODO (v2-dns): can we move the recursion into the data fetcher?
maxRecursionLevelDefault = 3 // This field comes from the V1 DNS server and affects V1 catalog lookups
maxRecurseRecords = 5
)
// v1DataFetcherDynamicConfig is used to store the dynamic configuration of the V1 data fetcher.
type v1DataFetcherDynamicConfig struct {
allowStale bool
maxStale time . Duration
useCache bool
cacheMaxAge time . Duration
onlyPassing bool
}
// V1DataFetcher is used to fetch data from the V1 catalog.
type V1DataFetcher struct {
dynamicConfig atomic . Value
logger hclog . Logger
rpcFunc func ( ctx context . Context , method string , args interface { } , reply interface { } ) error
}
// NewV1DataFetcher creates a new V1 data fetcher.
func NewV1DataFetcher ( config * config . RuntimeConfig ,
rpcFunc func ( ctx context . Context , method string , args interface { } , reply interface { } ) error ,
logger hclog . Logger ) * V1DataFetcher {
f := & V1DataFetcher {
rpcFunc : rpcFunc ,
logger : logger ,
}
f . LoadConfig ( config )
return f
}
// LoadConfig loads the configuration for the V1 data fetcher.
func ( f * V1DataFetcher ) LoadConfig ( config * config . RuntimeConfig ) {
dynamicConfig := & v1DataFetcherDynamicConfig {
allowStale : config . DNSAllowStale ,
maxStale : config . DNSMaxStale ,
useCache : config . DNSUseCache ,
cacheMaxAge : config . DNSCacheMaxAge ,
onlyPassing : config . DNSOnlyPassing ,
}
f . dynamicConfig . Store ( dynamicConfig )
}
// TODO (v2-dns): Implementation of the V1 data fetcher
// FetchNodes fetches A/AAAA/CNAME
func ( f * V1DataFetcher ) FetchNodes ( ctx Context , req * QueryPayload ) ( [ ] * Result , error ) {
return nil , nil
}
// FetchEndpoints fetches records for A/AAAA/CNAME or SRV requests for services
func ( f * V1DataFetcher ) FetchEndpoints ( ctx Context , req * QueryPayload , lookupType LookupType ) ( [ ] * Result , error ) {
return nil , nil
}
// FetchVirtualIP fetches A/AAAA records for virtual IPs
func ( f * V1DataFetcher ) FetchVirtualIP ( ctx Context , req * QueryPayload ) ( * Result , error ) {
args := structs . ServiceSpecificRequest {
// The datacenter of the request is not specified because cross-datacenter virtual IP
// queries are not supported. This guard rail is in place because virtual IPs are allocated
// within a DC, therefore their uniqueness is not guaranteed globally.
PeerName : req . Tenancy . Peer ,
ServiceName : req . Name ,
EnterpriseMeta : req . Tenancy . EnterpriseMeta ,
QueryOptions : structs . QueryOptions {
Token : ctx . Token ,
} ,
}
var out string
if err := f . rpcFunc ( context . Background ( ) , "Catalog.VirtualIPForService" , & args , & out ) ; err != nil {
return nil , err
}
result := & Result {
Address : out ,
Type : ResultTypeVirtual ,
}
return result , nil
}
// FetchRecordsByIp is used for PTR requests to look up a service/node from an IP.
func ( f * V1DataFetcher ) FetchRecordsByIp ( ctx Context , ip net . IP ) ( [ ] * Result , error ) {
return nil , nil
}
// FetchWorkload fetches a single Result associated with
// V2 Workload. V2-only.
func ( f * V1DataFetcher ) FetchWorkload ( ctx Context , req * QueryPayload ) ( * Result , error ) {
return nil , nil
}
// FetchPreparedQuery evaluates the results of a prepared query.
// deprecated in V2
func ( f * V1DataFetcher ) FetchPreparedQuery ( ctx Context , req * QueryPayload ) ( [ ] * Result , error ) {
return nil , nil
}