func (flag *ClientFlag) newClient() (*vim25.Client, error) { sc := soap.NewClient(flag.url, flag.insecure) // Add retry functionality before making any calls rt := attachRetries(sc) c, err := vim25.NewClient(context.TODO(), rt) if err != nil { return nil, err } // Set client, since we didn't pass it in the constructor c.Client = sc m := session.NewManager(c) err = m.Login(context.TODO(), flag.url.User) if err != nil { return nil, err } err = flag.saveClient(c) if err != nil { return nil, err } return c, nil }
// NewAuthenticatedClient creates a new vim25.Client, authenticates the user // specified in the test URL, and returns it. func NewAuthenticatedClient(t *testing.T) *vim25.Client { u := URL() if u == nil { t.SkipNow() } soapClient := soap.NewClient(u, true) vimClient, err := vim25.NewClient(context.Background(), soapClient) if err != nil { t.Fatal(err) } req := types.Login{ This: *vimClient.ServiceContent.SessionManager, } req.UserName = u.User.Username() if pw, ok := u.User.Password(); ok { req.Password = pw } _, err = methods.Login(context.Background(), vimClient, &req) if err != nil { t.Fatal(err) } return vimClient }
func TestClientSerialization(t *testing.T) { var c1, c2 *Client soapClient := soap.NewClient(testURL(t), true) c1, err := NewClient(context.Background(), soapClient) if err != nil { t.Fatal(err) } // Login sessionLogin(t, c1) sessionCheck(t, c1) // Serialize/deserialize b, err := json.Marshal(c1) if err != nil { t.Fatal(err) } c2 = &Client{} err = json.Unmarshal(b, c2) if err != nil { t.Fatal(err) } // Check the session is still valid sessionCheck(t, c2) }
func (flag *ClientFlag) newClient() (*vim25.Client, error) { ctx := context.TODO() sc := soap.NewClient(flag.url, flag.insecure) isTunnel := false if flag.cert != "" { isTunnel = true cert, err := tls.LoadX509KeyPair(flag.cert, flag.key) if err != nil { return nil, err } sc.SetCertificate(cert) } rt, err := flag.configure(sc) if err != nil { return nil, err } c, err := vim25.NewClient(ctx, rt) if err != nil { return nil, err } // Set client, since we didn't pass it in the constructor c.Client = sc m := session.NewManager(c) u := flag.url.User if u.Username() == "" { // Assume we are running on an ESX or Workstation host if no username is provided u, err = flag.localTicket(ctx, m) if err != nil { return nil, err } } if isTunnel { err = m.LoginExtensionByCertificate(ctx, u.Username(), "") if err != nil { return nil, err } } else { err = m.Login(ctx, u) if err != nil { return nil, err } } err = flag.saveClient(c) if err != nil { return nil, err } return c, nil }
func (flag *ClientFlag) newClient() (*vim25.Client, error) { sc := soap.NewClient(flag.url, flag.insecure) isTunnel := false if flag.cert != "" { isTunnel = true cert, err := tls.LoadX509KeyPair(flag.cert, flag.key) if err != nil { return nil, err } sc.SetCertificate(cert) } // Set namespace and version sc.Namespace = flag.vimNamespace sc.Version = flag.vimVersion // Add retry functionality before making any calls rt := attachRetries(sc) c, err := vim25.NewClient(context.TODO(), rt) if err != nil { return nil, err } // Set client, since we didn't pass it in the constructor c.Client = sc m := session.NewManager(c) u := flag.url.User if u.Username() == "" { // Assume we are running on an ESX or Workstation host if no username is provided u, err = flag.localTicket(context.TODO(), m) if err != nil { return nil, err } } if isTunnel { err = m.LoginExtensionByCertificate(context.TODO(), u.Username(), "") if err != nil { return nil, err } } else { err = m.Login(context.TODO(), u) if err != nil { return nil, err } } err = flag.saveClient(c) if err != nil { return nil, err } return c, nil }
func sessionClient(u *url.URL, t *testing.T) *Manager { soapClient := soap.NewClient(u, true) vimClient, err := vim25.NewClient(context.Background(), soapClient) if err != nil { t.Fatal(err) } return NewManager(vimClient) }
func newManager(t *testing.T) (*Manager, *url.URL) { u := test.URL() if u == nil { t.SkipNow() } soapClient := soap.NewClient(u, true) vimClient, err := vim25.NewClient(context.Background(), soapClient) if err != nil { t.Fatal(err) } return NewManager(vimClient), u }
func (flag *ClientFlag) newClient() (*vim25.Client, error) { sc := soap.NewClient(flag.url, flag.insecure) isTunnel := false if flag.cert != "" { isTunnel = true cert, err := tls.LoadX509KeyPair(flag.cert, flag.key) if err != nil { return nil, err } sc.SetCertificate(cert) } // Add retry functionality before making any calls rt := attachRetries(sc) c, err := vim25.NewClient(context.TODO(), rt) if err != nil { return nil, err } // Set client, since we didn't pass it in the constructor c.Client = sc m := session.NewManager(c) u := flag.url.User if isTunnel { err = m.LoginExtensionByCertificate(context.TODO(), u.Username(), "") if err != nil { return nil, err } } else { err = m.Login(context.TODO(), u) if err != nil { return nil, err } } err = flag.saveClient(c) if err != nil { return nil, err } return c, nil }
// NewClient creates a new client from a URL. The client authenticates with the // server with username/password before returning if the URL contains user information. func NewClient(ctx context.Context, u *url.URL, insecure bool) (*Client, error) { soapClient := soap.NewClient(u, insecure) vimClient, err := vim25.NewClient(ctx, soapClient) if err != nil { return nil, err } c := &Client{ Client: vimClient, SessionManager: session.NewManager(vimClient), } // Only login if the URL contains user information. if u.User != nil { err = c.Login(ctx, u.User) if err != nil { return nil, err } } return c, nil }
// NewClientWithCertificate creates a new client from a URL. The client authenticates with the // server with the certificate before returning if the URL contains user information. func NewClientWithCertificate(ctx context.Context, u *url.URL, insecure bool, cert tls.Certificate) (*Client, error) { soapClient := soap.NewClient(u, insecure) soapClient.SetCertificate(cert) vimClient, err := vim25.NewClient(ctx, soapClient) if err != nil { return nil, err } c := &Client{ Client: vimClient, SessionManager: session.NewManager(vimClient), } if u.User != nil { err = c.LoginExtensionByCertificate(ctx, u.User.Username(), "") if err != nil { return nil, err } } return c, nil }
func (cmd *cert) Run(ctx context.Context, f *flag.FlagSet) error { u := cmd.URLWithoutPassword() c := soap.NewClient(u, false) t := c.Client.Transport.(*http.Transport) r := certResult{cmd: cmd} if err := cmd.SetRootCAs(c); err != nil { return err } if err := r.info.FromURL(u, t.TLSClientConfig); err != nil { return err } if r.info.Err != nil && r.cmd.IsSecure() { cmd.Out = os.Stderr // using same exit code as curl: defer os.Exit(60) } return r.Write(cmd.Out) }
// Connect establishes the connection for the session but nothing more func (s *Session) Connect(ctx context.Context) (*Session, error) { soapURL, err := soap.ParseURL(s.Service) if soapURL == nil || err != nil { return nil, errors.Errorf("SDK URL (%s) could not be parsed: %s", s.Service, err) } // LoginExtensionByCertificate proxies connections to a virtual host (sdkTunnel:8089) and // Go's http.Transport.DialTLS isn't called when using a proxy. Even if using a known CA, // "sdkTunnel" does not pass Go's tls.VerifyHostname check. // We are moving away from LoginExtensionByCertificate anyhow, so disable thumbprint checks for now. if s.HasCertificate() { s.Insecure = true } // Update the service URL with expanded defaults s.Service = soapURL.String() soapClient := soap.NewClient(soapURL, s.Insecure) var login func(context.Context) error if s.HasCertificate() { cert, err2 := tls.X509KeyPair([]byte(s.ExtensionCert), []byte(s.ExtensionKey)) if err2 != nil { return nil, errors.Errorf("Unable to load X509 key pair(%s,%s): %s", s.ExtensionCert, s.ExtensionKey, err2) } soapClient.SetCertificate(cert) log.Debugf("Logging in via extension %s certificate", s.ExtensionName) login = func(ctx context.Context) error { return s.LoginExtensionByCertificate(ctx, s.ExtensionName, "") } } else { log.Debugf("Logging in via username/password") login = func(ctx context.Context) error { return s.Client.Login(ctx, soapURL.User) } } soapClient.SetThumbprint(soapURL.Host, s.Thumbprint) // TODO: option to set http.Client.Transport.TLSClientConfig.RootCAs vimClient, err := vim25.NewClient(ctx, soapClient) if err != nil { return nil, errors.Errorf("Failed to connect to %s: %s", soapURL.Host, err) } if s.Keepalive != 0 { vimClient.RoundTripper = session.KeepAliveHandler(soapClient, s.Keepalive, func(roundTripper soap.RoundTripper) error { _, err := methods.GetCurrentTime(context.Background(), roundTripper) if err == nil { return nil } log.Warnf("session keepalive error: %s", err) if isNotAuthenticated(err) { if err = login(ctx); err != nil { log.Errorf("session keepalive failed to re-authenticate: %s", err) } else { log.Info("session keepalive re-authenticated") } } return nil }) } // TODO: get rid of govmomi.Client usage, only provides a few helpers we don't need. s.Client = &govmomi.Client{ Client: vimClient, SessionManager: session.NewManager(vimClient), } err = login(ctx) if err != nil { return nil, errors.Errorf("Failed to log in to %s: %s", soapURL.Host, err) } s.Finder = find.NewFinder(s.Vim25(), false) // log high-level environment information s.logEnvironmentInfo() return s, nil }
func TestServeHTTPS(t *testing.T) { s := New(NewServiceInstance(esx.ServiceContent, esx.RootFolder)) s.TLS = new(tls.Config) ts := s.NewServer() defer ts.Close() ctx := context.Background() // insecure=true OK client, err := govmomi.NewClient(ctx, ts.URL, true) if err != nil { t.Fatal(err) } err = client.Login(ctx, ts.URL.User) if err != nil { t.Fatal(err) } // insecure=false should FAIL _, err = govmomi.NewClient(ctx, ts.URL, false) if err == nil { t.Fatal("expected error") } uerr, ok := err.(*url.Error) if !ok { t.Fatalf("err type=%T", err) } _, ok = uerr.Err.(x509.UnknownAuthorityError) if !ok { t.Fatalf("err type=%T", uerr.Err) } sinfo := ts.CertificateInfo() // Test thumbprint validation sc := soap.NewClient(ts.URL, false) // Add host with thumbprint mismatch should fail sc.SetThumbprint(ts.URL.Host, "nope") _, err = vim25.NewClient(ctx, sc) if err == nil { t.Error("expected error") } // Add host with thumbprint match should pass sc.SetThumbprint(ts.URL.Host, sinfo.ThumbprintSHA1) _, err = vim25.NewClient(ctx, sc) if err != nil { t.Fatal(err) } var pinfo object.HostCertificateInfo err = pinfo.FromURL(ts.URL, nil) if err != nil { t.Fatal(err) } if pinfo.ThumbprintSHA1 != sinfo.ThumbprintSHA1 { t.Error("thumbprint mismatch") } // Test custom RootCAs list sc = soap.NewClient(ts.URL, false) caFile, err := ts.CertificateFile() if err != nil { t.Fatal(err) } if err = sc.SetRootCAs(caFile); err != nil { t.Fatal(err) } _, err = vim25.NewClient(ctx, sc) if err != nil { t.Fatal(err) } }