* Initial PoC for a Project Role Assignment resource Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * fix: move project_role_assignment into new "authorization" resource group Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * feat: add authorization_project_role_assignment acceptance test Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * docs: add authorization_project_role_assignment docs and examples Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * fix: linting Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * feat: add generic role_assignment resources Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * feat: add infrastructure for experimental features Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * feat: Make IAM resources part of the iam experiment Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * fix: Log an error if an experiment does not exist Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> * fix: Do not cache the experiment check Caching the experiment check causes problems when running the provider in debug mode, since configure in the provider can be called multiple times there with different configurations, with different experiments enabled. Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> --------- Signed-off-by: Benjamin Ritter <benjamin.ritter@stackit.cloud> Co-authored-by: Benjamin Ritter <benjamin.ritter@stackit.cloud>
101 lines
3.7 KiB
Go
101 lines
3.7 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
|
)
|
|
|
|
// Separator used for concatenation of TF-internal resource ID
|
|
const Separator = ","
|
|
|
|
type ProviderData struct {
|
|
RoundTripper http.RoundTripper
|
|
ServiceAccountEmail string // Deprecated: ServiceAccountEmail is not required and will be removed after 12th June 2025.
|
|
// Deprecated: Use DefaultRegion instead
|
|
Region string
|
|
DefaultRegion string
|
|
ArgusCustomEndpoint string
|
|
AuthorizationCustomEndpoint string
|
|
DnsCustomEndpoint string
|
|
IaaSCustomEndpoint string
|
|
LoadBalancerCustomEndpoint string
|
|
LogMeCustomEndpoint string
|
|
MariaDBCustomEndpoint string
|
|
MongoDBFlexCustomEndpoint string
|
|
ObjectStorageCustomEndpoint string
|
|
ObservabilityCustomEndpoint string
|
|
OpenSearchCustomEndpoint string
|
|
PostgresFlexCustomEndpoint string
|
|
RabbitMQCustomEndpoint string
|
|
RedisCustomEndpoint string
|
|
ResourceManagerCustomEndpoint string
|
|
SecretsManagerCustomEndpoint string
|
|
SQLServerFlexCustomEndpoint string
|
|
ServerBackupCustomEndpoint string
|
|
ServerUpdateCustomEndpoint string
|
|
SKECustomEndpoint string
|
|
ServiceEnablementCustomEndpoint string
|
|
EnableBetaResources bool
|
|
Experiments []string
|
|
}
|
|
|
|
// GetRegion returns the effective region for the provider, falling back to the deprecated _region_ attribute
|
|
func (pd *ProviderData) GetRegion() string {
|
|
if pd.DefaultRegion != "" {
|
|
return pd.DefaultRegion
|
|
} else if pd.Region != "" {
|
|
return pd.Region
|
|
}
|
|
// final fallback
|
|
return "eu01"
|
|
}
|
|
|
|
// DiagsToError Converts TF diagnostics' errors into an error with a human-readable description.
|
|
// If there are no errors, the output is nil
|
|
func DiagsToError(diags diag.Diagnostics) error {
|
|
if !diags.HasError() {
|
|
return nil
|
|
}
|
|
|
|
diagsError := diags.Errors()
|
|
diagsStrings := make([]string, 0)
|
|
for _, diagnostic := range diagsError {
|
|
diagsStrings = append(diagsStrings, fmt.Sprintf(
|
|
"(%s) %s",
|
|
diagnostic.Summary(),
|
|
diagnostic.Detail(),
|
|
))
|
|
}
|
|
return fmt.Errorf("%s", strings.Join(diagsStrings, ";"))
|
|
}
|
|
|
|
// LogAndAddError Logs the error and adds it to the diags
|
|
func LogAndAddError(ctx context.Context, diags *diag.Diagnostics, summary, detail string) {
|
|
tflog.Error(ctx, fmt.Sprintf("%s | %s", summary, detail))
|
|
diags.AddError(summary, detail)
|
|
}
|
|
|
|
// LogAndAddWarning Logs the warning and adds it to the diags
|
|
func LogAndAddWarning(ctx context.Context, diags *diag.Diagnostics, summary, detail string) {
|
|
tflog.Warn(ctx, fmt.Sprintf("%s | %s", summary, detail))
|
|
diags.AddWarning(summary, detail)
|
|
}
|
|
|
|
func LogAndAddWarningBeta(ctx context.Context, diags *diag.Diagnostics, name, resourceType string) {
|
|
warnTitle := fmt.Sprintf("The %s %q is in beta", resourceType, name)
|
|
warnContent := fmt.Sprintf("The %s %q is in beta and may be subject to breaking changes in the future. Use with caution.", resourceType, name)
|
|
tflog.Warn(ctx, fmt.Sprintf("%s | %s", warnTitle, warnContent))
|
|
diags.AddWarning(warnTitle, warnContent)
|
|
}
|
|
|
|
func LogAndAddErrorBeta(ctx context.Context, diags *diag.Diagnostics, name, resourceType string) {
|
|
errTitle := fmt.Sprintf("The %s %q is in beta and beta is not enabled", resourceType, name)
|
|
errContent := fmt.Sprintf(`The %s %q is in beta and the beta functionality is currently not enabled. To enable it, set the environment variable STACKIT_TF_ENABLE_BETA_RESOURCES to "true" or set the "enable_beta_resources" provider field to true.`, resourceType, name)
|
|
tflog.Error(ctx, fmt.Sprintf("%s | %s", errTitle, errContent))
|
|
diags.AddError(errTitle, errContent)
|
|
}
|