Skip to content

Commit

Permalink
Add data source of obs object
Browse files Browse the repository at this point in the history
  • Loading branch information
smilemusic committed Aug 27, 2020
1 parent fa465f9 commit efdb20c
Show file tree
Hide file tree
Showing 5 changed files with 421 additions and 0 deletions.
144 changes: 144 additions & 0 deletions huaweicloud/data_source_huaweicloud_obs_bucket_object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package huaweicloud

import (
"fmt"
"io/ioutil"
"log"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/huaweicloud/golangsdk/openstack/obs"
)

func dataSourceObsBucketObject() *schema.Resource {
return &schema.Resource{
Read: dataSourceObsBucketObjectRead,

Schema: map[string]*schema.Schema{
"body": {
Type: schema.TypeString,
Computed: true,
},
"bucket": {
Type: schema.TypeString,
Required: true,
},

"key": {
Type: schema.TypeString,
Required: true,
},

"storage_class": {
Type: schema.TypeString,
Computed: true,
},

"acl": {
Type: schema.TypeString,
Computed: true,
},

"content_type": {
Type: schema.TypeString,
Computed: true,
},

"etag": {
Type: schema.TypeString,
Computed: true,
},

"version_id": {
Type: schema.TypeString,
Computed: true,
},

"size": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}

// Attribute parameters are not returned in one interface.
// Three interfaces need to be called to get all parameters
func dataSourceObsBucketObjectRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
obsClient, err := config.newObjectStorageClient(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud OBS client: %s", err)
}
bucket := d.Get("bucket").(string)
key := d.Get("key").(string)
uniqueId := bucket + "/" + key

resp, err := obsClient.GetObject(&obs.GetObjectInput{
GetObjectMetadataInput: obs.GetObjectMetadataInput{
Bucket: bucket,
Key: key,
},
})
if err != nil {
return getObsError("Error get object info of OBS bucket", bucket, err)
}
log.Printf("[DEBUG] Data Source Reading OBS Bucket Object : %#v", resp)

d.Set("content_type", resp.ContentType)
if resp.Body != nil {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return getObsError("Error get body of OBS bucket object", bucket, err)
}
d.Set("body", string(body))
}

respAcl, err := obsClient.GetObjectAcl(&obs.GetObjectAclInput{
Bucket: bucket,
Key: key,
})
if err != nil {
return getObsError("Error get object acl of OBS bucket", bucket, err)
}
log.Printf("[DEBUG] Data Source Reading OBS Bucket Object Acl: %#v", respAcl)
d.Set("version_id", respAcl.VersionId)
d.Set("acl", respAcl.Delivered)

respList, err := obsClient.ListObjects(&obs.ListObjectsInput{
Bucket: bucket,
ListObjsInput: obs.ListObjsInput{
Prefix: key,
},
})
if err != nil {
return getObsError("Error listing objects of OBS bucket", bucket, err)
}

var exist bool
var object obs.Content
for _, content := range respList.Contents {
if key == content.Key {
exist = true
object = content
break
}
}
if !exist {
d.SetId("")
return fmt.Errorf("object %s not found in bucket %s", key, bucket)
}
log.Printf("[DEBUG] Data Source Reading OBS Bucket Object %s: %#v", key, object)

class := string(object.StorageClass)
if class == "" {
d.Set("storage_class", "STANDARD")
} else {
d.Set("storage_class", normalizeStorageClass(class))
}
d.SetId(uniqueId)
d.Set("size", object.Size)
d.Set("etag", strings.Trim(object.ETag, `"`))

return nil
}
224 changes: 224 additions & 0 deletions huaweicloud/data_source_huaweicloud_obs_bucket_object_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package huaweicloud

import (
"fmt"
"io/ioutil"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/huaweicloud/golangsdk/openstack/obs"
)

func TestAccHuaweiCloudObsBucketObjectDataSource_content(t *testing.T) {
rInt := acctest.RandInt()
resourceConf, dataSourceConf := testAccHuaweiCloudObsBucketObjectDataSource_content(rInt)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckS3(t) },
Providers: testAccProviders,
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
{
Config: resourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckObsBucketObjectExists("huaweicloud_obs_bucket_object.object"),
),
},
{
Config: dataSourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsObsObjectDataSourceExists("data.huaweicloud_obs_bucket_object.obj"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "content_type", "binary/octet-stream"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "storage_class", "STANDARD"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "acl", ""),
),
},
},
})
}

func TestAccHuaweiCloudObsBucketObjectDataSource_source(t *testing.T) {
tmpFile, err := ioutil.TempFile("", "tf-acc-obs-obj-source")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpFile.Name())

rInt := acctest.RandInt()
// write some data to the tempfile
err = ioutil.WriteFile(tmpFile.Name(), []byte("initial object state"), 0644)
if err != nil {
t.Fatal(err)
}
resourceConf, dataSourceConf := testAccHuaweiCloudObsBucketObjectDataSource_source(rInt, tmpFile.Name())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckS3(t) },
Providers: testAccProviders,
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
{
Config: resourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckObsBucketObjectExists("huaweicloud_obs_bucket_object.object"),
),
},
{
Config: dataSourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsObsObjectDataSourceExists("data.huaweicloud_obs_bucket_object.obj"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "content_type", "binary/octet-stream"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "storage_class", "STANDARD"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "body", "initial object state"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "acl", ""),
),
},
},
})
}

func TestAccHuaweiCloudObsBucketObjectDataSource_allParams(t *testing.T) {
rInt := acctest.RandInt()
resourceConf, dataSourceConf := testAccHuaweiCloudObsBucketObjectDataSource_allParams(rInt)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheckS3(t) },
Providers: testAccProviders,
PreventPostDestroyRefresh: true,
Steps: []resource.TestStep{
{
Config: resourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckObsBucketObjectExists("huaweicloud_obs_bucket_object.object"),
),
},
{
Config: dataSourceConf,
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsObsObjectDataSourceExists("data.huaweicloud_obs_bucket_object.obj"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "content_type", "application/unknown"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "storage_class", "STANDARD"),
resource.TestCheckResourceAttr("data.huaweicloud_obs_bucket_object.obj", "body", "\t{\"msg\": \"Hi there!\"}\n"),
),
},
},
})
}

func testAccCheckAwsObsObjectDataSourceExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find Obs object data source: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("Obs object data source ID not set")
}

bucket := rs.Primary.Attributes["bucket"]
key := rs.Primary.Attributes["key"]

config := testAccProvider.Meta().(*Config)
obsClient, err := config.newObjectStorageClient(OS_REGION_NAME)
if err != nil {
return fmt.Errorf("Error creating HuaweiCloud OBS client: %s", err)
}

respList, err := obsClient.ListObjects(&obs.ListObjectsInput{
Bucket: bucket,
ListObjsInput: obs.ListObjsInput{
Prefix: key,
},
})
if err != nil {
return getObsError("Error listing objects of OBS bucket", bucket, err)
}

var exist bool
for _, content := range respList.Contents {
if key == content.Key {
exist = true
break
}
}
if !exist {
return fmt.Errorf("object %s not found in bucket %s", key, bucket)
}

return nil
}
}

func testAccHuaweiCloudObsBucketObjectDataSource_content(randInt int) (string, string) {
resource := fmt.Sprintf(`
resource "huaweicloud_obs_bucket" "object_bucket" {
bucket = "tf-object-test-bucket-%d"
}
resource "huaweicloud_obs_bucket_object" "object" {
bucket = huaweicloud_obs_bucket.object_bucket.bucket
key = "test-key-%d"
content = "some_bucket_content"
}
`, randInt, randInt)

dataSource := fmt.Sprintf(`%s
data "huaweicloud_obs_bucket_object" "obj" {
bucket = "tf-object-test-bucket-%d"
key = "test-key-%d"
}`, resource, randInt, randInt)

return resource, dataSource
}

func testAccHuaweiCloudObsBucketObjectDataSource_source(randInt int, source string) (string, string) {
resource := fmt.Sprintf(`
resource "huaweicloud_obs_bucket" "object_bucket" {
bucket = "tf-object-test-bucket-%d"
}
resource "huaweicloud_obs_bucket_object" "object" {
bucket = huaweicloud_obs_bucket.object_bucket.bucket
key = "test-key-%d"
source = "%s"
content_type = "binary/octet-stream"
}
`, randInt, randInt, source)

dataSource := fmt.Sprintf(`%s
data "huaweicloud_obs_bucket_object" "obj" {
bucket = "tf-object-test-bucket-%d"
key = "test-key-%d"
}`, resource, randInt, randInt)

return resource, dataSource
}

func testAccHuaweiCloudObsBucketObjectDataSource_allParams(randInt int) (string, string) {
resource := fmt.Sprintf(`
resource "huaweicloud_obs_bucket" "object_bucket" {
bucket = "tf-object-test-bucket-%d"
}
resource "huaweicloud_obs_bucket_object" "object" {
bucket = huaweicloud_obs_bucket.object_bucket.bucket
key = "test-key-%d"
content = <<CONTENT
{"msg": "Hi there!"}
CONTENT
acl = "private"
content_type = "application/unknown"
storage_class = "STANDARD"
encryption = true
}
`, randInt, randInt)

dataSource := fmt.Sprintf(`%s
data "huaweicloud_obs_bucket_object" "obj" {
bucket = "tf-object-test-bucket-%d"
key = "test-key-%d"
}`, resource, randInt, randInt)

return resource, dataSource
}
1 change: 1 addition & 0 deletions huaweicloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ func Provider() terraform.ResourceProvider {
"huaweicloud_kms_data_key": dataSourceKmsDataKeyV1(),
"huaweicloud_networking_port": dataSourceNetworkingPortV2(),
"huaweicloud_networking_secgroup": dataSourceNetworkingSecGroupV2(),
"huaweicloud_obs_bucket_object": dataSourceObsBucketObject(),
"huaweicloud_rds_flavors": dataSourceRdsFlavorV3(),
"huaweicloud_sfs_file_system": dataSourceSFSFileSystemV2(),
"huaweicloud_vpc": dataSourceVirtualPrivateCloudVpcV1(),
Expand Down
Loading

0 comments on commit efdb20c

Please sign in to comment.