Skip to content

Commit

Permalink
fix(resource): fix schema and add tests for resource provider
Browse files Browse the repository at this point in the history
The schema for the resource provider resource and datasources is
fixed and corresponding tests are added. Furthermore, some attribute
names were improved.

Resolves #337
  • Loading branch information
kuntzed committed Jul 27, 2023
1 parent a76fb78 commit 6d5f3c8
Show file tree
Hide file tree
Showing 14 changed files with 3,161 additions and 97 deletions.
14 changes: 9 additions & 5 deletions docs/resources/globalaccount_resource_provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,23 @@ resource "btp_globalaccount_resource_provider" "aws" {

### Required

- `id` (String) The unique technical name of the resource provider.
- `parameters` (String, Sensitive) Any relevant information about the resource provider that is not provided by other parameter values.
- `resource_provider` (String) Provider of the requested resource. Possible values are:
- `configuration` (String, Sensitive) The configuration properties for the resource provider as required by the vendor.
- `display_name` (String) The descriptive name of the resource provider.
- `provider_type` (String) The cloud vendor from which to consume services through your subscribed account. Possible values are:

| value | description |
| --- | --- |
| `AWS` | Amazon Web Services |
| `AZURE` | Microsoft Azure |
- `technical_name` (String) The unique technical name of the resource provider.

### Read-Only
### Optional

- `description` (String) The description of the resource provider.
- `display_name` (String) The descriptive name of the resource provider.

### Read-Only

- `id` (String, Deprecated) The unique technical name of the resource provider.

## Import

Expand Down
26 changes: 13 additions & 13 deletions internal/btpcli/facade_accounts_resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,39 +25,39 @@ func (f *accountsResourceProviderFacade) List(ctx context.Context) ([]provisioni
}))
}

func (f *accountsResourceProviderFacade) Get(ctx context.Context, resourceProvider string, resourceTechnicalName string) (provisioning.ResourceProviderResponseObject, CommandResponse, error) {
func (f *accountsResourceProviderFacade) Get(ctx context.Context, provider string, technicalName string) (provisioning.ResourceProviderResponseObject, CommandResponse, error) {
return doExecute[provisioning.ResourceProviderResponseObject](f.cliClient, ctx, NewGetRequest(f.getCommand(), map[string]string{
"globalAccount": f.cliClient.GetGlobalAccountSubdomain(),
"provider": resourceProvider,
"technicalName": resourceTechnicalName,
"provider": provider,
"technicalName": technicalName,
}))
}

type GlobalaccountResourceProviderCreateInput struct {
Provider string `btpcli:"provider"`
TechnicalName string `btpcli:"technicalName"`
DisplayName string `btpcli:"displayName"`
Description string `btpcli:"description"`
ConfigurationInfo string `btpcli:"configurationInfo"`
Provider string `btpcli:"provider"`
TechnicalName string `btpcli:"technicalName"`
DisplayName string `btpcli:"displayName"`
Description string `btpcli:"description"`
Configuration string `btpcli:"configurationInfo"`
Globalaccount string `btpcli:"globalAccount"`
}

func (f *accountsResourceProviderFacade) Create(ctx context.Context, args GlobalaccountResourceProviderCreateInput) (provisioning.ResourceProviderResponseObject, CommandResponse, error) {
args.Globalaccount = f.cliClient.GetGlobalAccountSubdomain()
params, err := tfutils.ToBTPCLIParamsMap(args)

if err != nil {
return provisioning.ResourceProviderResponseObject{}, CommandResponse{}, err
}

params["globalAccount"] = f.cliClient.GetGlobalAccountSubdomain()

return doExecute[provisioning.ResourceProviderResponseObject](f.cliClient, ctx, NewCreateRequest(f.getCommand(), params))
}

func (f *accountsResourceProviderFacade) Delete(ctx context.Context, resourceProvider string, resourceTechnicalName string) (provisioning.ResourceProviderResponseObject, CommandResponse, error) {
func (f *accountsResourceProviderFacade) Delete(ctx context.Context, provider string, technicalName string) (provisioning.ResourceProviderResponseObject, CommandResponse, error) {
return doExecute[provisioning.ResourceProviderResponseObject](f.cliClient, ctx, NewDeleteRequest(f.getCommand(), map[string]string{
"globalAccount": f.cliClient.GetGlobalAccountSubdomain(),
"provider": resourceProvider,
"technicalName": resourceTechnicalName,
"provider": provider,
"technicalName": technicalName,
"confirm": "true",
}))
}
28 changes: 14 additions & 14 deletions internal/btpcli/facade_accounts_resource_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ func TestAccountsResourceProviderFacade_Get(t *testing.T) {
func TestAccountsResourceProviderFacade_Create(t *testing.T) {
command := "accounts/resource-provider"

resourceProvider := "AWS"
resourceTechnicalName := "my_id"
provider := "AWS"
technicalName := "my_id"
description := "my-description"
displayName := "My display name"
configurationInfo := "{}"
configuration := "{}"

t.Run("constructs the CLI params correctly", func(t *testing.T) {
var srvCalled bool
Expand All @@ -77,21 +77,21 @@ func TestAccountsResourceProviderFacade_Create(t *testing.T) {

assertCall(t, r, command, ActionCreate, map[string]string{
"globalAccount": "795b53bb-a3f0-4769-adf0-26173282a975",
"provider": resourceProvider,
"technicalName": resourceTechnicalName,
"provider": provider,
"technicalName": technicalName,
"description": description,
"displayName": displayName,
"configurationInfo": configurationInfo,
"configurationInfo": configuration,
})
}))
defer srv.Close()

_, res, err := uut.Accounts.ResourceProvider.Create(context.TODO(), GlobalaccountResourceProviderCreateInput{
Provider: resourceProvider,
TechnicalName: resourceTechnicalName,
Description: description,
DisplayName: displayName,
ConfigurationInfo: configurationInfo,
Provider: provider,
TechnicalName: technicalName,
Description: description,
DisplayName: displayName,
Configuration: configuration,
})

if assert.True(t, srvCalled) && assert.NoError(t, err) {
Expand All @@ -103,8 +103,8 @@ func TestAccountsResourceProviderFacade_Create(t *testing.T) {
func TestAccountsResourceProviderFacade_Delete(t *testing.T) {
command := "accounts/resource-provider"

resourceProvider := "AWS"
resourceTechnicalName := "my_id"
provider := "AWS"
technicalName := "my_id"

t.Run("constructs the CLI params correctly", func(t *testing.T) {
var srvCalled bool
Expand All @@ -122,7 +122,7 @@ func TestAccountsResourceProviderFacade_Delete(t *testing.T) {
}))
defer srv.Close()

_, res, err := uut.Accounts.ResourceProvider.Delete(context.TODO(), resourceProvider, resourceTechnicalName)
_, res, err := uut.Accounts.ResourceProvider.Delete(context.TODO(), provider, technicalName)

if assert.True(t, srvCalled) && assert.NoError(t, err) {
assert.Equal(t, 200, res.StatusCode)
Expand Down
4 changes: 2 additions & 2 deletions internal/btpcli/types/provisioning/resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
)

type ResourceProviderResponseObject struct {
// Unique technical name of the resource.
ResourceTechnicalName string `json:"technicalName,omitempty"`
// Unique technical name of the resource provider.
TechnicalName string `json:"technicalName,omitempty"`
// Type of the resource.
ResourceType string `json:"resourceType,omitempty"`
// Provider of the requested resource. For example, IaaS provider: AWS.
Expand Down
20 changes: 11 additions & 9 deletions internal/provider/datasource_globalaccount_resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ You must be assigned to the global account admin or viewer role.
__Further documentation:__
<https://help.sap.com/docs/btp/sap-business-technology-platform/managing-resource-providers>`,
Attributes: map[string]schema.Attribute{
"resource_provider": schema.StringAttribute{
MarkdownDescription: "The provider of the requested resource. Possible values are: \n" +
"provider_type": schema.StringAttribute{
MarkdownDescription: "The cloud vendor from which to consume services through your subscribed account. Possible values are: \n" +
getFormattedValueAsTableRow("value", "description") +
getFormattedValueAsTableRow("---", "---") +
getFormattedValueAsTableRow("`AWS`", "Amazon Web Services") +
Expand All @@ -53,12 +53,14 @@ __Further documentation:__
stringvalidator.LengthAtLeast(1),
},
},
"id": schema.StringAttribute{
"technical_name": schema.StringAttribute{
MarkdownDescription: "The unique technical name of the resource provider.",
Required: true,
Validators: []validator.String{
stringvalidator.LengthAtLeast(1),
},
},
"id": schema.StringAttribute{
DeprecationMessage: "Use the `technical_name` attribute instead",
MarkdownDescription: "The unique technical name of the resource provider.",
Computed: true,
},
"display_name": schema.StringAttribute{
MarkdownDescription: "The descriptive name of the resource provider.",
Expand All @@ -68,8 +70,8 @@ __Further documentation:__
MarkdownDescription: "The description of the resource provider.",
Computed: true,
},
"parameters": schema.StringAttribute{
MarkdownDescription: "Shows any relevant information about the resource provider that is not provided by other parameter values.",
"configuration": schema.StringAttribute{
MarkdownDescription: "The configuration properties for the resource provider as required by the vendor.",
Computed: true,
Sensitive: true,
},
Expand All @@ -87,7 +89,7 @@ func (ds *globalaccountResourceProviderDataSource) Read(ctx context.Context, req
return
}

cliRes, _, err := ds.cli.Accounts.ResourceProvider.Get(ctx, data.ResourceProvider.ValueString(), data.Id.ValueString())
cliRes, _, err := ds.cli.Accounts.ResourceProvider.Get(ctx, data.Provider.ValueString(), data.TechnicalName.ValueString())
if err != nil {
resp.Diagnostics.AddError("API Error Reading Resource Resource Provider (Global Account)", fmt.Sprintf("%s", err))
return
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package provider

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestDataSourceGlobalaccountResourceProvider(t *testing.T) {
t.Parallel()
t.Run("happy path", func(t *testing.T) {
rec := setupVCR(t, "fixtures/datasource_globalaccount_resource_provider")
defer stopQuietly(rec)

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProtoV6ProviderFactories: getProviders(rec.GetDefaultClient()),
Steps: []resource.TestStep{
{
Config: hclProvider() + hclDatasourceGlobalaccountResourceProvider("uut",
"AWS",
"tf_test_resource_provider"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "provider_type", "AWS"),
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "technical_name", "tf_test_resource_provider"),
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "id", "tf_test_resource_provider"),
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "display_name", "Test AWS Resource Provider"),
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "description", "Description of the resource provider"),
resource.TestCheckResourceAttr("data.btp_globalaccount_resource_provider.uut", "configuration", "{\"access_key_id\":\"AWSACCESSKEY\",\"secret_access_key\":\"AWSSECRETKEY\",\"vpc_id\":\"vpc-test\",\"region\":\"eu-central-1\"}"),
),
},
},
})
})
}

func hclDatasourceGlobalaccountResourceProvider(resourceName string, provider string, technicalName string) string {
return fmt.Sprintf(`
data "btp_globalaccount_resource_provider" "%s" {
provider_type = "%s"
technical_name = "%s"
}`, resourceName, provider, technicalName)
}
58 changes: 33 additions & 25 deletions internal/provider/datasource_globalaccount_resource_providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package provider
import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
Expand All @@ -12,39 +11,40 @@ import (
)

func newGlobalaccountResourceProvidersDataSource() datasource.DataSource {
return &globalaccountGlobalaccountResourceProvidersDataSource{}
return &globalaccountResourceProvidersDataSource{}
}

type globalaccountGlobalaccountResourceProvidersValue struct {
ResourceProvider types.String `tfsdk:"resource_provider"`
Id types.String `tfsdk:"id"`
DisplayName types.String `tfsdk:"display_name"`
Description types.String `tfsdk:"description"`
type globalaccountResourceProvidersValue struct {
Provider types.String `tfsdk:"provider_type"`
TechnicalName types.String `tfsdk:"technical_name"`
DisplayName types.String `tfsdk:"display_name"`
Description types.String `tfsdk:"description"`
}

type globalaccountGlobalaccountResourceProvidersDataSourceConfig struct {
type globalaccountResourceProvidersDataSourceConfig struct {
/* INPUT */
/* OUTPUT */
Values []globalaccountGlobalaccountResourceProvidersValue `tfsdk:"values"`
Id types.String `tfsdk:"id"`
Values []globalaccountResourceProvidersValue `tfsdk:"values"`
}

type globalaccountGlobalaccountResourceProvidersDataSource struct {
type globalaccountResourceProvidersDataSource struct {
cli *btpcli.ClientFacade
}

func (ds *globalaccountGlobalaccountResourceProvidersDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
func (ds *globalaccountResourceProvidersDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = fmt.Sprintf("%s_globalaccount_resource_providers", req.ProviderTypeName)
}

func (ds *globalaccountGlobalaccountResourceProvidersDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
func (ds *globalaccountResourceProvidersDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) {
if req.ProviderData == nil {
return
}

ds.cli = req.ProviderData.(*btpcli.ClientFacade)
}

func (ds *globalaccountGlobalaccountResourceProvidersDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
func (ds *globalaccountResourceProvidersDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
MarkdownDescription: `Lists all the resource provider instances in a global account.
Expand All @@ -54,18 +54,23 @@ You must be assigned to the global account admin or viewer role.
__Further documentation:__
<https://help.sap.com/docs/btp/sap-business-technology-platform/managing-resource-providers>`,
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{ // required by hashicorps terraform plugin testing framework
DeprecationMessage: "Use the `btp_globalaccount` datasource instead",
MarkdownDescription: "The ID of the global account",
Computed: true,
},
"values": schema.ListNestedAttribute{
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"resource_provider": schema.StringAttribute{
MarkdownDescription: "The provider of the requested resource. Possible values are: \n" +
"provider_type": schema.StringAttribute{
MarkdownDescription: "The cloud vendor from which to consume services through your subscribed account. Possible values are: \n" +
getFormattedValueAsTableRow("value", "description") +
getFormattedValueAsTableRow("---", "---") +
getFormattedValueAsTableRow("`AWS`", "Amazon Web Services") +
getFormattedValueAsTableRow("`AZURE`", "Microsoft Azure"),
Computed: true,
},
"id": schema.StringAttribute{
"technical_name": schema.StringAttribute{
MarkdownDescription: "The unique technical name of the resource provider.",
Computed: true,
},
Expand All @@ -85,8 +90,8 @@ __Further documentation:__
}
}

func (ds *globalaccountGlobalaccountResourceProvidersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data globalaccountGlobalaccountResourceProvidersDataSourceConfig
func (ds *globalaccountResourceProvidersDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var data globalaccountResourceProvidersDataSourceConfig

diags := req.Config.Get(ctx, &data)

Expand All @@ -101,15 +106,18 @@ func (ds *globalaccountGlobalaccountResourceProvidersDataSource) Read(ctx contex
return
}

data.Values = []globalaccountGlobalaccountResourceProvidersValue{}
data.Id = types.StringValue(ds.cli.GetGlobalAccountSubdomain())
data.Values = []globalaccountResourceProvidersValue{}

for _, provider := range cliRes {
data.Values = append(data.Values, globalaccountGlobalaccountResourceProvidersValue{
ResourceProvider: types.StringValue(provider.ResourceProvider),
Id: types.StringValue(provider.ResourceTechnicalName),
DisplayName: types.StringValue(provider.DisplayName),
Description: types.StringValue(provider.Description),
})
resourceProvider := globalaccountResourceProvidersValue{
Provider: types.StringValue(provider.ResourceProvider),
TechnicalName: types.StringValue(provider.TechnicalName),
DisplayName: types.StringValue(provider.DisplayName),
Description: types.StringValue(provider.Description),
}

data.Values = append(data.Values, resourceProvider)
}

diags = resp.State.Set(ctx, &data)
Expand Down
Loading

0 comments on commit 6d5f3c8

Please sign in to comment.