Skip to content

Commit

Permalink
fix: make root node data source compatible with all nodes (#27)
Browse files Browse the repository at this point in the history
* Make rood node data source compatible with all nodes

* Add other attributes
  • Loading branch information
1riatsila1 authored Sep 16, 2024
1 parent e83c9fb commit c90a7e6
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 109 deletions.
138 changes: 138 additions & 0 deletions pkg/config-api-provider/provider/data-sources/group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package datasources

import (
"context"

config_api_client "github.com/aruba-uxi/configuration-api-terraform-provider/pkg/config-api-client"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
_ datasource.DataSource = &groupDataSource{}
_ datasource.DataSourceWithConfigure = &groupDataSource{}
)

func NewGroupDataSource() datasource.DataSource {
return &groupDataSource{}
}

type groupDataSource struct {
client *config_api_client.APIClient
}

type groupDataSourceModel struct {
ID types.String `tfsdk:"id"`
Path types.String `tfsdk:"path"`
ParentGroupID types.String `tfsdk:"parent_group_id"`
Name types.String `tfsdk:"name"`
Filter struct {
GroupID *string `tfsdk:"group_id"`
IsRoot *bool `tfsdk:"is_root"`
} `tfsdk:"filter"`
}

func (d *groupDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_group"
}

func (d *groupDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
"path": schema.StringAttribute{
Computed: true,
Optional: true,
},
"parent_group_id": schema.StringAttribute{
Computed: true,
},
"name": schema.StringAttribute{
Computed: true,
},
"filter": schema.SingleNestedAttribute{
Required: true,
Attributes: map[string]schema.Attribute{
"group_id": schema.StringAttribute{
Optional: true,
},
"is_root": schema.BoolAttribute{
Optional: true,
},
},
},
},
}
}

func (d *groupDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var state groupDataSourceModel

// Read configuration from request
diags := req.Config.Get(ctx, &state)
if state.Filter.GroupID == nil && (state.Filter.IsRoot == nil || !*state.Filter.IsRoot) {
diags.AddError("invalid Group data source", "either filter.group_id must be set or 'filter.is_root = true' is required")
} else if state.Filter.GroupID != nil && state.Filter.IsRoot != nil && *state.Filter.IsRoot {
diags.AddError("invalid Group data source", "group_id and 'is_root = true' cannot both be set")
}
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

request := d.client.ConfigurationAPI.GroupsGetConfigurationAppV1GroupsGet(context.Background())

if state.Filter.IsRoot != nil && *state.Filter.IsRoot {
request = request.Uid(*state.Filter.GroupID) // TODO: use root group filter here
} else {
request = request.Uid(*state.Filter.GroupID)
}

groupResponse, _, err := request.Execute()

if err != nil || len(groupResponse.Groups) != 1 {
resp.Diagnostics.AddError(
"Error reading Group",
"Could not retrieve Group, unexpected error: "+err.Error(),
)
return
}

group := groupResponse.Groups[0]
state.ID = types.StringValue(group.Uid)
state.Name = types.StringValue(group.Name)
state.Path = types.StringValue(group.Path)
if group.ParentUid.IsSet() {
state.ParentGroupID = types.StringValue(*group.ParentUid.Get())
}

// Set state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}

func (d *groupDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Add a nil check when handling ProviderData because Terraform
// sets that data after it calls the ConfigureProvider RPC.
if req.ProviderData == nil {
return
}

client, ok := req.ProviderData.(*config_api_client.APIClient)

if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
"Data Source type: Group. Please report this issue to the provider developers.",
)
return
}

d.client = client
}
73 changes: 0 additions & 73 deletions pkg/config-api-provider/provider/data-sources/root_group.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/config-api-provider/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (p *uxiConfigurationProvider) Configure(ctx context.Context, req provider.C
// DataSources defines the data sources implemented in the provider.
func (p *uxiConfigurationProvider) DataSources(_ context.Context) []func() datasource.DataSource {
return []func() datasource.DataSource{
datasources.NewRootGroupDataSource,
datasources.NewGroupDataSource,
datasources.NewWiredNetworkDataSource,
datasources.NewWirelessNetworkDataSource,
datasources.NewSensorGroupAssignmentDataSource,
Expand Down
86 changes: 86 additions & 0 deletions pkg/config-api-provider/test/data_source_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package test

import (
"regexp"
"testing"

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

func TestGroupDataSource(t *testing.T) {
defer gock.Off()
MockOAuth()

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
// Test no filters set
{
Config: providerConfig + `
data "uxi_group" "my_group" {
filter = {}
}
`,
ExpectError: regexp.MustCompile(`either filter.group_id must be set or 'filter.is_root = true' is required`),
},
// Test too many filters set
{
Config: providerConfig + `
data "uxi_group" "my_group" {
filter = {
is_root = true
group_id = "uid"
}
}
`,
ExpectError: regexp.MustCompile(`group_id and 'is_root = true' cannot both be set`),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.uxi_root_group.my_root_group", "id", "mock_uid"),
),
},
// Test Read, is_root not set
{
PreConfig: func() {
MockGetGroup(
"uid",
GenerateGroupPaginatedResponse([]map[string]interface{}{StructToMap(GenerateGroupResponseModel("uid", "", ""))}),
3,
)
},
Config: providerConfig + `
data "uxi_group" "my_group" {
filter = {
group_id = "uid"
}
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.uxi_group.my_group", "id", "uid"),
),
},
// Test Read, is_root is false
{
PreConfig: func() {
MockGetGroup(
"uid",
GenerateGroupPaginatedResponse([]map[string]interface{}{StructToMap(GenerateGroupResponseModel("uid", "", ""))}),
3,
)
},
Config: providerConfig + `
data "uxi_group" "my_group" {
filter = {
is_root = false
group_id = "uid"
}
}
`,
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.uxi_group.my_group", "id", "uid"),
),
},
// TODO: Test retrieving the root group
},
})
}
35 changes: 0 additions & 35 deletions pkg/config-api-provider/test/data_source_root_group_test.go

This file was deleted.

0 comments on commit c90a7e6

Please sign in to comment.