Skip to content

Commit 3d2df71

Browse files
authored
Merge pull request #594 from ovh/dev/aamstutz/generate-new-order
Use new generated order schema to order products + add resource ovh_vps
2 parents cbb97ea + 3bd4b84 commit 3d2df71

File tree

167 files changed

+10760
-331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+10760
-331
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ require (
44
github.com/google/go-cmp v0.6.0
55
github.com/hashicorp/go-cleanhttp v0.5.2
66
github.com/hashicorp/go-version v1.6.0
7-
github.com/hashicorp/terraform-plugin-framework v1.6.1
7+
github.com/hashicorp/terraform-plugin-framework v1.7.0
88
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
9-
github.com/hashicorp/terraform-plugin-go v0.22.0
9+
github.com/hashicorp/terraform-plugin-go v0.22.1
10+
github.com/hashicorp/terraform-plugin-log v0.9.0
1011
github.com/hashicorp/terraform-plugin-mux v0.15.0
1112
github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
1213
github.com/hashicorp/terraform-plugin-testing v1.7.0
@@ -35,7 +36,6 @@ require (
3536
github.com/hashicorp/logutils v1.0.0 // indirect
3637
github.com/hashicorp/terraform-exec v0.20.0 // indirect
3738
github.com/hashicorp/terraform-json v0.21.0 // indirect
38-
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
3939
github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
4040
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
4141
github.com/hashicorp/yamux v0.1.1 // indirect
@@ -60,7 +60,7 @@ require (
6060
golang.org/x/tools v0.13.0 // indirect
6161
google.golang.org/appengine v1.6.8 // indirect
6262
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
63-
google.golang.org/grpc v1.62.0 // indirect
63+
google.golang.org/grpc v1.62.1 // indirect
6464
google.golang.org/protobuf v1.33.0 // indirect
6565
gopkg.in/ini.v1 v1.67.0 // indirect
6666
)

go.sum

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,16 @@ github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8J
7474
github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw=
7575
github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U=
7676
github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
77-
github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI=
78-
github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY=
7977
github.com/hashicorp/terraform-plugin-framework v1.6.1 h1:hw2XrmUu8d8jVL52ekxim2IqDc+2Kpekn21xZANARLU=
8078
github.com/hashicorp/terraform-plugin-framework v1.6.1/go.mod h1:aJI+n/hBPhz1J+77GdgNfk5svW12y7fmtxe/5L5IuwI=
79+
github.com/hashicorp/terraform-plugin-framework v1.7.0 h1:wOULbVmfONnJo9iq7/q+iBOBJul5vRovaYJIu2cY/Pw=
80+
github.com/hashicorp/terraform-plugin-framework v1.7.0/go.mod h1:jY9Id+3KbZ17OMpulgnWLSfwxNVYSoYBQFTgsx044CI=
8181
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc=
8282
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg=
8383
github.com/hashicorp/terraform-plugin-go v0.22.0 h1:1OS1Jk5mO0f5hrziWJGXXIxBrMe2j/B8E+DVGw43Xmc=
8484
github.com/hashicorp/terraform-plugin-go v0.22.0/go.mod h1:mPULV91VKss7sik6KFEcEu7HuTogMLLO/EvWCuFkRVE=
85+
github.com/hashicorp/terraform-plugin-go v0.22.1 h1:iTS7WHNVrn7uhe3cojtvWWn83cm2Z6ryIUDTRO0EV7w=
86+
github.com/hashicorp/terraform-plugin-go v0.22.1/go.mod h1:qrjnqRghvQ6KnDbB12XeZ4FluclYwptntoWCr9QaXTI=
8587
github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
8688
github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
8789
github.com/hashicorp/terraform-plugin-mux v0.15.0 h1:+/+lDx0WUsIOpkAmdwBIoFU8UP9o2eZASoOnLsWbKME=
@@ -225,6 +227,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:
225227
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
226228
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
227229
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
230+
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
231+
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
228232
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
229233
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
230234
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=

ovh/notification_email.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import (
77
"strings"
88
)
99

10-
func notificationEmailSortedIds(meta interface{}) ([]int64, error) {
11-
config := meta.(*Config)
12-
10+
func notificationEmailSortedIds(config *Config) ([]int64, error) {
1311
// Create Order
1412
log.Printf("[DEBUG] Will read notification emails ids")
1513
res := []int64{}
@@ -24,10 +22,8 @@ func notificationEmailSortedIds(meta interface{}) ([]int64, error) {
2422
return res, nil
2523
}
2624

27-
func getNewNotificationEmail(matches []string, oldIds []int64, meta interface{}) (*NotificationEmail, error) {
28-
config := meta.(*Config)
29-
30-
curIds, err := notificationEmailSortedIds(meta)
25+
func getNewNotificationEmail(matches []string, oldIds []int64, config *Config) (*NotificationEmail, error) {
26+
curIds, err := notificationEmailSortedIds(config)
3127
if err != nil {
3228
return nil, err
3329
}

ovh/order.go

Lines changed: 110 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package ovh
22

33
import (
4+
"errors"
45
"fmt"
56
"log"
67
"net/url"
78
"regexp"
89
"strings"
910
"time"
1011

12+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1113
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1214
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1315
"github.com/ovh/go-ovh/ovh"
1416
"github.com/ovh/terraform-provider-ovh/ovh/helpers"
17+
"github.com/ovh/terraform-provider-ovh/ovh/types"
1518
)
1619

1720
var (
@@ -218,24 +221,36 @@ func genericOrderSchema(withOptions bool) map[string]*schema.Schema {
218221
return orderSchema
219222
}
220223

221-
func orderCreate(d *schema.ResourceData, meta interface{}, product string) error {
224+
func orderCreateFromResource(d *schema.ResourceData, meta interface{}, product string) error {
222225
config := meta.(*Config)
226+
order := (&OrderModel{}).FromResource(d)
223227

228+
err := orderCreate(order, config, product)
229+
if err != nil {
230+
return err
231+
}
232+
233+
d.SetId(fmt.Sprint(order.Order.OrderId.ValueInt64()))
234+
235+
return nil
236+
}
237+
238+
func orderCreate(d *OrderModel, config *Config, product string) error {
224239
// create Cart
225240
cartParams := &OrderCartCreateOpts{
226-
OvhSubsidiary: strings.ToUpper(d.Get("ovh_subsidiary").(string)),
241+
OvhSubsidiary: strings.ToUpper(d.OvhSubsidiary.ValueString()),
227242
}
228243

229-
cart, err := orderCartCreate(meta, cartParams, true)
244+
cart, err := orderCartCreate(config, cartParams, true)
230245
if err != nil {
231246
return fmt.Errorf("calling creating order cart: %q", err)
232247
}
233248

234249
// Create Product Item
235250
item := &OrderCartItem{}
236-
cartPlanParams := (&OrderCartPlanCreateOpts{
237-
Quantity: 1,
238-
}).FromResourceWithPath(d, "plan.0")
251+
cartPlanParamsList := d.Plan.Elements()
252+
cartPlanParams := cartPlanParamsList[0].(PlanValue)
253+
cartPlanParams.Quantity = types.TfInt64Value{Int64Value: basetypes.NewInt64Value(1)}
239254

240255
log.Printf("[DEBUG] Will create order item %s for cart: %s", product, cart.CartId)
241256
endpoint := fmt.Sprintf("/order/cart/%s/%s", url.PathEscape(cart.CartId), product)
@@ -244,62 +259,53 @@ func orderCreate(d *schema.ResourceData, meta interface{}, product string) error
244259
}
245260

246261
// apply configurations
247-
nbOfConfigurations := d.Get("plan.0.configuration.#").(int)
248-
for i := 0; i < nbOfConfigurations; i++ {
262+
configs := cartPlanParams.Configuration.Elements()
263+
264+
for _, cfg := range configs {
249265
log.Printf("[DEBUG] Will create order cart item configuration for cart item: %s/%d",
250266
item.CartId,
251267
item.ItemId,
252268
)
253269
itemConfig := &OrderCartItemConfiguration{}
254-
itemConfigParams := (&OrderCartItemConfigurationOpts{}).FromResourceWithPath(
255-
d,
256-
fmt.Sprintf("plan.0.configuration.%d", i),
257-
)
258270
endpoint := fmt.Sprintf("/order/cart/%s/item/%d/configuration",
259271
url.PathEscape(item.CartId),
260272
item.ItemId,
261273
)
262-
if err := config.OVHClient.Post(endpoint, itemConfigParams, itemConfig); err != nil {
263-
return fmt.Errorf("calling Post %s with params %v:\n\t %q", endpoint, itemConfigParams, err)
274+
if err := config.OVHClient.Post(endpoint, cfg, itemConfig); err != nil {
275+
return fmt.Errorf("calling Post %s with params %v:\n\t %q", endpoint, cfg, err)
264276
}
265277
}
266278

279+
planOptionValue := d.PlanOption.Elements()
280+
267281
// Create Product Options Items
268-
nbOfOptions := d.Get("plan_option.#").(int)
269-
for i := 0; i < nbOfOptions; i++ {
270-
optionPath := fmt.Sprintf("plan_option.%d", i)
282+
for _, option := range planOptionValue {
283+
opt := option.(PlanOptionValue)
284+
271285
log.Printf("[DEBUG] Will create order item options %s for cart: %s", product, cart.CartId)
272286
productOptionsItem := &OrderCartItem{}
273-
cartPlanOptionsParams := (&OrderCartPlanOptionsCreateOpts{
274-
ItemId: item.ItemId,
275-
Quantity: 1,
276-
}).FromResourceWithPath(
277-
d,
278-
optionPath,
279-
)
287+
288+
opt.ItemId = types.TfInt64Value{Int64Value: basetypes.NewInt64Value(item.ItemId)}
289+
opt.Quantity = types.TfInt64Value{Int64Value: basetypes.NewInt64Value(1)}
290+
280291
endpoint := fmt.Sprintf("/order/cart/%s/%s/options", url.PathEscape(cart.CartId), product)
281-
if err := config.OVHClient.Post(endpoint, cartPlanOptionsParams, productOptionsItem); err != nil {
292+
if err := config.OVHClient.Post(endpoint, opt, productOptionsItem); err != nil {
282293
return fmt.Errorf("calling Post %s with params %v:\n\t %q", endpoint, cartPlanParams, err)
283294
}
284295

285-
// apply configurations
286-
nbOfConfigurations := d.Get(fmt.Sprintf("%s.configuration.#", optionPath)).(int)
287-
for j := 0; j < nbOfConfigurations; j++ {
296+
optionConfigs := opt.Configuration.Elements()
297+
for _, cfg := range optionConfigs {
288298
log.Printf("[DEBUG] Will create order cart item configuration for cart item: %s/%d",
289299
item.CartId,
290300
item.ItemId,
291301
)
292302
itemConfig := &OrderCartItemConfiguration{}
293-
itemConfigParams := (&OrderCartItemConfigurationOpts{}).FromResourceWithPath(
294-
d,
295-
fmt.Sprintf("%s.configuration.%d", optionPath, j),
296-
)
297303
endpoint := fmt.Sprintf("/order/cart/%s/item/%d/configuration",
298304
url.PathEscape(item.CartId),
299305
item.ItemId,
300306
)
301-
if err := config.OVHClient.Post(endpoint, itemConfigParams, itemConfig); err != nil {
302-
return fmt.Errorf("calling Post %s with params %v:\n\t %q", endpoint, itemConfigParams, err)
307+
if err := config.OVHClient.Post(endpoint, cfg, itemConfig); err != nil {
308+
return fmt.Errorf("calling Post %s with params %v:\n\t %q", endpoint, cfg, err)
303309
}
304310
}
305311
}
@@ -384,15 +390,33 @@ func orderCreate(d *schema.ResourceData, meta interface{}, product string) error
384390
return fmt.Errorf("waiting for order (%d): %s", checkout.OrderID, err)
385391
}
386392

387-
d.SetId(fmt.Sprint(checkout.OrderID))
393+
d.Order.OrderId = types.TfInt64Value{Int64Value: basetypes.NewInt64Value(checkout.OrderID)}
388394

389395
return nil
390396
}
391397

392-
func orderRead(d *schema.ResourceData, meta interface{}) (*MeOrder, []*MeOrderDetail, error) {
398+
func orderReadInResource(d *schema.ResourceData, meta interface{}) (*MeOrder, []*MeOrderDetail, error) {
393399
config := meta.(*Config)
394400
orderId := d.Id()
395401

402+
order, details, err := orderRead(orderId, config)
403+
if err != nil {
404+
return nil, nil, err
405+
}
406+
407+
detailsData := make([]map[string]interface{}, len(details))
408+
for i, detail := range details {
409+
detailsData[i] = detail.ToMap()
410+
}
411+
412+
orderData := order.ToMap()
413+
orderData["details"] = detailsData
414+
d.Set("order", []interface{}{orderData})
415+
416+
return order, details, nil
417+
}
418+
419+
func orderRead(orderId string, config *Config) (*MeOrder, []*MeOrderDetail, error) {
396420
order := &MeOrder{}
397421
log.Printf("[DEBUG] Will read order %s", orderId)
398422
endpoint := fmt.Sprintf("/me/order/%s",
@@ -408,26 +432,31 @@ func orderRead(d *schema.ResourceData, meta interface{}) (*MeOrder, []*MeOrderDe
408432
}
409433

410434
if len(details) < 1 {
411-
return nil, nil, fmt.Errorf("There is no order details for id %s. This shouldn't happen. This is a bug with the API.", orderId)
435+
return nil, nil, fmt.Errorf("there is no order details for id %s. This shouldn't happen. This is a bug with the API", orderId)
412436
}
413437

414-
detailsData := make([]map[string]interface{}, len(details))
415-
for i, detail := range details {
416-
detailsData[i] = detail.ToMap()
417-
}
418-
419-
orderData := order.ToMap()
420-
orderData["details"] = detailsData
421-
d.Set("order", []interface{}{orderData})
422-
423438
return order, details, nil
424439
}
425440

426441
type TerminateFunc func() (string, error)
427442
type ConfirmTerminationFunc func(token string) error
428443

429-
func orderDelete(d *schema.ResourceData, meta interface{}, terminate TerminateFunc, confirm ConfirmTerminationFunc) error {
430-
oldEmailsIds, err := notificationEmailSortedIds(meta)
444+
func orderDeleteFromResource(d *schema.ResourceData, meta interface{}, terminate TerminateFunc, confirm ConfirmTerminationFunc) error {
445+
config := meta.(*Config)
446+
447+
if err := orderDelete(config, terminate, confirm); err != nil {
448+
return err
449+
}
450+
451+
if d != nil {
452+
d.SetId("")
453+
}
454+
455+
return nil
456+
}
457+
458+
func orderDelete(config *Config, terminate TerminateFunc, confirm ConfirmTerminationFunc) error {
459+
oldEmailsIds, err := notificationEmailSortedIds(config)
431460
if err != nil {
432461
return err
433462
}
@@ -450,7 +479,7 @@ func orderDelete(d *schema.ResourceData, meta interface{}, terminate TerminateFu
450479
var email *NotificationEmail
451480
// wait for email
452481
err = resource.Retry(30*time.Minute, func() *resource.RetryError {
453-
email, err = getNewNotificationEmail(matches, oldEmailsIds, meta)
482+
email, err = getNewNotificationEmail(matches, oldEmailsIds, config)
454483
if err != nil {
455484
log.Printf("[DEBUG] error while getting email notification. retry: %v", err)
456485
return resource.RetryableError(err)
@@ -478,10 +507,6 @@ func orderDelete(d *schema.ResourceData, meta interface{}, terminate TerminateFu
478507
return err
479508
}
480509

481-
if d != nil {
482-
d.SetId("")
483-
}
484-
485510
return nil
486511
}
487512

@@ -507,6 +532,38 @@ func orderDetails(c *ovh.Client, orderId int64) ([]*MeOrderDetail, error) {
507532
return details, nil
508533
}
509534

535+
func serviceNameFromOrder(c *ovh.Client, orderId int64, plan string) (string, error) {
536+
detailIds := []int64{}
537+
endpoint := fmt.Sprintf("/me/order/%d/details", orderId)
538+
if err := c.Get(endpoint, &detailIds); err != nil {
539+
return "", fmt.Errorf("calling get %s:\n\t %q", endpoint, err)
540+
}
541+
542+
for _, detailId := range detailIds {
543+
detailExtension := &MeOrderDetailExtension{}
544+
log.Printf("[DEBUG] Will read order detail extension %d/%d", orderId, detailId)
545+
endpoint := fmt.Sprintf("/me/order/%d/details/%d/extension", orderId, detailId)
546+
if err := c.Get(endpoint, detailExtension); err != nil {
547+
return "", fmt.Errorf("calling get %s:\n\t %q", endpoint, err)
548+
}
549+
550+
if detailExtension.Order.Plan.Code != plan {
551+
continue
552+
}
553+
554+
detail := &MeOrderDetail{}
555+
log.Printf("[DEBUG] Will read order detail %d/%d", orderId, detailId)
556+
endpoint = fmt.Sprintf("/me/order/%d/details/%d", orderId, detailId)
557+
if err := c.Get(endpoint, detail); err != nil {
558+
return "", fmt.Errorf("calling get %s:\n\t %q", endpoint, err)
559+
}
560+
561+
return detail.Domain, nil
562+
}
563+
564+
return "", errors.New("serviceName not found")
565+
}
566+
510567
func waitForOrder(c *ovh.Client, id int64) resource.StateRefreshFunc {
511568
return func() (interface{}, string, error) {
512569
var r string

0 commit comments

Comments
 (0)