From 20324eeebc97d339561c13955eecb0fb4872359e Mon Sep 17 00:00:00 2001 From: Maisem Ali Date: Fri, 21 Oct 2022 23:05:43 +0000 Subject: [PATCH] ipn/prefs: add views Signed-off-by: Maisem Ali --- ipn/ipn_view.go | 120 ++++++++++++++++++++++++++++++++++ ipn/prefs.go | 26 +++++++- types/persist/persist.go | 2 +- types/persist/persist_view.go | 80 +++++++++++++++++++++++ types/views/views.go | 5 ++ 5 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 ipn/ipn_view.go create mode 100644 types/persist/persist_view.go diff --git a/ipn/ipn_view.go b/ipn/ipn_view.go new file mode 100644 index 000000000..90c07e148 --- /dev/null +++ b/ipn/ipn_view.go @@ -0,0 +1,120 @@ +// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by tailscale/cmd/viewer; DO NOT EDIT. + +package ipn + +import ( + "encoding/json" + "errors" + "net/netip" + + "tailscale.com/tailcfg" + "tailscale.com/types/persist" + "tailscale.com/types/preftype" + "tailscale.com/types/views" +) + +//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=Prefs + +// View returns a readonly view of Prefs. +func (p *Prefs) View() PrefsView { + return PrefsView{ж: p} +} + +// PrefsView provides a read-only view over Prefs. +// +// Its methods should only be called if `Valid()` returns true. +type PrefsView struct { + // ж is the underlying mutable value, named with a hard-to-type + // character that looks pointy like a pointer. + // It is named distinctively to make you think of how dangerous it is to escape + // to callers. You must not let callers be able to mutate it. + ж *Prefs +} + +// Valid reports whether underlying value is non-nil. +func (v PrefsView) Valid() bool { return v.ж != nil } + +// AsStruct returns a clone of the underlying value which aliases no memory with +// the original. +func (v PrefsView) AsStruct() *Prefs { + if v.ж == nil { + return nil + } + return v.ж.Clone() +} + +func (v PrefsView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } + +func (v *PrefsView) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } + if len(b) == 0 { + return nil + } + var x Prefs + if err := json.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v PrefsView) ControlURL() string { return v.ж.ControlURL } +func (v PrefsView) RouteAll() bool { return v.ж.RouteAll } +func (v PrefsView) AllowSingleHosts() bool { return v.ж.AllowSingleHosts } +func (v PrefsView) ExitNodeID() tailcfg.StableNodeID { return v.ж.ExitNodeID } +func (v PrefsView) ExitNodeIP() netip.Addr { return v.ж.ExitNodeIP } +func (v PrefsView) ExitNodeAllowLANAccess() bool { return v.ж.ExitNodeAllowLANAccess } +func (v PrefsView) CorpDNS() bool { return v.ж.CorpDNS } +func (v PrefsView) RunSSH() bool { return v.ж.RunSSH } +func (v PrefsView) WantRunning() bool { return v.ж.WantRunning } +func (v PrefsView) LoggedOut() bool { return v.ж.LoggedOut } +func (v PrefsView) ShieldsUp() bool { return v.ж.ShieldsUp } +func (v PrefsView) AdvertiseTags() views.Slice[string] { return views.SliceOf(v.ж.AdvertiseTags) } +func (v PrefsView) Hostname() string { return v.ж.Hostname } +func (v PrefsView) NotepadURLs() bool { return v.ж.NotepadURLs } +func (v PrefsView) ForceDaemon() bool { return v.ж.ForceDaemon } +func (v PrefsView) Egg() bool { return v.ж.Egg } +func (v PrefsView) AdvertiseRoutes() views.IPPrefixSlice { + return views.IPPrefixSliceOf(v.ж.AdvertiseRoutes) +} +func (v PrefsView) NoSNAT() bool { return v.ж.NoSNAT } +func (v PrefsView) NetfilterMode() preftype.NetfilterMode { return v.ж.NetfilterMode } +func (v PrefsView) OperatorUser() string { return v.ж.OperatorUser } +func (v PrefsView) Persist() *persist.Persist { + if v.ж.Persist == nil { + return nil + } + x := *v.ж.Persist + return &x +} + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _PrefsViewNeedsRegeneration = Prefs(struct { + ControlURL string + RouteAll bool + AllowSingleHosts bool + ExitNodeID tailcfg.StableNodeID + ExitNodeIP netip.Addr + ExitNodeAllowLANAccess bool + CorpDNS bool + RunSSH bool + WantRunning bool + LoggedOut bool + ShieldsUp bool + AdvertiseTags []string + Hostname string + NotepadURLs bool + ForceDaemon bool + Egg bool + AdvertiseRoutes []netip.Prefix + NoSNAT bool + NetfilterMode preftype.NetfilterMode + OperatorUser string + Persist *persist.Persist +}{}) diff --git a/ipn/prefs.go b/ipn/prefs.go index 51b7fff64..37fb712ce 100644 --- a/ipn/prefs.go +++ b/ipn/prefs.go @@ -27,7 +27,7 @@ "tailscale.com/util/dnsname" ) -//go:generate go run tailscale.com/cmd/cloner -type=Prefs +//go:generate go run tailscale.com/cmd/viewer -type=Prefs // DefaultControlURL is the URL base of the control plane // ("coordination server") for use when no explicit one is configured. @@ -288,6 +288,8 @@ func (m *MaskedPrefs) Pretty() string { // IsEmpty reports whether p is nil or pointing to a Prefs zero value. func (p *Prefs) IsEmpty() bool { return p == nil || p.Equals(&Prefs{}) } +func (p PrefsView) Pretty() string { return p.ж.Pretty() } + func (p *Prefs) Pretty() string { return p.pretty(runtime.GOOS) } func (p *Prefs) pretty(goos string) string { var sb strings.Builder @@ -347,6 +349,10 @@ func (p *Prefs) pretty(goos string) string { return sb.String() } +func (p PrefsView) ToBytes() []byte { + return p.ж.ToBytes() +} + func (p *Prefs) ToBytes() []byte { data, err := json.MarshalIndent(p, "", "\t") if err != nil { @@ -355,6 +361,10 @@ func (p *Prefs) ToBytes() []byte { return data } +func (p PrefsView) Equals(p2 PrefsView) bool { + return p.ж.Equals(p2.ж) +} + func (p *Prefs) Equals(p2 *Prefs) bool { if p == nil && p2 == nil { return true @@ -431,6 +441,14 @@ func NewPrefs() *Prefs { } } +// ControlURLOrDefault returns the coordination server's URL base. +// +// If not configured, or if the configured value is a legacy name equivalent to +// the default, then DefaultControlURL is returned instead. +func (p PrefsView) ControlURLOrDefault() string { + return p.ж.ControlURLOrDefault() +} + // ControlURLOrDefault returns the coordination server's URL base. // // If not configured, or if the configured value is a legacy name equivalent to @@ -588,6 +606,12 @@ func (p *Prefs) SetExitNodeIP(s string, st *ipnstate.Status) error { return err } +// ShouldSSHBeRunning reports whether the SSH server should be running based on +// the prefs. +func (p PrefsView) ShouldSSHBeRunning() bool { + return p.Valid() && p.ж.ShouldSSHBeRunning() +} + // ShouldSSHBeRunning reports whether the SSH server should be running based on // the prefs. func (p *Prefs) ShouldSSHBeRunning() bool { diff --git a/types/persist/persist.go b/types/persist/persist.go index d137de1c0..9b9034005 100644 --- a/types/persist/persist.go +++ b/types/persist/persist.go @@ -12,7 +12,7 @@ "tailscale.com/types/structs" ) -//go:generate go run tailscale.com/cmd/cloner -type=Persist +//go:generate go run tailscale.com/cmd/viewer -type=Persist // Persist is the JSON type stored on disk on nodes to remember their // settings between runs. diff --git a/types/persist/persist_view.go b/types/persist/persist_view.go new file mode 100644 index 000000000..6e0772706 --- /dev/null +++ b/types/persist/persist_view.go @@ -0,0 +1,80 @@ +// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by tailscale/cmd/viewer; DO NOT EDIT. + +package persist + +import ( + "encoding/json" + "errors" + + "tailscale.com/types/key" + "tailscale.com/types/structs" +) + +//go:generate go run tailscale.com/cmd/cloner -clonefunc=false -type=Persist + +// View returns a readonly view of Persist. +func (p *Persist) View() PersistView { + return PersistView{ж: p} +} + +// PersistView provides a read-only view over Persist. +// +// Its methods should only be called if `Valid()` returns true. +type PersistView struct { + // ж is the underlying mutable value, named with a hard-to-type + // character that looks pointy like a pointer. + // It is named distinctively to make you think of how dangerous it is to escape + // to callers. You must not let callers be able to mutate it. + ж *Persist +} + +// Valid reports whether underlying value is non-nil. +func (v PersistView) Valid() bool { return v.ж != nil } + +// AsStruct returns a clone of the underlying value which aliases no memory with +// the original. +func (v PersistView) AsStruct() *Persist { + if v.ж == nil { + return nil + } + return v.ж.Clone() +} + +func (v PersistView) MarshalJSON() ([]byte, error) { return json.Marshal(v.ж) } + +func (v *PersistView) UnmarshalJSON(b []byte) error { + if v.ж != nil { + return errors.New("already initialized") + } + if len(b) == 0 { + return nil + } + var x Persist + if err := json.Unmarshal(b, &x); err != nil { + return err + } + v.ж = &x + return nil +} + +func (v PersistView) LegacyFrontendPrivateMachineKey() key.MachinePrivate { + return v.ж.LegacyFrontendPrivateMachineKey +} +func (v PersistView) PrivateNodeKey() key.NodePrivate { return v.ж.PrivateNodeKey } +func (v PersistView) OldPrivateNodeKey() key.NodePrivate { return v.ж.OldPrivateNodeKey } +func (v PersistView) Provider() string { return v.ж.Provider } +func (v PersistView) LoginName() string { return v.ж.LoginName } + +// A compilation failure here means this code must be regenerated, with the command at the top of this file. +var _PersistViewNeedsRegeneration = Persist(struct { + _ structs.Incomparable + LegacyFrontendPrivateMachineKey key.MachinePrivate + PrivateNodeKey key.NodePrivate + OldPrivateNodeKey key.NodePrivate + Provider string + LoginName string +}{}) diff --git a/types/views/views.go b/types/views/views.go index fe3fe8031..c8d147a3d 100644 --- a/types/views/views.go +++ b/types/views/views.go @@ -201,6 +201,11 @@ func (v IPPrefixSlice) AsSlice() []netip.Prefix { return v.ж.AsSlice() } +// Filter returns a new slice, containing elements of v that match f. +func (v IPPrefixSlice) Filter(f func(netip.Prefix) bool) []netip.Prefix { + return tsaddr.FilterPrefixesCopy(v.ж.ж, f) +} + // PrefixesContainsIP reports whether any IPPrefix contains IP. func (v IPPrefixSlice) ContainsIP(ip netip.Addr) bool { return tsaddr.PrefixesContainsIP(v.ж.ж, ip)