github.com/kjdelisle/consul@v1.4.5/agent/translate_addr.go (about)

     1  package agent
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/consul/agent/structs"
     7  )
     8  
     9  // TranslateAddress is used to provide the final, translated address for a node,
    10  // depending on how the agent and the other node are configured. The dc
    11  // parameter is the dc the datacenter this node is from.
    12  func (a *Agent) TranslateAddress(dc string, addr string, taggedAddresses map[string]string) string {
    13  	if a.config.TranslateWANAddrs && (a.config.Datacenter != dc) {
    14  		wanAddr := taggedAddresses["wan"]
    15  		if wanAddr != "" {
    16  			addr = wanAddr
    17  		}
    18  	}
    19  	return addr
    20  }
    21  
    22  // TranslateAddresses translates addresses in the given structure into the
    23  // final, translated address, depending on how the agent and the other node are
    24  // configured. The dc parameter is the datacenter this structure is from.
    25  func (a *Agent) TranslateAddresses(dc string, subj interface{}) {
    26  	// CAUTION - SUBTLE! An agent running on a server can, in some cases,
    27  	// return pointers directly into the immutable state store for
    28  	// performance (it's via the in-memory RPC mechanism). It's never safe
    29  	// to modify those values, so we short circuit here so that we never
    30  	// update any structures that are from our own datacenter. This works
    31  	// for address translation because we *never* need to translate local
    32  	// addresses, but this is super subtle, so we've piped all the in-place
    33  	// address translation into this function which makes sure this check is
    34  	// done. This also happens to skip looking at any of the incoming
    35  	// structure for the common case of not needing to translate, so it will
    36  	// skip a lot of work if no translation needs to be done.
    37  	if !a.config.TranslateWANAddrs || (a.config.Datacenter == dc) {
    38  		return
    39  	}
    40  
    41  	// Translate addresses in-place, subject to the condition checked above
    42  	// which ensures this is safe to do since we are operating on a local
    43  	// copy of the data.
    44  	switch v := subj.(type) {
    45  	case structs.CheckServiceNodes:
    46  		for _, entry := range v {
    47  			entry.Node.Address = a.TranslateAddress(dc, entry.Node.Address, entry.Node.TaggedAddresses)
    48  		}
    49  	case *structs.Node:
    50  		v.Address = a.TranslateAddress(dc, v.Address, v.TaggedAddresses)
    51  	case structs.Nodes:
    52  		for _, node := range v {
    53  			node.Address = a.TranslateAddress(dc, node.Address, node.TaggedAddresses)
    54  		}
    55  	case structs.ServiceNodes:
    56  		for _, entry := range v {
    57  			entry.Address = a.TranslateAddress(dc, entry.Address, entry.TaggedAddresses)
    58  		}
    59  	default:
    60  		panic(fmt.Errorf("Unhandled type passed to address translator: %#v", subj))
    61  	}
    62  }