github.com/vmware/go-vcloud-director/v2@v2.24.0/samples/discover/discover.go (about) 1 /* 2 * Copyright 2018 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 3 */ 4 5 package main 6 7 /* This sample program shows how to list organizations, vDCs, vApps, and catalog items 8 using a vCD client 9 10 Usage: 11 12 BEFORE USING, copy the file sample_config.json to config.json and fill it with your vCD credentials 13 (or do the same with sample_config.yaml) 14 JSON is a subset of YAML. The YAML interpreter will take care of either configuration file 15 (http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/) 16 17 (1) On the command line 18 cd samples 19 go run discover.go ./config_file.json 20 Or 21 go run discover.go ./config_file.yaml 22 23 (2) In GoLand 24 * In the menu "Run" / "edit configurations", add the full path to your JSON or YAML file into "Program arguments" 25 * From the menu "Run", choose "Run 'go build discover.go'" 26 27 ================ 28 Troubleshooting. 29 ================ 30 If there are problems during the configuration load, you can use the SAMPLES_DEBUG environment variable to show 31 what was read from the file and how it was interpreted. 32 33 On the command line: 34 35 SAMPLES_DEBUG=1 go run discover.go ./config_file.json 36 37 In Goland: 38 39 * In the menu "Run" / "edit configurations", clock on "Environment", then add a variable with the "+" button: write 40 "SAMPLES_DEBUG" under "name" and "1" under "value." 41 42 */ 43 44 import ( 45 "fmt" 46 "net/url" 47 "os" 48 "path/filepath" 49 "sigs.k8s.io/yaml" 50 51 "github.com/vmware/go-vcloud-director/v2/govcd" 52 ) 53 54 type Config struct { 55 User string `json:"user"` 56 Password string `json:"password"` 57 Org string `json:"org"` 58 Href string `json:"href"` 59 VDC string `json:"vdc"` 60 Insecure bool `json:"insecure"` 61 Token string `json:"token"` 62 } 63 64 // Checks that a configuration structure is complete 65 func check_configuration(conf Config) { 66 will_exit := false 67 exit := func(s string) { 68 fmt.Printf("configuration field '%s' empty or missing\n", s) 69 will_exit = true 70 } 71 if conf.Org == "" { 72 exit("org") 73 } 74 if conf.Href == "" || conf.Href == "https://YOUR_VCD_IP/api" { 75 exit("href") 76 } 77 if conf.VDC == "" { 78 exit("vdc") 79 } 80 if conf.Token != "" { 81 return 82 } 83 if conf.User == "" { 84 exit("user") 85 } 86 if conf.Password == "" { 87 exit("password") 88 } 89 if will_exit { 90 os.Exit(1) 91 } 92 } 93 94 // Retrieves the configuration from a Json or Yaml file 95 func getConfig(config_file string) Config { 96 var configuration Config 97 buffer, err := os.ReadFile(filepath.Clean(config_file)) 98 if err != nil { 99 fmt.Printf("Configuration file %s not found\n%s\n", config_file, err) 100 os.Exit(1) 101 } 102 err = yaml.Unmarshal(buffer, &configuration) 103 if err != nil { 104 fmt.Printf("Error retrieving configuration from file %s\n%s\n", config_file, err) 105 os.Exit(1) 106 } 107 check_configuration(configuration) 108 109 // If something goes wrong, rerun the program after setting 110 // the environment variable SAMPLES_DEBUG, and you can check how the 111 // configuration was read 112 if os.Getenv("SAMPLES_DEBUG") != "" { 113 fmt.Printf("configuration text: %s\n", buffer) 114 fmt.Printf("configuration rec: %#v\n", configuration) 115 new_conf, _ := yaml.Marshal(configuration) 116 fmt.Printf("YAML configuration: \n%s\n", new_conf) 117 } 118 return configuration 119 } 120 121 // Creates a vCD client 122 func (c *Config) Client() (*govcd.VCDClient, error) { 123 u, err := url.ParseRequestURI(c.Href) 124 if err != nil { 125 return nil, fmt.Errorf("unable to pass url: %s", err) 126 } 127 128 vcdClient := govcd.NewVCDClient(*u, c.Insecure) 129 if c.Token != "" { 130 _ = vcdClient.SetToken(c.Org, govcd.AuthorizationHeader, c.Token) 131 } else { 132 resp, err := vcdClient.GetAuthResponse(c.User, c.Password, c.Org) 133 if err != nil { 134 return nil, fmt.Errorf("unable to authenticate: %s", err) 135 } 136 fmt.Printf("Token: %s\n", resp.Header[govcd.AuthorizationHeader]) 137 } 138 return vcdClient, nil 139 } 140 141 func main() { 142 // This program requires a configuration file, which must be passed 143 // on the command line 144 if len(os.Args) < 2 { 145 fmt.Printf("Syntax: discover config_file.json\n") 146 os.Exit(1) 147 } 148 149 // Reads the configuration file 150 config := getConfig(os.Args[1]) 151 152 // Instantiates the client 153 client, err := config.Client() // We now have a client 154 if err != nil { 155 fmt.Println(err) 156 os.Exit(1) 157 } 158 159 org, err := client.GetOrgByName(config.Org) 160 if err != nil { 161 fmt.Printf("organization %s not found : %s\n", config.Org, err) 162 os.Exit(1) 163 } 164 vdc, err := org.GetVDCByName(config.VDC, false) 165 if err != nil { 166 fmt.Printf("VDC %s not found : %s\n", config.VDC, err) 167 os.Exit(1) 168 } 169 170 fmt.Printf("Organization items\n") 171 fmt.Printf("Organization '%s' URL: %s\n", config.Org, org.Org.HREF) 172 173 catalogName := "" 174 for N, item := range org.Org.Link { 175 fmt.Printf("%3d %-40s %s\n", N, item.Name, item.Type) 176 // Retrieve the first catalog name for further usage 177 if item.Type == "application/vnd.vmware.vcloud.catalog+xml" && catalogName == "" { 178 catalogName = item.Name 179 } 180 } 181 fmt.Println("") 182 183 fmt.Printf("\nvdc items\n") 184 for _, res := range vdc.Vdc.ResourceEntities { 185 for N, item := range res.ResourceEntity { 186 fmt.Printf("%3d %-40s %s\n", N, item.Name, item.Type) 187 } 188 } 189 fmt.Println("") 190 191 if catalogName != "" { 192 fmt.Printf("\ncatalog items\n") 193 cat, err := org.GetCatalogByName(catalogName, false) 194 if err != nil { 195 fmt.Printf("Error retrieving catalog %s\n%s\n", catalogName, err) 196 os.Exit(1) 197 } 198 for _, item := range cat.Catalog.CatalogItems { 199 for N, deepItem := range item.CatalogItem { 200 fmt.Printf("%3d %-40s %s (ID: %s)\n", N, deepItem.Name, deepItem.Type, deepItem.ID) 201 } 202 } 203 } 204 }