Skip to content

Commit

Permalink
fix: logs_new_value has computed group by (#303)
Browse files Browse the repository at this point in the history
* fix: logs_new_value has computed group by
* docs: new tmpl, guides
  • Loading branch information
celaus authored Jan 9, 2025
1 parent 0121394 commit 000de35
Show file tree
Hide file tree
Showing 8 changed files with 517 additions and 67 deletions.
76 changes: 42 additions & 34 deletions coralogix/resource_coralogix_alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -1189,7 +1189,7 @@ func (r *AlertResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
Optional: true,
Computed: true,
PlanModifiers: []planmodifier.List{
ComputedForMetricAlerts{},
ComputedForSomeAlerts{},
},
Validators: []validator.List{
//imidiate, new value, tracing-immidiate,
Expand Down Expand Up @@ -1293,10 +1293,6 @@ func (r *AlertResource) Schema(_ context.Context, _ resource.SchemaRequest, resp
}
}

func timeZoneSchema() {
panic("todo")
}

type GroupByValidator struct {
}

Expand Down Expand Up @@ -1328,18 +1324,18 @@ func (g GroupByValidator) ValidateList(ctx context.Context, request validator.Li
}
}

type ComputedForMetricAlerts struct {
type ComputedForSomeAlerts struct {
}

func (c ComputedForMetricAlerts) Description(ctx context.Context) string {
func (c ComputedForSomeAlerts) Description(ctx context.Context) string {
return "Computed for metric alerts."
}

func (c ComputedForMetricAlerts) MarkdownDescription(ctx context.Context) string {
func (c ComputedForSomeAlerts) MarkdownDescription(ctx context.Context) string {
return "Computed for metric alerts."
}

func (c ComputedForMetricAlerts) PlanModifyList(ctx context.Context, request planmodifier.ListRequest, response *planmodifier.ListResponse) {
func (c ComputedForSomeAlerts) PlanModifyList(ctx context.Context, request planmodifier.ListRequest, response *planmodifier.ListResponse) {
paths, diags := request.Plan.PathMatches(ctx, path.MatchRoot("type_definition"))
if diags.HasError() {
response.Diagnostics.Append(diags...)
Expand All @@ -1352,14 +1348,18 @@ func (c ComputedForMetricAlerts) PlanModifyList(ctx context.Context, request pla
return
}

// special case for metric alerts
var typeDefinitionStr string
if !objIsNullOrUnknown(typeDefinition.MetricThreshold) {
typeDefinitionStr = "metric_threshold"
} else if !objIsNullOrUnknown(typeDefinition.MetricAnomaly) {
typeDefinitionStr = "metric_anomaly"
} else if !objIsNullOrUnknown(typeDefinition.LogsNewValue) {
typeDefinitionStr = "logs_new_value"
}

if typeDefinitionStr != "" {
switch typeDefinitionStr {
case "metric_threshold", "metric_anomaly":
paths, diags = request.Plan.PathMatches(ctx, path.MatchRoot("type_definition").AtName(typeDefinitionStr).AtName("metric_filter").AtName("promql"))
if diags.HasError() {
response.Diagnostics.Append(diags...)
Expand Down Expand Up @@ -1388,8 +1388,36 @@ func (c ComputedForMetricAlerts) PlanModifyList(ctx context.Context, request pla
}
return
}
}
case "logs_new_value": // keypath_to_track values end up in the group_by attribute
paths, diags = request.Plan.PathMatches(ctx, path.MatchRoot("type_definition").AtName(typeDefinitionStr).AtName("rules"))
if diags.HasError() {
response.Diagnostics.Append(diags...)
return
}

var rulesPlan types.Set
diags = request.Plan.GetAttribute(ctx, paths[0], &rulesPlan)
if diags.HasError() {
response.Diagnostics.Append(diags...)
return
}

var rulesState types.Set
diags = request.State.GetAttribute(ctx, paths[0], &rulesState)
if diags.HasError() {
response.Diagnostics.Append(diags...)
return
}

if request.ConfigValue.IsUnknown() || request.ConfigValue.IsNull() {
if !rulesState.Equal(rulesPlan) {
response.PlanValue = types.ListUnknown(types.StringType)
} else {
response.PlanValue = request.StateValue
}
return
}
}
response.PlanValue = request.ConfigValue
}

Expand Down Expand Up @@ -1778,19 +1806,6 @@ func extractNotificationGroup(ctx context.Context, notificationGroupObject types
return notificationGroup, nil
}

func expandNotificationTargetSettings(ctx context.Context, notificationGroupModel NotificationGroupModel, notificationGroup *cxsdk.AlertDefNotificationGroup) (*cxsdk.AlertDefNotificationGroup, diag.Diagnostics) {
notificationGroup.Webhooks = []*cxsdk.AlertDefWebhooksSettings{}
if webhooksSettings := notificationGroupModel.WebhooksSettings; !(webhooksSettings.IsNull() || webhooksSettings.IsUnknown()) {
notifications, diags := extractWebhooksSettings(ctx, webhooksSettings)
if diags.HasError() {
return nil, diags
}
notificationGroup.Webhooks = notifications
}

return notificationGroup, nil
}

func extractWebhooksSettings(ctx context.Context, webhooksSettings types.Set) ([]*cxsdk.AlertDefWebhooksSettings, diag.Diagnostics) {
if webhooksSettings.IsNull() || webhooksSettings.IsUnknown() {
return nil, nil
Expand Down Expand Up @@ -3342,14 +3357,14 @@ func extractAlertDef(ctx context.Context, def types.Object) (*cxsdk.FlowStagesGr
func (r *AlertResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
var state *AlertResourceModel
diags := req.State.Get(ctx, &state)
//Get refreshed Alert value from Coralogix
id := state.ID.ValueString()
log.Printf("[INFO] Reading Alert: %s", id)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

//Get refreshed Alert value from Coralogix
id := state.ID.ValueString()
log.Printf("[INFO] Reading Alert: %s", id)
getAlertReq := &cxsdk.GetAlertDefRequest{Id: wrapperspb.String(id)}
getAlertResp, err := r.client.Get(ctx, getAlertReq)
if err != nil {
Expand Down Expand Up @@ -4905,13 +4920,6 @@ func alertScheduleActiveOnAttr() map[string]attr.Type {
}
}

func timeOfDayAttr() map[string]attr.Type {
return map[string]attr.Type{
"hours": types.Int64Type,
"minutes": types.Int64Type,
}
}

func logsTimeRelativeAttr() map[string]attr.Type {
return map[string]attr.Type{
"logs_filter": types.ObjectType{AttrTypes: logsFilterAttr()},
Expand Down
4 changes: 2 additions & 2 deletions docs/data-sources/alert.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Coralogix Alert. For more info please review - https://coralogix.com/docs/gettin
- `deleted` (Boolean)
- `description` (String) Alert description.
- `enabled` (Boolean) Alert enabled status. True by default.
- `group_by` (Set of String) Group by fields.
- `group_by` (List of String) Group by fields.
- `incidents_settings` (Attributes) (see [below for nested schema](#nestedatt--incidents_settings))
- `labels` (Map of String)
- `name` (String) Alert name.
Expand Down Expand Up @@ -56,7 +56,7 @@ Read-Only:

Read-Only:

- `group_by_keys` (Set of String)
- `group_by_keys` (List of String)
- `webhooks_settings` (Attributes Set) (see [below for nested schema](#nestedatt--notification_group--webhooks_settings))

<a id="nestedatt--notification_group--webhooks_settings"></a>
Expand Down
141 changes: 141 additions & 0 deletions docs/guides/alerts-migration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
page_title: "Migration Guide for Alerts (from pre 2.0)"
---

# Guide to Using the Terraform Migration Script

!> Before following this guide, please reach out to your customer support representative for more information.

This guide provides step-by-step instructions on how to use the Terraform migration scripts effectively.

---

## Prerequisites
0. **Get the scripts**:
- Download from [https://github.com/coralogix/coralogix-management-sdk/tree/master/tools/terraform-importer]()
1. **Terraform Installed**:
- Ensure you have Terraform installed. You can download it [here](https://www.terraform.io/downloads).
2. **Go Installed**:
- Install Go from [golang.org](https://golang.org/dl/).
3. **Python Installed**:
- The script uses Python 3 for JSON processing, so make sure you have Python 3 installed.
4. **`hcl2json` Installed**:
- Install the `hcl2json` utility. You can find it [here](https://github.com/tmccombs/hcl2json).

---

## Usage

### 1. Script Purpose
The script allows you to:
- Migrate Terraform configurations based on:
- A folder containing a `terraform.tfstate` file.
- A specific resource type (e.g., `alert`, `dashboard`).
- Generate a migration folder with cleaned and updated configurations.
- Specify the provider version interactively during the process.

---

### 2. Running the Script
Before running the script, ensure you defined the required environment variables -
`CORALOGIX_API_KEY` and `CORALOGIX_ENV` or `CORALOGIX_DOMAIN`.

Use the script as follows:
```bash
./generate_and_migrate.sh
```

---

### 3. Interactive Steps

#### Step 1: Select Migration Type
You will be prompted to choose the migration type:
- **Option 1**: Migrate based on a folder containing a `terraform.tfstate` file.
- Provide the path to the folder.
- The script ensures that the folder contains a valid `terraform.tfstate` file.
- **Option 2**: Migrate based on a specific resource type.
- A list of resource types will be displayed. Choose from options like:
- `alert`, `dashboard`, `archive_logs`, `events2metrics`, etc.
- Select the desired resource type from the list.

#### Step 2: Specify Provider Version
After selecting the migration type, you will be prompted to specify the Terraform provider version:
- Example: `~>1.19.0`.
- The script will default to `>=2.0.0` if no input is provided.

---

### 4. What Happens Next

#### Step 3: Generate Migration Folder
- The script creates a new migration folder based on your input:
- For a folder, it appends `_migration` to the folder name.
- For a resource type, it creates a folder like `./<resource_type>_migration`.

#### Step 4: Run `generate_imports.go`
- The script runs a Go program (`generate_imports.go`) to generate an `imports.tf` file inside the migration folder.

#### Step 5: Generate `provider.tf`
- A `provider.tf` file is generated in the migration folder with the specified provider version.

#### Step 6: Run `terraform init`
- The script initializes Terraform inside the migration folder using `terraform init`.

#### Step 7: Run `terraform plan`
- The script runs `terraform plan` with the `-generate-config-out` flag to generate a new configuration file (`generated.tf`).

#### Step 8: Remove Null Values
- Python is used to clean the JSON file by removing null values, generating a cleaned JSON file (`cleaned_config.json`).

#### Step 9: Apply the Configuration
- The script applies the cleaned configuration using `terraform apply`.
**Note**: The script will prompt you to confirm the apply action and will override your existing resources with the new configuration.
If you choose not to apply, the script will exit.

#### Step 10: Cleanup
- Temporary files are deleted.

---

### 5. Example Outputs

#### Migration Type Selection
```plaintext
[INFO] Select the migration type:
[INFO] 1) Migrate based on a folder containing terraform.tfstate
[INFO] 2) Migrate based on a specific resource name
Enter your choice (1 or 2): 2
```

#### Provider Version Prompt
```plaintext
Enter the Terraform provider version to migrate to (e.g., ~>1.19.0): >=2.0.0
```

#### Logs During Execution
```plaintext
2024-12-01 15:45:22 [INFO] Creating migration folder: ./alert_migration
2024-12-01 15:45:22 [INFO] Running generate_imports.go with -type...
2024-12-01 15:45:22 [INFO] Successfully generated imports.tf at ./alert_migration.
2024-12-01 15:45:22 [INFO] Generating provider configuration in ./alert_migration/provider.tf...
2024-12-01 15:45:22 [INFO] Provider configuration generated in ./alert_migration/provider.tf.
2024-12-01 15:45:22 [INFO] Initializing Terraform in ./alert_migration...
2024-12-01 15:45:22 [INFO] Running terraform plan in ./alert_migration...
...
2024-12-01 15:45:22 [INFO] Terraform apply completed.
2024-12-01 15:45:22 [INFO] Cleanup completed.
2024-12-01 15:45:22 [INFO] Script completed successfully.
```

---

### 6. Notes
- **Customization**:
- Update the resource types in the script if new ones are added.
- Adjust the default provider version if needed.
- **Error Handling**:
- The script will exit if any step fails (`set -e`).
- Logs are color-coded for better visibility (`INFO`, `ERROR`, `WARNING`, etc.).

---
Loading

0 comments on commit 000de35

Please sign in to comment.