1568 lines
48 KiB
Go
1568 lines
48 KiB
Go
package observability
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
|
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
|
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
|
"github.com/stackitcloud/stackit-sdk-go/services/observability"
|
|
)
|
|
|
|
func fixtureEmailConfigsModel() basetypes.ListValue {
|
|
return types.ListValueMust(types.ObjectType{AttrTypes: emailConfigsTypes}, []attr.Value{
|
|
types.ObjectValueMust(emailConfigsTypes, map[string]attr.Value{
|
|
"auth_identity": types.StringValue("identity"),
|
|
"auth_password": types.StringValue("password"),
|
|
"auth_username": types.StringValue("username"),
|
|
"from": types.StringValue("notification@example.com"),
|
|
"smart_host": types.StringValue("smtp.example.com"),
|
|
"to": types.StringValue("me@example.com"),
|
|
}),
|
|
})
|
|
}
|
|
|
|
func fixtureOpsGenieConfigsModel() basetypes.ListValue {
|
|
return types.ListValueMust(types.ObjectType{AttrTypes: opsgenieConfigsTypes}, []attr.Value{
|
|
types.ObjectValueMust(opsgenieConfigsTypes, map[string]attr.Value{
|
|
"api_key": types.StringValue("key"),
|
|
"tags": types.StringValue("tag"),
|
|
"api_url": types.StringValue("ops.example.com"),
|
|
"priority": types.StringValue("P3"),
|
|
}),
|
|
})
|
|
}
|
|
|
|
func fixtureWebHooksConfigsModel() basetypes.ListValue {
|
|
return types.ListValueMust(types.ObjectType{AttrTypes: webHooksConfigsTypes}, []attr.Value{
|
|
types.ObjectValueMust(webHooksConfigsTypes, map[string]attr.Value{
|
|
"url": types.StringValue("http://example.com"),
|
|
"ms_teams": types.BoolValue(true),
|
|
"google_chat": types.BoolValue(true),
|
|
}),
|
|
})
|
|
}
|
|
|
|
func fixtureReceiverModel(emailConfigs, opsGenieConfigs, webHooksConfigs basetypes.ListValue) basetypes.ObjectValue {
|
|
return types.ObjectValueMust(receiversTypes, map[string]attr.Value{
|
|
"name": types.StringValue("name"),
|
|
"email_configs": emailConfigs,
|
|
"opsgenie_configs": opsGenieConfigs,
|
|
"webhooks_configs": webHooksConfigs,
|
|
})
|
|
}
|
|
|
|
func fixtureRouteModel() basetypes.ObjectValue {
|
|
return types.ObjectValueMust(routeTypes, map[string]attr.Value{
|
|
"group_by": types.ListValueMust(types.StringType, []attr.Value{
|
|
types.StringValue("label1"),
|
|
types.StringValue("label2"),
|
|
}),
|
|
"group_interval": types.StringValue("1m"),
|
|
"group_wait": types.StringValue("1m"),
|
|
"match": types.MapValueMust(types.StringType, map[string]attr.Value{"key": types.StringValue("value")}),
|
|
"match_regex": types.MapValueMust(types.StringType, map[string]attr.Value{"key": types.StringValue("value")}),
|
|
"receiver": types.StringValue("name"),
|
|
"repeat_interval": types.StringValue("1m"),
|
|
// "routes": types.ListNull(getRouteListType()),
|
|
"routes": types.ListValueMust(getRouteListType(), []attr.Value{
|
|
types.ObjectValueMust(getRouteListType().AttrTypes, map[string]attr.Value{
|
|
"group_by": types.ListValueMust(types.StringType, []attr.Value{
|
|
types.StringValue("label1"),
|
|
types.StringValue("label2"),
|
|
}),
|
|
"group_interval": types.StringValue("1m"),
|
|
"group_wait": types.StringValue("1m"),
|
|
"match": types.MapValueMust(types.StringType, map[string]attr.Value{"key": types.StringValue("value")}),
|
|
"match_regex": types.MapValueMust(types.StringType, map[string]attr.Value{"key": types.StringValue("value")}),
|
|
"receiver": types.StringValue("name"),
|
|
"repeat_interval": types.StringValue("1m"),
|
|
}),
|
|
}),
|
|
})
|
|
}
|
|
|
|
func fixtureNullRouteModel() basetypes.ObjectValue {
|
|
return types.ObjectValueMust(routeTypes, map[string]attr.Value{
|
|
"group_by": types.ListNull(types.StringType),
|
|
"group_interval": types.StringNull(),
|
|
"group_wait": types.StringNull(),
|
|
"match": types.MapNull(types.StringType),
|
|
"match_regex": types.MapNull(types.StringType),
|
|
"receiver": types.StringNull(),
|
|
"repeat_interval": types.StringNull(),
|
|
"routes": types.ListNull(getRouteListType()),
|
|
})
|
|
}
|
|
|
|
func fixtureGlobalConfigModel() basetypes.ObjectValue {
|
|
return types.ObjectValueMust(globalConfigurationTypes, map[string]attr.Value{
|
|
"opsgenie_api_key": types.StringValue("key"),
|
|
"opsgenie_api_url": types.StringValue("ops.example.com"),
|
|
"resolve_timeout": types.StringValue("1m"),
|
|
"smtp_auth_identity": types.StringValue("identity"),
|
|
"smtp_auth_username": types.StringValue("username"),
|
|
"smtp_auth_password": types.StringValue("password"),
|
|
"smtp_from": types.StringValue("me@example.com"),
|
|
"smtp_smart_host": types.StringValue("smtp.example.com:25"),
|
|
})
|
|
}
|
|
|
|
func fixtureNullGlobalConfigModel() basetypes.ObjectValue {
|
|
return types.ObjectValueMust(globalConfigurationTypes, map[string]attr.Value{
|
|
"opsgenie_api_key": types.StringNull(),
|
|
"opsgenie_api_url": types.StringNull(),
|
|
"resolve_timeout": types.StringNull(),
|
|
"smtp_auth_identity": types.StringNull(),
|
|
"smtp_auth_username": types.StringNull(),
|
|
"smtp_auth_password": types.StringNull(),
|
|
"smtp_from": types.StringNull(),
|
|
"smtp_smart_host": types.StringNull(),
|
|
})
|
|
}
|
|
|
|
func fixtureEmailConfigsPayload() observability.CreateAlertConfigReceiverPayloadEmailConfigsInner {
|
|
return observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{
|
|
AuthIdentity: utils.Ptr("identity"),
|
|
AuthPassword: utils.Ptr("password"),
|
|
AuthUsername: utils.Ptr("username"),
|
|
From: utils.Ptr("notification@example.com"),
|
|
Smarthost: utils.Ptr("smtp.example.com"),
|
|
To: utils.Ptr("me@example.com"),
|
|
}
|
|
}
|
|
|
|
func fixtureOpsGenieConfigsPayload() observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner {
|
|
return observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{
|
|
ApiKey: utils.Ptr("key"),
|
|
Tags: utils.Ptr("tag"),
|
|
ApiUrl: utils.Ptr("ops.example.com"),
|
|
Priority: utils.Ptr("P3"),
|
|
}
|
|
}
|
|
|
|
func fixtureWebHooksConfigsPayload() observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner {
|
|
return observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner{
|
|
Url: utils.Ptr("http://example.com"),
|
|
MsTeams: utils.Ptr(true),
|
|
GoogleChat: utils.Ptr(true),
|
|
}
|
|
}
|
|
|
|
func fixtureReceiverPayload(emailConfigs *[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner, opsGenieConfigs *[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner, webHooksConfigs *[]observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner) observability.UpdateAlertConfigsPayloadReceiversInner {
|
|
return observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
EmailConfigs: emailConfigs,
|
|
Name: utils.Ptr("name"),
|
|
OpsgenieConfigs: opsGenieConfigs,
|
|
WebHookConfigs: webHooksConfigs,
|
|
}
|
|
}
|
|
|
|
func fixtureRoutePayload() *observability.UpdateAlertConfigsPayloadRoute {
|
|
return &observability.UpdateAlertConfigsPayloadRoute{
|
|
GroupBy: utils.Ptr([]string{"label1", "label2"}),
|
|
GroupInterval: utils.Ptr("1m"),
|
|
GroupWait: utils.Ptr("1m"),
|
|
Match: &map[string]interface{}{"key": "value"},
|
|
MatchRe: &map[string]interface{}{"key": "value"},
|
|
Receiver: utils.Ptr("name"),
|
|
RepeatInterval: utils.Ptr("1m"),
|
|
Routes: &[]observability.UpdateAlertConfigsPayloadRouteRoutesInner{
|
|
{
|
|
GroupBy: utils.Ptr([]string{"label1", "label2"}),
|
|
GroupInterval: utils.Ptr("1m"),
|
|
GroupWait: utils.Ptr("1m"),
|
|
Match: &map[string]interface{}{"key": "value"},
|
|
MatchRe: &map[string]interface{}{"key": "value"},
|
|
Receiver: utils.Ptr("name"),
|
|
RepeatInterval: utils.Ptr("1m"),
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func fixtureGlobalConfigPayload() *observability.UpdateAlertConfigsPayloadGlobal {
|
|
return &observability.UpdateAlertConfigsPayloadGlobal{
|
|
OpsgenieApiKey: utils.Ptr("key"),
|
|
OpsgenieApiUrl: utils.Ptr("ops.example.com"),
|
|
ResolveTimeout: utils.Ptr("1m"),
|
|
SmtpAuthIdentity: utils.Ptr("identity"),
|
|
SmtpAuthUsername: utils.Ptr("username"),
|
|
SmtpAuthPassword: utils.Ptr("password"),
|
|
SmtpFrom: utils.Ptr("me@example.com"),
|
|
SmtpSmarthost: utils.Ptr("smtp.example.com:25"),
|
|
}
|
|
}
|
|
|
|
func fixtureReceiverResponse(emailConfigs *[]observability.EmailConfig, opsGenieConfigs *[]observability.OpsgenieConfig, webhookConfigs *[]observability.WebHook) observability.Receivers {
|
|
return observability.Receivers{
|
|
Name: utils.Ptr("name"),
|
|
EmailConfigs: emailConfigs,
|
|
OpsgenieConfigs: opsGenieConfigs,
|
|
WebHookConfigs: webhookConfigs,
|
|
}
|
|
}
|
|
|
|
func fixtureEmailConfigsResponse() observability.EmailConfig {
|
|
return observability.EmailConfig{
|
|
AuthIdentity: utils.Ptr("identity"),
|
|
AuthPassword: utils.Ptr("password"),
|
|
AuthUsername: utils.Ptr("username"),
|
|
From: utils.Ptr("notification@example.com"),
|
|
Smarthost: utils.Ptr("smtp.example.com"),
|
|
To: utils.Ptr("me@example.com"),
|
|
}
|
|
}
|
|
|
|
func fixtureOpsGenieConfigsResponse() observability.OpsgenieConfig {
|
|
return observability.OpsgenieConfig{
|
|
ApiKey: utils.Ptr("key"),
|
|
Tags: utils.Ptr("tag"),
|
|
ApiUrl: utils.Ptr("ops.example.com"),
|
|
Priority: utils.Ptr("P3"),
|
|
}
|
|
}
|
|
|
|
func fixtureWebHooksConfigsResponse() observability.WebHook {
|
|
return observability.WebHook{
|
|
Url: utils.Ptr("http://example.com"),
|
|
MsTeams: utils.Ptr(true),
|
|
GoogleChat: utils.Ptr(true),
|
|
}
|
|
}
|
|
|
|
func fixtureRouteResponse() *observability.Route {
|
|
return &observability.Route{
|
|
GroupBy: utils.Ptr([]string{"label1", "label2"}),
|
|
GroupInterval: utils.Ptr("1m"),
|
|
GroupWait: utils.Ptr("1m"),
|
|
Match: &map[string]string{"key": "value"},
|
|
MatchRe: &map[string]string{"key": "value"},
|
|
Receiver: utils.Ptr("name"),
|
|
RepeatInterval: utils.Ptr("1m"),
|
|
Routes: &[]observability.RouteSerializer{
|
|
{
|
|
GroupBy: utils.Ptr([]string{"label1", "label2"}),
|
|
GroupInterval: utils.Ptr("1m"),
|
|
GroupWait: utils.Ptr("1m"),
|
|
Match: &map[string]string{"key": "value"},
|
|
MatchRe: &map[string]string{"key": "value"},
|
|
Receiver: utils.Ptr("name"),
|
|
RepeatInterval: utils.Ptr("1m"),
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func fixtureGlobalConfigResponse() *observability.Global {
|
|
return &observability.Global{
|
|
OpsgenieApiKey: utils.Ptr("key"),
|
|
OpsgenieApiUrl: utils.Ptr("ops.example.com"),
|
|
ResolveTimeout: utils.Ptr("1m"),
|
|
SmtpAuthIdentity: utils.Ptr("identity"),
|
|
SmtpAuthUsername: utils.Ptr("username"),
|
|
SmtpAuthPassword: utils.Ptr("password"),
|
|
SmtpFrom: utils.Ptr("me@example.com"),
|
|
SmtpSmarthost: utils.Ptr("smtp.example.com:25"),
|
|
}
|
|
}
|
|
|
|
func fixtureRouteAttributeSchema(route *schema.ListNestedAttribute, isDatasource bool) map[string]schema.Attribute {
|
|
attributeMap := map[string]schema.Attribute{
|
|
"group_by": schema.ListAttribute{
|
|
Description: routeDescriptions["group_by"],
|
|
Optional: !isDatasource,
|
|
Computed: isDatasource,
|
|
ElementType: types.StringType,
|
|
},
|
|
"group_interval": schema.StringAttribute{
|
|
Description: routeDescriptions["group_interval"],
|
|
Optional: !isDatasource,
|
|
Computed: true,
|
|
PlanModifiers: []planmodifier.String{
|
|
stringplanmodifier.UseStateForUnknown(),
|
|
},
|
|
},
|
|
"group_wait": schema.StringAttribute{
|
|
Description: routeDescriptions["group_wait"],
|
|
Optional: !isDatasource,
|
|
Computed: true,
|
|
PlanModifiers: []planmodifier.String{
|
|
stringplanmodifier.UseStateForUnknown(),
|
|
},
|
|
},
|
|
"match": schema.MapAttribute{
|
|
Description: routeDescriptions["match"],
|
|
Optional: !isDatasource,
|
|
Computed: isDatasource,
|
|
ElementType: types.StringType,
|
|
},
|
|
"match_regex": schema.MapAttribute{
|
|
Description: routeDescriptions["match_regex"],
|
|
Optional: !isDatasource,
|
|
Computed: isDatasource,
|
|
ElementType: types.StringType,
|
|
},
|
|
"receiver": schema.StringAttribute{
|
|
Description: routeDescriptions["receiver"],
|
|
Required: !isDatasource,
|
|
Computed: isDatasource,
|
|
},
|
|
"repeat_interval": schema.StringAttribute{
|
|
Description: routeDescriptions["repeat_interval"],
|
|
Optional: !isDatasource,
|
|
Computed: true,
|
|
PlanModifiers: []planmodifier.String{
|
|
stringplanmodifier.UseStateForUnknown(),
|
|
},
|
|
},
|
|
}
|
|
if route != nil {
|
|
attributeMap["routes"] = *route
|
|
}
|
|
return attributeMap
|
|
}
|
|
|
|
func TestMapFields(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
instanceResp *observability.GetInstanceResponse
|
|
listACLResp *observability.ListACLResponse
|
|
getMetricsRetentionResp *observability.GetMetricsStorageRetentionResponse
|
|
expected Model
|
|
isValid bool
|
|
}{
|
|
{
|
|
"default_ok",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
},
|
|
&observability.ListACLResponse{},
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
Model{
|
|
Id: types.StringValue("pid,iid"),
|
|
ProjectId: types.StringValue("pid"),
|
|
InstanceId: types.StringValue("iid"),
|
|
PlanId: types.StringNull(),
|
|
PlanName: types.StringNull(),
|
|
Name: types.StringNull(),
|
|
Parameters: types.MapNull(types.StringType),
|
|
ACL: types.SetNull(types.StringType),
|
|
MetricsRetentionDays: types.Int64Value(60),
|
|
MetricsRetentionDays1hDownsampling: types.Int64Value(30),
|
|
MetricsRetentionDays5mDownsampling: types.Int64Value(7),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"values_ok",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: utils.Ptr("name"),
|
|
PlanName: utils.Ptr("plan1"),
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameters: &map[string]string{"key": "value"},
|
|
Instance: &observability.InstanceSensitiveData{
|
|
MetricsRetentionTimeRaw: utils.Ptr(int64(60)),
|
|
MetricsRetentionTime1h: utils.Ptr(int64(30)),
|
|
MetricsRetentionTime5m: utils.Ptr(int64(7)),
|
|
},
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{
|
|
"1.1.1.1/32",
|
|
},
|
|
Message: utils.Ptr("message"),
|
|
},
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
Model{
|
|
Id: types.StringValue("pid,iid"),
|
|
ProjectId: types.StringValue("pid"),
|
|
Name: types.StringValue("name"),
|
|
InstanceId: types.StringValue("iid"),
|
|
PlanId: types.StringValue("planId"),
|
|
PlanName: types.StringValue("plan1"),
|
|
Parameters: toTerraformStringMapMust(context.Background(), map[string]string{"key": "value"}),
|
|
ACL: types.SetValueMust(types.StringType, []attr.Value{
|
|
types.StringValue("1.1.1.1/32"),
|
|
}),
|
|
MetricsRetentionDays: types.Int64Value(60),
|
|
MetricsRetentionDays1hDownsampling: types.Int64Value(30),
|
|
MetricsRetentionDays5mDownsampling: types.Int64Value(7),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"values_ok_multiple_acls",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: utils.Ptr("name"),
|
|
PlanName: utils.Ptr("plan1"),
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameters: &map[string]string{"key": "value"},
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{
|
|
"1.1.1.1/32",
|
|
"8.8.8.8/32",
|
|
},
|
|
Message: utils.Ptr("message"),
|
|
},
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
Model{
|
|
Id: types.StringValue("pid,iid"),
|
|
ProjectId: types.StringValue("pid"),
|
|
Name: types.StringValue("name"),
|
|
InstanceId: types.StringValue("iid"),
|
|
PlanId: types.StringValue("planId"),
|
|
PlanName: types.StringValue("plan1"),
|
|
Parameters: toTerraformStringMapMust(context.Background(), map[string]string{"key": "value"}),
|
|
ACL: types.SetValueMust(types.StringType, []attr.Value{
|
|
types.StringValue("1.1.1.1/32"),
|
|
types.StringValue("8.8.8.8/32"),
|
|
}),
|
|
MetricsRetentionDays: types.Int64Value(60),
|
|
MetricsRetentionDays1hDownsampling: types.Int64Value(30),
|
|
MetricsRetentionDays5mDownsampling: types.Int64Value(7),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"nullable_fields_ok",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: nil,
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{},
|
|
Message: nil,
|
|
},
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
Model{
|
|
Id: types.StringValue("pid,iid"),
|
|
ProjectId: types.StringValue("pid"),
|
|
InstanceId: types.StringValue("iid"),
|
|
PlanId: types.StringNull(),
|
|
PlanName: types.StringNull(),
|
|
Name: types.StringNull(),
|
|
Parameters: types.MapNull(types.StringType),
|
|
ACL: types.SetNull(types.StringType),
|
|
MetricsRetentionDays: types.Int64Value(60),
|
|
MetricsRetentionDays1hDownsampling: types.Int64Value(30),
|
|
MetricsRetentionDays5mDownsampling: types.Int64Value(7),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"response_nil_fail",
|
|
nil,
|
|
nil,
|
|
nil,
|
|
Model{},
|
|
false,
|
|
},
|
|
{
|
|
"no_resource_id",
|
|
&observability.GetInstanceResponse{},
|
|
nil,
|
|
nil,
|
|
Model{},
|
|
false,
|
|
},
|
|
{
|
|
"empty metrics retention",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: nil,
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{},
|
|
Message: nil,
|
|
},
|
|
&observability.GetMetricsStorageRetentionResponse{},
|
|
Model{},
|
|
false,
|
|
},
|
|
{
|
|
"nil metrics retention",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: nil,
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{},
|
|
Message: nil,
|
|
},
|
|
nil,
|
|
Model{},
|
|
false,
|
|
},
|
|
{
|
|
"update metrics retention",
|
|
&observability.GetInstanceResponse{
|
|
Id: utils.Ptr("iid"),
|
|
Name: utils.Ptr("name"),
|
|
PlanName: utils.Ptr("plan1"),
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameters: &map[string]string{"key": "value"},
|
|
Instance: &observability.InstanceSensitiveData{
|
|
MetricsRetentionTimeRaw: utils.Ptr(int64(30)),
|
|
MetricsRetentionTime1h: utils.Ptr(int64(15)),
|
|
MetricsRetentionTime5m: utils.Ptr(int64(10)),
|
|
},
|
|
},
|
|
&observability.ListACLResponse{
|
|
Acl: &[]string{
|
|
"1.1.1.1/32",
|
|
},
|
|
Message: utils.Ptr("message"),
|
|
},
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
Model{
|
|
Id: types.StringValue("pid,iid"),
|
|
ProjectId: types.StringValue("pid"),
|
|
Name: types.StringValue("name"),
|
|
InstanceId: types.StringValue("iid"),
|
|
PlanId: types.StringValue("planId"),
|
|
PlanName: types.StringValue("plan1"),
|
|
Parameters: toTerraformStringMapMust(context.Background(), map[string]string{"key": "value"}),
|
|
ACL: types.SetValueMust(types.StringType, []attr.Value{
|
|
types.StringValue("1.1.1.1/32"),
|
|
}),
|
|
MetricsRetentionDays: types.Int64Value(60),
|
|
MetricsRetentionDays1hDownsampling: types.Int64Value(30),
|
|
MetricsRetentionDays5mDownsampling: types.Int64Value(7),
|
|
},
|
|
true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
state := &Model{
|
|
ProjectId: tt.expected.ProjectId,
|
|
ACL: types.SetNull(types.StringType),
|
|
}
|
|
err := mapFields(context.Background(), tt.instanceResp, state)
|
|
aclErr := mapACLField(tt.listACLResp, state)
|
|
metricsErr := mapMetricsRetentionField(tt.getMetricsRetentionResp, state)
|
|
if !tt.isValid && err == nil && aclErr == nil && metricsErr == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && (err != nil || aclErr != nil || metricsErr != nil) {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
|
|
if tt.isValid {
|
|
diff := cmp.Diff(state, &tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMapAlertConfigField(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
alertConfigResp *observability.GetAlertConfigsResponse
|
|
expected Model
|
|
isValid bool
|
|
}{
|
|
{
|
|
description: "basic_ok",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
&[]observability.EmailConfig{
|
|
fixtureEmailConfigsResponse(),
|
|
},
|
|
&[]observability.OpsgenieConfig{
|
|
fixtureOpsGenieConfigsResponse(),
|
|
},
|
|
&[]observability.WebHook{
|
|
fixtureWebHooksConfigsResponse(),
|
|
},
|
|
),
|
|
},
|
|
Route: fixtureRouteResponse(),
|
|
Global: fixtureGlobalConfigResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
"route": fixtureRouteModel(),
|
|
"global": fixtureGlobalConfigModel(),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "receivers only emailconfigs",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
&[]observability.EmailConfig{
|
|
fixtureEmailConfigsResponse(),
|
|
},
|
|
nil,
|
|
nil,
|
|
),
|
|
},
|
|
Route: fixtureRouteResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
types.ListNull(types.ObjectType{AttrTypes: opsgenieConfigsTypes}),
|
|
types.ListNull(types.ObjectType{AttrTypes: webHooksConfigsTypes}),
|
|
),
|
|
}),
|
|
"route": fixtureRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "receivers only opsgenieconfigs",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
nil,
|
|
&[]observability.OpsgenieConfig{
|
|
fixtureOpsGenieConfigsResponse(),
|
|
},
|
|
nil,
|
|
),
|
|
},
|
|
Route: fixtureRouteResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
types.ListNull(types.ObjectType{AttrTypes: emailConfigsTypes}),
|
|
fixtureOpsGenieConfigsModel(),
|
|
types.ListNull(types.ObjectType{AttrTypes: webHooksConfigsTypes}),
|
|
),
|
|
}),
|
|
"route": fixtureRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "receivers only webhooksconfigs",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
nil,
|
|
nil,
|
|
&[]observability.WebHook{
|
|
fixtureWebHooksConfigsResponse(),
|
|
},
|
|
),
|
|
},
|
|
Route: fixtureRouteResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
types.ListNull(types.ObjectType{AttrTypes: emailConfigsTypes}),
|
|
types.ListNull(types.ObjectType{AttrTypes: opsgenieConfigsTypes}),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
"route": fixtureRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "no receivers, no routes",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{},
|
|
Route: &observability.Route{},
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{}),
|
|
"route": fixtureNullRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "no receivers, default routes",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{},
|
|
Route: fixtureRouteResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{}),
|
|
"route": fixtureRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "default receivers, no routes",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
&[]observability.EmailConfig{
|
|
fixtureEmailConfigsResponse(),
|
|
},
|
|
&[]observability.OpsgenieConfig{
|
|
fixtureOpsGenieConfigsResponse(),
|
|
},
|
|
&[]observability.WebHook{
|
|
fixtureWebHooksConfigsResponse(),
|
|
},
|
|
),
|
|
},
|
|
Route: &observability.Route{},
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
"route": fixtureNullRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "nil receivers",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: nil,
|
|
Route: fixtureRouteResponse(),
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListNull(types.ObjectType{AttrTypes: receiversTypes}),
|
|
"route": fixtureRouteModel(),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "nil route",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
&[]observability.EmailConfig{
|
|
fixtureEmailConfigsResponse(),
|
|
},
|
|
&[]observability.OpsgenieConfig{
|
|
fixtureOpsGenieConfigsResponse(),
|
|
},
|
|
&[]observability.WebHook{
|
|
fixtureWebHooksConfigsResponse(),
|
|
},
|
|
),
|
|
},
|
|
Route: nil,
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
"route": types.ObjectNull(routeTypes),
|
|
"global": types.ObjectNull(globalConfigurationTypes),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "empty global options",
|
|
alertConfigResp: &observability.GetAlertConfigsResponse{
|
|
Data: &observability.Alert{
|
|
Receivers: &[]observability.Receivers{
|
|
fixtureReceiverResponse(
|
|
&[]observability.EmailConfig{
|
|
fixtureEmailConfigsResponse(),
|
|
},
|
|
&[]observability.OpsgenieConfig{
|
|
fixtureOpsGenieConfigsResponse(),
|
|
},
|
|
&[]observability.WebHook{
|
|
fixtureWebHooksConfigsResponse(),
|
|
},
|
|
),
|
|
},
|
|
Route: fixtureRouteResponse(),
|
|
Global: &observability.Global{},
|
|
},
|
|
},
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectValueMust(alertConfigTypes, map[string]attr.Value{
|
|
"receivers": types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
"route": fixtureRouteModel(),
|
|
"global": fixtureNullGlobalConfigModel(),
|
|
}),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "nil resp",
|
|
alertConfigResp: nil,
|
|
expected: Model{
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
AlertConfig: types.ObjectNull(receiversTypes),
|
|
},
|
|
isValid: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
state := &Model{
|
|
ProjectId: tt.expected.ProjectId,
|
|
ACL: types.SetNull(types.StringType),
|
|
Parameters: types.MapNull(types.StringType),
|
|
}
|
|
err := mapAlertConfigField(context.Background(), tt.alertConfigResp, state)
|
|
if !tt.isValid && err == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && err != nil {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
|
|
if tt.isValid {
|
|
diff := cmp.Diff(state.AlertConfig, tt.expected.AlertConfig)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToCreatePayload(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input *Model
|
|
expected *observability.CreateInstancePayload
|
|
isValid bool
|
|
}{
|
|
{
|
|
"basic_ok",
|
|
&Model{
|
|
PlanId: types.StringValue("planId"),
|
|
},
|
|
&observability.CreateInstancePayload{
|
|
Name: nil,
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameter: &map[string]interface{}{},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"ok",
|
|
&Model{
|
|
Name: types.StringValue("Name"),
|
|
PlanId: types.StringValue("planId"),
|
|
Parameters: makeTestMap(t),
|
|
},
|
|
&observability.CreateInstancePayload{
|
|
Name: utils.Ptr("Name"),
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameter: &map[string]interface{}{"key": `"value"`},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"nil_model",
|
|
nil,
|
|
nil,
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output, err := toCreatePayload(tt.input)
|
|
if !tt.isValid && err == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && err != nil {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
if tt.isValid {
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToPayloadUpdate(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input *Model
|
|
expected *observability.UpdateInstancePayload
|
|
isValid bool
|
|
}{
|
|
{
|
|
"basic_ok",
|
|
&Model{
|
|
PlanId: types.StringValue("planId"),
|
|
},
|
|
&observability.UpdateInstancePayload{
|
|
Name: nil,
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameter: &map[string]any{},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"ok",
|
|
&Model{
|
|
Name: types.StringValue("Name"),
|
|
PlanId: types.StringValue("planId"),
|
|
Parameters: makeTestMap(t),
|
|
},
|
|
&observability.UpdateInstancePayload{
|
|
Name: utils.Ptr("Name"),
|
|
PlanId: utils.Ptr("planId"),
|
|
Parameter: &map[string]any{"key": `"value"`},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"nil_model",
|
|
nil,
|
|
nil,
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output, err := toUpdatePayload(tt.input)
|
|
if !tt.isValid && err == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && err != nil {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
if tt.isValid {
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToUpdateMetricsStorageRetentionPayload(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
retentionDaysRaw *int64
|
|
retentionDays1h *int64
|
|
retentionDays5m *int64
|
|
getMetricsResp *observability.GetMetricsStorageRetentionResponse
|
|
expected *observability.UpdateMetricsStorageRetentionPayload
|
|
isValid bool
|
|
}{
|
|
{
|
|
"basic_ok",
|
|
utils.Ptr(int64(120)),
|
|
utils.Ptr(int64(60)),
|
|
utils.Ptr(int64(14)),
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
&observability.UpdateMetricsStorageRetentionPayload{
|
|
MetricsRetentionTimeRaw: utils.Ptr("120d"),
|
|
MetricsRetentionTime1h: utils.Ptr("60d"),
|
|
MetricsRetentionTime5m: utils.Ptr("14d"),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"only_raw_given",
|
|
utils.Ptr(int64(120)),
|
|
nil,
|
|
nil,
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
&observability.UpdateMetricsStorageRetentionPayload{
|
|
MetricsRetentionTimeRaw: utils.Ptr("120d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"only_1h_given",
|
|
nil,
|
|
utils.Ptr(int64(60)),
|
|
nil,
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
&observability.UpdateMetricsStorageRetentionPayload{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("60d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"only_5m_given",
|
|
nil,
|
|
nil,
|
|
utils.Ptr(int64(14)),
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
&observability.UpdateMetricsStorageRetentionPayload{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("14d"),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"none_given",
|
|
nil,
|
|
nil,
|
|
nil,
|
|
&observability.GetMetricsStorageRetentionResponse{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
&observability.UpdateMetricsStorageRetentionPayload{
|
|
MetricsRetentionTimeRaw: utils.Ptr("60d"),
|
|
MetricsRetentionTime1h: utils.Ptr("30d"),
|
|
MetricsRetentionTime5m: utils.Ptr("7d"),
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"nil_response",
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
false,
|
|
},
|
|
{
|
|
"empty_response",
|
|
nil,
|
|
nil,
|
|
nil,
|
|
&observability.GetMetricsStorageRetentionResponse{},
|
|
nil,
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output, err := toUpdateMetricsStorageRetentionPayload(tt.retentionDaysRaw, tt.retentionDays5m, tt.retentionDays1h, tt.getMetricsResp)
|
|
if !tt.isValid && err == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && err != nil {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
if tt.isValid {
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToUpdateAlertConfigPayload(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
input alertConfigModel
|
|
expected *observability.UpdateAlertConfigsPayload
|
|
isValid bool
|
|
}{
|
|
{
|
|
description: "base",
|
|
input: alertConfigModel{
|
|
Receivers: types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
Route: fixtureRouteModel(),
|
|
GlobalConfiguration: fixtureGlobalConfigModel(),
|
|
},
|
|
expected: &observability.UpdateAlertConfigsPayload{
|
|
Receivers: &[]observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
fixtureReceiverPayload(
|
|
&[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{fixtureEmailConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{fixtureOpsGenieConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner{fixtureWebHooksConfigsPayload()},
|
|
),
|
|
},
|
|
Route: fixtureRoutePayload(),
|
|
Global: fixtureGlobalConfigPayload(),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "receivers only emailconfigs",
|
|
input: alertConfigModel{
|
|
Receivers: types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
types.ListNull(types.ObjectType{AttrTypes: opsgenieConfigsTypes}),
|
|
types.ListNull(types.ObjectType{AttrTypes: webHooksConfigsTypes}),
|
|
),
|
|
}),
|
|
Route: fixtureRouteModel(),
|
|
},
|
|
expected: &observability.UpdateAlertConfigsPayload{
|
|
Receivers: &[]observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
fixtureReceiverPayload(
|
|
&[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{fixtureEmailConfigsPayload()},
|
|
nil,
|
|
nil,
|
|
),
|
|
},
|
|
Route: fixtureRoutePayload(),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "receivers only opsgenieconfigs",
|
|
input: alertConfigModel{
|
|
Receivers: types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
types.ListNull(types.ObjectType{AttrTypes: emailConfigsTypes}),
|
|
fixtureOpsGenieConfigsModel(),
|
|
types.ListNull(types.ObjectType{AttrTypes: webHooksConfigsTypes}),
|
|
),
|
|
}),
|
|
Route: fixtureRouteModel(),
|
|
},
|
|
expected: &observability.UpdateAlertConfigsPayload{
|
|
Receivers: &[]observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
fixtureReceiverPayload(
|
|
nil,
|
|
&[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{fixtureOpsGenieConfigsPayload()},
|
|
nil,
|
|
),
|
|
},
|
|
Route: fixtureRoutePayload(),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "multiple receivers",
|
|
input: alertConfigModel{
|
|
Receivers: types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
Route: fixtureRouteModel(),
|
|
},
|
|
expected: &observability.UpdateAlertConfigsPayload{
|
|
Receivers: &[]observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
fixtureReceiverPayload(
|
|
&[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{fixtureEmailConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{fixtureOpsGenieConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner{fixtureWebHooksConfigsPayload()},
|
|
),
|
|
fixtureReceiverPayload(
|
|
&[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{fixtureEmailConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{fixtureOpsGenieConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner{fixtureWebHooksConfigsPayload()},
|
|
),
|
|
},
|
|
Route: fixtureRoutePayload(),
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "empty global options",
|
|
input: alertConfigModel{
|
|
Receivers: types.ListValueMust(types.ObjectType{AttrTypes: receiversTypes}, []attr.Value{
|
|
fixtureReceiverModel(
|
|
fixtureEmailConfigsModel(),
|
|
fixtureOpsGenieConfigsModel(),
|
|
fixtureWebHooksConfigsModel(),
|
|
),
|
|
}),
|
|
Route: fixtureRouteModel(),
|
|
GlobalConfiguration: fixtureNullGlobalConfigModel(),
|
|
},
|
|
expected: &observability.UpdateAlertConfigsPayload{
|
|
Receivers: &[]observability.UpdateAlertConfigsPayloadReceiversInner{
|
|
fixtureReceiverPayload(
|
|
&[]observability.CreateAlertConfigReceiverPayloadEmailConfigsInner{fixtureEmailConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadOpsgenieConfigsInner{fixtureOpsGenieConfigsPayload()},
|
|
&[]observability.CreateAlertConfigReceiverPayloadWebHookConfigsInner{fixtureWebHooksConfigsPayload()},
|
|
),
|
|
},
|
|
Route: fixtureRoutePayload(),
|
|
Global: &observability.UpdateAlertConfigsPayloadGlobal{},
|
|
},
|
|
isValid: true,
|
|
},
|
|
{
|
|
description: "empty alert config",
|
|
input: alertConfigModel{},
|
|
isValid: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output, err := toUpdateAlertConfigPayload(context.Background(), &tt.input)
|
|
if !tt.isValid && err == nil {
|
|
t.Fatalf("Should have failed")
|
|
}
|
|
if tt.isValid && err != nil {
|
|
t.Fatalf("Should not have failed: %v", err)
|
|
}
|
|
if tt.isValid {
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRouteNestedObjectAux(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
startingLevel int
|
|
recursionLimit int
|
|
isDatasource bool
|
|
expected schema.ListNestedAttribute
|
|
}{
|
|
{
|
|
"no recursion, resource",
|
|
1,
|
|
1,
|
|
false,
|
|
schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Optional: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(nil, false),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"recursion 1, resource",
|
|
1,
|
|
2,
|
|
false,
|
|
schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Optional: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(
|
|
&schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Optional: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(nil, false),
|
|
},
|
|
},
|
|
false,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"no recursion,datasource",
|
|
1,
|
|
1,
|
|
true,
|
|
schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Computed: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(nil, true),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"recursion 1, datasource",
|
|
1,
|
|
2,
|
|
true,
|
|
schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Computed: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(
|
|
&schema.ListNestedAttribute{
|
|
Description: routeDescriptions["routes"],
|
|
Computed: true,
|
|
Validators: []validator.List{
|
|
listvalidator.SizeAtLeast(1),
|
|
},
|
|
NestedObject: schema.NestedAttributeObject{
|
|
Attributes: fixtureRouteAttributeSchema(nil, true),
|
|
},
|
|
},
|
|
true,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output := getRouteNestedObjectAux(tt.isDatasource, tt.startingLevel, tt.recursionLimit)
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRouteListTypeAux(t *testing.T) {
|
|
tests := []struct {
|
|
description string
|
|
startingLevel int
|
|
recursionLimit int
|
|
expected types.ObjectType
|
|
}{
|
|
{
|
|
"no recursion",
|
|
1,
|
|
1,
|
|
types.ObjectType{
|
|
AttrTypes: map[string]attr.Type{
|
|
"group_by": types.ListType{ElemType: types.StringType},
|
|
"group_interval": types.StringType,
|
|
"group_wait": types.StringType,
|
|
"match": types.MapType{ElemType: types.StringType},
|
|
"match_regex": types.MapType{ElemType: types.StringType},
|
|
"receiver": types.StringType,
|
|
"repeat_interval": types.StringType,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"recursion 1",
|
|
1,
|
|
2,
|
|
types.ObjectType{
|
|
AttrTypes: map[string]attr.Type{
|
|
"group_by": types.ListType{ElemType: types.StringType},
|
|
"group_interval": types.StringType,
|
|
"group_wait": types.StringType,
|
|
"match": types.MapType{ElemType: types.StringType},
|
|
"match_regex": types.MapType{ElemType: types.StringType},
|
|
"receiver": types.StringType,
|
|
"repeat_interval": types.StringType,
|
|
"routes": types.ListType{ElemType: types.ObjectType{AttrTypes: map[string]attr.Type{
|
|
"group_by": types.ListType{ElemType: types.StringType},
|
|
"group_interval": types.StringType,
|
|
"group_wait": types.StringType,
|
|
"match": types.MapType{ElemType: types.StringType},
|
|
"match_regex": types.MapType{ElemType: types.StringType},
|
|
"receiver": types.StringType,
|
|
"repeat_interval": types.StringType,
|
|
}}},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"recursion 2",
|
|
2,
|
|
2,
|
|
types.ObjectType{
|
|
AttrTypes: map[string]attr.Type{
|
|
"group_by": types.ListType{ElemType: types.StringType},
|
|
"group_interval": types.StringType,
|
|
"group_wait": types.StringType,
|
|
"match": types.MapType{ElemType: types.StringType},
|
|
"match_regex": types.MapType{ElemType: types.StringType},
|
|
"receiver": types.StringType,
|
|
"repeat_interval": types.StringType,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.description, func(t *testing.T) {
|
|
output := getRouteListTypeAux(tt.startingLevel, tt.recursionLimit)
|
|
diff := cmp.Diff(output, tt.expected)
|
|
if diff != "" {
|
|
t.Fatalf("Data does not match: %s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func makeTestMap(t *testing.T) basetypes.MapValue {
|
|
p := make(map[string]attr.Value, 1)
|
|
p["key"] = types.StringValue("value")
|
|
params, diag := types.MapValueFrom(context.Background(), types.StringType, p)
|
|
if diag.HasError() {
|
|
t.Fail()
|
|
}
|
|
return params
|
|
}
|
|
|
|
// ToTerraformStringMapMust Silently ignores the error
|
|
func toTerraformStringMapMust(ctx context.Context, m map[string]string) basetypes.MapValue {
|
|
labels := make(map[string]attr.Value, len(m))
|
|
for l, v := range m {
|
|
stringValue := types.StringValue(v)
|
|
labels[l] = stringValue
|
|
}
|
|
res, diags := types.MapValueFrom(ctx, types.StringType, m)
|
|
if diags.HasError() {
|
|
return types.MapNull(types.StringType)
|
|
}
|
|
return res
|
|
}
|