/
githubmirror
/
origin
Обзор
Документация
Войти
/
githubmirror
/
origin
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
vendor/github.com/vmware/govmomi/session/manager.go
312 строк
7 KB
Justin Pierce
Add compat_otp package with openshift-tests-private (OTP) util implementations
11 авг 2025, 18:00
11 авг 2025, 18:00
80ac5c1
Код
Авторство
О чём код?
// © Broadcom. All Rights Reserved. // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. // SPDX-License-Identifier: Apache-2.0 package session import ( "context" "net/url" "os" "strings" "sync" "github.com/vmware/govmomi/fault" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/methods" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" ) // Locale defaults to "en_US" and can be overridden via this var or the GOVMOMI_LOCALE env var. // A value of "_" uses the server locale setting. var Locale = os.Getenv("GOVMOMI_LOCALE") func init() { if Locale == "_" { Locale = "" } else if Locale == "" { Locale = "en_US" } } // Secret returns the contents if a file path value is given, otherwise returns value itself. func Secret(value string) (string, error) { if len(value) == 0 { return value, nil } contents, err := os.ReadFile(value) if err != nil { if os.IsPermission(err) { return "", err } return value, nil } return strings.TrimSpace(string(contents)), nil } type Manager struct { client *vim25.Client userSession *types.UserSession mu sync.Mutex } func NewManager(client *vim25.Client) *Manager { m := Manager{ client: client, } return &m } func (sm *Manager) Reference() types.ManagedObjectReference { return *sm.client.ServiceContent.SessionManager } func (sm *Manager) SetLocale(ctx context.Context, locale string) error { req := types.SetLocale{ This: sm.Reference(), Locale: locale, } _, err := methods.SetLocale(ctx, sm.client, &req) 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(), Locale: Locale, } if u != nil { req.UserName = u.Username() if pw, ok := u.Password(); ok { req.Password = pw } } login, err := methods.Login(ctx, sm.client, &req) if err != nil { return err } sm.setUserSession(&login.Returnval) return nil } // LoginExtensionByCertificate uses the vCenter SDK tunnel to login using a client certificate. // The client certificate can be set using the soap.Client.SetCertificate method. func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string) error { c := sm.client u := c.URL() if u.Hostname() != "sdkTunnel" { sc := c.Tunnel() c = &vim25.Client{ Client: sc, RoundTripper: sc, ServiceContent: c.ServiceContent, } // When http.Transport.Proxy is used, our thumbprint checker is bypassed, resulting in: // "Post https://sdkTunnel:8089/sdk: x509: certificate is valid for $vcenter_hostname, not sdkTunnel" // The only easy way around this is to disable verification for the call to LoginExtensionByCertificate(). // TODO: find a way to avoid disabling InsecureSkipVerify. c.DefaultTransport().TLSClientConfig.InsecureSkipVerify = true } req := types.LoginExtensionByCertificate{ This: sm.Reference(), ExtensionKey: key, Locale: Locale, } login, err := methods.LoginExtensionByCertificate(ctx, c, &req) if err != nil { return err } // Copy the session cookie sm.client.Jar.SetCookies(u, c.Jar.Cookies(c.URL())) sm.setUserSession(&login.Returnval) return nil } func (sm *Manager) LoginByToken(ctx context.Context) error { req := types.LoginByToken{ This: sm.Reference(), Locale: Locale, } login, err := methods.LoginByToken(ctx, sm.client, &req) if err != nil { return err } sm.setUserSession(&login.Returnval) return nil } func (sm *Manager) Logout(ctx context.Context) error { req := types.Logout{ This: sm.Reference(), } _, err := methods.Logout(ctx, sm.client, &req) if err != nil { return err } sm.setUserSession(nil) return nil } // UserSession retrieves and returns the SessionManager's CurrentSession field. // Nil is returned if the session is not authenticated. func (sm *Manager) UserSession(ctx context.Context) (*types.UserSession, error) { var mgr mo.SessionManager pc := property.DefaultCollector(sm.client) err := pc.RetrieveOne(ctx, sm.Reference(), []string{"currentSession"}, &mgr) if err != nil { // It's OK if we can't retrieve properties because we're not authenticated if fault.Is(err, &types.NotAuthenticated{}) { return nil, nil } return nil, err } return mgr.CurrentSession, nil } func (sm *Manager) TerminateSession(ctx context.Context, sessionId []string) error { req := types.TerminateSession{ This: sm.Reference(), SessionId: sessionId, } _, err := methods.TerminateSession(ctx, sm.client, &req) return 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) { userSession, ok := sm.getUserSession() if !ok { return false, nil } req := types.SessionIsActive{ This: sm.Reference(), SessionID: userSession.Key, UserName: userSession.UserName, } active, err := methods.SessionIsActive(ctx, sm.client, &req) if err != nil { return false, err } return active.Returnval, err } func (sm *Manager) AcquireGenericServiceTicket(ctx context.Context, spec types.BaseSessionManagerServiceRequestSpec) (*types.SessionManagerGenericServiceTicket, error) { req := types.AcquireGenericServiceTicket{ This: sm.Reference(), Spec: spec, } res, err := methods.AcquireGenericServiceTicket(ctx, sm.client, &req) if err != nil { return nil, err } return &res.Returnval, nil } func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*types.SessionManagerLocalTicket, error) { req := types.AcquireLocalTicket{ This: sm.Reference(), UserName: userName, } res, err := methods.AcquireLocalTicket(ctx, sm.client, &req) if err != nil { return nil, err } return &res.Returnval, nil } func (sm *Manager) AcquireCloneTicket(ctx context.Context) (string, error) { req := types.AcquireCloneTicket{ This: sm.Reference(), } res, err := methods.AcquireCloneTicket(ctx, sm.client, &req) if err != nil { return "", err } return res.Returnval, nil } func (sm *Manager) CloneSession(ctx context.Context, ticket string) error { req := types.CloneSession{ This: sm.Reference(), CloneTicket: ticket, } res, err := methods.CloneSession(ctx, sm.client, &req) if err != nil { return err } sm.setUserSession(&res.Returnval) return nil } func (sm *Manager) UpdateServiceMessage(ctx context.Context, message string) error { req := types.UpdateServiceMessage{ This: sm.Reference(), Message: message, } _, err := methods.UpdateServiceMessage(ctx, sm.client, &req) return err } func (sm *Manager) ImpersonateUser(ctx context.Context, name string) error { req := types.ImpersonateUser{ This: sm.Reference(), UserName: name, Locale: Locale, } res, err := methods.ImpersonateUser(ctx, sm.client, &req) if err != nil { return err } sm.setUserSession(&res.Returnval) return nil }