diff --git a/internal/juju/client.go b/internal/juju/client.go index 05e70d09..41d2d19a 100644 --- a/internal/juju/client.go +++ b/internal/juju/client.go @@ -128,6 +128,7 @@ func (sc *sharedClient) IsJAAS(defaultVal bool) bool { isJAAS = defaultVal return } + defer conn.Close() isJAAS = conn.BestFacadeVersion("JIMM") != 0 }) return isJAAS diff --git a/internal/provider/validator_avoid_jaas.go b/internal/provider/validator_avoid_jaas.go index 01ec4843..2e18e167 100644 --- a/internal/provider/validator_avoid_jaas.go +++ b/internal/provider/validator_avoid_jaas.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/juju/terraform-provider-juju/internal/juju" ) @@ -35,28 +35,30 @@ func (v AvoidJAASValidator) MarkdownDescription(_ context.Context) string { // ValidateResource performs the validation on the data source. func (v AvoidJAASValidator) ValidateDataSource(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) { - resp.Diagnostics = v.Validate(ctx, req.Config) + resp.Diagnostics = v.validate() } // ValidateResource performs the validation on the resource. func (v AvoidJAASValidator) ValidateResource(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) { - resp.Diagnostics = v.Validate(ctx, req.Config) + resp.Diagnostics = v.validate() } -// Validate runs the main validation logic of the validator, reading configuration data out of `config` and returning with diagnostics. -func (v AvoidJAASValidator) Validate(ctx context.Context, config tfsdk.Config) diag.Diagnostics { +// validate runs the main validation logic of the validator, reading configuration data out of `config` and returning with diagnostics. +func (v AvoidJAASValidator) validate() diag.Diagnostics { var diags diag.Diagnostics + // Return without error if a nil client is detected. + // This is possible since validation is called at various points throughout resource creation. if v.Client != nil && v.Client.IsJAAS() { hint := "" if v.PreferredObject != "" { hint = "Try the " + v.PreferredObject + " resource instead." } diags.AddError("Invalid use of resource with JAAS.", - "It is not supported to use this resource with a JAAS setup. "+ + "This resource is not supported with JAAS. "+ hint+ "JAAS offers additional enterprise features through the use of dedicated resources. "+ - "See the provider documentation for more details.") + "See https://jaas.ai/ for more details.") } return diags } diff --git a/internal/provider/validator_require_jaas.go b/internal/provider/validator_require_jaas.go index 6fcf238f..7497dbbe 100644 --- a/internal/provider/validator_require_jaas.go +++ b/internal/provider/validator_require_jaas.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/tfsdk" + "github.com/juju/terraform-provider-juju/internal/juju" ) @@ -26,28 +26,30 @@ func (v RequiresJAASValidator) Description(ctx context.Context) string { return v.MarkdownDescription(ctx) } -// // MarkdownDescription returns a markdown formatted description of the validator's behavior, suitable for a practitioner to understand its impact. +// MarkdownDescription returns a markdown formatted description of the validator's behavior, suitable for a practitioner to understand its impact. func (v RequiresJAASValidator) MarkdownDescription(_ context.Context) string { return "Enforces that this resource can only be used with JAAS" } // ValidateResource performs the validation on the data source. func (v RequiresJAASValidator) ValidateDataSource(ctx context.Context, req datasource.ValidateConfigRequest, resp *datasource.ValidateConfigResponse) { - resp.Diagnostics = v.Validate(ctx, req.Config) + resp.Diagnostics = v.validate() } // ValidateResource performs the validation on the resource. func (v RequiresJAASValidator) ValidateResource(ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse) { - resp.Diagnostics = v.Validate(ctx, req.Config) + resp.Diagnostics = v.validate() } -// Validate runs the main validation logic of the validator, reading configuration data out of `config` and returning with diagnostics. -func (v RequiresJAASValidator) Validate(ctx context.Context, config tfsdk.Config) diag.Diagnostics { +// validate runs the main validation logic of the validator, reading configuration data out of `config` and returning with diagnostics. +func (v RequiresJAASValidator) validate() diag.Diagnostics { var diags diag.Diagnostics - if v.Client != nil && v.Client.IsJAAS() { + // Return without error if a nil client is detected. + // This is possible since validation is called at various points throughout resource creation. + if v.Client != nil && !v.Client.IsJAAS() { diags.AddError("Attempted use of resource without JAAS.", - "This resource can only be used with a JAAS setup offering additional enterprise features - see https://jaas.ai/ for more details.") + "This resource can only be used with JAAS, which offers additional enterprise features - see https://jaas.ai/ for more details.") } return diags