Blame vendor/github.com/vmware/govmomi/session/manager.go

Packit 63bb0d
/*
Packit 63bb0d
Copyright (c) 2015 VMware, Inc. All Rights Reserved.
Packit 63bb0d
Packit 63bb0d
Licensed under the Apache License, Version 2.0 (the "License");
Packit 63bb0d
you may not use this file except in compliance with the License.
Packit 63bb0d
You may obtain a copy of the License at
Packit 63bb0d
Packit 63bb0d
    http://www.apache.org/licenses/LICENSE-2.0
Packit 63bb0d
Packit 63bb0d
Unless required by applicable law or agreed to in writing, software
Packit 63bb0d
distributed under the License is distributed on an "AS IS" BASIS,
Packit 63bb0d
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 63bb0d
See the License for the specific language governing permissions and
Packit 63bb0d
limitations under the License.
Packit 63bb0d
*/
Packit 63bb0d
Packit 63bb0d
package session
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"context"
Packit 63bb0d
	"io/ioutil"
Packit 63bb0d
	"net/url"
Packit 63bb0d
	"os"
Packit 63bb0d
	"strings"
Packit 63bb0d
Packit 63bb0d
	"github.com/vmware/govmomi/property"
Packit 63bb0d
	"github.com/vmware/govmomi/vim25"
Packit 63bb0d
	"github.com/vmware/govmomi/vim25/methods"
Packit 63bb0d
	"github.com/vmware/govmomi/vim25/mo"
Packit 63bb0d
	"github.com/vmware/govmomi/vim25/types"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// Locale defaults to "en_US" and can be overridden via this var or the GOVMOMI_LOCALE env var.
Packit 63bb0d
// A value of "_" uses the server locale setting.
Packit 63bb0d
var Locale = os.Getenv("GOVMOMI_LOCALE")
Packit 63bb0d
Packit 63bb0d
func init() {
Packit 63bb0d
	if Locale == "_" {
Packit 63bb0d
		Locale = ""
Packit 63bb0d
	} else if Locale == "" {
Packit 63bb0d
		Locale = "en_US"
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Secret returns the contents if a file path value is given, otherwise returns value itself.
Packit 63bb0d
func Secret(value string) (string, error) {
Packit 63bb0d
	if len(value) == 0 {
Packit 63bb0d
		return value, nil
Packit 63bb0d
	}
Packit 63bb0d
	contents, err := ioutil.ReadFile(value)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		if os.IsPermission(err) {
Packit 63bb0d
			return "", err
Packit 63bb0d
		}
Packit 63bb0d
		return value, nil
Packit 63bb0d
	}
Packit 63bb0d
	return strings.TrimSpace(string(contents)), nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
type Manager struct {
Packit 63bb0d
	client      *vim25.Client
Packit 63bb0d
	userSession *types.UserSession
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func NewManager(client *vim25.Client) *Manager {
Packit 63bb0d
	m := Manager{
Packit 63bb0d
		client: client,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &m
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm Manager) Reference() types.ManagedObjectReference {
Packit 63bb0d
	return *sm.client.ServiceContent.SessionManager
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) SetLocale(ctx context.Context, locale string) error {
Packit 63bb0d
	req := types.SetLocale{
Packit 63bb0d
		This:   sm.Reference(),
Packit 63bb0d
		Locale: locale,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	_, err := methods.SetLocale(ctx, sm.client, &req)
Packit 63bb0d
	return err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) Login(ctx context.Context, u *url.Userinfo) error {
Packit 63bb0d
	req := types.Login{
Packit 63bb0d
		This:   sm.Reference(),
Packit 63bb0d
		Locale: Locale,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if u != nil {
Packit 63bb0d
		req.UserName = u.Username()
Packit 63bb0d
		if pw, ok := u.Password(); ok {
Packit 63bb0d
			req.Password = pw
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	login, err := methods.Login(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	sm.userSession = &login.Returnval
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// LoginExtensionByCertificate uses the vCenter SDK tunnel to login using a client certificate.
Packit 63bb0d
// The client certificate can be set using the soap.Client.SetCertificate method.
Packit 63bb0d
// See: https://kb.vmware.com/s/article/2004305
Packit 63bb0d
func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string) error {
Packit 63bb0d
	c := sm.client
Packit 63bb0d
	u := c.URL()
Packit 63bb0d
	if u.Hostname() != "sdkTunnel" {
Packit 63bb0d
		sc := c.Tunnel()
Packit 63bb0d
		c = &vim25.Client{
Packit 63bb0d
			Client:         sc,
Packit 63bb0d
			RoundTripper:   sc,
Packit 63bb0d
			ServiceContent: c.ServiceContent,
Packit 63bb0d
		}
Packit 63bb0d
		// When http.Transport.Proxy is used, our thumbprint checker is bypassed, resulting in:
Packit 63bb0d
		// "Post https://sdkTunnel:8089/sdk: x509: certificate is valid for $vcenter_hostname, not sdkTunnel"
Packit 63bb0d
		// The only easy way around this is to disable verification for the call to LoginExtensionByCertificate().
Packit 63bb0d
		// TODO: find a way to avoid disabling InsecureSkipVerify.
Packit 63bb0d
		c.DefaultTransport().TLSClientConfig.InsecureSkipVerify = true
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	req := types.LoginExtensionByCertificate{
Packit 63bb0d
		This:         sm.Reference(),
Packit 63bb0d
		ExtensionKey: key,
Packit 63bb0d
		Locale:       Locale,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	login, err := methods.LoginExtensionByCertificate(ctx, c, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Copy the session cookie
Packit 63bb0d
	sm.client.Jar.SetCookies(u, c.Jar.Cookies(c.URL()))
Packit 63bb0d
Packit 63bb0d
	sm.userSession = &login.Returnval
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) LoginByToken(ctx context.Context) error {
Packit 63bb0d
	req := types.LoginByToken{
Packit 63bb0d
		This:   sm.Reference(),
Packit 63bb0d
		Locale: Locale,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	login, err := methods.LoginByToken(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	sm.userSession = &login.Returnval
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) Logout(ctx context.Context) error {
Packit 63bb0d
	req := types.Logout{
Packit 63bb0d
		This: sm.Reference(),
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	_, err := methods.Logout(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	sm.userSession = nil
Packit 63bb0d
	return nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// UserSession retrieves and returns the SessionManager's CurrentSession field.
Packit 63bb0d
// Nil is returned if the session is not authenticated.
Packit 63bb0d
func (sm *Manager) UserSession(ctx context.Context) (*types.UserSession, error) {
Packit 63bb0d
	var mgr mo.SessionManager
Packit 63bb0d
Packit 63bb0d
	pc := property.DefaultCollector(sm.client)
Packit 63bb0d
	err := pc.RetrieveOne(ctx, sm.Reference(), []string{"currentSession"}, &mgr)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		// It's OK if we can't retrieve properties because we're not authenticated
Packit 63bb0d
		if f, ok := err.(types.HasFault); ok {
Packit 63bb0d
			switch f.Fault().(type) {
Packit 63bb0d
			case *types.NotAuthenticated:
Packit 63bb0d
				return nil, nil
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		return nil, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return mgr.CurrentSession, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) TerminateSession(ctx context.Context, sessionId []string) error {
Packit 63bb0d
	req := types.TerminateSession{
Packit 63bb0d
		This:      sm.Reference(),
Packit 63bb0d
		SessionId: sessionId,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	_, err := methods.TerminateSession(ctx, sm.client, &req)
Packit 63bb0d
	return err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// SessionIsActive checks whether the session that was created at login is
Packit 63bb0d
// still valid. This function only works against vCenter.
Packit 63bb0d
func (sm *Manager) SessionIsActive(ctx context.Context) (bool, error) {
Packit 63bb0d
	if sm.userSession == nil {
Packit 63bb0d
		return false, nil
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	req := types.SessionIsActive{
Packit 63bb0d
		This:      sm.Reference(),
Packit 63bb0d
		SessionID: sm.userSession.Key,
Packit 63bb0d
		UserName:  sm.userSession.UserName,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	active, err := methods.SessionIsActive(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return false, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return active.Returnval, err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) AcquireGenericServiceTicket(ctx context.Context, spec types.BaseSessionManagerServiceRequestSpec) (*types.SessionManagerGenericServiceTicket, error) {
Packit 63bb0d
	req := types.AcquireGenericServiceTicket{
Packit 63bb0d
		This: sm.Reference(),
Packit 63bb0d
		Spec: spec,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	res, err := methods.AcquireGenericServiceTicket(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return nil, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &res.Returnval, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) AcquireLocalTicket(ctx context.Context, userName string) (*types.SessionManagerLocalTicket, error) {
Packit 63bb0d
	req := types.AcquireLocalTicket{
Packit 63bb0d
		This:     sm.Reference(),
Packit 63bb0d
		UserName: userName,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	res, err := methods.AcquireLocalTicket(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return nil, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return &res.Returnval, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) AcquireCloneTicket(ctx context.Context) (string, error) {
Packit 63bb0d
	req := types.AcquireCloneTicket{
Packit 63bb0d
		This: sm.Reference(),
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	res, err := methods.AcquireCloneTicket(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return "", err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return res.Returnval, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (sm *Manager) CloneSession(ctx context.Context, ticket string) error {
Packit 63bb0d
	req := types.CloneSession{
Packit 63bb0d
		This:        sm.Reference(),
Packit 63bb0d
		CloneTicket: ticket,
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	res, err := methods.CloneSession(ctx, sm.client, &req)
Packit 63bb0d
	if err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	sm.userSession = &res.Returnval
Packit 63bb0d
	return nil
Packit 63bb0d
}