github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/vsphere_resource_pool.go (about) 1 /* 2 * Copyright 2023 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 3 */ 4 5 package govcd 6 7 import ( 8 "fmt" 9 "github.com/vmware/go-vcloud-director/v2/types/v56" 10 "github.com/vmware/go-vcloud-director/v2/util" 11 "net/url" 12 ) 13 14 type ResourcePool struct { 15 ResourcePool *types.ResourcePool 16 vcenter *VCenter 17 client *VCDClient 18 } 19 20 // GetAllResourcePools retrieves all resource pools for a given vCenter 21 func (vcenter VCenter) GetAllResourcePools(queryParams url.Values) ([]*ResourcePool, error) { 22 client := vcenter.client.Client 23 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointResourcePoolsBrowseAll 24 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 25 if err != nil { 26 return nil, err 27 } 28 29 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, vcenter.VSphereVCenter.VcId)) 30 if err != nil { 31 return nil, err 32 } 33 34 retrieved := []*types.ResourcePool{{}} 35 36 err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParams, &retrieved, nil) 37 if err != nil { 38 return nil, fmt.Errorf("error getting resource pool list: %s", err) 39 } 40 41 if len(retrieved) == 0 { 42 return nil, nil 43 } 44 var returnList []*ResourcePool 45 46 for _, r := range retrieved { 47 newRp := r 48 returnList = append(returnList, &ResourcePool{ 49 ResourcePool: newRp, 50 vcenter: &vcenter, 51 client: vcenter.client, 52 }) 53 } 54 return returnList, nil 55 } 56 57 // GetAvailableHardwareVersions finds the hardware versions of a given resource pool 58 // In addition to proper resource pools, this method also works for any entity that is retrieved as a resource pool, 59 // such as provider VDCs and Org VDCs 60 func (rp ResourcePool) GetAvailableHardwareVersions() (*types.OpenApiSupportedHardwareVersions, error) { 61 62 client := rp.client.Client 63 endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointResourcePoolHardware 64 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 65 if err != nil { 66 return nil, err 67 } 68 69 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, rp.vcenter.VSphereVCenter.VcId, rp.ResourcePool.Moref)) 70 if err != nil { 71 return nil, err 72 } 73 74 retrieved := types.OpenApiSupportedHardwareVersions{} 75 err = client.OpenApiGetItem(minimumApiVersion, urlRef, nil, &retrieved, nil) 76 if err != nil { 77 return nil, fmt.Errorf("error getting resource pool hardware versions: %s", err) 78 } 79 80 return &retrieved, nil 81 } 82 83 // GetDefaultHardwareVersion retrieves the default hardware version for a given resource pool. 84 // The default version is usually the highest available, but it's not guaranteed 85 func (rp ResourcePool) GetDefaultHardwareVersion() (string, error) { 86 87 versions, err := rp.GetAvailableHardwareVersions() 88 if err != nil { 89 return "", err 90 } 91 92 for _, v := range versions.SupportedVersions { 93 if v.IsDefault { 94 return v.Name, nil 95 } 96 } 97 return "", fmt.Errorf("no default hardware version found for resource pool %s", rp.ResourcePool.Name) 98 } 99 100 // GetResourcePoolById retrieves a resource pool by its ID (Moref) 101 func (vcenter VCenter) GetResourcePoolById(id string) (*ResourcePool, error) { 102 resourcePools, err := vcenter.GetAllResourcePools(nil) 103 if err != nil { 104 return nil, err 105 } 106 for _, rp := range resourcePools { 107 if rp.ResourcePool.Moref == id { 108 return rp, nil 109 } 110 } 111 return nil, fmt.Errorf("no resource pool found with ID '%s' :%s", id, ErrorEntityNotFound) 112 } 113 114 // GetResourcePoolByName retrieves a resource pool by name. 115 // It may fail if there are several resource pools with the same name 116 func (vcenter VCenter) GetResourcePoolByName(name string) (*ResourcePool, error) { 117 resourcePools, err := vcenter.GetAllResourcePools(nil) 118 if err != nil { 119 return nil, err 120 } 121 var found []*ResourcePool 122 for _, rp := range resourcePools { 123 if rp.ResourcePool.Name == name { 124 found = append(found, rp) 125 } 126 } 127 if len(found) == 0 { 128 return nil, fmt.Errorf("no resource pool found with name '%s' :%s", name, ErrorEntityNotFound) 129 } 130 if len(found) > 1 { 131 var idList []string 132 for _, f := range found { 133 idList = append(idList, f.ResourcePool.Moref) 134 } 135 return nil, fmt.Errorf("more than one resource pool was found with name %s - use resource pool ID instead - %v", name, idList) 136 } 137 return found[0], nil 138 } 139 140 // GetAllResourcePools retrieves all available resource pool, across all vCenters 141 func (vcdClient *VCDClient) GetAllResourcePools(queryParams url.Values) ([]*ResourcePool, error) { 142 143 vcenters, err := vcdClient.GetAllVCenters(queryParams) 144 if err != nil { 145 return nil, err 146 } 147 var result []*ResourcePool 148 for _, vc := range vcenters { 149 resourcePools, err := vc.GetAllResourcePools(queryParams) 150 if err != nil { 151 return nil, err 152 } 153 result = append(result, resourcePools...) 154 } 155 return result, nil 156 } 157 158 // ResourcePoolsFromIds returns a slice of resource pools from a slice of resource pool IDs 159 func (vcdClient *VCDClient) ResourcePoolsFromIds(resourcePoolIds []string) ([]*ResourcePool, error) { 160 if len(resourcePoolIds) == 0 { 161 return nil, nil 162 } 163 164 var result []*ResourcePool 165 166 // 1. make sure there are no duplicates in the input IDs 167 uniqueIds := make(map[string]bool) 168 var duplicates []string 169 for _, id := range resourcePoolIds { 170 _, seen := uniqueIds[id] 171 if seen { 172 duplicates = append(duplicates, id) 173 } 174 uniqueIds[id] = true 175 } 176 177 if len(duplicates) > 0 { 178 return nil, fmt.Errorf("duplicate IDs found in input: %v", duplicates) 179 } 180 181 // 2. get all resource pools 182 resourcePools, err := vcdClient.GetAllResourcePools(nil) 183 if err != nil { 184 return nil, err 185 } 186 187 util.Logger.Printf("wantedRecords: %v\n", resourcePoolIds) 188 // 3. build a map of resource pools, indexed by ID, for easy search 189 var foundRecords = make(map[string]*ResourcePool) 190 191 for _, rpr := range resourcePools { 192 foundRecords[rpr.ResourcePool.Moref] = rpr 193 } 194 195 // 4. loop through the requested IDs 196 for wanted := range uniqueIds { 197 // 4.1 if the wanted ID is not found, exit with an error 198 foundResourcePool, ok := foundRecords[wanted] 199 if !ok { 200 return nil, fmt.Errorf("resource pool ID '%s' not found in VCD", wanted) 201 } 202 result = append(result, foundResourcePool) 203 } 204 205 // 5. Check that we got as many resource pools as the requested IDs 206 if len(result) != len(uniqueIds) { 207 return result, fmt.Errorf("%d IDs were requested, but only %d found", len(uniqueIds), len(result)) 208 } 209 210 return result, nil 211 }