mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
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))
|
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
|
// ObserveDNSResponse is a callback invoked by the DNS resolver when a DNS
|
||||||
// response is being returned over the PeerAPI. The response is parsed and
|
// response is being returned over the PeerAPI. The response is parsed and
|
||||||
// matched against the configured domains, if matched the routeAdvertiser is
|
// 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
|
return
|
||||||
}
|
}
|
||||||
writeJSON(w, res)
|
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":
|
case "/sockstats":
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
http.Error(w, "bad method", http.StatusMethodNotAllowed)
|
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) {
|
func (b *LocalBackend) handleC2NUpdateGet(w http.ResponseWriter, r *http.Request) {
|
||||||
b.logf("c2n: GET /update received")
|
b.logf("c2n: GET /update received")
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package tailcfg
|
package tailcfg
|
||||||
|
|
||||||
|
import "net/netip"
|
||||||
|
|
||||||
// C2NSSHUsernamesRequest is the request for the /ssh/usernames.
|
// C2NSSHUsernamesRequest is the request for the /ssh/usernames.
|
||||||
// A GET request without a request body is equivalent to the zero value of this type.
|
// 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.
|
// Otherwise, a POST request with a JSON-encoded request body is expected.
|
||||||
@ -64,3 +66,12 @@ type C2NPostureIdentityResponse struct {
|
|||||||
// device posture collection.
|
// device posture collection.
|
||||||
PostureDisabled bool `json:",omitempty"`
|
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
Block a user