diff --git a/pkg/config-api-provider/provider/data-sources/wired_network.go b/pkg/config-api-provider/provider/data-sources/wired_network.go new file mode 100644 index 00000000..e3f6e42b --- /dev/null +++ b/pkg/config-api-provider/provider/data-sources/wired_network.go @@ -0,0 +1,107 @@ +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" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ datasource.DataSource = &wiredNetworkDataSource{} + _ datasource.DataSourceWithConfigure = &wiredNetworkDataSource{} +) + +func NewWiredNetworkDataSource() datasource.DataSource { + return &wiredNetworkDataSource{} +} + +type wiredNetworkDataSource struct { + client *config_api_client.APIClient +} + +type wiredNetworkDataSourceModel struct { + ID types.String `tfsdk:"id"` + Filter struct { + WiredNetworkID string `tfsdk:"wired_network_id"` + } `tfsdk:"filter"` +} + +func (d *wiredNetworkDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_wired_network" +} + +func (d *wiredNetworkDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "filter": schema.SingleNestedAttribute{ + Required: true, + Attributes: map[string]schema.Attribute{ + "wired_network_id": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + } +} + +func (d *wiredNetworkDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state wiredNetworkDataSourceModel + + // Read configuration from request + diags := req.Config.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + networkResponse, _, err := d.client.ConfigurationAPI. + GetConfigurationAppV1WiredNetworksGet(context.Background()). + Uid(state.Filter.WiredNetworkID). + Execute() + + if err != nil || len(networkResponse.WiredNetworks) != 1 { + resp.Diagnostics.AddError( + "Error reading Wired Network", + "Could not retrieve Wired Network, unexpected error: "+err.Error(), + ) + return + } + + network := networkResponse.WiredNetworks[0] + state.ID = types.StringValue(network.Uid) + + // Set state + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (d *wiredNetworkDataSource) 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: Wired Network. Please report this issue to the provider developers.", + ) + return + } + + d.client = client +} diff --git a/pkg/config-api-provider/provider/data-sources/wireless_network.go b/pkg/config-api-provider/provider/data-sources/wireless_network.go new file mode 100644 index 00000000..fb247a40 --- /dev/null +++ b/pkg/config-api-provider/provider/data-sources/wireless_network.go @@ -0,0 +1,107 @@ +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" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ datasource.DataSource = &wirelessNetworkDataSource{} + _ datasource.DataSourceWithConfigure = &wirelessNetworkDataSource{} +) + +func NewWirelessNetworkDataSource() datasource.DataSource { + return &wirelessNetworkDataSource{} +} + +type wirelessNetworkDataSource struct { + client *config_api_client.APIClient +} + +type wirelessNetworkDataSourceModel struct { + ID types.String `tfsdk:"id"` + Filter struct { + WirelessNetworkID string `tfsdk:"wireless_network_id"` + } `tfsdk:"filter"` +} + +func (d *wirelessNetworkDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_wireless_network" +} + +func (d *wirelessNetworkDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "filter": schema.SingleNestedAttribute{ + Required: true, + Attributes: map[string]schema.Attribute{ + "wireless_network_id": schema.StringAttribute{ + Required: true, + }, + }, + }, + }, + } +} + +func (d *wirelessNetworkDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state wirelessNetworkDataSourceModel + + // Read configuration from request + diags := req.Config.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + networkResponse, _, err := d.client.ConfigurationAPI. + GetConfigurationAppV1WirelessNetworksGet(context.Background()). + Uid(state.Filter.WirelessNetworkID). + Execute() + + if err != nil || len(networkResponse.WirelessNetworks) != 1 { + resp.Diagnostics.AddError( + "Error reading Wireless Network", + "Could not retrieve Wireless Network, unexpected error: "+err.Error(), + ) + return + } + + network := networkResponse.WirelessNetworks[0] + state.ID = types.StringValue(network.Uid) + + // Set state + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (d *wirelessNetworkDataSource) 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: Wireless Network. Please report this issue to the provider developers.", + ) + return + } + + d.client = client +} diff --git a/pkg/config-api-provider/provider/provider.go b/pkg/config-api-provider/provider/provider.go index bb81bc4c..1fa217ee 100644 --- a/pkg/config-api-provider/provider/provider.go +++ b/pkg/config-api-provider/provider/provider.go @@ -156,6 +156,8 @@ func (p *uxiConfigurationProvider) Configure(ctx context.Context, req provider.C func (p *uxiConfigurationProvider) DataSources(_ context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ datasources.NewGroupDataSource, + datasources.NewWiredNetworkDataSource, + datasources.NewWirelessNetworkDataSource, } } diff --git a/pkg/config-api-provider/test/data_source_wired_group_test.go b/pkg/config-api-provider/test/data_source_wired_group_test.go new file mode 100644 index 00000000..078f1b0c --- /dev/null +++ b/pkg/config-api-provider/test/data_source_wired_group_test.go @@ -0,0 +1,39 @@ +package test + +import ( + "testing" + + "github.com/h2non/gock" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestWiredNetworkDataSource(t *testing.T) { + defer gock.Off() + MockOAuth() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + PreConfig: func() { + MockGetWiredNetwork( + "uid", + GenerateWiredNetworkPaginatedResponse([]map[string]interface{}{GenerateWiredNetworkResponse("uid", "")}), + 3, + ) + }, + Config: providerConfig + ` + data "uxi_wired_network" "my_wired_network" { + filter = { + wired_network_id = "uid" + } + } + `, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.uxi_wired_network.my_wired_network", "id", "uid"), + ), + }, + }, + }) +} diff --git a/pkg/config-api-provider/test/data_source_wireless_group_test.go b/pkg/config-api-provider/test/data_source_wireless_group_test.go new file mode 100644 index 00000000..ab3028ab --- /dev/null +++ b/pkg/config-api-provider/test/data_source_wireless_group_test.go @@ -0,0 +1,39 @@ +package test + +import ( + "testing" + + "github.com/h2non/gock" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestWirelessNetworkDataSource(t *testing.T) { + defer gock.Off() + MockOAuth() + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + PreConfig: func() { + MockGetWirelessNetwork( + "uid", + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), + 3, + ) + }, + Config: providerConfig + ` + data "uxi_wireless_network" "my_wireless_network" { + filter = { + wireless_network_id = "uid" + } + } + `, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.uxi_wireless_network.my_wireless_network", "id", "uid"), + ), + }, + }, + }) +} diff --git a/pkg/config-api-provider/test/network_group_assignment_test.go b/pkg/config-api-provider/test/network_group_assignment_test.go index 80a44c32..3e45da7e 100644 --- a/pkg/config-api-provider/test/network_group_assignment_test.go +++ b/pkg/config-api-provider/test/network_group_assignment_test.go @@ -214,7 +214,7 @@ func TestNetworkGroupAssignmentResource(t *testing.T) { // required for network import MockGetWirelessNetwork( "network_uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("network_uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("network_uid", "")}), 2, ) // required for group create @@ -271,12 +271,12 @@ func TestNetworkGroupAssignmentResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "network_uid_2", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("network_uid_2", "_2")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("network_uid_2", "_2")}), 2, ) MockGetWirelessNetwork( "network_uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("network_uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("network_uid", "")}), 2, ) @@ -355,12 +355,12 @@ func TestNetworkGroupAssignmentResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "network_uid_2", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("network_uid_2", "_2")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("network_uid_2", "_2")}), 1, ) MockGetWirelessNetwork( "network_uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("network_uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("network_uid", "")}), 1, ) MockGetGroup("group_uid", GenerateGroupPaginatedResponse( diff --git a/pkg/config-api-provider/test/utils.go b/pkg/config-api-provider/test/utils.go index a2228cef..fe1b5e8b 100644 --- a/pkg/config-api-provider/test/utils.go +++ b/pkg/config-api-provider/test/utils.go @@ -104,7 +104,7 @@ func GenerateWiredNetworkPaginatedResponse(wiredNetworks []map[string]interface{ } } -func GenerateWirelessNetworkResponseModel(uid string, postfix string) map[string]interface{} { +func GenerateWirelessNetworkResponse(uid string, postfix string) map[string]interface{} { return map[string]interface{}{ "uid": uid, "ssid": "ssid" + postfix, diff --git a/pkg/config-api-provider/test/wireless_network_test.go b/pkg/config-api-provider/test/wireless_network_test.go index 6243fda2..0493ec15 100644 --- a/pkg/config-api-provider/test/wireless_network_test.go +++ b/pkg/config-api-provider/test/wireless_network_test.go @@ -34,7 +34,7 @@ func TestWirelessNetworkResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), 2, ) }, @@ -58,7 +58,7 @@ func TestWirelessNetworkResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), 1, ) }, @@ -71,7 +71,7 @@ func TestWirelessNetworkResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), 1, ) }, @@ -86,7 +86,7 @@ func TestWirelessNetworkResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), 1, ) }, @@ -98,7 +98,7 @@ func TestWirelessNetworkResource(t *testing.T) { PreConfig: func() { MockGetWirelessNetwork( "uid", - GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponseModel("uid", "")}), + GenerateWirelessNetworkPaginatedResponse([]map[string]interface{}{GenerateWirelessNetworkResponse("uid", "")}), 1, ) },