From db0eec0f6da1248607b0cdc4433efb00a45e97f6 Mon Sep 17 00:00:00 2001 From: Carlos Gajardo Date: Fri, 15 Mar 2024 11:50:28 -0300 Subject: [PATCH] Migrate data source licenses --- pagerduty/data_source_pagerduty_licenses.go | 1 + pagerduty/provider.go | 1 + .../data_source_pagerduty_license.go | 30 ++-- .../data_source_pagerduty_licenses.go | 131 ++++++++++++++++++ .../data_source_pagerduty_licenses_test.go | 10 +- pagerdutyplugin/provider.go | 1 + 6 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 pagerdutyplugin/data_source_pagerduty_licenses.go rename {pagerduty => pagerdutyplugin}/data_source_pagerduty_licenses_test.go (89%) diff --git a/pagerduty/data_source_pagerduty_licenses.go b/pagerduty/data_source_pagerduty_licenses.go index 3310a3b83..04cc68f19 100644 --- a/pagerduty/data_source_pagerduty_licenses.go +++ b/pagerduty/data_source_pagerduty_licenses.go @@ -11,6 +11,7 @@ import ( "github.com/heimweh/go-pagerduty/pagerduty" ) +// Deprecated: Migrated to pagerdutyplugin.dataSourceLicenses. Kept for testing purposes. func dataSourcePagerDutyLicenses() *schema.Resource { return &schema.Resource{ Read: dataSourcePagerDutyLicensesRead, diff --git a/pagerduty/provider.go b/pagerduty/provider.go index bcbc8e2b0..ca29bec28 100644 --- a/pagerduty/provider.go +++ b/pagerduty/provider.go @@ -154,6 +154,7 @@ func Provider(isMux bool) *schema.Provider { if isMux { delete(p.DataSourcesMap, "pagerduty_business_service") + delete(p.DataSourcesMap, "pagerduty_licenses") delete(p.DataSourcesMap, "pagerduty_service") delete(p.DataSourcesMap, "pagerduty_service_integration") diff --git a/pagerdutyplugin/data_source_pagerduty_license.go b/pagerdutyplugin/data_source_pagerduty_license.go index ed69d4bbb..72e661a3c 100644 --- a/pagerdutyplugin/data_source_pagerduty_license.go +++ b/pagerdutyplugin/data_source_pagerduty_license.go @@ -26,21 +26,21 @@ func (*dataSourceLicense) Metadata(ctx context.Context, req datasource.MetadataR } func (*dataSourceLicense) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = schema.Schema{ - Attributes: map[string]schema.Attribute{ - "id": schema.StringAttribute{Optional: true, Computed: true}, - "name": schema.StringAttribute{Optional: true, Computed: true}, - "description": schema.StringAttribute{Optional: true, Computed: true}, - "type": schema.StringAttribute{Computed: true}, - "summary": schema.StringAttribute{Computed: true}, - "role_group": schema.StringAttribute{Computed: true}, - "current_value": schema.Int64Attribute{Computed: true}, - "allocations_available": schema.Int64Attribute{Computed: true}, - "valid_roles": schema.ListAttribute{Computed: true, ElementType: types.StringType}, - "self": schema.StringAttribute{Computed: true}, - "html_url": schema.StringAttribute{Computed: true}, - }, - } + resp.Schema = schema.Schema{Attributes: dataSourceLicenseAttributes} +} + +var dataSourceLicenseAttributes = map[string]schema.Attribute{ + "id": schema.StringAttribute{Optional: true, Computed: true}, + "name": schema.StringAttribute{Optional: true, Computed: true}, + "description": schema.StringAttribute{Optional: true, Computed: true}, + "type": schema.StringAttribute{Computed: true}, + "summary": schema.StringAttribute{Computed: true}, + "role_group": schema.StringAttribute{Computed: true}, + "current_value": schema.Int64Attribute{Computed: true}, + "allocations_available": schema.Int64Attribute{Computed: true}, + "valid_roles": schema.ListAttribute{Computed: true, ElementType: types.StringType}, + "self": schema.StringAttribute{Computed: true}, + "html_url": schema.StringAttribute{Computed: true}, } func (d *dataSourceLicense) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { diff --git a/pagerdutyplugin/data_source_pagerduty_licenses.go b/pagerdutyplugin/data_source_pagerduty_licenses.go new file mode 100644 index 000000000..6697d908d --- /dev/null +++ b/pagerdutyplugin/data_source_pagerduty_licenses.go @@ -0,0 +1,131 @@ +package pagerduty + +import ( + "context" + "log" + "time" + + "github.com/PagerDuty/go-pagerduty" + "github.com/PagerDuty/terraform-provider-pagerduty/util" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/id" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" +) + +type dataSourceLicenses struct{ client *pagerduty.Client } + +var _ datasource.DataSourceWithConfigure = (*dataSourceLicenses)(nil) + +func (*dataSourceLicenses) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = "pagerduty_licenses" +} + +func (*dataSourceLicenses) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{Optional: true}, + "licenses": schema.ListAttribute{ + Computed: true, + // NestedObject: schema.NestedAttributeObject{ Attributes: dataSourceLicenseAttributes, }, + ElementType: licenseObjectType, + }, + }, + } +} + +func (d *dataSourceLicenses) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + resp.Diagnostics.Append(ConfigurePagerdutyClient(&d.client, req.ProviderData)...) +} + +func (d *dataSourceLicenses) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var model dataSourceLicensesModel + log.Println("[INFO] Reading PagerDuty licenses") + + diags := req.Config.Get(ctx, &model) + if resp.Diagnostics.Append(diags...); diags.HasError() { + return + } + + uid := "" + if model.ID.IsNull() { + uid = id.UniqueId() + } else { + uid = model.ID.ValueString() + } + + err := retry.RetryContext(ctx, 2*time.Minute, func() *retry.RetryError { + list, err := d.client.ListLicensesWithContext(ctx) + if err != nil { + if util.IsBadRequestError(err) { + return retry.NonRetryableError(err) + } + return retry.RetryableError(err) + } + + model = flattenLicenses(uid, list.Licenses, &resp.Diagnostics) + return nil + }) + if err != nil { + resp.Diagnostics.AddError( + "Error reading PagerDuty licenses", + err.Error(), + ) + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &model)...) +} + +type dataSourceLicensesModel struct { + ID types.String `tfsdk:"id"` + Licenses types.List `tfsdk:"licenses"` +} + +func flattenLicenses(uid string, licenses []pagerduty.License, diags *diag.Diagnostics) dataSourceLicensesModel { + elements := make([]attr.Value, 0, len(licenses)) + for _, license := range licenses { + model := flattenLicense(&license) + e, d := types.ObjectValue(licenseObjectType.AttrTypes, map[string]attr.Value{ + "id": model.ID, + "name": model.Name, + "description": model.Description, + "type": model.Type, + "summary": model.Summary, + "role_group": model.RoleGroup, + "current_value": model.CurrentValue, + "allocations_available": model.AllocationsAvailable, + "valid_roles": model.ValidRoles, + "self": model.Self, + "html_url": model.HTMLURL, + }) + diags.Append(d...) + if d.HasError() { + continue + } + elements = append(elements, e) + } + + return dataSourceLicensesModel{ + Licenses: types.ListValueMust(licenseObjectType, elements), + ID: types.StringValue(uid), + } +} + +var licenseObjectType = types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "id": types.StringType, + "name": types.StringType, + "description": types.StringType, + "type": types.StringType, + "summary": types.StringType, + "role_group": types.StringType, + "current_value": types.Int64Type, + "allocations_available": types.Int64Type, + "valid_roles": types.ListType{ElemType: types.StringType}, + "self": types.StringType, + "html_url": types.StringType, + }, +} diff --git a/pagerduty/data_source_pagerduty_licenses_test.go b/pagerdutyplugin/data_source_pagerduty_licenses_test.go similarity index 89% rename from pagerduty/data_source_pagerduty_licenses_test.go rename to pagerdutyplugin/data_source_pagerduty_licenses_test.go index b5b45e817..e7f9b75bd 100644 --- a/pagerduty/data_source_pagerduty_licenses_test.go +++ b/pagerdutyplugin/data_source_pagerduty_licenses_test.go @@ -13,8 +13,8 @@ func TestAccDataSourcePagerDutyLicenses_Basic(t *testing.T) { name := fmt.Sprintf("tf-%s", acctest.RandString(5)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(), Steps: []resource.TestStep{ { Config: testAccDataSourcePagerDutyLicensesConfig(name), @@ -30,8 +30,8 @@ func TestAccDataSourcePagerDutyLicenses_WithID(t *testing.T) { name := fmt.Sprintf("tf-%s", acctest.RandString(5)) resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: testAccProtoV5ProviderFactories(), Steps: []resource.TestStep{ { Config: testAccDataSourcePagerDutyLicensesConfigWithID(name), @@ -80,7 +80,7 @@ func testAccDataSourcePagerDutyLicensesWithID(n string, id string) resource.Test a := r.Primary.Attributes if val, ok := a["id"]; !ok || val != id { - return fmt.Errorf("Expected id to match provided value: %s", id) + return fmt.Errorf("Expected id to match provided value: %s\n%#v", id, a) } return testLicenses(a) diff --git a/pagerdutyplugin/provider.go b/pagerdutyplugin/provider.go index e63e1405b..eba69b028 100644 --- a/pagerdutyplugin/provider.go +++ b/pagerdutyplugin/provider.go @@ -56,6 +56,7 @@ func (p *Provider) DataSources(_ context.Context) [](func() datasource.DataSourc func() datasource.DataSource { return &dataSourceExtensionSchema{} }, func() datasource.DataSource { return &dataSourceIntegration{} }, func() datasource.DataSource { return &dataSourceLicense{} }, + func() datasource.DataSource { return &dataSourceLicenses{} }, func() datasource.DataSource { return &dataSourceService{} }, func() datasource.DataSource { return &dataSourceStandardsResourceScores{} }, func() datasource.DataSource { return &dataSourceStandardsResourcesScores{} },