Skip to content

Commit 9561dfd

Browse files
authored
feat(object): added object resource (#1464)
1 parent 260d616 commit 9561dfd

14 files changed

+9839
-0
lines changed

docs/resources/object.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
page_title: "Scaleway: scaleway_object"
3+
description: |-
4+
Manages Scaleway object storage objects.
5+
---
6+
7+
# scaleway_object
8+
9+
Creates and manages Scaleway object storage objects.
10+
For more information, see [the documentation](https://www.scaleway.com/en/docs/object-storage-feature/).
11+
12+
## Example Usage
13+
14+
```hcl
15+
resource "scaleway_object_bucket" "some_bucket" {
16+
name = "some-unique-name"
17+
}
18+
19+
resource scaleway_object "some_file" {
20+
bucket = scaleway_object_bucket.some_bucket.name
21+
key = "object_path"
22+
23+
file = "myfile"
24+
hash = filemd5("myfile")
25+
}
26+
```
27+
28+
## Arguments Reference
29+
30+
31+
The following arguments are supported:
32+
33+
* `bucket` - (Required) The name of the bucket.
34+
* `key` - (Required) The path of the object.
35+
* `file` - (Optional) The name of the file to upload, defaults to an empty file
36+
* `hash` - (Optional) Hash of the file, used to trigger upload on file change
37+
* `storage_class` - (Optional) Specifies the Scaleway [storage class](https://www.scaleway.com/en/docs/storage/object/concepts/#storage-class) `STANDARD`, `GLACIER`, `ONEZONE_IA` used to store the object.
38+
* `visibility` - (Optional) Visibility of the object, `public-read` or `private`
39+
* `metadata` - (Optional) Map of metadata used for the object, keys must be lowercase
40+
* `tags` - (Optional) Map of tags
41+
42+
## Attributes Reference
43+
44+
In addition to all above arguments, the following attribute is exported:
45+
46+
* `id` - The path of the object, including bucket name.
47+
* `region` - The Scaleway region this bucket resides in.
48+
49+
## Import
50+
51+
Objects can be imported using the `{region}/{bucketName}/{objectKey}` identifier, e.g.
52+
53+
```bash
54+
$ terraform import scaleway_object.some_object fr-par/some-bucket/some-file
55+
```

scaleway/helpers.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ func parseRegionalID(regionalID string) (region scw.Region, id string, err error
151151
return
152152
}
153153

154+
// parseRegionalNestedID parses a regionalNestedID and extracts the resource region, inner and outer ID.
155+
func parseRegionalNestedID(regionalNestedID string) (region scw.Region, outerID, innerID string, err error) {
156+
locality, innerID, outerID, err := parseLocalizedNestedID(regionalNestedID)
157+
if err != nil {
158+
return
159+
}
160+
161+
region, err = scw.ParseRegion(locality)
162+
return
163+
}
164+
154165
// newZonedIDString constructs a unique identifier based on resource zone and id
155166
func newZonedIDString(zone scw.Zone, id string) string {
156167
return fmt.Sprintf("%s/%s", zone, id)
@@ -585,6 +596,21 @@ func flattenMap(m map[string]string) interface{} {
585596
return flattenedMap
586597
}
587598

599+
func flattenMapStringStringPtr(m map[string]*string) interface{} {
600+
if m == nil {
601+
return nil
602+
}
603+
flattenedMap := make(map[string]interface{})
604+
for k, v := range m {
605+
if v != nil {
606+
flattenedMap[k] = *v
607+
} else {
608+
flattenedMap[k] = ""
609+
}
610+
}
611+
return flattenedMap
612+
}
613+
588614
func diffSuppressFuncDuration(k, oldValue, newValue string, d *schema.ResourceData) bool {
589615
if oldValue == newValue {
590616
return true
@@ -632,6 +658,17 @@ func expandMapPtrStringString(data interface{}) *map[string]string {
632658
return &m
633659
}
634660

661+
func expandMapStringStringPtr(data interface{}) map[string]*string {
662+
if data == nil {
663+
return nil
664+
}
665+
m := make(map[string]*string)
666+
for k, v := range data.(map[string]interface{}) {
667+
m[k] = expandStringPtr(v)
668+
}
669+
return m
670+
}
671+
635672
func errorCheck(err error, message string) bool {
636673
return strings.Contains(err.Error(), message)
637674
}
@@ -707,3 +744,20 @@ func ErrorCheck(t *testing.T, endpointIDs ...string) resource.ErrorCheckFunc {
707744
return err
708745
}
709746
}
747+
748+
func validateMapKeyLowerCase() schema.SchemaValidateDiagFunc {
749+
return func(i interface{}, path cty.Path) diag.Diagnostics {
750+
m := expandMapStringStringPtr(i)
751+
for k := range m {
752+
if strings.ToLower(k) != k {
753+
return diag.Diagnostics{diag.Diagnostic{
754+
Severity: diag.Error,
755+
AttributePath: cty.IndexStringPath(k),
756+
Summary: "Invalid map content",
757+
Detail: fmt.Sprintf("key (%s) should be lowercase", k),
758+
}}
759+
}
760+
}
761+
return nil
762+
}
763+
}

scaleway/helpers_object.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,21 @@ func s3ClientWithRegionAndName(m interface{}, name string) (*s3.S3, scw.Region,
8686
return s3Client, region, name, err
8787
}
8888

89+
func s3ClientWithRegionAndNestedName(m interface{}, name string) (*s3.S3, scw.Region, string, string, error) {
90+
meta := m.(*Meta)
91+
region, outerID, innerID, err := parseRegionalNestedID(name)
92+
if err != nil {
93+
return nil, "", outerID, innerID, err
94+
}
95+
accessKey, _ := meta.scwClient.GetAccessKey()
96+
secretKey, _ := meta.scwClient.GetSecretKey()
97+
s3Client, err := newS3Client(meta.httpClient, region.String(), accessKey, secretKey)
98+
if err != nil {
99+
return nil, "", "", "", err
100+
}
101+
return s3Client, region, outerID, innerID, err
102+
}
103+
89104
func flattenObjectBucketTags(tagsSet []*s3.Tag) map[string]interface{} {
90105
tags := map[string]interface{}{}
91106

scaleway/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
139139
"scaleway_rdb_user": resourceScalewayRdbUser(),
140140
"scaleway_rdb_read_replica": resourceScalewayRdbReadReplica(),
141141
"scaleway_redis_cluster": resourceScalewayRedisCluster(),
142+
"scaleway_object": resourceScalewayObject(),
142143
"scaleway_object_bucket": resourceScalewayObjectBucket(),
143144
"scaleway_object_bucket_policy": resourceScalewayObjectBucketPolicy(),
144145
"scaleway_object_bucket_website_configuration": ResourceBucketWebsiteConfiguration(),

0 commit comments

Comments
 (0)