feat: add cidr_list attribute to stackit_public_ip_ranges datasource (#1001)
* feat: add cidr_list attribute to stackit_public_ip_ranges datasource Signed-off-by: Mauritz Uphoff <mauritz.uphoff@stackit.cloud>
This commit is contained in:
parent
800c18fa0b
commit
fcc7a99488
6 changed files with 188 additions and 3 deletions
|
|
@ -14,6 +14,22 @@ A list of all public IP ranges that STACKIT uses.
|
||||||
|
|
||||||
```terraform
|
```terraform
|
||||||
data "stackit_public_ip_ranges" "example" {}
|
data "stackit_public_ip_ranges" "example" {}
|
||||||
|
|
||||||
|
# example usage: allow stackit services and customer vpn cidr to access observability apis
|
||||||
|
locals {
|
||||||
|
vpn_cidrs = ["X.X.X.X/32", "X.X.X.X/24"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "stackit_observability_instance" "example" {
|
||||||
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
name = "example-instance"
|
||||||
|
plan_name = "Observability-Monitoring-Medium-EU01"
|
||||||
|
# Allow all stackit services and customer vpn cidr to access observability apis
|
||||||
|
acl = concat(data.stackit_public_ip_ranges.example.cidr_list, local.vpn_cidrs)
|
||||||
|
metrics_retention_days = 90
|
||||||
|
metrics_retention_days_5m_downsampling = 90
|
||||||
|
metrics_retention_days_1h_downsampling = 90
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- schema generated by tfplugindocs -->
|
<!-- schema generated by tfplugindocs -->
|
||||||
|
|
@ -21,6 +37,7 @@ data "stackit_public_ip_ranges" "example" {}
|
||||||
|
|
||||||
### Read-Only
|
### Read-Only
|
||||||
|
|
||||||
|
- `cidr_list` (List of String) A list of IP range strings (CIDRs) extracted from the public_ip_ranges for easy consumption.
|
||||||
- `id` (String) Terraform's internal resource ID. It takes the values of "`public_ip_ranges.*.cidr`".
|
- `id` (String) Terraform's internal resource ID. It takes the values of "`public_ip_ranges.*.cidr`".
|
||||||
- `public_ip_ranges` (Attributes List) A list of all public IP ranges. (see [below for nested schema](#nestedatt--public_ip_ranges))
|
- `public_ip_ranges` (Attributes List) A list of all public IP ranges. (see [below for nested schema](#nestedatt--public_ip_ranges))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,17 @@
|
||||||
data "stackit_public_ip_ranges" "example" {}
|
data "stackit_public_ip_ranges" "example" {}
|
||||||
|
|
||||||
|
# example usage: allow stackit services and customer vpn cidr to access observability apis
|
||||||
|
locals {
|
||||||
|
vpn_cidrs = ["X.X.X.X/32", "X.X.X.X/24"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "stackit_observability_instance" "example" {
|
||||||
|
project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
name = "example-instance"
|
||||||
|
plan_name = "Observability-Monitoring-Medium-EU01"
|
||||||
|
# Allow all stackit services and customer vpn cidr to access observability apis
|
||||||
|
acl = concat(data.stackit_public_ip_ranges.example.cidr_list, local.vpn_cidrs)
|
||||||
|
metrics_retention_days = 90
|
||||||
|
metrics_retention_days_5m_downsampling = 90
|
||||||
|
metrics_retention_days_1h_downsampling = 90
|
||||||
|
}
|
||||||
|
|
@ -38,6 +38,9 @@ var (
|
||||||
//go:embed testdata/datasource-image-v2-variants.tf
|
//go:embed testdata/datasource-image-v2-variants.tf
|
||||||
dataSourceImageVariants string
|
dataSourceImageVariants string
|
||||||
|
|
||||||
|
//go:embed testdata/datasource-public-ip-ranges.tf
|
||||||
|
datasourcePublicIpRanges string
|
||||||
|
|
||||||
//go:embed testdata/resource-image-min.tf
|
//go:embed testdata/resource-image-min.tf
|
||||||
resourceImageMinConfig string
|
resourceImageMinConfig string
|
||||||
|
|
||||||
|
|
@ -4159,6 +4162,25 @@ func TestAccImageV2DatasourceSearchVariants(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccDatasourcePublicIpRanges(t *testing.T) {
|
||||||
|
t.Log("TestDataSource STACKIT Public Ip Ranges")
|
||||||
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
|
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
// Read
|
||||||
|
{
|
||||||
|
ConfigVariables: config.Variables{},
|
||||||
|
Config: fmt.Sprintf("%s\n%s", datasourcePublicIpRanges, testutil.IaaSProviderConfig()),
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttrSet("data.stackit_public_ip_ranges.example", "id"),
|
||||||
|
resource.TestCheckResourceAttrSet("data.stackit_public_ip_ranges.example", "public_ip_ranges.0.cidr"),
|
||||||
|
resource.TestCheckResourceAttrSet("data.stackit_public_ip_ranges.example", "cidr_list.0"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccProject(t *testing.T) {
|
func TestAccProject(t *testing.T) {
|
||||||
projectId := testutil.ProjectId
|
projectId := testutil.ProjectId
|
||||||
resource.ParallelTest(t, resource.TestCase{
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ type publicIpRangesDataSource struct {
|
||||||
type Model struct {
|
type Model struct {
|
||||||
Id types.String `tfsdk:"id"` // needed by TF
|
Id types.String `tfsdk:"id"` // needed by TF
|
||||||
PublicIpRanges types.List `tfsdk:"public_ip_ranges"`
|
PublicIpRanges types.List `tfsdk:"public_ip_ranges"`
|
||||||
|
CidrList types.List `tfsdk:"cidr_list"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var publicIpRangesTypes = map[string]attr.Type{
|
var publicIpRangesTypes = map[string]attr.Type{
|
||||||
|
|
@ -97,6 +98,11 @@ func (d *publicIpRangesDataSource) Schema(_ context.Context, _ datasource.Schema
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"cidr_list": schema.ListAttribute{
|
||||||
|
Description: "A list of IP range strings (CIDRs) extracted from the public_ip_ranges for easy consumption.",
|
||||||
|
ElementType: types.StringType,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,18 +161,19 @@ func mapFields(ctx context.Context, publicIpRangeResp *iaas.PublicNetworkListRes
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapPublicIpRanges map the response publicIpRanges to the model
|
// mapPublicIpRanges map the response publicIpRanges to the model
|
||||||
func mapPublicIpRanges(_ context.Context, publicIpRanges *[]iaas.PublicNetwork, model *Model) error {
|
func mapPublicIpRanges(ctx context.Context, publicIpRanges *[]iaas.PublicNetwork, model *Model) error {
|
||||||
if publicIpRanges == nil {
|
if publicIpRanges == nil {
|
||||||
return fmt.Errorf("publicIpRanges input is nil")
|
return fmt.Errorf("publicIpRanges input is nil")
|
||||||
}
|
}
|
||||||
if len(*publicIpRanges) == 0 {
|
if len(*publicIpRanges) == 0 {
|
||||||
model.PublicIpRanges = types.ListNull(types.ObjectType{AttrTypes: publicIpRangesTypes})
|
model.PublicIpRanges = types.ListNull(types.ObjectType{AttrTypes: publicIpRangesTypes})
|
||||||
|
model.CidrList = types.ListNull(types.StringType)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var apiIpRanges []string
|
var apiIpRanges []string
|
||||||
for _, ipRange := range *publicIpRanges {
|
for _, ipRange := range *publicIpRanges {
|
||||||
if ipRange.Cidr != nil || *ipRange.Cidr != "" {
|
if ipRange.Cidr != nil && *ipRange.Cidr != "" {
|
||||||
apiIpRanges = append(apiIpRanges, *ipRange.Cidr)
|
apiIpRanges = append(apiIpRanges, *ipRange.Cidr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -197,5 +204,12 @@ func mapPublicIpRanges(_ context.Context, publicIpRanges *[]iaas.PublicNetwork,
|
||||||
}
|
}
|
||||||
|
|
||||||
model.PublicIpRanges = ipRangesTF
|
model.PublicIpRanges = ipRangesTF
|
||||||
|
|
||||||
|
cidrListTF, diags := types.ListValueFrom(ctx, types.StringType, apiIpRanges)
|
||||||
|
if diags.HasError() {
|
||||||
|
return core.DiagsToError(diags)
|
||||||
|
}
|
||||||
|
model.CidrList = cidrListTF
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
115
stackit/internal/services/iaas/publicipranges/datasource_test.go
Normal file
115
stackit/internal/services/iaas/publicipranges/datasource_test.go
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
package publicipranges
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
coreUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
|
||||||
|
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMapPublicIpRanges(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input *[]iaas.PublicNetwork
|
||||||
|
expected Model
|
||||||
|
isValid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil input should return error",
|
||||||
|
input: nil,
|
||||||
|
isValid: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty input should return nulls",
|
||||||
|
input: &[]iaas.PublicNetwork{},
|
||||||
|
expected: Model{
|
||||||
|
PublicIpRanges: types.ListNull(types.ObjectType{AttrTypes: publicIpRangesTypes}),
|
||||||
|
CidrList: types.ListNull(types.StringType),
|
||||||
|
},
|
||||||
|
isValid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid cidr entries",
|
||||||
|
input: &[]iaas.PublicNetwork{
|
||||||
|
{Cidr: coreUtils.Ptr("192.168.0.0/24")},
|
||||||
|
{Cidr: coreUtils.Ptr("192.168.1.0/24")},
|
||||||
|
},
|
||||||
|
expected: func() Model {
|
||||||
|
cidrs := []string{"192.168.0.0/24", "192.168.1.0/24"}
|
||||||
|
ipRangesList := make([]attr.Value, 0, len(cidrs))
|
||||||
|
for _, cidr := range cidrs {
|
||||||
|
ipRange, _ := types.ObjectValue(publicIpRangesTypes, map[string]attr.Value{
|
||||||
|
"cidr": types.StringValue(cidr),
|
||||||
|
})
|
||||||
|
ipRangesList = append(ipRangesList, ipRange)
|
||||||
|
}
|
||||||
|
ipRangesVal, _ := types.ListValue(types.ObjectType{AttrTypes: publicIpRangesTypes}, ipRangesList)
|
||||||
|
cidrListVal, _ := types.ListValueFrom(ctx, types.StringType, cidrs)
|
||||||
|
|
||||||
|
return Model{
|
||||||
|
PublicIpRanges: ipRangesVal,
|
||||||
|
CidrList: cidrListVal,
|
||||||
|
Id: utils.BuildInternalTerraformId(cidrs...),
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
isValid: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "filter out empty CIDRs",
|
||||||
|
input: &[]iaas.PublicNetwork{
|
||||||
|
{Cidr: coreUtils.Ptr("")},
|
||||||
|
{Cidr: nil},
|
||||||
|
{Cidr: coreUtils.Ptr("10.0.0.0/8")},
|
||||||
|
},
|
||||||
|
expected: func() Model {
|
||||||
|
cidrs := []string{"10.0.0.0/8"}
|
||||||
|
ipRange, _ := types.ObjectValue(publicIpRangesTypes, map[string]attr.Value{
|
||||||
|
"cidr": types.StringValue("10.0.0.0/8"),
|
||||||
|
})
|
||||||
|
ipRangesVal, _ := types.ListValue(types.ObjectType{AttrTypes: publicIpRangesTypes}, []attr.Value{ipRange})
|
||||||
|
cidrListVal, _ := types.ListValueFrom(ctx, types.StringType, cidrs)
|
||||||
|
return Model{
|
||||||
|
PublicIpRanges: ipRangesVal,
|
||||||
|
CidrList: cidrListVal,
|
||||||
|
Id: utils.BuildInternalTerraformId(cidrs...),
|
||||||
|
}
|
||||||
|
}(),
|
||||||
|
isValid: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var model Model
|
||||||
|
err := mapPublicIpRanges(ctx, tt.input, &model)
|
||||||
|
|
||||||
|
if !tt.isValid {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error but got nil")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(tt.expected.Id, model.Id); diff != "" {
|
||||||
|
t.Errorf("ID does not match:\n%s", diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(tt.expected.CidrList, model.CidrList); diff != "" {
|
||||||
|
t.Errorf("cidr_list does not match:\n%s", diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(tt.expected.PublicIpRanges, model.PublicIpRanges); diff != "" {
|
||||||
|
t.Errorf("public_ip_ranges does not match:\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
1
stackit/internal/services/iaas/testdata/datasource-public-ip-ranges.tf
vendored
Normal file
1
stackit/internal/services/iaas/testdata/datasource-public-ip-ranges.tf
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
data "stackit_public_ip_ranges" "example" {}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue