diff --git a/cmd/tailscale/cli/advertise.go b/cmd/tailscale/cli/advertise.go deleted file mode 100644 index cfba800b5..000000000 --- a/cmd/tailscale/cli/advertise.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package cli - -import ( - "context" - "flag" - "fmt" - "strings" - - "github.com/peterbourgon/ff/v3/ffcli" - "tailscale.com/envknob" - "tailscale.com/ipn" - "tailscale.com/tailcfg" -) - -var advertiseArgs struct { - services string // comma-separated list of services to advertise -} - -// TODO(naman): This flag may move to set.go or serve_v2.go after the WIPCode -// envknob is not needed. -func advertiseCmd() *ffcli.Command { - if !envknob.UseWIPCode() { - return nil - } - return &ffcli.Command{ - Name: "advertise", - ShortUsage: "tailscale advertise --services=", - ShortHelp: "Advertise this node as a destination for a service", - Exec: runAdvertise, - FlagSet: (func() *flag.FlagSet { - fs := newFlagSet("advertise") - fs.StringVar(&advertiseArgs.services, "services", "", "comma-separated services to advertise; each must start with \"svc:\" (e.g. \"svc:idp,svc:nas,svc:database\")") - return fs - })(), - } -} - -func runAdvertise(ctx context.Context, args []string) error { - if len(args) > 0 { - return flag.ErrHelp - } - - services, err := parseServiceNames(advertiseArgs.services) - if err != nil { - return err - } - if len(services) > 0 { - fmt.Println("Advertising this node as new destination for services:", services) - fmt.Println("This node will accept connection for services once the services are configured locally and approved on the admin console.") - sc, err := localClient.GetServeConfig(ctx) - if err != nil { - return fmt.Errorf("failed to get serve config: %w", err) - } - notServedServices := make([]string, 0) - for _, svc := range services { - if _, ok := sc.Services[tailcfg.ServiceName(svc)]; !ok { - notServedServices = append(notServedServices, svc) - } - } - if len(notServedServices) > 0 { - fmt.Println("The following services are not configured to be served yet: ", strings.Join(notServedServices, ", ")) - fmt.Println("To configure services, run tailscale serve --service=\"\" for each service.") - fmt.Printf("eg. tailscale serve --service=%q 3000\n", notServedServices[0]) - } - } - - _, err = localClient.EditPrefs(ctx, &ipn.MaskedPrefs{ - AdvertiseServicesSet: true, - Prefs: ipn.Prefs{ - AdvertiseServices: services, - }, - }) - return err -} - -// parseServiceNames takes a comma-separated list of service names -// (eg. "svc:hello,svc:webserver,svc:catphotos"), splits them into -// a list and validates each service name. If valid, it returns -// the service names in a slice of strings. -func parseServiceNames(servicesArg string) ([]string, error) { - var services []string - if servicesArg != "" { - services = strings.Split(servicesArg, ",") - for _, svc := range services { - err := tailcfg.ServiceName(svc).Validate() - if err != nil { - return nil, fmt.Errorf("service %q: %s", svc, err) - } - } - } - return services, nil -} diff --git a/cmd/tailscale/cli/serve_legacy.go b/cmd/tailscale/cli/serve_legacy.go index abd12f80c..1789ad93e 100644 --- a/cmd/tailscale/cli/serve_legacy.go +++ b/cmd/tailscale/cli/serve_legacy.go @@ -142,6 +142,7 @@ type localServeClient interface { WatchIPNBus(ctx context.Context, mask ipn.NotifyWatchOpt) (*tailscale.IPNBusWatcher, error) IncrementCounter(ctx context.Context, name string, delta int) error GetPrefs(ctx context.Context) (*ipn.Prefs, error) + EditPrefs(ctx context.Context, mp *ipn.MaskedPrefs) (*ipn.Prefs, error) } // serveEnv is the environment the serve command runs within. All I/O should be diff --git a/cmd/tailscale/cli/serve_v2.go b/cmd/tailscale/cli/serve_v2.go index 67537ba08..83277891c 100644 --- a/cmd/tailscale/cli/serve_v2.go +++ b/cmd/tailscale/cli/serve_v2.go @@ -353,12 +353,11 @@ func (e *serveEnv) runServeCombined(subcmd serveMode) execFunc { var msg string if turnOff { - if wasDefaultServe && forService { - delete(sc.Services, tailcfg.ServiceName(dnsName)) - } else { + if !wasDefaultServe { // only unset serve when trying to unset with parameters. err = e.unsetServe(sc, st, dnsName, srvType, srvPort, mount) } } else { + e.addServiceToPrefs(ctx, dnsName) if err := e.validateConfig(parentSC, srvPort, srvType, dnsName); err != nil { return err } @@ -367,7 +366,7 @@ func (e *serveEnv) runServeCombined(subcmd serveMode) execFunc { target = args[0] } err = e.setServe(sc, st, dnsName, srvType, srvPort, mount, target, funnel) - msg = e.messageForPort(sc, st, prefs, dnsName, srvType, srvPort) + msg = e.messageForPort(sc, st, dnsName, srvType, srvPort) } if err != nil { fmt.Fprintf(e.stderr(), "error: %v\n\n", err) @@ -502,14 +501,13 @@ var ( msgDisableProxy = "To disable the proxy, run: tailscale %s --%s=%d off" msgDisableServiceProxy = "To disable the proxy, run: tailscale serve --service=%s --%s=%d off" msgDisableServiceTun = "To disable the service in TUN mode, run: tailscale serve --service=%s --tun off" - msgDisableService = "To disable the service entirely, run: tailscale serve --service=%s off" - msgServiceNotAdvertised = "This service is not advertised on this node yet, use `tailscale advertise --services=svc:%s` to advertise it." + msgDisableService = "To remove config for the service, run: tailscale serve clear --service=%s" msgToExit = "Press Ctrl+C to exit." ) // messageForPort returns a message for the given port based on the // serve config and status. -func (e *serveEnv) messageForPort(sc *ipn.ServeConfig, st *ipnstate.Status, prefs *ipn.Prefs, dnsName string, srvType serveType, srvPort uint16) string { +func (e *serveEnv) messageForPort(sc *ipn.ServeConfig, st *ipnstate.Status, dnsName string, srvType serveType, srvPort uint16) string { var output strings.Builder forService := ipn.IsServiceName(dnsName) var hp ipn.HostPort @@ -618,10 +616,6 @@ func (e *serveEnv) messageForPort(sc *ipn.ServeConfig, st *ipnstate.Status, pref output.WriteString(fmt.Sprintf(msgRunningInBackground, subCmdUpper)) output.WriteString("\n") if forService { - if !slices.Contains(prefs.AdvertiseServices, dnsName) { - output.WriteString(fmt.Sprintf(msgServiceNotAdvertised, dnsName)) - output.WriteString("\n") - } output.WriteString(fmt.Sprintf(msgDisableServiceProxy, dnsName, srvType.String(), srvPort)) output.WriteString("\n") output.WriteString(fmt.Sprintf(msgDisableService, dnsName))