@@ -2,6 +2,7 @@ package vsphere
22
33import (
44 "context"
5+ "fmt"
56 "net/http"
67 liburl "net/url"
78 "path"
@@ -85,6 +86,7 @@ const (
8586 fThumbprint = "summary.config.sslThumbprint"
8687 fMgtServerIp = "summary.managementServerIp"
8788 fScsiLun = "config.storageDevice.scsiLun"
89+ fAdvancedOption = "configManager.advancedOption"
8890 // Network
8991 fTag = "tag"
9092 fSummary = "summary"
@@ -315,6 +317,24 @@ func (r *Collector) HasParity() bool {
315317 return r .parity
316318}
317319
320+ // Follow
321+ func (r * Collector ) Follow (moRef interface {}, p []string , dst interface {}) error {
322+ ref , ok := moRef .(types.ManagedObjectReference )
323+ if ! ok {
324+ return fmt .Errorf ("reference must be of type ManagedObjectReference" )
325+ }
326+
327+ ctx := context .Background ()
328+ ctx , cancel := context .WithTimeout (ctx , 30 * time .Second )
329+ defer cancel ()
330+ client , err := r .buildClient (ctx )
331+ if err != nil {
332+ return err
333+ }
334+ defer client .CloseIdleConnections ()
335+ return client .RetrieveOne (ctx , ref , p , dst )
336+ }
337+
318338// Test connect/logout.
319339func (r * Collector ) Test () (status int , err error ) {
320340 ctx := context .Background ()
@@ -531,35 +551,39 @@ func (r *Collector) watch() (list []*libmodel.Watch) {
531551// Build the client.
532552func (r * Collector ) connect (ctx context.Context ) (status int , err error ) {
533553 r .close ()
534- url , err := liburl . Parse ( r . url )
554+ r . client , err = r . buildClient ( ctx )
535555 if err != nil {
536- err = liberr .Wrap (err )
556+ if strings .Contains (err .Error (), "incorrect" ) && strings .Contains (err .Error (), "password" ) {
557+ return http .StatusUnauthorized , err
558+ }
537559 return
538560 }
561+
562+ return http .StatusOK , nil
563+ }
564+
565+ // Build the client.
566+ func (r * Collector ) buildClient (ctx context.Context ) (* govmomi.Client , error ) {
567+ url , err := liburl .Parse (r .url )
568+ if err != nil {
569+ return nil , liberr .Wrap (err )
570+ }
539571 url .User = liburl .UserPassword (
540572 r .user (),
541573 r .password ())
542574 soapClient := soap .NewClient (url , r .getInsecureSkipVerifyFlag ())
543575 soapClient .SetThumbprint (url .Host , r .thumbprint ())
544576 vimClient , err := vim25 .NewClient (ctx , soapClient )
545577 if err != nil {
546- err = liberr .Wrap (err )
547- return
578+ return nil , liberr .Wrap (err )
548579 }
549- r . client = & govmomi.Client {
580+ client : = & govmomi.Client {
550581 SessionManager : session .NewManager (vimClient ),
551582 Client : vimClient ,
552583 }
553- err = r .client .Login (ctx , url .User )
554- if err != nil {
555- err = liberr .Wrap (err )
556- if strings .Contains (err .Error (), "incorrect" ) && strings .Contains (err .Error (), "password" ) {
557- return http .StatusUnauthorized , err
558- }
559- return
560- }
584+ err = client .Login (ctx , url .User )
585+ return client , err
561586
562- return http .StatusOK , nil
563587}
564588
565589// Close connections.
@@ -702,6 +726,7 @@ func (r *Collector) propertySpec() []types.PropertySpec {
702726 fPNIC ,
703727 fVNIC ,
704728 fScsiLun ,
729+ fAdvancedOption ,
705730 },
706731 },
707732 { // Network
0 commit comments