feat: add Teleport support with unifi_setting_teleport resource (#39)
* feat: add Telepor support with `unifi_setting_teleport` resource * add cidr validators * fix teleport tests by specifying version constraints * fix teleport version needed * require version 7.1 * lint
This commit is contained in:
committed by
GitHub
parent
5da978a5d3
commit
7856ec4764
65
internal/provider/acctest/resource_setting_teleport_test.go
Normal file
65
internal/provider/acctest/resource_setting_teleport_test.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package acctest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
pt "github.com/filipowm/terraform-provider-unifi/internal/provider/testing"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/plancheck"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var settingTeleportLock = &sync.Mutex{}
|
||||||
|
|
||||||
|
func TestAccSettingTeleport(t *testing.T) {
|
||||||
|
AcceptanceTest(t, AcceptanceTestCase{
|
||||||
|
VersionConstraint: ">= 7.1",
|
||||||
|
Lock: settingTeleportLock,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccSettingTeleportConfig(true, ""),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttrSet("unifi_setting_teleport.test", "id"),
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "site", "default"),
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "enabled", "true"),
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "subnet", ""),
|
||||||
|
),
|
||||||
|
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_teleport.test", plancheck.ResourceActionCreate),
|
||||||
|
},
|
||||||
|
pt.ImportStepWithSite("unifi_setting_teleport.test"),
|
||||||
|
{
|
||||||
|
Config: testAccSettingTeleportConfig(true, "192.168.100.0/24"),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "enabled", "true"),
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "subnet", "192.168.100.0/24"),
|
||||||
|
),
|
||||||
|
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_teleport.test", plancheck.ResourceActionUpdate),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Config: testAccSettingTeleportConfigWithoutSubnet(false),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "enabled", "false"),
|
||||||
|
resource.TestCheckResourceAttr("unifi_setting_teleport.test", "subnet", ""),
|
||||||
|
),
|
||||||
|
ConfigPlanChecks: pt.CheckResourceActions("unifi_setting_teleport.test", plancheck.ResourceActionUpdate),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccSettingTeleportConfig(enabled bool, subnetCidr string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "unifi_setting_teleport" "test" {
|
||||||
|
enabled = %t
|
||||||
|
subnet = %q
|
||||||
|
}
|
||||||
|
`, enabled, subnetCidr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccSettingTeleportConfigWithoutSubnet(enabled bool) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "unifi_setting_teleport" "test" {
|
||||||
|
enabled = %t
|
||||||
|
}
|
||||||
|
`, enabled)
|
||||||
|
}
|
||||||
@@ -9,6 +9,12 @@ func asVersion(versionString string) *version.Version {
|
|||||||
return version.Must(version.NewVersion(versionString))
|
return version.Must(version.NewVersion(versionString))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsVersion converts a string version to a *version.Version
|
||||||
|
// This is a utility function for consumers of this package
|
||||||
|
func AsVersion(versionString string) *version.Version {
|
||||||
|
return asVersion(versionString)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ControllerV6 = asVersion("6.0.0")
|
ControllerV6 = asVersion("6.0.0")
|
||||||
ControllerV7 = asVersion("7.0.0")
|
ControllerV7 = asVersion("7.0.0")
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ func (p *unifiProvider) Resources(_ context.Context) []func() resource.Resource
|
|||||||
settings.NewNetworkOptimizationResource,
|
settings.NewNetworkOptimizationResource,
|
||||||
settings.NewNtpResource,
|
settings.NewNtpResource,
|
||||||
settings.NewSslInspectionResource,
|
settings.NewSslInspectionResource,
|
||||||
|
settings.NewTeleportResource,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
103
internal/provider/settings/resource_setting_teleport.go
Normal file
103
internal/provider/settings/resource_setting_teleport.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package settings
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/filipowm/go-unifi/unifi"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider/validators"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type teleportModel struct {
|
||||||
|
base.Model
|
||||||
|
Enabled types.Bool `tfsdk:"enabled"`
|
||||||
|
Subnet types.String `tfsdk:"subnet"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *teleportModel) AsUnifiModel() (interface{}, diag.Diagnostics) {
|
||||||
|
diags := diag.Diagnostics{}
|
||||||
|
|
||||||
|
model := &unifi.SettingTeleport{
|
||||||
|
ID: d.ID.ValueString(),
|
||||||
|
Enabled: d.Enabled.ValueBool(),
|
||||||
|
SubnetCidr: d.Subnet.ValueString(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return model, diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *teleportModel) Merge(other interface{}) diag.Diagnostics {
|
||||||
|
diags := diag.Diagnostics{}
|
||||||
|
|
||||||
|
model, ok := other.(*unifi.SettingTeleport)
|
||||||
|
if !ok {
|
||||||
|
diags.AddError("Cannot merge", "Cannot merge type that is not *unifi.SettingTeleport")
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
d.ID = types.StringValue(model.ID)
|
||||||
|
d.Enabled = types.BoolValue(model.Enabled)
|
||||||
|
d.Subnet = types.StringValue(model.SubnetCidr)
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ base.ResourceModel = &teleportModel{}
|
||||||
|
_ resource.Resource = &teleportResource{}
|
||||||
|
_ resource.ResourceWithConfigure = &teleportResource{}
|
||||||
|
_ resource.ResourceWithImportState = &teleportResource{}
|
||||||
|
_ resource.ResourceWithConfigValidators = &teleportResource{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type teleportResource struct {
|
||||||
|
*BaseSettingResource[*teleportModel]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *teleportResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
|
||||||
|
resp.Schema = schema.Schema{
|
||||||
|
MarkdownDescription: "Manages Teleport settings for a UniFi site. Teleport is a secure remote access technology that allows authorized users to connect to UniFi devices from anywhere.",
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"id": base.ID(),
|
||||||
|
"site": base.SiteAttribute(),
|
||||||
|
"enabled": schema.BoolAttribute{
|
||||||
|
MarkdownDescription: "Whether Teleport is enabled.",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
"subnet": schema.StringAttribute{
|
||||||
|
MarkdownDescription: "The subnet CIDR for Teleport (e.g., `192.168.1.0/24`). Can be empty but must be set explicitly.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
validators.CIDROrEmpty(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *teleportResource) ConfigValidators(_ context.Context) []resource.ConfigValidator {
|
||||||
|
return []resource.ConfigValidator{
|
||||||
|
validators.ResourceRequireMinVersion(r.GetClient(), "7.1", "Teleport requires UniFi controller version 7.1 or higher"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTeleportResource() resource.Resource {
|
||||||
|
r := &teleportResource{}
|
||||||
|
r.BaseSettingResource = NewBaseSettingResource(
|
||||||
|
"unifi_setting_teleport",
|
||||||
|
func() *teleportModel { return &teleportModel{} },
|
||||||
|
func(ctx context.Context, client *base.Client, site string) (interface{}, error) {
|
||||||
|
return client.GetSettingTeleport(ctx, site)
|
||||||
|
},
|
||||||
|
func(ctx context.Context, client *base.Client, site string, body interface{}) (interface{}, error) {
|
||||||
|
return client.UpdateSettingTeleport(ctx, site, body.(*unifi.SettingTeleport))
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return r
|
||||||
|
}
|
||||||
67
internal/provider/validators/cidr.go
Normal file
67
internal/provider/validators/cidr.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package validators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CIDR returns a validator which ensures that a string value is a valid CIDR notation.
|
||||||
|
func CIDR() validator.String {
|
||||||
|
return cidrValidator{
|
||||||
|
allowEmpty: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CIDROrEmpty returns a validator which ensures that a string value is either empty or a valid CIDR notation.
|
||||||
|
func CIDROrEmpty() validator.String {
|
||||||
|
return cidrValidator{
|
||||||
|
allowEmpty: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ validator.String = cidrValidator{}
|
||||||
|
)
|
||||||
|
|
||||||
|
type cidrValidator struct {
|
||||||
|
allowEmpty bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v cidrValidator) Description(ctx context.Context) string {
|
||||||
|
return "value must be a valid CIDR notation (e.g., '192.168.1.0/24')"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v cidrValidator) MarkdownDescription(ctx context.Context) string {
|
||||||
|
return "value must be a valid CIDR notation (e.g., `192.168.1.0/24`)"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v cidrValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
value := req.ConfigValue.ValueString()
|
||||||
|
if value == "" {
|
||||||
|
if !v.allowEmpty {
|
||||||
|
resp.Diagnostics.AddAttributeError(
|
||||||
|
req.Path,
|
||||||
|
"Invalid CIDR Notation",
|
||||||
|
"CIDR notation cannot be empty",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := net.ParseCIDR(value)
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics.AddAttributeError(
|
||||||
|
req.Path,
|
||||||
|
"Invalid CIDR Notation",
|
||||||
|
fmt.Sprintf("Value %q is not a valid CIDR notation: %v", value, err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
127
internal/provider/validators/cidr_test.go
Normal file
127
internal/provider/validators/cidr_test.go
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package validators_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider/validators"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCIDR(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
val types.String
|
||||||
|
expectError bool
|
||||||
|
}
|
||||||
|
tests := map[string]testCase{
|
||||||
|
"unknown": {
|
||||||
|
val: types.StringUnknown(),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"null": {
|
||||||
|
val: types.StringNull(),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
val: types.StringValue(""),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"valid-ipv4": {
|
||||||
|
val: types.StringValue("192.168.1.0/24"),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"invalid-ipv4": {
|
||||||
|
val: types.StringValue("192.168.1.0"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"valid-ipv6": {
|
||||||
|
val: types.StringValue("2001:db8::/32"),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"invalid-ipv6": {
|
||||||
|
val: types.StringValue("2001:db8::"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
request := validator.StringRequest{
|
||||||
|
ConfigValue: test.val,
|
||||||
|
}
|
||||||
|
response := validator.StringResponse{}
|
||||||
|
validators.CIDR().ValidateString(context.Background(), request, &response)
|
||||||
|
|
||||||
|
if test.expectError {
|
||||||
|
require.NotEmpty(t, response.Diagnostics)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.Empty(t, response.Diagnostics)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCIDROrEmpty(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
type testCase struct {
|
||||||
|
val types.String
|
||||||
|
expectError bool
|
||||||
|
}
|
||||||
|
tests := map[string]testCase{
|
||||||
|
"unknown": {
|
||||||
|
val: types.StringUnknown(),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"null": {
|
||||||
|
val: types.StringNull(),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
val: types.StringValue(""),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"valid-ipv4": {
|
||||||
|
val: types.StringValue("192.168.1.0/24"),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"invalid-ipv4": {
|
||||||
|
val: types.StringValue("192.168.1.0"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
"valid-ipv6": {
|
||||||
|
val: types.StringValue("2001:db8::/32"),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
"invalid-ipv6": {
|
||||||
|
val: types.StringValue("2001:db8::"),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
name, test := name, test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
request := validator.StringRequest{
|
||||||
|
ConfigValue: test.val,
|
||||||
|
}
|
||||||
|
response := validator.StringResponse{}
|
||||||
|
validators.CIDROrEmpty().ValidateString(context.Background(), request, &response)
|
||||||
|
|
||||||
|
if test.expectError {
|
||||||
|
require.NotEmpty(t, response.Diagnostics)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.Empty(t, response.Diagnostics)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
437
internal/provider/validators/controller_version.go
Normal file
437
internal/provider/validators/controller_version.go
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
package validators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ resource.ConfigValidator = &ControllerVersionValidator{}
|
||||||
|
_ datasource.ConfigValidator = &ControllerVersionValidator{}
|
||||||
|
_ validator.String = &ControllerVersionValidator{}
|
||||||
|
_ validator.Bool = &ControllerVersionValidator{}
|
||||||
|
_ validator.Int64 = &ControllerVersionValidator{}
|
||||||
|
_ validator.Float64 = &ControllerVersionValidator{}
|
||||||
|
_ validator.List = &ControllerVersionValidator{}
|
||||||
|
_ validator.Map = &ControllerVersionValidator{}
|
||||||
|
_ validator.Object = &ControllerVersionValidator{}
|
||||||
|
_ validator.Set = &ControllerVersionValidator{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ControllerVersionValidator is a validator that checks if the UniFi controller version
|
||||||
|
// matches the specified constraints.
|
||||||
|
type ControllerVersionValidator struct {
|
||||||
|
client *base.Client
|
||||||
|
minVersion *version.Version
|
||||||
|
maxVersion *version.Version
|
||||||
|
exactVersion *version.Version
|
||||||
|
conditionMessage string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Description returns a description of the validator.
|
||||||
|
func (v ControllerVersionValidator) Description(ctx context.Context) string {
|
||||||
|
return v.MarkdownDescription(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkdownDescription returns a markdown description of the validator.
|
||||||
|
func (v ControllerVersionValidator) MarkdownDescription(_ context.Context) string {
|
||||||
|
if v.exactVersion != nil {
|
||||||
|
return fmt.Sprintf("Validates that the controller version is exactly %s", v.exactVersion)
|
||||||
|
}
|
||||||
|
if v.minVersion != nil && v.maxVersion != nil {
|
||||||
|
return fmt.Sprintf("Validates that the controller version is between %s and %s", v.minVersion, v.maxVersion)
|
||||||
|
}
|
||||||
|
if v.minVersion != nil {
|
||||||
|
return fmt.Sprintf("Validates that the controller version is at least %s", v.minVersion)
|
||||||
|
}
|
||||||
|
if v.maxVersion != nil {
|
||||||
|
return fmt.Sprintf("Validates that the controller version is at most %s", v.maxVersion)
|
||||||
|
}
|
||||||
|
return "Validates the controller version"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateResource validates the resource configuration.
|
||||||
|
func (v ControllerVersionValidator) ValidateResource(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) {
|
||||||
|
if v.client == nil || v.client.Version == nil {
|
||||||
|
resp.Diagnostics.AddWarning("Controller version not available", "Provider was not initialized properly. UniFi client or controller version is not available")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v.validateVersion(ctx, &resp.Diagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateDataSource validates the datasource configuration.
|
||||||
|
func (v ControllerVersionValidator) ValidateDataSource(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) {
|
||||||
|
if v.client == nil || v.client.Version == nil {
|
||||||
|
resp.Diagnostics.AddWarning("Controller version not available", "Provider was not initialized properly. UniFi client or controller version is not available")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v.validateVersion(ctx, &resp.Diagnostics)
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateVersion checks if the controller version meets the constraints
|
||||||
|
func (v ControllerVersionValidator) validateVersion(_ context.Context, diags *diag.Diagnostics) {
|
||||||
|
controllerVersion := v.client.Version
|
||||||
|
|
||||||
|
message := v.conditionMessage
|
||||||
|
if message == "" {
|
||||||
|
message = "Controller version does not meet requirements"
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.exactVersion != nil && !controllerVersion.Equal(v.exactVersion) {
|
||||||
|
diags.AddError(
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s does not match required version %s", controllerVersion, v.exactVersion),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.minVersion != nil && controllerVersion.LessThan(v.minVersion) {
|
||||||
|
diags.AddError(
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s is less than minimum required version %s", controllerVersion, v.minVersion),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.maxVersion != nil && controllerVersion.GreaterThan(v.maxVersion) {
|
||||||
|
diags.AddError(
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s is greater than maximum allowed version %s", controllerVersion, v.maxVersion),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateAttributeVersion is a helper function for attribute validators
|
||||||
|
func (v ControllerVersionValidator) validateAttributeVersion(ctx context.Context, req path.Path) diag.Diagnostics {
|
||||||
|
diags := diag.Diagnostics{}
|
||||||
|
|
||||||
|
if v.client == nil || v.client.Version == nil {
|
||||||
|
diags.AddWarning("Controller version not available", "Provider was not initialized properly. UniFi client or controller version is not available")
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerVersion := v.client.Version
|
||||||
|
|
||||||
|
message := v.conditionMessage
|
||||||
|
if message == "" {
|
||||||
|
message = "Controller version does not meet requirements"
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.exactVersion != nil && !controllerVersion.Equal(v.exactVersion) {
|
||||||
|
diags.Append(validatordiag.InvalidAttributeValueDiagnostic(
|
||||||
|
req,
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s does not match required version %s to use given attribute", controllerVersion, v.exactVersion),
|
||||||
|
))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.minVersion != nil && controllerVersion.LessThan(v.minVersion) {
|
||||||
|
diags.Append(validatordiag.InvalidAttributeValueDiagnostic(
|
||||||
|
req,
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s is less than minimum required version %s to use given attribute", controllerVersion, v.minVersion),
|
||||||
|
))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.maxVersion != nil && controllerVersion.GreaterThan(v.maxVersion) {
|
||||||
|
diags.Append(validatordiag.InvalidAttributeValueDiagnostic(
|
||||||
|
req,
|
||||||
|
message,
|
||||||
|
fmt.Sprintf("Controller version %s is greater than maximum allowed version %s to use given attribute", controllerVersion, v.maxVersion),
|
||||||
|
))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateString implements validator.String
|
||||||
|
func (v ControllerVersionValidator) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBool implements validator.Bool
|
||||||
|
func (v ControllerVersionValidator) ValidateBool(ctx context.Context, req validator.BoolRequest, resp *validator.BoolResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateInt64 implements validator.Int64
|
||||||
|
func (v ControllerVersionValidator) ValidateInt64(ctx context.Context, req validator.Int64Request, resp *validator.Int64Response) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateFloat64 implements validator.Float64
|
||||||
|
func (v ControllerVersionValidator) ValidateFloat64(ctx context.Context, req validator.Float64Request, resp *validator.Float64Response) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateList implements validator.List
|
||||||
|
func (v ControllerVersionValidator) ValidateList(ctx context.Context, req validator.ListRequest, resp *validator.ListResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateMap implements validator.Map
|
||||||
|
func (v ControllerVersionValidator) ValidateMap(ctx context.Context, req validator.MapRequest, resp *validator.MapResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateObject implements validator.Object
|
||||||
|
func (v ControllerVersionValidator) ValidateObject(ctx context.Context, req validator.ObjectRequest, resp *validator.ObjectResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateSet implements validator.Set
|
||||||
|
func (v ControllerVersionValidator) ValidateSet(ctx context.Context, req validator.SetRequest, resp *validator.SetResponse) {
|
||||||
|
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.Diagnostics.Append(v.validateAttributeVersion(ctx, req.Path)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceRequireMinVersion returns a resource validator that checks if the controller version
|
||||||
|
// is at least the specified version.
|
||||||
|
func ResourceRequireMinVersion(client *base.Client, minVersion string, conditionMessage string) resource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceRequireMaxVersion returns a resource validator that checks if the controller version
|
||||||
|
// is at most the specified version.
|
||||||
|
func ResourceRequireMaxVersion(client *base.Client, maxVersion string, conditionMessage string) resource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceRequireVersionRange returns a resource validator that checks if the controller version
|
||||||
|
// is within the specified range (inclusive).
|
||||||
|
func ResourceRequireVersionRange(client *base.Client, minVersion, maxVersion string, conditionMessage string) resource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResourceRequireExactVersion returns a resource validator that checks if the controller version
|
||||||
|
// matches the specified version exactly.
|
||||||
|
func ResourceRequireExactVersion(client *base.Client, exactVersion string, conditionMessage string) resource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
exactVersion: base.AsVersion(exactVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatasourceRequireMinVersion returns a datasource validator that checks if the controller version
|
||||||
|
// is at least the specified version.
|
||||||
|
func DatasourceRequireMinVersion(client *base.Client, minVersion string, conditionMessage string) datasource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatasourceRequireMaxVersion returns a datasource validator that checks if the controller version
|
||||||
|
// is at most the specified version.
|
||||||
|
func DatasourceRequireMaxVersion(client *base.Client, maxVersion string, conditionMessage string) datasource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatasourceRequireVersionRange returns a datasource validator that checks if the controller version
|
||||||
|
// is within the specified range (inclusive).
|
||||||
|
func DatasourceRequireVersionRange(client *base.Client, minVersion, maxVersion string, conditionMessage string) datasource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatasourceRequireExactVersion returns a datasource validator that checks if the controller version
|
||||||
|
// matches the specified version exactly.
|
||||||
|
func DatasourceRequireExactVersion(client *base.Client, exactVersion string, conditionMessage string) datasource.ConfigValidator {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
exactVersion: base.AsVersion(exactVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringRequireMinVersion returns a string validator that checks if the controller version
|
||||||
|
// is at least the specified version.
|
||||||
|
func StringRequireMinVersion(client *base.Client, minVersion string, conditionMessage string) validator.String {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringRequireMaxVersion returns a string validator that checks if the controller version
|
||||||
|
// is at most the specified version.
|
||||||
|
func StringRequireMaxVersion(client *base.Client, maxVersion string, conditionMessage string) validator.String {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringRequireVersionRange returns a string validator that checks if the controller version
|
||||||
|
// is within the specified range (inclusive).
|
||||||
|
func StringRequireVersionRange(client *base.Client, minVersion, maxVersion string, conditionMessage string) validator.String {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringRequireExactVersion returns a string validator that checks if the controller version
|
||||||
|
// matches the specified version exactly.
|
||||||
|
func StringRequireExactVersion(client *base.Client, exactVersion string, conditionMessage string) validator.String {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
exactVersion: base.AsVersion(exactVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolRequireMinVersion returns a bool validator that checks if the controller version
|
||||||
|
// is at least the specified version.
|
||||||
|
func BoolRequireMinVersion(client *base.Client, minVersion string, conditionMessage string) validator.Bool {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolRequireMaxVersion returns a bool validator that checks if the controller version
|
||||||
|
// is at most the specified version.
|
||||||
|
func BoolRequireMaxVersion(client *base.Client, maxVersion string, conditionMessage string) validator.Bool {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolRequireVersionRange returns a bool validator that checks if the controller version
|
||||||
|
// is within the specified range (inclusive).
|
||||||
|
func BoolRequireVersionRange(client *base.Client, minVersion, maxVersion string, conditionMessage string) validator.Bool {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoolRequireExactVersion returns a bool validator that checks if the controller version
|
||||||
|
// matches the specified version exactly.
|
||||||
|
func BoolRequireExactVersion(client *base.Client, exactVersion string, conditionMessage string) validator.Bool {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
exactVersion: base.AsVersion(exactVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64RequireMinVersion returns an int64 validator that checks if the controller version
|
||||||
|
// is at least the specified version.
|
||||||
|
func Int64RequireMinVersion(client *base.Client, minVersion string, conditionMessage string) validator.Int64 {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64RequireMaxVersion returns an int64 validator that checks if the controller version
|
||||||
|
// is at most the specified version.
|
||||||
|
func Int64RequireMaxVersion(client *base.Client, maxVersion string, conditionMessage string) validator.Int64 {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64RequireVersionRange returns an int64 validator that checks if the controller version
|
||||||
|
// is within the specified range (inclusive).
|
||||||
|
func Int64RequireVersionRange(client *base.Client, minVersion, maxVersion string, conditionMessage string) validator.Int64 {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
minVersion: base.AsVersion(minVersion),
|
||||||
|
maxVersion: base.AsVersion(maxVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int64RequireExactVersion returns an int64 validator that checks if the controller version
|
||||||
|
// matches the specified version exactly.
|
||||||
|
func Int64RequireExactVersion(client *base.Client, exactVersion string, conditionMessage string) validator.Int64 {
|
||||||
|
return ControllerVersionValidator{
|
||||||
|
client: client,
|
||||||
|
exactVersion: base.AsVersion(exactVersion),
|
||||||
|
conditionMessage: conditionMessage,
|
||||||
|
}
|
||||||
|
}
|
||||||
375
internal/provider/validators/controller_version_test.go
Normal file
375
internal/provider/validators/controller_version_test.go
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
package validators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
|
||||||
|
"github.com/hashicorp/go-version"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestControllerVersionValidator_Description(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
validator ControllerVersionValidator
|
||||||
|
expected string
|
||||||
|
description string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "exact version",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
exactVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expected: "Validates that the controller version is exactly 7.0.0",
|
||||||
|
description: "Should describe exact version check",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "min version",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expected: "Validates that the controller version is at least 7.0.0",
|
||||||
|
description: "Should describe minimum version check",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "max version",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
maxVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expected: "Validates that the controller version is at most 7.0.0",
|
||||||
|
description: "Should describe maximum version check",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "version range",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
maxVersion: base.AsVersion("8.0.0"),
|
||||||
|
},
|
||||||
|
expected: "Validates that the controller version is between 7.0.0 and 8.0.0",
|
||||||
|
description: "Should describe version range check",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no constraint",
|
||||||
|
validator: ControllerVersionValidator{},
|
||||||
|
expected: "Validates the controller version",
|
||||||
|
description: "Should provide generic description when no constraints",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
actual := test.validator.Description(ctx)
|
||||||
|
assert.Equal(t, test.expected, actual, test.description)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestControllerVersionValidator_ValidateResource(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
controllerVersion string
|
||||||
|
validator ControllerVersionValidator
|
||||||
|
expectError bool
|
||||||
|
description string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "exact version match",
|
||||||
|
controllerVersion: "7.0.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
exactVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expectError: false,
|
||||||
|
description: "Should pass when exact version matches",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "exact version mismatch",
|
||||||
|
controllerVersion: "7.0.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
exactVersion: base.AsVersion("7.1.0"),
|
||||||
|
},
|
||||||
|
expectError: true,
|
||||||
|
description: "Should fail when exact version doesn't match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "min version satisfied",
|
||||||
|
controllerVersion: "7.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expectError: false,
|
||||||
|
description: "Should pass when version meets minimum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "min version not satisfied",
|
||||||
|
controllerVersion: "6.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expectError: true,
|
||||||
|
description: "Should fail when version doesn't meet minimum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "max version satisfied",
|
||||||
|
controllerVersion: "6.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
maxVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expectError: false,
|
||||||
|
description: "Should pass when version is below maximum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "max version not satisfied",
|
||||||
|
controllerVersion: "7.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
maxVersion: base.AsVersion("7.0.0"),
|
||||||
|
},
|
||||||
|
expectError: true,
|
||||||
|
description: "Should fail when version exceeds maximum",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "version in range",
|
||||||
|
controllerVersion: "7.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
maxVersion: base.AsVersion("8.0.0"),
|
||||||
|
},
|
||||||
|
expectError: false,
|
||||||
|
description: "Should pass when version is in range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "version below range",
|
||||||
|
controllerVersion: "6.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
maxVersion: base.AsVersion("8.0.0"),
|
||||||
|
},
|
||||||
|
expectError: true,
|
||||||
|
description: "Should fail when version is below range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "version above range",
|
||||||
|
controllerVersion: "8.5.0",
|
||||||
|
validator: ControllerVersionValidator{
|
||||||
|
minVersion: base.AsVersion("7.0.0"),
|
||||||
|
maxVersion: base.AsVersion("8.0.0"),
|
||||||
|
},
|
||||||
|
expectError: true,
|
||||||
|
description: "Should fail when version is above range",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Create a mock client with the specified version
|
||||||
|
mockClient := &base.Client{
|
||||||
|
Version: version.Must(version.NewVersion(test.controllerVersion)),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the validator with the mock client
|
||||||
|
test.validator.client = mockClient
|
||||||
|
|
||||||
|
// Create request and response objects
|
||||||
|
req := resource.ValidateConfigRequest{}
|
||||||
|
resp := resource.ValidateConfigResponse{
|
||||||
|
Diagnostics: diag.Diagnostics{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the validator
|
||||||
|
test.validator.ValidateResource(ctx, req, &resp)
|
||||||
|
|
||||||
|
// Check if the result matches expectations
|
||||||
|
if test.expectError {
|
||||||
|
assert.True(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
} else {
|
||||||
|
assert.False(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResourceHelperFunctions(t *testing.T) {
|
||||||
|
mockClient := &base.Client{
|
||||||
|
Version: base.AsVersion("7.5.0"),
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
validator resource.ConfigValidator
|
||||||
|
expectError bool
|
||||||
|
description string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ResourceRequireMinVersion passing",
|
||||||
|
validator: ResourceRequireMinVersion(mockClient, "7.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "ResourceRequireMinVersion should pass with sufficient version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireMinVersion failing",
|
||||||
|
validator: ResourceRequireMinVersion(mockClient, "8.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "ResourceRequireMinVersion should fail with insufficient version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireMaxVersion passing",
|
||||||
|
validator: ResourceRequireMaxVersion(mockClient, "8.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "ResourceRequireMaxVersion should pass with acceptable version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireMaxVersion failing",
|
||||||
|
validator: ResourceRequireMaxVersion(mockClient, "7.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "ResourceRequireMaxVersion should fail with too high version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireVersionRange passing",
|
||||||
|
validator: ResourceRequireVersionRange(mockClient, "7.0.0", "8.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "ResourceRequireVersionRange should pass with version in range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireVersionRange failing (below)",
|
||||||
|
validator: ResourceRequireVersionRange(mockClient, "7.6.0", "8.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "ResourceRequireVersionRange should fail with version below range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireVersionRange failing (above)",
|
||||||
|
validator: ResourceRequireVersionRange(mockClient, "6.0.0", "7.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "ResourceRequireVersionRange should fail with version above range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireExactVersion passing",
|
||||||
|
validator: ResourceRequireExactVersion(mockClient, "7.5.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "ResourceRequireExactVersion should pass with exact version match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ResourceRequireExactVersion failing",
|
||||||
|
validator: ResourceRequireExactVersion(mockClient, "7.5.1", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "ResourceRequireExactVersion should fail with version mismatch",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Create request and response objects
|
||||||
|
req := resource.ValidateConfigRequest{}
|
||||||
|
resp := resource.ValidateConfigResponse{
|
||||||
|
Diagnostics: diag.Diagnostics{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the validator
|
||||||
|
test.validator.(ControllerVersionValidator).ValidateResource(ctx, req, &resp)
|
||||||
|
|
||||||
|
// Check if the result matches expectations
|
||||||
|
if test.expectError {
|
||||||
|
assert.True(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
} else {
|
||||||
|
assert.False(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDatasourceHelperFunctions(t *testing.T) {
|
||||||
|
mockClient := &base.Client{
|
||||||
|
Version: base.AsVersion("7.5.0"),
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
validator datasource.ConfigValidator
|
||||||
|
expectError bool
|
||||||
|
description string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireMinVersion passing",
|
||||||
|
validator: DatasourceRequireMinVersion(mockClient, "7.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "DatasourceRequireMinVersion should pass with sufficient version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireMinVersion failing",
|
||||||
|
validator: DatasourceRequireMinVersion(mockClient, "8.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "DatasourceRequireMinVersion should fail with insufficient version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireMaxVersion passing",
|
||||||
|
validator: DatasourceRequireMaxVersion(mockClient, "8.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "DatasourceRequireMaxVersion should pass with acceptable version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireMaxVersion failing",
|
||||||
|
validator: DatasourceRequireMaxVersion(mockClient, "7.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "DatasourceRequireMaxVersion should fail with too high version",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireVersionRange passing",
|
||||||
|
validator: DatasourceRequireVersionRange(mockClient, "7.0.0", "8.0.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "DatasourceRequireVersionRange should pass with version in range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireVersionRange failing (below)",
|
||||||
|
validator: DatasourceRequireVersionRange(mockClient, "7.6.0", "8.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "DatasourceRequireVersionRange should fail with version below range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireVersionRange failing (above)",
|
||||||
|
validator: DatasourceRequireVersionRange(mockClient, "6.0.0", "7.0.0", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "DatasourceRequireVersionRange should fail with version above range",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireExactVersion passing",
|
||||||
|
validator: DatasourceRequireExactVersion(mockClient, "7.5.0", ""),
|
||||||
|
expectError: false,
|
||||||
|
description: "DatasourceRequireExactVersion should pass with exact version match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "DatasourceRequireExactVersion failing",
|
||||||
|
validator: DatasourceRequireExactVersion(mockClient, "7.5.1", ""),
|
||||||
|
expectError: true,
|
||||||
|
description: "DatasourceRequireExactVersion should fail with version mismatch",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Create request and response objects
|
||||||
|
req := datasource.ValidateConfigRequest{}
|
||||||
|
resp := datasource.ValidateConfigResponse{
|
||||||
|
Diagnostics: diag.Diagnostics{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the validator
|
||||||
|
test.validator.(ControllerVersionValidator).ValidateDataSource(ctx, req, &resp)
|
||||||
|
|
||||||
|
// Check if the result matches expectations
|
||||||
|
if test.expectError {
|
||||||
|
assert.True(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
} else {
|
||||||
|
assert.False(t, resp.Diagnostics.HasError(), test.description)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user