Model apps as a set instead of an ordered list #2
@@ -25,7 +25,7 @@ type secretBackendRoleResource struct {
|
|||||||
type secretBackendRoleModel struct {
|
type secretBackendRoleModel struct {
|
||||||
Backend types.String `tfsdk:"backend"`
|
Backend types.String `tfsdk:"backend"`
|
||||||
Name types.String `tfsdk:"name"`
|
Name types.String `tfsdk:"name"`
|
||||||
Apps types.List `tfsdk:"apps"`
|
Apps types.Set `tfsdk:"apps"`
|
||||||
TTL types.Int64 `tfsdk:"ttl"`
|
TTL types.Int64 `tfsdk:"ttl"`
|
||||||
MaxTTL types.Int64 `tfsdk:"max_ttl"`
|
MaxTTL types.Int64 `tfsdk:"max_ttl"`
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ func (r *secretBackendRoleResource) Schema(_ context.Context, _ resource.SchemaR
|
|||||||
stringplanmodifier.RequiresReplace(),
|
stringplanmodifier.RequiresReplace(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"apps": schema.ListAttribute{
|
"apps": schema.SetAttribute{
|
||||||
Description: "arr apps a generated key may access (subset of sonarr, radarr, prowlarr).",
|
Description: "arr apps a generated key may access (subset of sonarr, radarr, prowlarr).",
|
||||||
ElementType: types.StringType,
|
ElementType: types.StringType,
|
||||||
Required: true,
|
Required: true,
|
||||||
@@ -212,9 +212,9 @@ func applyRoleData(m *secretBackendRoleModel, role map[string]interface{}) diag.
|
|||||||
var diags diag.Diagnostics
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
apps := toStringSlice(role["apps"])
|
apps := toStringSlice(role["apps"])
|
||||||
appList, appDiags := types.ListValueFrom(context.Background(), types.StringType, apps)
|
appSet, appDiags := types.SetValueFrom(context.Background(), types.StringType, apps)
|
||||||
diags.Append(appDiags...)
|
diags.Append(appDiags...)
|
||||||
m.Apps = appList
|
m.Apps = appSet
|
||||||
|
|
||||||
if n, ok := toInt64(role["ttl"]); ok && n != 0 {
|
if n, ok := toInt64(role["ttl"]); ok && n != 0 {
|
||||||
m.TTL = types.Int64Value(n)
|
m.TTL = types.Int64Value(n)
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func listOf(t *testing.T, vals ...string) types.List {
|
func setOf(t *testing.T, vals ...string) types.Set {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
l, diags := types.ListValueFrom(context.Background(), types.StringType, vals)
|
s, diags := types.SetValueFrom(context.Background(), types.StringType, vals)
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
t.Fatalf("building list: %v", diags)
|
t.Fatalf("building set: %v", diags)
|
||||||
}
|
}
|
||||||
return l
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRoleDataOmitsUnsetTTLs(t *testing.T) {
|
func TestRoleDataOmitsUnsetTTLs(t *testing.T) {
|
||||||
m := secretBackendRoleModel{
|
m := secretBackendRoleModel{
|
||||||
Apps: listOf(t, "sonarr", "radarr", "prowlarr"),
|
Apps: setOf(t, "sonarr", "radarr", "prowlarr"),
|
||||||
TTL: types.Int64Null(),
|
TTL: types.Int64Null(),
|
||||||
MaxTTL: types.Int64Null(),
|
MaxTTL: types.Int64Null(),
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ func TestRoleDataOmitsUnsetTTLs(t *testing.T) {
|
|||||||
|
|
||||||
func TestRoleDataIncludesTTLs(t *testing.T) {
|
func TestRoleDataIncludesTTLs(t *testing.T) {
|
||||||
m := secretBackendRoleModel{
|
m := secretBackendRoleModel{
|
||||||
Apps: listOf(t, "prowlarr"),
|
Apps: setOf(t, "prowlarr"),
|
||||||
TTL: types.Int64Value(60),
|
TTL: types.Int64Value(60),
|
||||||
MaxTTL: types.Int64Value(86400),
|
MaxTTL: types.Int64Value(86400),
|
||||||
}
|
}
|
||||||
@@ -70,16 +70,34 @@ func TestApplyRoleDataMapsEngineResponse(t *testing.T) {
|
|||||||
if diags := applyRoleData(&m, role); diags.HasError() {
|
if diags := applyRoleData(&m, role); diags.HasError() {
|
||||||
t.Fatalf("applyRoleData: %v", diags)
|
t.Fatalf("applyRoleData: %v", diags)
|
||||||
}
|
}
|
||||||
var apps []string
|
if !m.Apps.Equal(setOf(t, "sonarr", "radarr", "prowlarr")) {
|
||||||
m.Apps.ElementsAs(context.Background(), &apps, false)
|
t.Errorf("apps = %v, want {sonarr radarr prowlarr}", m.Apps)
|
||||||
if len(apps) != 3 || apps[2] != "prowlarr" {
|
|
||||||
t.Errorf("apps = %v, want [sonarr radarr prowlarr]", apps)
|
|
||||||
}
|
}
|
||||||
if m.TTL.ValueInt64() != 60 || m.MaxTTL.ValueInt64() != 86400 {
|
if m.TTL.ValueInt64() != 60 || m.MaxTTL.ValueInt64() != 86400 {
|
||||||
t.Errorf("ttl/max_ttl = %d/%d, want 60/86400", m.TTL.ValueInt64(), m.MaxTTL.ValueInt64())
|
t.Errorf("ttl/max_ttl = %d/%d, want 60/86400", m.TTL.ValueInt64(), m.MaxTTL.ValueInt64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApplyRoleDataOrderInsensitive(t *testing.T) {
|
||||||
|
// The engine returns apps alphabetically sorted regardless of the order
|
||||||
|
// they were written in; the read-back must still equal the config value.
|
||||||
|
configApps := setOf(t, "sonarr", "prowlarr", "radarr")
|
||||||
|
role := map[string]interface{}{
|
||||||
|
"apps": []interface{}{"prowlarr", "radarr", "sonarr"},
|
||||||
|
}
|
||||||
|
m := secretBackendRoleModel{
|
||||||
|
Apps: configApps,
|
||||||
|
TTL: types.Int64Null(),
|
||||||
|
MaxTTL: types.Int64Null(),
|
||||||
|
}
|
||||||
|
if diags := applyRoleData(&m, role); diags.HasError() {
|
||||||
|
t.Fatalf("applyRoleData: %v", diags)
|
||||||
|
}
|
||||||
|
if !m.Apps.Equal(configApps) {
|
||||||
|
t.Errorf("apps after read-back = %v, not equal to config value %v", m.Apps, configApps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestApplyRoleDataZeroTTLLeavesNull(t *testing.T) {
|
func TestApplyRoleDataZeroTTLLeavesNull(t *testing.T) {
|
||||||
// The engine returns 0 for an unset TTL, which must not clobber the null
|
// The engine returns 0 for an unset TTL, which must not clobber the null
|
||||||
// model value into a spurious 0.
|
// model value into a spurious 0.
|
||||||
|
|||||||
Reference in New Issue
Block a user