forked from IBM-Cloud/terraform-provider-ibm
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ibm_event_streams_quota data source and resource (IBM-Cloud…
…#5610) * add ibm_event_streams_quota * review comments
- Loading branch information
Showing
9 changed files
with
727 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
ibm/service/eventstreams/data_source_ibm_event_streams_quota.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
// Copyright IBM Corp. 2024 All Rights Reserved. | ||
// Licensed under the Mozilla Public License v2.0 | ||
|
||
package eventstreams | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" | ||
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/flex" | ||
"github.com/IBM/eventstreams-go-sdk/pkg/adminrestv1" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
// A quota in an Event Streams service instance. | ||
// The ID is the CRN with the last two components "quota:entity". | ||
func DataSourceIBMEventStreamsQuota() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: dataSourceIBMEventStreamsQuotaRead, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"resource_instance_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The ID or CRN of the Event Streams service instance", | ||
}, | ||
"entity": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The entity for which the quota is set; 'default' or IAM ID", | ||
}, | ||
"producer_byte_rate": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "The producer quota in bytes per second, -1 means no quota", | ||
}, | ||
"consumer_byte_rate": { | ||
Type: schema.TypeInt, | ||
Computed: true, | ||
Description: "The consumer quota in bytes per second, -1 means no quota", | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
// read quota properties using the admin-rest API | ||
func dataSourceIBMEventStreamsQuotaRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
adminrestClient, instanceCRN, entity, err := getQuotaClientInstanceEntity(d, meta) | ||
if err != nil { | ||
tfErr := flex.TerraformErrorf(err, "Error getting Event Streams instance", "ibm_event_streams_quota", "read") | ||
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage()) | ||
return tfErr.GetDiag() | ||
} | ||
|
||
getQuotaOptions := &adminrestv1.GetQuotaOptions{} | ||
getQuotaOptions.SetEntityName(entity) | ||
quota, response, err := adminrestClient.GetQuotaWithContext(context, getQuotaOptions) | ||
if err != nil { | ||
var tfErr *flex.TerraformProblem | ||
if response != nil && response.StatusCode == 404 { | ||
tfErr = flex.TerraformErrorf(err, fmt.Sprintf("Quota for '%s' does not exist", entity), "ibm_event_streams_quota", "read") | ||
} else { | ||
tfErr = flex.TerraformErrorf(err, fmt.Sprintf("GetQuota failed with response: %s", response), "ibm_event_streams_quota", "read") | ||
} | ||
log.Printf("[DEBUG]\n%s", tfErr.GetDebugMessage()) | ||
return tfErr.GetDiag() | ||
} | ||
|
||
d.Set("resource_instance_id", instanceCRN) | ||
d.Set("entity", entity) | ||
d.Set("producer_byte_rate", getQuotaValue(quota.ProducerByteRate)) | ||
d.Set("consumer_byte_rate", getQuotaValue(quota.ConsumerByteRate)) | ||
d.SetId(getQuotaID(instanceCRN, entity)) | ||
|
||
return nil | ||
} | ||
|
||
// Returns | ||
// admin-rest client (set to use the service instance) | ||
// CRN for the service instance | ||
// entity name | ||
// Any error that occurred | ||
func getQuotaClientInstanceEntity(d *schema.ResourceData, meta interface{}) (*adminrestv1.AdminrestV1, string, string, error) { | ||
adminrestClient, err := meta.(conns.ClientSession).ESadminRestSession() | ||
if err != nil { | ||
return nil, "", "", err | ||
} | ||
instanceCRN := d.Get("resource_instance_id").(string) | ||
if instanceCRN == "" { // importing | ||
id := d.Id() | ||
crnSegments := strings.Split(id, ":") | ||
if len(crnSegments) != 10 || crnSegments[8] != "quota" || crnSegments[9] == "" { | ||
return nil, "", "", fmt.Errorf("ID '%s' is not a quota resource", id) | ||
} | ||
entity := crnSegments[9] | ||
crnSegments[8] = "" | ||
crnSegments[9] = "" | ||
instanceCRN = strings.Join(crnSegments, ":") | ||
d.Set("resource_instance_id", instanceCRN) | ||
d.Set("entity", entity) | ||
} | ||
|
||
instance, err := getInstanceDetails(instanceCRN, meta) | ||
if err != nil { | ||
return nil, "", "", err | ||
} | ||
adminURL := instance.Extensions["kafka_http_url"].(string) | ||
adminrestClient.SetServiceURL(adminURL) | ||
return adminrestClient, instanceCRN, d.Get("entity").(string), nil | ||
} | ||
|
||
func getQuotaID(instanceCRN string, entity string) string { | ||
crnSegments := strings.Split(instanceCRN, ":") | ||
crnSegments[8] = "quota" | ||
crnSegments[9] = entity | ||
return strings.Join(crnSegments, ":") | ||
} | ||
|
||
// admin-rest API returns nil for undefined rate, convert that to -1 | ||
func getQuotaValue(v *int64) int { | ||
if v == nil { | ||
return -1 | ||
} | ||
return int(*v) | ||
} |
84 changes: 84 additions & 0 deletions
84
ibm/service/eventstreams/data_source_ibm_event_streams_quota_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright IBM Corp. 2024 All Rights Reserved. | ||
// Licensed under the Mozilla Public License v2.0 | ||
|
||
package eventstreams_test | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"testing" | ||
|
||
acc "github.com/IBM-Cloud/terraform-provider-ibm/ibm/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
const ( | ||
// Data source test requires MZR instance have this quota with producer rate 10000, consumer rate 20000 | ||
testQuotaEntity1 = "iam-ServiceId-00001111-2222-3333-4444-555566667777" | ||
// Data source test requires MZR instance have this quota with producer rate 4096, consumer rate not defined | ||
testQuotaEntity2 = "iam-ServiceId-77776666-5555-4444-3333-222211110000" | ||
// Resource test requires MZR instance NOT have a quota for this | ||
testQuotaEntity3 = "iam-ServiceId-99998888-7777-6666-5555-444433332222" | ||
// Resource test requires MZR instance NOT have a quota for this | ||
testQuotaEntity4 = "default" | ||
) | ||
|
||
func TestAccIBMEventStreamsQuotaDataSource(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
Providers: acc.TestAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccCheckIBMEventStreamsQuotaDataSourceConfig(getTestInstanceName(mzrKey), testQuotaEntity1), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckIBMEventStreamsQuotaDataSourceProperties("data.ibm_event_streams_quota.es_quota", testQuotaEntity1, "10000", "20000"), | ||
), | ||
}, | ||
{ | ||
Config: testAccCheckIBMEventStreamsQuotaDataSourceConfig(getTestInstanceName(mzrKey), testQuotaEntity2), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckIBMEventStreamsQuotaDataSourceProperties("data.ibm_event_streams_quota.es_quota", testQuotaEntity2, "4096", "-1"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckIBMEventStreamsQuotaDataSourceConfig(instanceName string, entity string) string { | ||
return fmt.Sprintf(` | ||
data "ibm_resource_group" "group" { | ||
is_default=true | ||
} | ||
data "ibm_resource_instance" "es_instance" { | ||
resource_group_id = data.ibm_resource_group.group.id | ||
name = "%s" | ||
} | ||
data "ibm_event_streams_quota" "es_quota" { | ||
resource_instance_id = data.ibm_resource_instance.es_instance.id | ||
entity = "%s" | ||
}`, instanceName, entity) | ||
} | ||
|
||
// check properties of the terraform data source object | ||
func testAccCheckIBMEventStreamsQuotaDataSourceProperties(name string, entity string, producerRate string, consumerRate string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
rs, ok := s.RootModule().Resources[name] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", name) | ||
} | ||
quotaID := rs.Primary.ID | ||
if quotaID == "" { | ||
return fmt.Errorf("[ERROR] Quota ID is not set") | ||
} | ||
if !strings.HasSuffix(quotaID, fmt.Sprintf(":quota:%s", entity)) { | ||
return fmt.Errorf("[ERROR] Quota ID for %s not expected CRN", quotaID) | ||
} | ||
if producerRate != rs.Primary.Attributes["producer_byte_rate"] { | ||
return fmt.Errorf("[ERROR] Quota for %s producer_byte_rate = %s, expected %s", entity, rs.Primary.Attributes["producer_byte_rate"], producerRate) | ||
} | ||
if consumerRate != rs.Primary.Attributes["consumer_byte_rate"] { | ||
return fmt.Errorf("[ERROR] Quota for %s consumer_byte_rate = %s, expected %s", entity, rs.Primary.Attributes["consumer_byte_rate"], consumerRate) | ||
} | ||
return nil | ||
} | ||
} |
Oops, something went wrong.