package main import ( "context" "flag" "fmt" "net/url" "os" "reflect" "strings" "time" _ "time/tzdata" "github.com/vmware/govmomi" "github.com/vmware/govmomi/ssoadmin" "github.com/vmware/govmomi/sts" "github.com/vmware/govmomi/vim25/soap" ) var ( c *govmomi.Client ctx context.Context cancel context.CancelFunc location *time.Location sha1ver string // sha1 revision used to build the program buildTime string // when the executable was built ) // From https://stackoverflow.com/a/33769379 func Scan(d interface{}) { v := reflect.ValueOf(d) i := reflect.Indirect(v) s := i.Type() println(s.NumField()) // will print out 0, if you change Host to have 1 field, it prints out 1 } func query(t reflect.Type) { value := reflect.New(t).Interface() Scan(value) } func main() { // Command line flags vURL := flag.String("url", "", "The URL of a vCenter server, eg https://server.domain.example/sdk") vUser := flag.String("user", "", "The username to use when connecting to vCenter") vPass := flag.String("password", "", "The password to use when connecting to vCenter") vTZ := flag.String("tz", "Australia/Sydney", "The timezone to use when converting vCenter UTC times") vInsecure := flag.Bool("insecure", true, "Allow insecure connections to vCenter") //vmName := flag.String("vmname", "example-vm", "The vm to query metrics") //begin := flag.Duration("b", time.Hour, "Begin time") // default BeginTime is 1h ago flag.Parse() /* // Print logs to file f, err := os.OpenFile("log.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { log.Fatalf("error opening file: %v", err) } defer f.Close() log.SetOutput(f) */ fmt.Printf("Starting execution. Built on %s from sha1 %s\n", buildTime, sha1ver) // So we can convert vCenter UTC to our local timezone fmt.Printf("Setting timezone to '%s'\n", *vTZ) _, err := time.LoadLocation(*vTZ) if err != nil { fmt.Fprintf(os.Stderr, "Error setting timezone to %s : %s\n", *vTZ, err) os.Exit(1) } u, err := url.Parse(*vURL) if err != nil { fmt.Fprintf(os.Stderr, "Error parsing url %s : %s\n", *vURL, err) os.Exit(1) } else { if !strings.HasSuffix(u.Path, "/sdk") { u.Path, _ = url.JoinPath(u.Path, "/sdk") fmt.Printf("Updated vCenter URL to '%v'\n", u) } } fmt.Printf("Connecting to vCenter %s\n", u) u.User = url.UserPassword(*vUser, *vPass) ctx, cancel = context.WithCancel(context.Background()) defer cancel() // Login to vcenter vc, err := govmomi.NewClient(ctx, u, *vInsecure) if err != nil { fmt.Fprintf(os.Stderr, "Logging in error: %s\n", err) os.Exit(1) } defer vc.Logout(ctx) header := soap.Header{ Security: &sts.Signer{}, } c, err := ssoadmin.NewClient(ctx, vc.Client) if err != nil { fmt.Printf("Error creating SSO client: %s\n", err) os.Exit(1) } stsClient, cerr := sts.NewClient(ctx, vc.Client) if cerr != nil { fmt.Printf("Error creating STS client: %s\n", cerr) os.Exit(1) } //fmt.Printf("Certificate: %v\n", vc.Client.Certificate()) req := sts.TokenRequest{ //Certificate: vc.Client.Certificate(), Userinfo: u.User, } header.Security, cerr = stsClient.Issue(ctx, req) if cerr != nil { fmt.Printf("Error issuing STS token: %s\n", cerr) os.Exit(1) } if err = c.Login(c.WithHeader(ctx, header)); err != nil { fmt.Printf("Error sso login: %s\n", err) os.Exit(1) } fmt.Printf("sso admin: %v\n", c) user, err := c.FindUser(ctx, "administrator") if err != nil { fmt.Printf("Error searching for user: %s\n", err) os.Exit(1) } fmt.Printf("User: %v\n", user) userInGroupList, err := c.FindUsersInGroup(ctx, "administrators", "") fmt.Printf("Group list: %v\n", userInGroupList) groupInGroupList, err := c.FindGroupsInGroup(ctx, "administrators", "") fmt.Printf("group in Group list: %v\n", groupInGroupList) }