diff --git a/session/manager.go b/session/manager.go index da993c546..ac8d11dff 100644 --- a/session/manager.go +++ b/session/manager.go @@ -21,6 +21,7 @@ import ( "net/url" "os" "strings" + "sync" "github.com/vmware/govmomi/fault" "github.com/vmware/govmomi/property" @@ -60,6 +61,7 @@ func Secret(value string) (string, error) { type Manager struct { client *vim25.Client userSession *types.UserSession + mu sync.Mutex } func NewManager(client *vim25.Client) *Manager { @@ -70,7 +72,7 @@ func NewManager(client *vim25.Client) *Manager { return &m } -func (sm Manager) Reference() types.ManagedObjectReference { +func (sm *Manager) Reference() types.ManagedObjectReference { return *sm.client.ServiceContent.SessionManager } @@ -84,6 +86,21 @@ func (sm *Manager) SetLocale(ctx context.Context, locale string) error { return err } +func (sm *Manager) setUserSession(val *types.UserSession) { + sm.mu.Lock() + sm.userSession = val + sm.mu.Unlock() +} + +func (sm *Manager) getUserSession() (types.UserSession, bool) { + sm.mu.Lock() + defer sm.mu.Unlock() + if sm.userSession == nil { + return types.UserSession{}, false + } + return *sm.userSession, true +} + func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error { req := types.Login{ This: sm.Reference(), @@ -102,7 +119,7 @@ func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error { return err } - sm.userSession = &login.Returnval + sm.setUserSession(&login.Returnval) return nil } @@ -140,7 +157,7 @@ func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string) // Copy the session cookie sm.client.Jar.SetCookies(u, c.Jar.Cookies(c.URL())) - sm.userSession = &login.Returnval + sm.setUserSession(&login.Returnval) return nil } @@ -155,7 +172,7 @@ func (sm *Manager) LoginByToken(ctx context.Context) error { return err } - sm.userSession = &login.Returnval + sm.setUserSession(&login.Returnval) return nil } @@ -169,7 +186,7 @@ func (sm *Manager) Logout(ctx context.Context) error { return err } - sm.userSession = nil + sm.setUserSession(nil) return nil } @@ -205,14 +222,15 @@ func (sm *Manager) TerminateSession(ctx context.Context, sessionId []string) err // SessionIsActive checks whether the session that was created at login is // still valid. This function only works against vCenter. func (sm *Manager) SessionIsActive(ctx context.Context) (bool, error) { - if sm.userSession == nil { + userSession, ok := sm.getUserSession() + if !ok { return false, nil } req := types.SessionIsActive{ This: sm.Reference(), - SessionID: sm.userSession.Key, - UserName: sm.userSession.UserName, + SessionID: userSession.Key, + UserName: userSession.UserName, } active, err := methods.SessionIsActive(ctx, sm.client, &req) @@ -275,7 +293,7 @@ func (sm *Manager) CloneSession(ctx context.Context, ticket string) error { return err } - sm.userSession = &res.Returnval + sm.setUserSession(&res.Returnval) return nil } @@ -302,6 +320,6 @@ func (sm *Manager) ImpersonateUser(ctx context.Context, name string) error { return err } - sm.userSession = &res.Returnval + sm.setUserSession(&res.Returnval) return nil }