From 225880a13c46343690c9e396d33d179c1f14d532 Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Thu, 25 Jul 2024 11:07:55 +1000 Subject: [PATCH] initial working example --- README.md | 0 go.mod | 5 ++ go.sum | 8 +++ main.go | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1673140 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module nathan/sso-query/v2 + +go 1.22.5 + +require github.com/vmware/govmomi v0.30.7 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..20f2b58 --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/vmware/govmomi v0.30.7 h1:YO8CcDpLJzmq6PK5/CBQbXyV21iCMh8SbdXt+xNkXp8= +github.com/vmware/govmomi v0.30.7/go.mod h1:epgoslm97rLECMV4D+08ORzUBEU7boFSepKjt7AYVGg= +github.com/vmware/govmomi v0.39.0 h1:soLZ08Q2zvjRSinNup8xVlw0KDDCJPPA1rIDmBhi7As= +github.com/vmware/govmomi v0.39.0/go.mod h1:oHzAQ1r6152zYDGcUqeK+EO8LhKo5wjtvWZBGHws2Hc= diff --git a/main.go b/main.go new file mode 100644 index 0000000..42d9b24 --- /dev/null +++ b/main.go @@ -0,0 +1,148 @@ +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) + +}