diff --git a/examples/cts_tracker.tf b/examples/cts_tracker.tf new file mode 100644 index 0000000000..dd1ec8eeb3 --- /dev/null +++ b/examples/cts_tracker.tf @@ -0,0 +1,18 @@ +resource "huaweicloud_s3_bucket" "bucket" { + bucket = "tf-test-bucket" + acl = "public-read" +} +resource "huaweicloud_smn_topic_v2" "topic_1" { + name = "topic_check" + display_name = "The display name of topic_1" +} + +resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${huaweicloud_s3_bucket.bucket.bucket}" + file_prefix_name = "yO8Q" + is_support_smn = true + topic_id = "${huaweicloud_smn_topic_v2.topic_1.id}" + is_send_all_key_operation = false + operations = ["delete","create","login"] + need_notify_user_list = ["user1"] +} \ No newline at end of file diff --git a/huaweicloud/config.go b/huaweicloud/config.go index 7bfbc258df..ff4c5d961d 100644 --- a/huaweicloud/config.go +++ b/huaweicloud/config.go @@ -459,3 +459,10 @@ func (c *Config) vbsV2Client(region string) (*golangsdk.ServiceClient, error) { Availability: c.getHwEndpointType(), }) } + +func (c *Config) ctsV1Client(region string) (*golangsdk.ServiceClient, error) { + return huaweisdk.NewCTSService(c.HwClient, golangsdk.EndpointOpts{ + Region: c.determineRegion(region), + Availability: c.getHwEndpointType(), + }) +} diff --git a/huaweicloud/data_source_huaweicloud_cts_tracker_v1.go b/huaweicloud/data_source_huaweicloud_cts_tracker_v1.go new file mode 100644 index 0000000000..bf4491f68f --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_cts_tracker_v1.go @@ -0,0 +1,116 @@ +package huaweicloud + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker" +) + +func dataSourceCTSTrackerV1() *schema.Resource { + return &schema.Resource{ + Read: dataSourceCTSTrackerV1Read, + + Schema: map[string]*schema.Schema{ + "region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "status": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "bucket_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "file_prefix_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "tracker_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "is_support_smn": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + }, + "topic_id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "operations": &schema.Schema{ + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "is_send_all_key_operation": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + }, + "need_notify_user_list": &schema.Schema{ + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + } +} + +func dataSourceCTSTrackerV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + trackerClient, err := config.ctsV1Client(GetRegion(d, config)) + + listOpts := tracker.ListOpts{ + TrackerName: d.Get("tracker_name").(string), + BucketName: d.Get("bucket_name").(string), + FilePrefixName: d.Get("file_prefix_name").(string), + Status: d.Get("status").(string), + } + + refinedTrackers, err := tracker.List(trackerClient, listOpts) + + if err != nil { + return fmt.Errorf("Unable to retrieve cts tracker: %s", err) + } + + if len(refinedTrackers) < 1 { + return fmt.Errorf("Your query returned no results. " + + "Please change your search criteria and try again.") + } + + if len(refinedTrackers) > 1 { + return fmt.Errorf("Your query returned more than one result." + + " Please try a more specific search criteria") + } + + trackers := refinedTrackers[0] + + log.Printf("[INFO] Retrieved cts tracker %s using given filter", trackers.TrackerName) + + d.SetId(trackers.TrackerName) + + d.Set("tracker_name", trackers.TrackerName) + d.Set("bucket_name", trackers.BucketName) + d.Set("file_prefix_name", trackers.FilePrefixName) + d.Set("status", trackers.Status) + d.Set("is_support_smn", trackers.SimpleMessageNotification.IsSupportSMN) + d.Set("topic_id", trackers.SimpleMessageNotification.TopicID) + d.Set("is_send_all_key_operation", trackers.SimpleMessageNotification.IsSendAllKeyOperation) + d.Set("operations", trackers.SimpleMessageNotification.Operations) + d.Set("need_notify_user_list", trackers.SimpleMessageNotification.NeedNotifyUserList) + + d.Set("region", GetRegion(d, config)) + + return nil +} diff --git a/huaweicloud/data_source_huaweicloud_cts_tracker_v1_test.go b/huaweicloud/data_source_huaweicloud_cts_tracker_v1_test.go new file mode 100644 index 0000000000..5db58b423e --- /dev/null +++ b/huaweicloud/data_source_huaweicloud_cts_tracker_v1_test.go @@ -0,0 +1,67 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccCTSTrackerV1DataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCTSTrackerV1DataSource_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCTSTrackerV1DataSourceID("data.huaweicloud_cts_tracker_v1.tracker_v1"), + resource.TestCheckResourceAttr("data.huaweicloud_cts_tracker_v1.tracker_v1", "bucket_name", "tf-test-bucket"), + resource.TestCheckResourceAttr("data.huaweicloud_cts_tracker_v1.tracker_v1", "status", "enabled"), + ), + }, + }, + }) +} + +func testAccCheckCTSTrackerV1DataSourceID(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Can't find cts tracker data source: %s ", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("tracker data source not set ") + } + + return nil + } +} + +const testAccCTSTrackerV1DataSource_basic = ` +resource "huaweicloud_s3_bucket" "bucket" { + bucket = "tf-test-bucket" + acl = "public-read" + force_destroy = true +} +resource "huaweicloud_smn_topic_v2" "topic_1" { + name = "tf-test-topic" + display_name = "The display name of tf-test-topic" +} + +resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${huaweicloud_s3_bucket.bucket.bucket}" + file_prefix_name = "yO8Q" + is_support_smn = true + topic_id = "${huaweicloud_smn_topic_v2.topic_1.id}" + is_send_all_key_operation = false + operations = ["login"] + need_notify_user_list = ["user1"] +} + +data "huaweicloud_cts_tracker_v1" "tracker_v1" { + tracker_name = "${huaweicloud_cts_tracker_v1.tracker_v1.id}" +} +` diff --git a/huaweicloud/import_huaweicloud_cts_tracker_v1_test.go b/huaweicloud/import_huaweicloud_cts_tracker_v1_test.go new file mode 100644 index 0000000000..f5416b9597 --- /dev/null +++ b/huaweicloud/import_huaweicloud_cts_tracker_v1_test.go @@ -0,0 +1,28 @@ +package huaweicloud + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccCTSTrackerV1_importBasic(t *testing.T) { + resourceName := "huaweicloud_cts_tracker_v1.tracker_v1" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCTSTrackerV1Destroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCTSTrackerV1_basic, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/huaweicloud/provider.go b/huaweicloud/provider.go index 10781fb935..242669a081 100644 --- a/huaweicloud/provider.go +++ b/huaweicloud/provider.go @@ -216,6 +216,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_dms_maintainwindow_v1": dataSourceDmsMaintainWindowV1(), "huaweicloud_vbs_backup_policy_v2": dataSourceVBSBackupPolicyV2(), "huaweicloud_vbs_backup_v2": dataSourceVBSBackupV2(), + "huaweicloud_cts_tracker_v1": dataSourceCTSTrackerV1(), }, ResourcesMap: map[string]*schema.Resource{ @@ -281,6 +282,7 @@ func Provider() terraform.ResourceProvider { "huaweicloud_as_policy_v1": resourceASPolicy(), "huaweicloud_vbs_backup_policy_v2": resourceVBSBackupPolicyV2(), "huaweicloud_vbs_backup_v2": resourceVBSBackupV2(), + "huaweicloud_cts_tracker_v1": resourceCTSTrackerV1(), }, ConfigureFunc: configureProvider, diff --git a/huaweicloud/resource_huaweicloud_cts_tracker_v1.go b/huaweicloud/resource_huaweicloud_cts_tracker_v1.go new file mode 100644 index 0000000000..fd7967551e --- /dev/null +++ b/huaweicloud/resource_huaweicloud_cts_tracker_v1.go @@ -0,0 +1,228 @@ +package huaweicloud + +import ( + "time" + + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker" +) + +func resourceCTSTrackerV1() *schema.Resource { + return &schema.Resource{ + Create: resourceCTSTrackerCreate, + Read: resourceCTSTrackerRead, + Update: resourceCTSTrackerUpdate, + Delete: resourceCTSTrackerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(10 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "region": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + }, + "status": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "tracker_name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "bucket_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "file_prefix_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validateName, + }, + "is_support_smn": &schema.Schema{ + Type: schema.TypeBool, + Required: true, + }, + "topic_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "operations": &schema.Schema{ + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + "is_send_all_key_operation": &schema.Schema{ + Type: schema.TypeBool, + Required: true, + }, + "need_notify_user_list": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + } + +} + +func resourceCTSTrackerCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + ctsClient, err := config.ctsV1Client(GetRegion(d, config)) + + if err != nil { + return fmt.Errorf("Error creating cts Client: %s", err) + } + + createOpts := tracker.CreateOptsWithSMN{ + BucketName: d.Get("bucket_name").(string), + FilePrefixName: d.Get("file_prefix_name").(string), + SimpleMessageNotification: tracker.SimpleMessageNotification{ + IsSupportSMN: d.Get("is_support_smn").(bool), + TopicID: d.Get("topic_id").(string), + Operations: resourceCTSOperations(d), + IsSendAllKeyOperation: d.Get("is_send_all_key_operation").(bool), + NeedNotifyUserList: resourceCTSNeedNotifyUserList(d), + }, + } + + trackers, err := tracker.Create(ctsClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating CTS tracker : %s", err) + } + + d.SetId(trackers.TrackerName) + + time.Sleep(20 * time.Second) + return resourceCTSTrackerRead(d, meta) +} + +func resourceCTSTrackerRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + ctsClient, err := config.ctsV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating cts Client: %s", err) + } + listOpts := tracker.ListOpts{ + TrackerName: d.Get("tracker_name").(string), + BucketName: d.Get("bucket_name").(string), + FilePrefixName: d.Get("file_prefix_name").(string), + Status: d.Get("status").(string), + } + trackers, err := tracker.List(ctsClient, listOpts) + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + log.Printf("[WARN] Removing cts tracker %s as it's already gone", d.Id()) + d.SetId("") + return nil + } + + return fmt.Errorf("Error retrieving cts tracker: %s", err) + } + + ctsTracker := trackers[0] + + d.Set("tracker_name", ctsTracker.TrackerName) + d.Set("bucket_name", ctsTracker.BucketName) + d.Set("status", ctsTracker.Status) + d.Set("file_prefix_name", ctsTracker.FilePrefixName) + d.Set("is_support_smn", ctsTracker.SimpleMessageNotification.IsSupportSMN) + d.Set("topic_id", ctsTracker.SimpleMessageNotification.TopicID) + d.Set("is_send_all_key_operation", ctsTracker.SimpleMessageNotification.IsSendAllKeyOperation) + d.Set("operations", ctsTracker.SimpleMessageNotification.Operations) + d.Set("need_notify_user_list", ctsTracker.SimpleMessageNotification.NeedNotifyUserList) + + d.Set("region", GetRegion(d, config)) + time.Sleep(20 * time.Second) + + return nil +} + +func resourceCTSTrackerUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + ctsClient, err := config.ctsV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating cts Client: %s", err) + } + var updateOpts tracker.UpdateOptsWithSMN + + //as bucket_name is mandatory while updating tracker + updateOpts.BucketName = d.Get("bucket_name").(string) + + updateOpts.SimpleMessageNotification.TopicID = d.Get("topic_id").(string) + + updateOpts.SimpleMessageNotification.Operations = resourceCTSOperations(d) + + updateOpts.SimpleMessageNotification.NeedNotifyUserList = resourceCTSNeedNotifyUserList(d) + + updateOpts.SimpleMessageNotification.IsSupportSMN = d.Get("is_support_smn").(bool) + + if d.HasChange("file_prefix_name") { + updateOpts.FilePrefixName = d.Get("file_prefix_name").(string) + } + if d.HasChange("status") { + updateOpts.Status = d.Get("status").(string) + } + if d.HasChange("is_send_all_key_operation") { + updateOpts.SimpleMessageNotification.IsSendAllKeyOperation = d.Get("is_send_all_key_operation").(bool) + } + + _, err = tracker.Update(ctsClient, updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating cts tracker: %s", err) + } + time.Sleep(20 * time.Second) + return resourceCTSTrackerRead(d, meta) +} + +func resourceCTSTrackerDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + ctsClient, err := config.ctsV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating cts Client: %s", err) + } + + result := tracker.Delete(ctsClient) + if result.Err != nil { + return err + } + + time.Sleep(20 * time.Second) + log.Printf("[DEBUG] Successfully deleted cts tracker %s", d.Id()) + + return nil +} + +func resourceCTSOperations(d *schema.ResourceData) []string { + rawOperations := d.Get("operations").(*schema.Set) + operation := make([]string, (rawOperations).Len()) + for i, raw := range rawOperations.List() { + operation[i] = raw.(string) + } + return operation +} + +func resourceCTSNeedNotifyUserList(d *schema.ResourceData) []string { + rawNotify := d.Get("need_notify_user_list").(*schema.Set) + notify := make([]string, (rawNotify).Len()) + for i, raw := range rawNotify.List() { + notify[i] = raw.(string) + } + return notify +} diff --git a/huaweicloud/resource_huaweicloud_cts_tracker_v1_test.go b/huaweicloud/resource_huaweicloud_cts_tracker_v1_test.go new file mode 100644 index 0000000000..d815bb18ee --- /dev/null +++ b/huaweicloud/resource_huaweicloud_cts_tracker_v1_test.go @@ -0,0 +1,187 @@ +package huaweicloud + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker" +) + +func TestAccCTSTrackerV1_basic(t *testing.T) { + var tracker tracker.Tracker + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCTSTrackerV1Destroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCTSTrackerV1_basic, + Check: resource.ComposeTestCheckFunc( + testAccCheckCTSTrackerV1Exists("huaweicloud_cts_tracker_v1.tracker_v1", &tracker), + resource.TestCheckResourceAttr( + "huaweicloud_cts_tracker_v1.tracker_v1", "bucket_name", "tf-test-bucket"), + resource.TestCheckResourceAttr( + "huaweicloud_cts_tracker_v1.tracker_v1", "file_prefix_name", "yO8Q"), + ), + }, + resource.TestStep{ + Config: testAccCTSTrackerV1_update, + Check: resource.ComposeTestCheckFunc( + testAccCheckCTSTrackerV1Exists("huaweicloud_cts_tracker_v1.tracker_v1", &tracker), + resource.TestCheckResourceAttr( + "huaweicloud_cts_tracker_v1.tracker_v1", "file_prefix_name", "yO8Q1"), + ), + }, + }, + }) +} + +func TestAccCTSTrackerV1_timeout(t *testing.T) { + var tracker tracker.Tracker + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCTSTrackerV1Destroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCTSTrackerV1_timeout, + Check: resource.ComposeTestCheckFunc( + testAccCheckCTSTrackerV1Exists("huaweicloud_cts_tracker_v1.tracker_v1", &tracker), + ), + }, + }, + }) +} + +func testAccCheckCTSTrackerV1Destroy(s *terraform.State) error { + config := testAccProvider.Meta().(*Config) + ctsClient, err := config.ctsV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating cts client: %s", err) + } + + for _, rs := range s.RootModule().Resources { + if rs.Type != "huaweicloud_cts_tracker_v1" { + continue + } + + _, err := tracker.List(ctsClient, tracker.ListOpts{TrackerName: rs.Primary.ID}) + if err != nil { + return fmt.Errorf("cts tracker still exists.") + } + if _, ok := err.(golangsdk.ErrDefault404); !ok { + return err + } + } + + return nil +} + +func testAccCheckCTSTrackerV1Exists(n string, trackers *tracker.Tracker) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set") + } + + config := testAccProvider.Meta().(*Config) + ctsClient, err := config.ctsV1Client(OS_REGION_NAME) + if err != nil { + return fmt.Errorf("Error creating cts client: %s", err) + } + + trackerList, err := tracker.List(ctsClient, tracker.ListOpts{TrackerName: rs.Primary.ID}) + if err != nil { + return err + } + found := trackerList[0] + if found.TrackerName != rs.Primary.ID { + return fmt.Errorf("cts tracker not found") + } + + *trackers = found + + return nil + } +} + +const testAccCTSTrackerV1_basic = ` +resource "huaweicloud_s3_bucket" "bucket" { + bucket = "tf-test-bucket" + acl = "public-read" + force_destroy = true +} + +resource "huaweicloud_smn_topic_v2" "topic_1" { + name = "topic_check" + display_name = "The display name of topic_check" +} + +resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${huaweicloud_s3_bucket.bucket.bucket}" + file_prefix_name = "yO8Q" + is_support_smn = true + topic_id = "${huaweicloud_smn_topic_v2.topic_1.id}" + is_send_all_key_operation = false + operations = ["login"] + need_notify_user_list = ["user1"] +} +` + +const testAccCTSTrackerV1_update = ` +resource "huaweicloud_s3_bucket" "bucket" { + bucket = "tf-test-bucket" + acl = "public-read" + force_destroy = true +} +resource "huaweicloud_smn_topic_v2" "topic_1" { + name = "topic_check1" + display_name = "The display name of topic_check" +} +resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${huaweicloud_s3_bucket.bucket.bucket}" + file_prefix_name = "yO8Q1" + is_support_smn = true + topic_id = "${huaweicloud_smn_topic_v2.topic_1.id}" + is_send_all_key_operation = false + operations = ["login"] + need_notify_user_list = ["user1"] +} +` + +const testAccCTSTrackerV1_timeout = ` +resource "huaweicloud_s3_bucket" "bucket" { + bucket = "tf-test-bucket" + acl = "public-read" + force_destroy = true +} + +resource "huaweicloud_smn_topic_v2" "topic_1" { + name = "topic_check-1" + display_name = "The display name of topic_check" +} + +resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${huaweicloud_s3_bucket.bucket.bucket}" + file_prefix_name = "yO8Q" + is_support_smn = true + topic_id = "${huaweicloud_smn_topic_v2.topic_1.id}" + is_send_all_key_operation = false + operations = ["login"] + need_notify_user_list = ["user1"] + +timeouts { + create = "5m" + delete = "5m" + } +} +` diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/client.go b/vendor/github.com/huaweicloud/golangsdk/openstack/client.go index 8ef6f0d1ec..4af992c776 100644 --- a/vendor/github.com/huaweicloud/golangsdk/openstack/client.go +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/client.go @@ -588,6 +588,12 @@ func NewAutoScalingService(client *golangsdk.ProviderClient, eo golangsdk.Endpoi return sc, err } +// NewAutoScalingV1 creates a ServiceClient that may be used to access the AS service +func NewAutoScalingV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "asv1") + return sc, err +} + // NewKmsKeyV1 creates a ServiceClient that may be used to access the v1 // kms key service. func NewKmsKeyV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { @@ -757,3 +763,21 @@ func NewVBS(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golan sc.ResourceBase = sc.Endpoint return sc, err } + +// NewCTSService creates a ServiceClient that can be used to access the Cloud Trace service. +func NewCTSService(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "cts") + return sc, err +} + +// NewELBV1 creates a ServiceClient that may be used to access the ELB service. +func NewELBV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "elbv1") + return sc, err +} + +// NewRDSV1 creates a ServiceClient that may be used to access the RDS service. +func NewRDSV1(client *golangsdk.ProviderClient, eo golangsdk.EndpointOpts) (*golangsdk.ServiceClient, error) { + sc, err := initClientOpts(client, eo, "rdsv1") + return sc, err +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/doc.go b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/doc.go new file mode 100644 index 0000000000..4b3797fb00 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/doc.go @@ -0,0 +1,53 @@ +/* +Package tracker provides operation records for cloud service resources. + +Example to List Tracker + listTracker := tracker.ListOpts{} + allTracker, err := tracker.List(client,listTracker) + if err != nil { + panic(err) + } + fmt.Println(allTracker) + + + +Example to Create a Tracker + createTracker:=tracker.CreateOpts{ + BucketName: "obs-e51d", + FilePrefixName: "mytracker", + SimpleMessageNotification:tracker.SimpleMessageNotification{ + IsSupportSMN: true, + TopicID: "urn:smn:eu-de:626ce20e52a346c090b09cffc3e038e5:c2c-topic", + IsSendAllKeyOperation: false, + Operations: []string{"login"}, + NeedNotifyUserList: []string{"user1","user2"}, + }} + out,err:=tracker.Create(client, createTracker).Extract() + fmt.Println(out) + fmt.Println(err) + + +Example to Update a Tracker + updateTracker:=tracker.UpdateOpts{ + BucketName : "ciros-img", + FilePrefixName : "mytracker", + Status : "disabled", + SimpleMessageNotification:tracker.SimpleMessageNotification{ + IsSupportSMN: false, + TopicID: "urn:smn:eu-de:626ce20e52a346c090b09cffc3e038e5:c2c-topic", + IsSendAllKeyOperation:false, + Operations: []string{"delete","create","login"}, + NeedNotifyUserList:[]string{"user1","user2"}, + }, + } + out,err:=tracker.Update(client, updateTracker).Extract() + fmt.Println(out) + + +Example to Delete a Tracker + out:= tracker.Delete(client).ExtractErr() + fmt.Println(out) + + +*/ +package tracker diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/requests.go b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/requests.go new file mode 100644 index 0000000000..0947276951 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/requests.go @@ -0,0 +1,183 @@ +package tracker + +import ( + "reflect" + + "github.com/huaweicloud/golangsdk" +) + +// ListOpts allows the filtering and sorting of paginated collections through +// the API. Filtering is achieved by passing in struct field values that map to +// the attributes you want to see returned. +type ListOpts struct { + TrackerName string `q:"tracker_name"` + BucketName string + FilePrefixName string + Status string +} + +// List returns collection of Tracker. It accepts a ListOpts struct, which allows you to filter and sort +// the returned collection for greater efficiency. +func List(client *golangsdk.ServiceClient, opts ListOpts) ([]Tracker, error) { + var r ListResult + _, r.Err = client.Get(rootURL(client), &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + + allTracker, err := r.ExtractTracker() + if err != nil { + return nil, err + } + + return FilterTracker(allTracker, opts) +} + +func FilterTracker(tracker []Tracker, opts ListOpts) ([]Tracker, error) { + + var refinedTracker []Tracker + var matched bool + m := map[string]interface{}{} + + if opts.BucketName != "" { + m["BucketName"] = opts.BucketName + } + if opts.FilePrefixName != "" { + m["FilePrefixName"] = opts.FilePrefixName + } + if opts.Status != "" { + m["Status"] = opts.Status + } + + if len(m) > 0 && len(tracker) > 0 { + for _, trackers := range tracker { + matched = true + + for key, value := range m { + if sVal := getStructField(&trackers, key); !(sVal == value) { + matched = false + } + } + + if matched { + refinedTracker = append(refinedTracker, trackers) + } + } + } else { + refinedTracker = tracker + } + return refinedTracker, nil +} + +func getStructField(v *Tracker, field string) string { + r := reflect.ValueOf(v) + f := reflect.Indirect(r).FieldByName(field) + return string(f.String()) +} + +// CreateOptsBuilder allows extensions to add additional parameters to the +// Create request. +type CreateOptsBuilder interface { + ToTrackerCreateMap() (map[string]interface{}, error) +} + +// CreateOptsWithSMN contains the options for create a Tracker. This object is +// passed to tracker.Create(). +type CreateOptsWithSMN struct { + BucketName string `json:"bucket_name" required:"true"` + FilePrefixName string `json:"file_prefix_name,omitempty"` + SimpleMessageNotification SimpleMessageNotification `json:"smn,omitempty"` +} + +// CreateOpts contains the options for create a Tracker. This object is +// passed to tracker.Create(). +type CreateOpts struct { + BucketName string `json:"bucket_name" required:"true"` + FilePrefixName string `json:"file_prefix_name,omitempty"` +} + +type SimpleMessageNotification struct { + IsSupportSMN bool `json:"is_support_smn"` + TopicID string `json:"topic_id"` + Operations []string `json:"operations" required:"true"` + IsSendAllKeyOperation bool `json:"is_send_all_key_operation"` + NeedNotifyUserList []string `json:"need_notify_user_list,omitempty"` +} + +// ToTrackerCreateMap assembles a request body based on the contents of a +// CreateOpts. +func (opts CreateOpts) ToTrackerCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// ToTrackerCreateMap assembles a request body based on the contents of a +// CreateOpts. +func (opts CreateOptsWithSMN) ToTrackerCreateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +// Create will create a new tracker based on the values in CreateOpts. To extract +// the tracker name from the response, call the Extract method on the +// CreateResult. +func Create(client *golangsdk.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { + b, err := opts.ToTrackerCreateMap() + + if err != nil { + r.Err = err + return + } + _, r.Err = client.Post(rootURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{201}, + }) + return +} + +// UpdateOptsWithSMN contains all the values needed to update a tracker +type UpdateOptsWithSMN struct { + Status string `json:"status,omitempty"` + BucketName string `json:"bucket_name" required:"true"` + FilePrefixName string `json:"file_prefix_name,omitempty"` + SimpleMessageNotification SimpleMessageNotification `json:"smn,omitempty"` +} + +// UpdateOpts contains all the values needed to update a tracker +type UpdateOpts struct { + Status string `json:"status,omitempty"` + BucketName string `json:"bucket_name" required:"true"` + FilePrefixName string `json:"file_prefix_name,omitempty"` +} + +// UpdateOptsBuilder allows extensions to add additional parameters to the +// Update request. +type UpdateOptsBuilder interface { + ToTrackerUpdateMap() (map[string]interface{}, error) +} + +// ToTrackerUpdateMap builds an update body based on UpdateOpts. +func (opts UpdateOptsWithSMN) ToTrackerUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +func (opts UpdateOpts) ToTrackerUpdateMap() (map[string]interface{}, error) { + return golangsdk.BuildRequestBody(opts, "") +} + +func Update(client *golangsdk.ServiceClient, opts UpdateOptsBuilder) (r UpdateResult) { + b, err := opts.ToTrackerUpdateMap() + if err != nil { + r.Err = err + return + } + _, r.Err = client.Put(resourceURL(client), b, &r.Body, &golangsdk.RequestOpts{ + OkCodes: []int{200}, + }) + return +} + +// Delete will permanently delete a particular tracker. +func Delete(client *golangsdk.ServiceClient) (r DeleteResult) { + _, r.Err = client.Delete(rootURL(client), &golangsdk.RequestOpts{ + OkCodes: []int{204}, + JSONBody: nil, + }) + return +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/results.go b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/results.go new file mode 100644 index 0000000000..ba63a9d190 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/results.go @@ -0,0 +1,58 @@ +package tracker + +import ( + "github.com/huaweicloud/golangsdk" + "github.com/huaweicloud/golangsdk/pagination" +) + +type Tracker struct { + Status string `json:"status"` + BucketName string `json:"bucket_name"` + FilePrefixName string `json:"file_prefix_name"` + TrackerName string `json:"tracker_name"` + SimpleMessageNotification SimpleMessageNotification `json:"smn"` +} + +// Extract will get the tracker object from the commonResult +func (r commonResult) Extract() (*Tracker, error) { + var s Tracker + err := r.ExtractInto(&s) + return &s, err +} + +type TrackerPage struct { + pagination.LinkedPageBase +} + +// ExtractTracker accepts a Page struct, specifically a TrackerPage struct, +// and extracts the elements into a slice of Tracker structs. In other words, +// a generic collection is mapped into a relevant slice. +func (r commonResult) ExtractTracker() ([]Tracker, error) { + var s []Tracker + err := r.ExtractInto(&s) + if err != nil { + return nil, err + } + + return s, nil + +} + +type commonResult struct { + golangsdk.Result +} + +type CreateResult struct { + commonResult +} + +type UpdateResult struct { + commonResult +} + +type DeleteResult struct { + golangsdk.ErrResult +} +type ListResult struct { + commonResult +} diff --git a/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/urls.go b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/urls.go new file mode 100644 index 0000000000..54d5826803 --- /dev/null +++ b/vendor/github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker/urls.go @@ -0,0 +1,14 @@ +package tracker + +import "github.com/huaweicloud/golangsdk" + +const rootPath = "tracker" +const trackerName = "system" + +func rootURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL(rootPath) +} + +func resourceURL(c *golangsdk.ServiceClient) string { + return c.ServiceURL(rootPath, trackerName) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 9114efb4d9..83e6acf0fe 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -542,10 +542,10 @@ "revisionTime": "2018-09-28T08:16:35Z" }, { - "checksumSHA1": "/jBVXITeGDO3ZvgO0M6GGTsBbjc=", + "checksumSHA1": "bcqYL0ILge3Hjxtii7h99crZ8+4=", "path": "github.com/huaweicloud/golangsdk/openstack", - "revision": "02234c041f693ec39067f110661bb38680003a7c", - "revisionTime": "2018-09-28T08:16:35Z" + "revision": "60672b79c76a4eec63f32293ce30b4119365e1bc", + "revisionTime": "2018-11-08T02:36:44Z" }, { "checksumSHA1": "/2W0SIigiurtg1dW3Pyz+x4F24k=", @@ -673,6 +673,12 @@ "revision": "75837c0e32c3577a74950b521e3ad3aaec05b34b", "revisionTime": "2018-09-11T07:04:38Z" }, + { + "checksumSHA1": "OScfh+YPl7cqQQrUv7n5jeT7Vt0=", + "path": "github.com/huaweicloud/golangsdk/openstack/cts/v1/tracker", + "revision": "60672b79c76a4eec63f32293ce30b4119365e1bc", + "revisionTime": "2018-11-08T02:36:44Z" + }, { "checksumSHA1": "bndllnyp7+JlhisoXzhyStpRP+4=", "path": "github.com/huaweicloud/golangsdk/openstack/dms/v1/availablezones", @@ -760,8 +766,8 @@ { "checksumSHA1": "JRRYtYkrco9209oThCcF5MEPIII=", "path": "github.com/huaweicloud/golangsdk/openstack/kms/v1/keys", - "revision": "02234c041f693ec39067f110661bb38680003a7c", - "revisionTime": "2018-09-28T08:16:35Z" + "revision": "60672b79c76a4eec63f32293ce30b4119365e1bc", + "revisionTime": "2018-11-08T02:36:44Z" }, { "checksumSHA1": "S03meuz/zX857hIqfpgyCUfrcFs=", diff --git a/website/docs/d/cts_tracker_v1.html.markdown b/website/docs/d/cts_tracker_v1.html.markdown new file mode 100644 index 0000000000..dbf2f7f251 --- /dev/null +++ b/website/docs/d/cts_tracker_v1.html.markdown @@ -0,0 +1,51 @@ +--- +layout: "huaweicloud" +page_title: "HuaweiCloud: huaweicloud_cts_tracker_v1" +sidebar_current: "docs-huaweicloud-datasource-cts-tracker-v1" +description: |- + CTS tracker allows you to collect, store, and query cloud resource operation records and use these records for security analysis, compliance auditing, resource tracking, and fault locating. +--- + +# Data Source: huaweicloud_cts_tracker_v1 + +CTS Tracker data source allows access of Cloud Tracker. + +## Example Usage + + +```hcl +variable "bucket_name" { } + +data "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${var.bucket_name}" +} + +``` + +## Argument Reference +The following arguments are supported: + +* `tracker_name` - (Optional) The tracker name. + +* `bucket_name` - (Optional) The OBS bucket name for a tracker. + +* `file_prefix_name` - (Optional) The prefix of a log that needs to be stored in an OBS bucket. + +* `status` - (Optional) Status of a tracker. + + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `is_support_smn` -Specifies SMN support. + +* `topic_id` - The theme of the SMN service. + +* `operations` -The trigger conditions for sending a notification + +* `is_send_all_key_operation` - Specifies Typical or All operations for Trigger Condition. + +* `need_notify_user_list` - The users using the login function. + + \ No newline at end of file diff --git a/website/docs/r/cts_tracker_v1.html.markdown b/website/docs/r/cts_tracker_v1.html.markdown new file mode 100644 index 0000000000..4ce1752bd6 --- /dev/null +++ b/website/docs/r/cts_tracker_v1.html.markdown @@ -0,0 +1,67 @@ +--- +layout: "huaweicloud" +page_title: "HuaweiCloud: resource_huaweicloud_cts_tracker_v1" +sidebar_current: "docs-huaweicloud-resource-cts-tracker-v1" +description: |- + CTS tracker allows you to collect, store, and query cloud resource operation records and use these records for security analysis, compliance auditing, resource tracking, and fault locating. +--- + +# huaweicloud_cts_tracker_v1 + +Allows you to collect, store, and query cloud resource operation records. + +## Example Usage + + ```hcl + variable "bucket_name" { } + variable "topic_id" { } + + resource "huaweicloud_cts_tracker_v1" "tracker_v1" { + bucket_name = "${var.bucket_name}" + file_prefix_name = "yO8Q" + is_support_smn = true + topic_id = "${var.topic_id}" + is_send_all_key_operation = false + operations = ["login"] + need_notify_user_list = ["user1"] + } + + ``` +## Argument Reference +The following arguments are supported: + +* `bucket_name` - (Required) The OBS bucket name for a tracker. + +* `file_prefix_name` - (Optional) The prefix of a log that needs to be stored in an OBS bucket. + +* `is_support_smn` - (Required) Specifies whether SMN is supported. When the value is false, topic_id and operations can be left empty. + +* `topic_id` - (Required)The theme of the SMN service, Is obtained from SMN and in the format of **urn:smn:([a-z]|[A-Z]|[0-9]|\-){1,32}:([a-z]|[A-Z]|[0-9]){32}:([a-z]|[A-Z]|[0-9]|\-|\_){1,256}**. + +* `operations` - (Required) Trigger conditions for sending a notification. + +* `is_send_all_key_operation` - (Required) When the value is **false**, operations cannot be left empty. + +* `need_notify_user_list` - (Optional) The users using the login function. When these users log in, notifications will be sent. + + + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: + +* `status` - The status of a tracker. The value is **enabled**. + +* `tracker_name` - The tracker name. Currently, only tracker **system** is available. + + +## Import + +CTS tracker can be imported using `tracker_name`, e.g. + +``` +$ terraform import huaweicloud_cts_tracker_v1.tracker system +``` + + + + diff --git a/website/huaweicloud.erb b/website/huaweicloud.erb index 43845e320c..8d1c1c332e 100644 --- a/website/huaweicloud.erb +++ b/website/huaweicloud.erb @@ -79,6 +79,9 @@