ipn: move Options.ServerURL into Prefs.

We can't rely on a frontend to provide a control
server URL, so this naturally belongs in server-persisted
state.

Signed-off-by: David Anderson <dave@natulte.net>
pull/78/head
David Anderson 5 years ago committed by Dave Anderson
parent 45d687e213
commit cf1e386cbd

@ -78,6 +78,7 @@ func main() {
// TODO(apenwarr): fix different semantics between prefs and uflags // TODO(apenwarr): fix different semantics between prefs and uflags
// TODO(apenwarr): allow setting/using CorpDNS // TODO(apenwarr): allow setting/using CorpDNS
prefs := ipn.Prefs{ prefs := ipn.Prefs{
ControlURL: *server,
WantRunning: true, WantRunning: true,
RouteAll: *routeall, RouteAll: *routeall,
AllowSingleHosts: !*nuroutes, AllowSingleHosts: !*nuroutes,
@ -106,8 +107,7 @@ func main() {
bc := ipn.NewBackendClient(log.Printf, clientToServer) bc := ipn.NewBackendClient(log.Printf, clientToServer)
bc.SetPrefs(prefs) bc.SetPrefs(prefs)
opts := ipn.Options{ opts := ipn.Options{
StateKey: globalStateKey, StateKey: globalStateKey,
ServerURL: *server,
Notify: func(n ipn.Notify) { Notify: func(n ipn.Notify) {
if n.ErrMessage != nil { if n.ErrMessage != nil {
log.Fatalf("backend error: %v\n", *n.ErrMessage) log.Fatalf("backend error: %v\n", *n.ErrMessage)

@ -72,9 +72,6 @@ type StateKey string
type Options struct { type Options struct {
// FrontendLogID is the public logtail id used by the frontend. // FrontendLogID is the public logtail id used by the frontend.
FrontendLogID string FrontendLogID string
// ServerURL is the base URL of the tailcontrol server to talk
// to. Required.
ServerURL string
// StateKey and Prefs together define the state the backend should // StateKey and Prefs together define the state the backend should
// use: // use:
// - StateKey=="" && Prefs!=nil: use Prefs for internal state, // - StateKey=="" && Prefs!=nil: use Prefs for internal state,

@ -168,8 +168,8 @@ func newNode(t *testing.T, prefix string, https *httptest.Server) testNode {
} }
n.Start(Options{ n.Start(Options{
FrontendLogID: prefix + "-f", FrontendLogID: prefix + "-f",
ServerURL: https.URL,
Prefs: &Prefs{ Prefs: &Prefs{
ControlURL: https.URL,
RouteAll: true, RouteAll: true,
AllowSingleHosts: true, AllowSingleHosts: true,
CorpDNS: true, CorpDNS: true,

@ -16,7 +16,7 @@ type FakeBackend struct {
} }
func (b *FakeBackend) Start(opts Options) error { func (b *FakeBackend) Start(opts Options) error {
b.serverURL = opts.ServerURL b.serverURL = opts.Prefs.ControlURL
if opts.Notify == nil { if opts.Notify == nil {
log.Fatalf("FakeBackend.Start: opts.Notify is nil\n") log.Fatalf("FakeBackend.Start: opts.Notify is nil\n")
} }

@ -5,7 +5,6 @@
package ipn package ipn
import ( import (
"strings"
"sync" "sync"
"time" "time"
@ -14,7 +13,6 @@ import (
) )
type Handle struct { type Handle struct {
serverURL string
frontendLogID string frontendLogID string
b Backend b Backend
xnotify func(n Notify) xnotify func(n Notify)
@ -43,7 +41,6 @@ func NewHandle(b Backend, logf logger.Logf, opts Options) (*Handle, error) {
} }
func (h *Handle) Start(opts Options) error { func (h *Handle) Start(opts Options) error {
h.serverURL = strings.TrimRight(opts.ServerURL, "/")
h.frontendLogID = opts.FrontendLogID h.frontendLogID = opts.FrontendLogID
h.xnotify = opts.Notify h.xnotify = opts.Notify
h.netmapCache = nil h.netmapCache = nil
@ -148,7 +145,7 @@ func (h *Handle) Expiry() time.Time {
} }
func (h *Handle) AdminPageURL() string { func (h *Handle) AdminPageURL() string {
return h.serverURL + "/admin/machines" return h.prefsCache.ControlURL + "/admin/machines"
} }
func (h *Handle) StartLoginInteractive() { func (h *Handle) StartLoginInteractive() {

@ -29,14 +29,6 @@ import (
"tailscale.com/wgengine" "tailscale.com/wgengine"
) )
// defaultLoginServer is the login URL used by an auto-starting
// server.
//
// TODO(danderson): the reason this is hardcoded is that the server
// URL is currently not stored in state, but passed in by the
// frontend. This needs to be fixed.
const defaultLoginServer = "https://login.tailscale.com"
// Options is the configuration of the Tailscale node agent. // Options is the configuration of the Tailscale node agent.
type Options struct { type Options struct {
// SocketPath, on unix systems, is the unix socket path to listen // SocketPath, on unix systems, is the unix socket path to listen
@ -122,8 +114,7 @@ func Run(rctx context.Context, logf logger.Logf, logid string, opts Options, e w
Version: version.LONG, Version: version.LONG,
Start: &ipn.StartArgs{ Start: &ipn.StartArgs{
Opts: ipn.Options{ Opts: ipn.Options{
ServerURL: defaultLoginServer, StateKey: opts.AutostartStateKey,
StateKey: opts.AutostartStateKey,
}, },
}, },
}) })

@ -149,13 +149,13 @@ func (b *LocalBackend) Start(opts Options) error {
hi.Services = b.hiCache.Services // keep any previous session hi.Services = b.hiCache.Services // keep any previous session
b.hiCache = hi b.hiCache = hi
b.state = NoState b.state = NoState
b.serverURL = opts.ServerURL
if err := b.loadStateWithLock(opts.StateKey, opts.Prefs); err != nil { if err := b.loadStateWithLock(opts.StateKey, opts.Prefs); err != nil {
b.mu.Unlock() b.mu.Unlock()
return fmt.Errorf("loading requested state: %v", err) return fmt.Errorf("loading requested state: %v", err)
} }
b.serverURL = b.prefs.ControlURL
hi.RoutableIPs = append(hi.RoutableIPs, b.prefs.AdvertiseRoutes...) hi.RoutableIPs = append(hi.RoutableIPs, b.prefs.AdvertiseRoutes...)
b.notify = opts.Notify b.notify = opts.Notify

@ -95,8 +95,9 @@ func TestClientServer(t *testing.T) {
ch := make(chan Notify, 256) ch := make(chan Notify, 256)
h, err := NewHandle(bc, clogf, Options{ h, err := NewHandle(bc, clogf, Options{
ServerURL: "http://example.com/fake", Prefs: &Prefs{
Prefs: &Prefs{}, ControlURL: "http://example.com/fake",
},
Notify: func(n Notify) { Notify: func(n Notify) {
ch <- n ch <- n
}, },

@ -19,6 +19,8 @@ import (
// Prefs are the user modifiable settings of the Tailscale node agent. // Prefs are the user modifiable settings of the Tailscale node agent.
type Prefs struct { type Prefs struct {
// ControlURL is the URL of the control server to use.
ControlURL string
// RouteAll specifies whether to accept subnet and default routes // RouteAll specifies whether to accept subnet and default routes
// advertised by other nodes on the Tailscale network. // advertised by other nodes on the Tailscale network.
RouteAll bool RouteAll bool
@ -91,6 +93,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
} }
return p != nil && p2 != nil && return p != nil && p2 != nil &&
p.ControlURL == p2.ControlURL &&
p.RouteAll == p2.RouteAll && p.RouteAll == p2.RouteAll &&
p.AllowSingleHosts == p2.AllowSingleHosts && p.AllowSingleHosts == p2.AllowSingleHosts &&
p.CorpDNS == p2.CorpDNS && p.CorpDNS == p2.CorpDNS &&
@ -118,6 +121,7 @@ func NewPrefs() Prefs {
// Provide default values for options which are normally // Provide default values for options which are normally
// true, but might be missing from the json data for any // true, but might be missing from the json data for any
// reason. The json can still override them to false. // reason. The json can still override them to false.
ControlURL: "https://login.tailscale.com",
RouteAll: true, RouteAll: true,
AllowSingleHosts: true, AllowSingleHosts: true,
CorpDNS: true, CorpDNS: true,
@ -142,6 +146,11 @@ func PrefsFromBytes(b []byte, enforceDefaults bool) (Prefs, error) {
log.Printf("Prefs parse: %v: %v\n", err, b) log.Printf("Prefs parse: %v: %v\n", err, b)
} }
} }
if p.ControlURL == "" {
// TODO(danderson): compat shim, remove after
// Options.ServerURL has been gone for a release.
p.ControlURL = "https://login.tailscale.com"
}
if enforceDefaults { if enforceDefaults {
p.RouteAll = true p.RouteAll = true
p.AllowSingleHosts = true p.AllowSingleHosts = true

@ -20,7 +20,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
} }
func TestPrefsEqual(t *testing.T) { func TestPrefsEqual(t *testing.T) {
prefsHandles := []string{"RouteAll", "AllowSingleHosts", "CorpDNS", "WantRunning", "UsePacketFilter", "AdvertiseRoutes", "NotepadURLs", "Persist"} prefsHandles := []string{"ControlURL", "RouteAll", "AllowSingleHosts", "CorpDNS", "WantRunning", "UsePacketFilter", "AdvertiseRoutes", "NotepadURLs", "Persist"}
if have := fieldsOf(reflect.TypeOf(Prefs{})); !reflect.DeepEqual(have, prefsHandles) { if have := fieldsOf(reflect.TypeOf(Prefs{})); !reflect.DeepEqual(have, prefsHandles) {
t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n", t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, prefsHandles) have, prefsHandles)
@ -56,6 +56,17 @@ func TestPrefsEqual(t *testing.T) {
true, true,
}, },
{
&Prefs{ControlURL: "https://login.tailscale.com"},
&Prefs{ControlURL: "https://login.private.co"},
false,
},
{
&Prefs{ControlURL: "https://login.tailscale.com"},
&Prefs{ControlURL: "https://login.tailscale.com"},
true,
},
{ {
&Prefs{RouteAll: true}, &Prefs{RouteAll: true},
&Prefs{RouteAll: false}, &Prefs{RouteAll: false},
@ -209,7 +220,9 @@ func checkPrefs(t *testing.T, p Prefs) {
} }
func TestBasicPrefs(t *testing.T) { func TestBasicPrefs(t *testing.T) {
p := Prefs{} p := Prefs{
ControlURL: "https://login.tailscale.com",
}
checkPrefs(t, p) checkPrefs(t, p)
} }
@ -218,8 +231,9 @@ func TestPrefsPersist(t *testing.T) {
LoginName: "test@example.com", LoginName: "test@example.com",
} }
p := Prefs{ p := Prefs{
CorpDNS: true, ControlURL: "https://login.tailscale.com",
Persist: &c, CorpDNS: true,
Persist: &c,
} }
checkPrefs(t, p) checkPrefs(t, p)
} }

Loading…
Cancel
Save