github.phpd.cn/hashicorp/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 }