github.com/vmware/go-vcloud-director/v2@v2.24.0/govcd/vdccomputepolicy_v2.go (about) 1 package govcd 2 3 /* 4 * Copyright 2022 VMware, Inc. All rights reserved. Licensed under the Apache v2 License. 5 */ 6 7 import ( 8 "fmt" 9 "net/http" 10 "net/url" 11 "strings" 12 13 "github.com/vmware/go-vcloud-director/v2/types/v56" 14 "github.com/vmware/go-vcloud-director/v2/util" 15 ) 16 17 // VdcComputePolicyV2 defines a VDC Compute Policy, which can be a VM Sizing Policy, a VM Placement Policy or a vGPU Policy. 18 type VdcComputePolicyV2 struct { 19 VdcComputePolicyV2 *types.VdcComputePolicyV2 20 Href string 21 client *Client 22 } 23 24 // GetVdcComputePolicyV2ById retrieves VDC Compute Policy (V2) by given ID 25 func (client *VCDClient) GetVdcComputePolicyV2ById(id string) (*VdcComputePolicyV2, error) { 26 return getVdcComputePolicyV2ById(&client.Client, id) 27 } 28 29 // getVdcComputePolicyV2ById retrieves VDC Compute Policy (V2) by given ID 30 func getVdcComputePolicyV2ById(client *Client, id string) (*VdcComputePolicyV2, error) { 31 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies 32 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 33 if err != nil { 34 return nil, err 35 } 36 37 if id == "" { 38 return nil, fmt.Errorf("empty VDC id") 39 } 40 41 urlRef, err := client.OpenApiBuildEndpoint(endpoint, id) 42 43 if err != nil { 44 return nil, err 45 } 46 47 vdcComputePolicy := &VdcComputePolicyV2{ 48 VdcComputePolicyV2: &types.VdcComputePolicyV2{}, 49 Href: urlRef.String(), 50 client: client, 51 } 52 53 err = client.OpenApiGetItem(minimumApiVersion, urlRef, nil, vdcComputePolicy.VdcComputePolicyV2, nil) 54 if err != nil { 55 return nil, err 56 } 57 58 return vdcComputePolicy, nil 59 } 60 61 // GetAllVdcComputePoliciesV2 retrieves all VDC Compute Policies (V2) using OpenAPI endpoint. Query parameters can be supplied to perform additional 62 // filtering 63 func (client *VCDClient) GetAllVdcComputePoliciesV2(queryParameters url.Values) ([]*VdcComputePolicyV2, error) { 64 return getAllVdcComputePoliciesV2(&client.Client, queryParameters) 65 } 66 67 // getAllVdcComputePolicies retrieves all VDC Compute Policies (V2) using OpenAPI endpoint. Query parameters can be supplied to perform additional 68 // filtering 69 func getAllVdcComputePoliciesV2(client *Client, queryParameters url.Values) ([]*VdcComputePolicyV2, error) { 70 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies 71 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 72 if err != nil { 73 return nil, err 74 } 75 76 urlRef, err := client.OpenApiBuildEndpoint(endpoint) 77 if err != nil { 78 return nil, err 79 } 80 81 responses := []*types.VdcComputePolicyV2{{}} 82 83 err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParameters, &responses, nil) 84 if err != nil { 85 return nil, err 86 } 87 88 var wrappedVdcComputePolicies []*VdcComputePolicyV2 89 for _, response := range responses { 90 wrappedVdcComputePolicy := &VdcComputePolicyV2{ 91 client: client, 92 VdcComputePolicyV2: response, 93 } 94 wrappedVdcComputePolicies = append(wrappedVdcComputePolicies, wrappedVdcComputePolicy) 95 } 96 97 return wrappedVdcComputePolicies, nil 98 } 99 100 // CreateVdcComputePolicyV2 creates a new VDC Compute Policy (V2) using OpenAPI endpoint 101 func (client *VCDClient) CreateVdcComputePolicyV2(newVdcComputePolicy *types.VdcComputePolicyV2) (*VdcComputePolicyV2, error) { 102 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies 103 minimumApiVersion, err := client.Client.checkOpenApiEndpointCompatibility(endpoint) 104 if err != nil { 105 return nil, err 106 } 107 108 urlRef, err := client.Client.OpenApiBuildEndpoint(endpoint) 109 if err != nil { 110 return nil, err 111 } 112 113 returnVdcComputePolicy := &VdcComputePolicyV2{ 114 VdcComputePolicyV2: &types.VdcComputePolicyV2{}, 115 client: &client.Client, 116 } 117 118 err = client.Client.OpenApiPostItem(minimumApiVersion, urlRef, nil, newVdcComputePolicy, returnVdcComputePolicy.VdcComputePolicyV2, nil) 119 if err != nil { 120 return nil, fmt.Errorf("error creating VDC Compute Policy: %s", getFriendlyErrorIfVmPlacementPolicyAlreadyExists(newVdcComputePolicy.Name, err)) 121 } 122 123 return returnVdcComputePolicy, nil 124 } 125 126 // Update existing VDC Compute Policy (V2) 127 func (vdcComputePolicy *VdcComputePolicyV2) Update() (*VdcComputePolicyV2, error) { 128 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies 129 minimumApiVersion, err := vdcComputePolicy.client.checkOpenApiEndpointCompatibility(endpoint) 130 if err != nil { 131 return nil, err 132 } 133 134 if vdcComputePolicy.VdcComputePolicyV2.ID == "" { 135 return nil, fmt.Errorf("cannot update VDC Compute Policy without ID") 136 } 137 138 urlRef, err := vdcComputePolicy.client.OpenApiBuildEndpoint(endpoint, vdcComputePolicy.VdcComputePolicyV2.ID) 139 if err != nil { 140 return nil, err 141 } 142 143 returnVdcComputePolicy := &VdcComputePolicyV2{ 144 VdcComputePolicyV2: &types.VdcComputePolicyV2{}, 145 client: vdcComputePolicy.client, 146 } 147 148 err = vdcComputePolicy.client.OpenApiPutItem(minimumApiVersion, urlRef, nil, vdcComputePolicy.VdcComputePolicyV2, returnVdcComputePolicy.VdcComputePolicyV2, nil) 149 if err != nil { 150 return nil, fmt.Errorf("error updating VDC Compute Policy: %s", err) 151 } 152 153 return returnVdcComputePolicy, nil 154 } 155 156 // Delete deletes VDC Compute Policy (V2) 157 func (vdcComputePolicy *VdcComputePolicyV2) Delete() error { 158 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcComputePolicies 159 minimumApiVersion, err := vdcComputePolicy.client.checkOpenApiEndpointCompatibility(endpoint) 160 if err != nil { 161 return err 162 } 163 164 if vdcComputePolicy.VdcComputePolicyV2.ID == "" { 165 return fmt.Errorf("cannot delete VDC Compute Policy without id") 166 } 167 168 urlRef, err := vdcComputePolicy.client.OpenApiBuildEndpoint(endpoint, vdcComputePolicy.VdcComputePolicyV2.ID) 169 if err != nil { 170 return err 171 } 172 173 err = vdcComputePolicy.client.OpenApiDeleteItem(minimumApiVersion, urlRef, nil, nil) 174 175 if err != nil { 176 return fmt.Errorf("error deleting VDC Compute Policy: %s", err) 177 } 178 179 return nil 180 } 181 182 // GetAllAssignedVdcComputePoliciesV2 retrieves all VDC assigned Compute Policies (V2) using OpenAPI endpoint. Query parameters can be supplied to perform additional 183 // filtering 184 func (vdc *AdminVdc) GetAllAssignedVdcComputePoliciesV2(queryParameters url.Values) ([]*VdcComputePolicyV2, error) { 185 return getAllAssignedVdcComputePoliciesV2(vdc.client, vdc.AdminVdc.ID, queryParameters) 186 } 187 188 // GetAllAssignedVdcComputePoliciesV2 retrieves all VDC assigned Compute Policies (V2) using OpenAPI endpoint and the mandatory VDC identifier. 189 // Query parameters can be supplied to perform additional filtering 190 func (vcdClient *VCDClient) GetAllAssignedVdcComputePoliciesV2(vdcId string, queryParameters url.Values) ([]*VdcComputePolicyV2, error) { 191 return getAllAssignedVdcComputePoliciesV2(&vcdClient.Client, vdcId, queryParameters) 192 } 193 194 // getAllAssignedVdcComputePoliciesV2 retrieves all VDC assigned Compute Policies (V2) using OpenAPI endpoint and the mandatory VDC identifier. 195 // Query parameters can be supplied to perform additional filtering 196 func getAllAssignedVdcComputePoliciesV2(client *Client, vdcId string, queryParameters url.Values) ([]*VdcComputePolicyV2, error) { 197 if strings.TrimSpace(vdcId) == "" { 198 return nil, fmt.Errorf("VDC ID is mandatory to retrieve its assigned VDC Compute Policies") 199 } 200 201 endpoint := types.OpenApiPathVersion2_0_0 + types.OpenApiEndpointVdcAssignedComputePolicies 202 minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint) 203 if err != nil { 204 return nil, err 205 } 206 207 urlRef, err := client.OpenApiBuildEndpoint(fmt.Sprintf(endpoint, vdcId)) 208 if err != nil { 209 return nil, err 210 } 211 212 responses := []*types.VdcComputePolicyV2{{}} 213 214 err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParameters, &responses, nil) 215 if err != nil { 216 return nil, err 217 } 218 219 var wrappedVdcComputePolicies []*VdcComputePolicyV2 220 for _, response := range responses { 221 wrappedVdcComputePolicy := &VdcComputePolicyV2{ 222 client: client, 223 VdcComputePolicyV2: response, 224 } 225 wrappedVdcComputePolicies = append(wrappedVdcComputePolicies, wrappedVdcComputePolicy) 226 } 227 228 return wrappedVdcComputePolicies, nil 229 } 230 231 // SetAssignedComputePolicies assign(set) Compute Policies to the receiver VDC. 232 func (vdc *AdminVdc) SetAssignedComputePolicies(computePolicyReferences types.VdcComputePolicyReferences) (*types.VdcComputePolicyReferences, error) { 233 util.Logger.Printf("[TRACE] Set Compute Policies started") 234 235 if !vdc.client.IsSysAdmin { 236 return nil, fmt.Errorf("functionality requires System Administrator privileges") 237 } 238 239 adminVdcPolicyHREF, err := url.ParseRequestURI(vdc.AdminVdc.HREF) 240 if err != nil { 241 return nil, fmt.Errorf("error parsing VDC URL: %s", err) 242 } 243 244 vdcId, err := GetUuidFromHref(vdc.AdminVdc.HREF, true) 245 if err != nil { 246 return nil, fmt.Errorf("unable to get vdc ID from HREF: %s", err) 247 } 248 adminVdcPolicyHREF.Path = "/api/admin/vdc/" + vdcId + "/computePolicies" 249 250 returnedVdcComputePolicies := &types.VdcComputePolicyReferences{} 251 computePolicyReferences.Xmlns = types.XMLNamespaceVCloud 252 253 _, err = vdc.client.ExecuteRequest(adminVdcPolicyHREF.String(), http.MethodPut, 254 types.MimeVdcComputePolicyReferences, "error setting Compute Policies for VDC: %s", computePolicyReferences, returnedVdcComputePolicies) 255 if err != nil { 256 return nil, err 257 } 258 259 return returnedVdcComputePolicies, nil 260 } 261 262 // getFriendlyErrorIfVmPlacementPolicyAlreadyExists is intended to be used when a VM Placement Policy already exists, and 263 // we try to create another one with the same name. When this happens, VCD discloses a lot of unnecessary information to the user that is 264 // hard to read and understand, so this function simplifies the message. 265 // Note: This function should not be needed anymore once VCD 10.4.0 is discontinued (this issue is fixed in 10.4.1). 266 func getFriendlyErrorIfVmPlacementPolicyAlreadyExists(vmPlacementPolicyName string, err error) error { 267 if err != nil && strings.Contains(err.Error(), "already exists") && strings.Contains(err.Error(), "duplicate key") { 268 return fmt.Errorf("VM Placement Policy with name '%s' already exists", vmPlacementPolicyName) 269 } 270 return err 271 }