Compare commits
1 Commits
main
...
mihaip/del
Author | SHA1 | Date |
---|---|---|
![]() |
6fa376ae50 |
|
@ -4204,6 +4204,16 @@ func (b *LocalBackend) DeleteProfile(p ipn.ProfileID) error {
|
||||||
return b.resetForProfileChangeLockedOnEntry()
|
return b.resetForProfileChangeLockedOnEntry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteProfiles removes all known profiles.
|
||||||
|
func (b *LocalBackend) DeleteAllProfiles() error {
|
||||||
|
b.mu.Lock()
|
||||||
|
if err := b.pm.DeleteAllProfiles(); err != nil {
|
||||||
|
b.mu.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return b.resetForProfileChangeLockedOnEntry()
|
||||||
|
}
|
||||||
|
|
||||||
// CurrentProfile returns the current LoginProfile.
|
// CurrentProfile returns the current LoginProfile.
|
||||||
// The value may be zero if the profile is not persisted.
|
// The value may be zero if the profile is not persisted.
|
||||||
func (b *LocalBackend) CurrentProfile() ipn.LoginProfile {
|
func (b *LocalBackend) CurrentProfile() ipn.LoginProfile {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"tailscale.com/ipn"
|
"tailscale.com/ipn"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
@ -349,6 +350,21 @@ func (pm *profileManager) DeleteProfile(id ipn.ProfileID) error {
|
||||||
return pm.writeKnownProfiles()
|
return pm.writeKnownProfiles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteAllProfiles removes all known profiles and switches to a new empty
|
||||||
|
// profile.
|
||||||
|
func (pm *profileManager) DeleteAllProfiles() error {
|
||||||
|
metricDeleteAllProfile.Add(1)
|
||||||
|
|
||||||
|
for _, kp := range pm.knownProfiles {
|
||||||
|
if err := pm.store.WriteState(kp.Key, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pm.NewProfile()
|
||||||
|
maps.Clear(pm.knownProfiles)
|
||||||
|
return pm.writeKnownProfiles()
|
||||||
|
}
|
||||||
|
|
||||||
func (pm *profileManager) writeKnownProfiles() error {
|
func (pm *profileManager) writeKnownProfiles() error {
|
||||||
b, err := json.Marshal(pm.knownProfiles)
|
b, err := json.Marshal(pm.knownProfiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -515,6 +531,7 @@ var (
|
||||||
metricNewProfile = clientmetric.NewCounter("profiles_new")
|
metricNewProfile = clientmetric.NewCounter("profiles_new")
|
||||||
metricSwitchProfile = clientmetric.NewCounter("profiles_switch")
|
metricSwitchProfile = clientmetric.NewCounter("profiles_switch")
|
||||||
metricDeleteProfile = clientmetric.NewCounter("profiles_delete")
|
metricDeleteProfile = clientmetric.NewCounter("profiles_delete")
|
||||||
|
metricDeleteAllProfile = clientmetric.NewCounter("profiles_delete_all")
|
||||||
|
|
||||||
metricMigration = clientmetric.NewCounter("profiles_migration")
|
metricMigration = clientmetric.NewCounter("profiles_migration")
|
||||||
metricMigrationError = clientmetric.NewCounter("profiles_migration_error")
|
metricMigrationError = clientmetric.NewCounter("profiles_migration_error")
|
||||||
|
|
|
@ -164,6 +164,14 @@ func TestProfileManagement(t *testing.T) {
|
||||||
delete(wantProfiles, "tagged-node.2.ts.net")
|
delete(wantProfiles, "tagged-node.2.ts.net")
|
||||||
wantCurProfile = "user@2.example.com"
|
wantCurProfile = "user@2.example.com"
|
||||||
checkProfiles(t)
|
checkProfiles(t)
|
||||||
|
|
||||||
|
t.Logf("Delete all")
|
||||||
|
pm.DeleteAllProfiles()
|
||||||
|
wantProfiles = map[string]ipn.PrefsView{
|
||||||
|
"": emptyPrefs,
|
||||||
|
}
|
||||||
|
wantCurProfile = ""
|
||||||
|
checkProfiles(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestProfileManagementWindows tests going into and out of Unattended mode on
|
// TestProfileManagementWindows tests going into and out of Unattended mode on
|
||||||
|
|
|
@ -1156,6 +1156,7 @@ func (h *Handler) serveTKADisable(w http.ResponseWriter, r *http.Request) {
|
||||||
// - GET /profiles/: list all profiles (JSON-encoded array of ipn.LoginProfiles)
|
// - GET /profiles/: list all profiles (JSON-encoded array of ipn.LoginProfiles)
|
||||||
// - PUT /profiles/: add new profile (no response). A separate
|
// - PUT /profiles/: add new profile (no response). A separate
|
||||||
// StartLoginInteractive() is needed to populate and persist the new profile.
|
// StartLoginInteractive() is needed to populate and persist the new profile.
|
||||||
|
// - DELETE /profiles/: delete all profile (no response)
|
||||||
// - GET /profiles/current: current profile (JSON-ecoded ipn.LoginProfile)
|
// - GET /profiles/current: current profile (JSON-ecoded ipn.LoginProfile)
|
||||||
// - GET /profiles/<id>: output profile (JSON-ecoded ipn.LoginProfile)
|
// - GET /profiles/<id>: output profile (JSON-ecoded ipn.LoginProfile)
|
||||||
// - POST /profiles/<id>: switch to profile (no response)
|
// - POST /profiles/<id>: switch to profile (no response)
|
||||||
|
@ -1182,6 +1183,13 @@ func (h *Handler) serveProfiles(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
case http.MethodDelete:
|
||||||
|
err := h.b.DeleteAllProfiles()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
default:
|
default:
|
||||||
http.Error(w, "use GET or PUT", http.StatusMethodNotAllowed)
|
http.Error(w, "use GET or PUT", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue