Skip to content

Commit 0b7fc98

Browse files
committed
feat(inference): add support
1 parent 4c1a7a9 commit 0b7fc98

File tree

6 files changed

+359
-0
lines changed

6 files changed

+359
-0
lines changed
+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package inference
2+
3+
import (
4+
"context"
5+
inference "github.com/scaleway/scaleway-sdk-go/api/inference/v1beta1"
6+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/account"
9+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/types"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
13+
"github.com/scaleway/scaleway-sdk-go/scw"
14+
_ "time"
15+
)
16+
17+
func ResourceDeployment() *schema.Resource {
18+
return &schema.Resource{
19+
CreateContext: ResourceDeploymentCreate,
20+
ReadContext: ResourceDeploymentRead,
21+
UpdateContext: ResourceDeploymentUpdate,
22+
DeleteContext: ResourceDeploymentDelete,
23+
Importer: &schema.ResourceImporter{
24+
StateContext: schema.ImportStatePassthroughContext,
25+
},
26+
Timeouts: &schema.ResourceTimeout{ // TODO: remove unused timeouts
27+
Create: schema.DefaultTimeout(defaultInferenceDeploymentTimeout),
28+
Read: schema.DefaultTimeout(defaultInferenceDeploymentTimeout),
29+
Update: schema.DefaultTimeout(defaultInferenceDeploymentTimeout),
30+
Delete: schema.DefaultTimeout(defaultInferenceDeploymentTimeout),
31+
Default: schema.DefaultTimeout(defaultInferenceDeploymentTimeout),
32+
},
33+
SchemaVersion: 0,
34+
Schema: map[string]*schema.Schema{
35+
"name": {
36+
Type: schema.TypeString,
37+
Computed: true,
38+
Optional: true,
39+
Description: "The deployment name",
40+
},
41+
"region": regional.Schema(),
42+
"project_id": account.ProjectIDSchema(),
43+
"organization_id": account.OrganizationIDSchema(),
44+
},
45+
}
46+
}
47+
48+
func ResourceDeploymentCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
49+
api, region, err := NewAPIWithRegion(d, m)
50+
if err != nil {
51+
return diag.FromErr(err)
52+
}
53+
54+
req := &inference.CreateDeploymentRequest{
55+
Region: region,
56+
ProjectID: d.Get("project_id").(string),
57+
Name: types.ExpandOrGenerateString(d.Get("name").(string), "deployment"),
58+
}
59+
60+
deployment, err := api.CreateDeployment(req, scw.WithContext(ctx))
61+
if err != nil {
62+
return diag.FromErr(err)
63+
}
64+
65+
d.SetId(regional.NewIDString(region, deployment.ID))
66+
67+
_, err = waitForDeployment(ctx, api, region, deployment.ID, d.Timeout(schema.TimeoutCreate))
68+
if err != nil {
69+
return diag.FromErr(err)
70+
}
71+
72+
return ResourceDeploymentRead(ctx, d, m)
73+
}
74+
75+
func ResourceDeploymentRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
76+
api, region, id, err := NewAPIWithRegionAndID(m, d.Id())
77+
if err != nil {
78+
return diag.FromErr(err)
79+
}
80+
81+
deployment, err := waitForDeployment(ctx, api, region, id, d.Timeout(schema.TimeoutRead))
82+
if err != nil {
83+
if httperrors.Is404(err) {
84+
d.SetId("")
85+
return nil
86+
}
87+
return diag.FromErr(err)
88+
}
89+
90+
_ = d.Set("name", deployment.Name)
91+
_ = d.Set("region", deployment.Region)
92+
_ = d.Set("project_id", deployment.ProjectID)
93+
94+
return nil
95+
}
96+
97+
func ResourceDeploymentUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
98+
api, region, id, err := NewAPIWithRegionAndID(m, d.Id())
99+
if err != nil {
100+
return diag.FromErr(err)
101+
}
102+
103+
deployment, err := waitForDeployment(ctx, api, region, id, d.Timeout(schema.TimeoutUpdate))
104+
if err != nil {
105+
if httperrors.Is404(err) {
106+
d.SetId("")
107+
return nil
108+
}
109+
return diag.FromErr(err)
110+
}
111+
req := &inference.UpdateDeploymentRequest{
112+
Region: region,
113+
DeploymentID: deployment.ID,
114+
}
115+
116+
if d.HasChange("name") {
117+
req.Name = types.ExpandUpdatedStringPtr(d.Get("name"))
118+
}
119+
120+
if _, err := api.UpdateDeployment(req, scw.WithContext(ctx)); err != nil {
121+
return diag.FromErr(err)
122+
}
123+
124+
return ResourceDeploymentRead(ctx, d, m)
125+
}
126+
127+
func ResourceDeploymentDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
128+
api, region, id, err := NewAPIWithRegionAndID(m, d.Id())
129+
if err != nil {
130+
return diag.FromErr(err)
131+
}
132+
133+
_, err = waitForDeployment(ctx, api, region, id, d.Timeout(schema.TimeoutDelete))
134+
if err != nil {
135+
return diag.FromErr(err)
136+
}
137+
_, err = api.DeleteDeployment(&inference.DeleteDeploymentRequest{
138+
Region: region,
139+
DeploymentID: id,
140+
}, scw.WithContext(ctx))
141+
if err != nil {
142+
return diag.FromErr(err)
143+
}
144+
_, err = waitForDeployment(ctx, api, region, id, d.Timeout(schema.TimeoutDelete))
145+
if err != nil && !httperrors.Is404(err) {
146+
return diag.FromErr(err)
147+
}
148+
149+
return nil
150+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package inference_test
2+
3+
import (
4+
"fmt"
5+
inferenceSDK "github.com/scaleway/scaleway-sdk-go/api/inference/v1beta1"
6+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/httperrors"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/inference"
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
13+
)
14+
15+
func TestAccDeployment_Basic(t *testing.T) {
16+
tt := acctest.NewTestTools(t)
17+
defer tt.Cleanup()
18+
19+
resource.ParallelTest(t, resource.TestCase{
20+
PreCheck: func() { acctest.PreCheck(t) },
21+
ProviderFactories: tt.ProviderFactories,
22+
CheckDestroy: testAccCheckDeploymentDestroy(tt),
23+
Steps: []resource.TestStep{
24+
{
25+
Config: `
26+
resource "scaleway_inference_deployment" "main" {
27+
name = "test-inferenceSDK-deployment-basic"
28+
}
29+
`,
30+
Check: resource.ComposeTestCheckFunc(
31+
testAccCheckDeploymentExists(tt, "scaleway_inference_deployment.main"),
32+
resource.TestCheckResourceAttr("scaleway_inference_deployment.main", "name", "test-inferenceSDK-deployment-basic"),
33+
),
34+
},
35+
},
36+
})
37+
}
38+
39+
func testAccCheckDeploymentExists(tt *acctest.TestTools, n string) resource.TestCheckFunc {
40+
return func(state *terraform.State) error {
41+
rs, ok := state.RootModule().Resources[n]
42+
if !ok {
43+
return fmt.Errorf("resource not found: %s", n)
44+
}
45+
46+
api, region, id, err := inference.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID)
47+
if err != nil {
48+
return err
49+
}
50+
51+
_, err = api.GetDeployment(&inferenceSDK.GetDeploymentRequest{
52+
DeploymentID: id,
53+
Region: region,
54+
})
55+
56+
if err != nil {
57+
return err
58+
}
59+
60+
return nil
61+
}
62+
}
63+
64+
func testAccCheckDeploymentDestroy(tt *acctest.TestTools) resource.TestCheckFunc {
65+
return func(state *terraform.State) error {
66+
for _, rs := range state.RootModule().Resources {
67+
if rs.Type != "scaleway_inference_deployment" {
68+
continue
69+
}
70+
71+
api, region, id, err := inference.NewAPIWithRegionAndID(tt.Meta, rs.Primary.ID)
72+
if err != nil {
73+
return err
74+
}
75+
76+
_, err = api.DeleteDeployment(&inferenceSDK.DeleteDeploymentRequest{
77+
DeploymentID: id,
78+
Region: region,
79+
})
80+
81+
if err == nil {
82+
return fmt.Errorf("inferenceSDK deployment (%s) still exists", rs.Primary.ID)
83+
}
84+
85+
if !httperrors.Is404(err) {
86+
return err
87+
}
88+
}
89+
90+
return nil
91+
}
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package inference
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
inference "github.com/scaleway/scaleway-sdk-go/api/inference/v1beta1"
6+
"github.com/scaleway/scaleway-sdk-go/scw"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/meta"
9+
"time"
10+
)
11+
12+
const (
13+
defaultInferenceDeploymentTimeout = 80 * time.Minute
14+
defaultDeploymentRetryInterval = 15 * time.Minute
15+
)
16+
17+
// NewAPIWithRegion returns a new inference API and the region for a Create request
18+
func NewAPIWithRegion(d *schema.ResourceData, m interface{}) (*inference.API, scw.Region, error) {
19+
inferenceAPI := inference.NewAPI(meta.ExtractScwClient(m))
20+
21+
region, err := meta.ExtractRegion(d, m)
22+
if err != nil {
23+
return nil, "", err
24+
}
25+
26+
return inferenceAPI, region, nil
27+
}
28+
29+
// NewAPIWithRegionAndID returns a new inference API with region and ID extracted from the state
30+
func NewAPIWithRegionAndID(m interface{}, regionalID string) (*inference.API, scw.Region, string, error) {
31+
inferenceAPI := inference.NewAPI(meta.ExtractScwClient(m))
32+
33+
region, ID, err := regional.ParseID(regionalID)
34+
if err != nil {
35+
return nil, "", "", err
36+
}
37+
38+
return inferenceAPI, region, ID, nil
39+
}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package inference_test
2+
3+
import (
4+
"fmt"
5+
inference "github.com/scaleway/scaleway-sdk-go/api/inference/v1beta1"
6+
"github.com/scaleway/scaleway-sdk-go/scw"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
8+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/logging"
9+
)
10+
11+
func testSweepDeployment(_ string) error {
12+
return acctest.SweepRegions((&inference.API{}).Regions(), func(scwClient *scw.Client, region scw.Region) error {
13+
inferenceAPI := inference.NewAPI(scwClient)
14+
logging.L.Debugf("sweeper: destroying the inference deployments in (%s)", region)
15+
listDeployments, err := inferenceAPI.ListDeployments(
16+
&inference.ListDeploymentsRequest{
17+
Region: region,
18+
}, scw.WithAllPages())
19+
if err != nil {
20+
return fmt.Errorf("error listing deployment in (%s) in sweeper: %s", region, err)
21+
}
22+
23+
for _, deployment := range listDeployments.Deployments {
24+
_, err := inferenceAPI.DeleteDeployment(&inference.DeleteDeploymentRequest{
25+
DeploymentID: deployment.ID,
26+
Region: region,
27+
})
28+
if err != nil {
29+
logging.L.Debugf("sweeper: error (%s)", err)
30+
31+
return fmt.Errorf("error deleting deployment in sweeper: %s", err)
32+
}
33+
}
34+
35+
return nil
36+
})
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package inferencetestfuncs
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
7+
)
8+
9+
func init() {
10+
inferencetestfuncs.AddTestSweepers()
11+
}
12+
13+
func TestMain(m *testing.M) {
14+
resource.TestMain(m)
15+
}
16+

internal/services/inference/waiter.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package inference
2+
3+
import (
4+
"context"
5+
inference "github.com/scaleway/scaleway-sdk-go/api/inference/v1beta1"
6+
"github.com/scaleway/scaleway-sdk-go/scw"
7+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/transport"
8+
"time"
9+
)
10+
11+
func waitForDeployment(ctx context.Context, inferenceAPI *inference.API, region scw.Region, id string, timeout time.Duration) (*inference.Deployment, error) {
12+
retryInterval := defaultDeploymentRetryInterval
13+
if transport.DefaultWaitRetryInterval != nil {
14+
retryInterval = *transport.DefaultWaitRetryInterval
15+
}
16+
17+
deployment, err := inferenceAPI.WaitForDeployment(&inference.WaitForDeploymentRequest{
18+
Region: region,
19+
DeploymentId: id,
20+
RetryInterval: &retryInterval,
21+
Timeout: scw.TimeDurationPtr(timeout),
22+
}, scw.WithContext(ctx))
23+
24+
return deployment, err
25+
}

0 commit comments

Comments
 (0)