tailcfg,ipn,appc: add c2n endpoint for appc domain routes
This change introduces a c2n endpoint that returns a map of domains to a slice of resolved IP addresses for the domain. Fixes tailscale/corp#15657 Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This commit is contained in:
parent
63062abadc
commit
f937cb6794
|
@ -81,6 +81,20 @@ func (e *AppConnector) Domains() views.Slice[string] {
|
|||
return views.SliceOf(xmaps.Keys(e.domains))
|
||||
}
|
||||
|
||||
// DomainRoutes returns a map of domains to resolved IP
|
||||
// addresses.
|
||||
func (e *AppConnector) DomainRoutes() map[string][]netip.Addr {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
drCopy := make(map[string][]netip.Addr)
|
||||
for k, v := range e.domains {
|
||||
copy(drCopy[k], v)
|
||||
}
|
||||
|
||||
return drCopy
|
||||
}
|
||||
|
||||
// ObserveDNSResponse is a callback invoked by the DNS resolver when a DNS
|
||||
// response is being returned over the PeerAPI. The response is parsed and
|
||||
// matched against the configured domains, if matched the routeAdvertiser is
|
||||
|
|
|
@ -121,6 +121,15 @@ func (b *LocalBackend) handleC2N(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
writeJSON(w, res)
|
||||
case "/appconnector/routes":
|
||||
switch r.Method {
|
||||
case httpm.GET:
|
||||
b.handleC2NAppConnectorDomainRoutesGet(w, r)
|
||||
return
|
||||
default:
|
||||
http.Error(w, "bad method", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
case "/sockstats":
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "bad method", http.StatusMethodNotAllowed)
|
||||
|
@ -139,6 +148,26 @@ func (b *LocalBackend) handleC2N(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// handleC2NAppConnectorDomainRoutesGet handles returning the domains
|
||||
// that the app connector is responsible for, as well as the resolved
|
||||
// IP addresses for each domain. If the node is not configured as
|
||||
// an app connector, an empty map is returned.
|
||||
func (b *LocalBackend) handleC2NAppConnectorDomainRoutesGet(w http.ResponseWriter, r *http.Request) {
|
||||
b.logf("c2n: GET /appconnector/routes received")
|
||||
|
||||
var res tailcfg.C2NAppConnectorDomainRoutesResponse
|
||||
if b.appConnector == nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
return
|
||||
}
|
||||
|
||||
res.Domains = b.appConnector.DomainRoutes()
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
}
|
||||
|
||||
func (b *LocalBackend) handleC2NUpdateGet(w http.ResponseWriter, r *http.Request) {
|
||||
b.logf("c2n: GET /update received")
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package tailcfg
|
||||
|
||||
import "net/netip"
|
||||
|
||||
// C2NSSHUsernamesRequest is the request for the /ssh/usernames.
|
||||
// A GET request without a request body is equivalent to the zero value of this type.
|
||||
// Otherwise, a POST request with a JSON-encoded request body is expected.
|
||||
|
@ -64,3 +66,12 @@ type C2NPostureIdentityResponse struct {
|
|||
// device posture collection.
|
||||
PostureDisabled bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// C2NAppConnectorDomainRoutesResponse contains a map of domains to
|
||||
// slice of addresses, indicating what IP addresses have been resolved
|
||||
// for each domain.
|
||||
type C2NAppConnectorDomainRoutesResponse struct {
|
||||
// Domains is a map of lower case domain names with no trailing dot,
|
||||
// to a list of resolved IP addresses.
|
||||
Domains map[string][]netip.Addr
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue