Skip to content

Commit 1366de3

Browse files
authored
Re-create purged cluster for databricks_mount (#1345)
Fix #1317
1 parent 75e5573 commit 1366de3

File tree

5 files changed

+126
-13
lines changed

5 files changed

+126
-13
lines changed

storage/aws_s3_mount.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,7 @@ func preprocessS3Mount(ctx context.Context, d *schema.ResourceData, m interface{
116116
return fmt.Errorf("cluster %s must have EC2 instance profile attached", clusterID)
117117
}
118118
} else if instanceProfile != "" {
119-
cluster, err := GetOrCreateMountingClusterWithInstanceProfile(clustersAPI, instanceProfile)
120-
if err != nil {
121-
return err
122-
}
123-
return d.Set("cluster_id", cluster.ClusterID)
119+
return mountS3ViaProfileAndSetClusterID(clustersAPI, instanceProfile, d)
124120
}
125121
return nil
126122
}

storage/aws_s3_mount_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"testing"
66

77
"github.com/databrickslabs/terraform-provider-databricks/clusters"
8-
"github.com/databrickslabs/terraform-provider-databricks/common"
98
"github.com/databrickslabs/terraform-provider-databricks/commands"
9+
"github.com/databrickslabs/terraform-provider-databricks/common"
1010

1111
"github.com/databrickslabs/terraform-provider-databricks/qa"
1212
"github.com/stretchr/testify/assert"
@@ -82,7 +82,7 @@ func TestResourceAwsS3MountCreate_invalid_arn(t *testing.T) {
8282
},
8383
Create: true,
8484
}.Apply(t)
85-
require.EqualError(t, err, "invalid arn: this_mount")
85+
require.EqualError(t, err, "mount via profile: invalid arn: this_mount")
8686
}
8787

8888
func TestResourceAwsS3MountRead(t *testing.T) {

storage/resource_mount_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func TestResourceAwsS3MountGenericCreate_invalid_arn(t *testing.T) {
288288
},
289289
Create: true,
290290
}.Apply(t)
291-
require.EqualError(t, err, "invalid arn: this_mount")
291+
require.EqualError(t, err, "mount via profile: invalid arn: this_mount")
292292
}
293293

294294
func TestResourceAwsS3MountGenericRead(t *testing.T) {

storage/s3.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,29 @@ func preprocessS3MountGeneric(ctx context.Context, s map[string]*schema.Schema,
6262
clustersAPI := clusters.NewClustersAPI(ctx, m)
6363
if clusterID != "" {
6464
clusterInfo, err := clustersAPI.Get(clusterID)
65+
if common.IsMissing(err) {
66+
if instanceProfile == "" {
67+
return fmt.Errorf("instance profile is required to re-create mounting cluster")
68+
}
69+
return mountS3ViaProfileAndSetClusterID(clustersAPI, instanceProfile, d)
70+
}
6571
if err != nil {
6672
return err
6773
}
6874
if clusterInfo.AwsAttributes == nil || len(clusterInfo.AwsAttributes.InstanceProfileArn) == 0 {
6975
return fmt.Errorf("cluster %s must have EC2 instance profile attached", clusterID)
7076
}
7177
} else if instanceProfile != "" {
72-
cluster, err := GetOrCreateMountingClusterWithInstanceProfile(clustersAPI, instanceProfile)
73-
if err != nil {
74-
return err
75-
}
76-
return d.Set("cluster_id", cluster.ClusterID)
78+
return mountS3ViaProfileAndSetClusterID(clustersAPI, instanceProfile, d)
7779
}
7880
return nil
7981
}
82+
83+
func mountS3ViaProfileAndSetClusterID(clustersAPI clusters.ClustersAPI,
84+
instanceProfile string, d *schema.ResourceData) error {
85+
cluster, err := GetOrCreateMountingClusterWithInstanceProfile(clustersAPI, instanceProfile)
86+
if err != nil {
87+
return fmt.Errorf("mount via profile: %w", err)
88+
}
89+
return d.Set("cluster_id", cluster.ClusterID)
90+
}

storage/s3_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package storage
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/databrickslabs/terraform-provider-databricks/clusters"
8+
"github.com/databrickslabs/terraform-provider-databricks/common"
9+
"github.com/databrickslabs/terraform-provider-databricks/qa"
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestPreprocessS3MountOnDeletedClusterNoInstanceProfileSpecifiedError(t *testing.T) {
14+
qa.HTTPFixturesApply(t, []qa.HTTPFixture{
15+
{
16+
Method: "GET",
17+
Resource: "/api/2.0/clusters/get?cluster_id=removed-cluster",
18+
Status: 404,
19+
Response: common.NotFound("cluster deleted"),
20+
},
21+
}, func(ctx context.Context, client *common.DatabricksClient) {
22+
r := ResourceMount()
23+
d := r.TestResourceData()
24+
d.Set("uri", "s3://bucket")
25+
d.Set("cluster_id", "removed-cluster")
26+
err := preprocessS3MountGeneric(ctx, r.Schema, d, client)
27+
assert.EqualError(t, err, "instance profile is required to re-create mounting cluster")
28+
})
29+
}
30+
31+
func TestPreprocessS3MountOnDeletedClusterWorks(t *testing.T) {
32+
qa.HTTPFixturesApply(t, []qa.HTTPFixture{
33+
{
34+
Method: "GET",
35+
Resource: "/api/2.0/clusters/get?cluster_id=removed-cluster",
36+
Status: 404,
37+
Response: common.NotFound("cluster deleted"),
38+
},
39+
{
40+
Method: "GET",
41+
Resource: "/api/2.0/clusters/list",
42+
Response: clusters.ClusterList{
43+
Clusters: []clusters.ClusterInfo{},
44+
},
45+
},
46+
{
47+
ReuseRequest: true,
48+
Method: "GET",
49+
Resource: "/api/2.0/clusters/spark-versions",
50+
},
51+
{
52+
ReuseRequest: true,
53+
Method: "GET",
54+
Resource: "/api/2.0/clusters/list-node-types",
55+
},
56+
{
57+
Method: "POST",
58+
Resource: "/api/2.0/clusters/create",
59+
ExpectedRequest: clusters.Cluster{
60+
CustomTags: map[string]string{
61+
"ResourceClass": "SingleNode",
62+
},
63+
ClusterName: "terraform-mount-s3-access",
64+
SparkVersion: "7.3.x-scala2.12",
65+
NumWorkers: 0,
66+
NodeTypeID: "i3.xlarge",
67+
AwsAttributes: &clusters.AwsAttributes{
68+
Availability: "SPOT",
69+
InstanceProfileArn: "arn:aws:iam::1234567:instance-profile/s3-access",
70+
},
71+
AutoterminationMinutes: 10,
72+
SparkConf: map[string]string{
73+
"spark.databricks.cluster.profile": "singleNode",
74+
"spark.master": "local[*]",
75+
"spark.scheduler.mode": "FIFO",
76+
},
77+
},
78+
Response: clusters.ClusterID{
79+
ClusterID: "new-cluster",
80+
},
81+
},
82+
{
83+
Method: "GET",
84+
Resource: "/api/2.0/clusters/get?cluster_id=new-cluster",
85+
Response: clusters.ClusterInfo{
86+
ClusterID: "new-cluster",
87+
State: "RUNNING",
88+
StateMessage: "created",
89+
},
90+
},
91+
}, func(ctx context.Context, client *common.DatabricksClient) {
92+
r := ResourceMount()
93+
d := r.TestResourceData()
94+
d.MarkNewResource()
95+
common.StructToData(GenericMount{
96+
URI: "s3://bucket",
97+
ClusterID: "removed-cluster",
98+
S3: &S3IamMount{
99+
InstanceProfile: "arn:aws:iam::1234567:instance-profile/s3-access",
100+
},
101+
}, r.Schema, d)
102+
err := preprocessS3MountGeneric(ctx, r.Schema, d, client)
103+
assert.NoError(t, err)
104+
assert.Equal(t, "new-cluster", d.Get("cluster_id"))
105+
})
106+
}

0 commit comments

Comments
 (0)