diff --git a/go.mod b/go.mod index 98a5fd37d..7724ef2aa 100644 --- a/go.mod +++ b/go.mod @@ -76,3 +76,5 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) + +replace github.com/heimweh/go-pagerduty => github.com/alexzakabluk/go-pagerduty v0.0.0-20240607142119-ac9a64bba6da diff --git a/go.sum b/go.sum index c7794d9a7..746f28393 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alexzakabluk/go-pagerduty v0.0.0-20240607142119-ac9a64bba6da h1:O2mVKSglj/gEz+Z7GX+L4Y1zGRIiDxPHdfp6Ri7klww= +github.com/alexzakabluk/go-pagerduty v0.0.0-20240607142119-ac9a64bba6da/go.mod h1:r59w5iyN01Qvi734yA5hZldbSeJJmsJzee/1kQ/MK7s= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= @@ -95,8 +97,6 @@ github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= -github.com/heimweh/go-pagerduty v0.0.0-20240503143637-3459408ac715 h1:DbdS2LIPkhsqgRcQzOAux0RpTJSH8VYOrN4rZZgznak= -github.com/heimweh/go-pagerduty v0.0.0-20240503143637-3459408ac715/go.mod h1:r59w5iyN01Qvi734yA5hZldbSeJJmsJzee/1kQ/MK7s= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_router.go b/pagerduty/resource_pagerduty_event_orchestration_path_router.go index 5a1a0e8b0..873864b42 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_router.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_router.go @@ -63,9 +63,29 @@ func resourcePagerDutyEventOrchestrationPathRouter() *schema.Resource { MaxItems: 1, // there can only be one action for router Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "dynamic_route_to": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "lookup_by": { + Type: schema.TypeString, + Required: true, + }, + "regex": { + Type: schema.TypeString, + Required: true, + }, + "source": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, "route_to": { Type: schema.TypeString, - Required: true, + Optional: true, ValidateFunc: func(v interface{}, key string) (warns []string, errs []error) { value := v.(string) if value == "unrouted" { @@ -294,7 +314,12 @@ func expandRouterActions(v interface{}) *pagerduty.EventOrchestrationPathRuleAct actions := new(pagerduty.EventOrchestrationPathRuleActions) for _, ai := range v.([]interface{}) { am := ai.(map[string]interface{}) - actions.RouteTo = am["route_to"].(string) + dra := am["dynamic_route_to"] + if !isNilFunc(dra) && len(dra.([]interface{})) > 0 { + actions.DynamicRouteTo = expandRouterDynamicRouteToAction(dra) + } else { + actions.RouteTo = am["route_to"].(string) + } } return actions @@ -311,6 +336,17 @@ func expandCatchAll(v interface{}) *pagerduty.EventOrchestrationPathCatchAll { return catchAll } +func expandRouterDynamicRouteToAction(v interface{}) *pagerduty.EventOrchestrationPathDynamicRouteTo { + dr := new(pagerduty.EventOrchestrationPathDynamicRouteTo) + for _, i := range v.([]interface{}) { + dra := i.(map[string]interface{}) + dr.LookupBy = dra["lookup_by"].(string) + dr.Regex = dra["regex"].(string) + dr.Source = dra["source"].(string) + } + return dr +} + func flattenSets(orchPathSets []*pagerduty.EventOrchestrationPathSet) []interface{} { var flattenedSets []interface{} for _, set := range orchPathSets { @@ -344,7 +380,11 @@ func flattenRouterActions(actions *pagerduty.EventOrchestrationPathRuleActions) var actionsMap []map[string]interface{} am := make(map[string]interface{}) - am["route_to"] = actions.RouteTo + if actions.DynamicRouteTo != nil { + am["dynamic_route_to"] = flattenRouterDynamicRouteToAction(actions.DynamicRouteTo) + } else { + am["route_to"] = actions.RouteTo + } actionsMap = append(actionsMap, am) return actionsMap } @@ -360,6 +400,18 @@ func flattenCatchAll(catchAll *pagerduty.EventOrchestrationPathCatchAll) []map[s return caMap } +func flattenRouterDynamicRouteToAction(dra *pagerduty.EventOrchestrationPathDynamicRouteTo) []map[string]interface{} { + var dr []map[string]interface{} + + dr = append(dr, map[string]interface{}{ + "lookup_by": dra.LookupBy, + "regex": dra.Regex, + "source": dra.Source, + }) + + return dr +} + func resourcePagerDutyEventOrchestrationPathRouterImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { client, err := meta.(*Config).Client() if err != nil { diff --git a/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go b/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go index 246c349d5..c2885623e 100644 --- a/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go +++ b/pagerduty/resource_pagerduty_event_orchestration_path_router_test.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/heimweh/go-pagerduty/pagerduty" ) func init() { @@ -23,6 +24,17 @@ func TestAccPagerDutyEventOrchestrationPathRouter_Basic(t *testing.T) { service := fmt.Sprintf("tf-%s", acctest.RandString(5)) orchestration := fmt.Sprintf("tf-orchestration-%s", acctest.RandString(5)) + dynamicRouteToByNameInput := &pagerduty.EventOrchestrationPathDynamicRouteTo{ + LookupBy: "service_name", + Regex: ".*", + Source: "event.custom_details.pd_service_name", + } + dynamicRouteToByIDInput := &pagerduty.EventOrchestrationPathDynamicRouteTo{ + LookupBy: "service_id", + Regex: "ID:(.*)", + Source: "event.custom_details.pd_service_id", + } + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -48,6 +60,27 @@ func TestAccPagerDutyEventOrchestrationPathRouter_Basic(t *testing.T) { "pagerduty_event_orchestration_router.router", "unrouted", true), //test for catch_all route_to prop, by default it should be unrouted ), }, + // Configure a Dynamic Routing rule: + { + Config: testAccCheckPagerDutyEventOrchestrationRouterDynamicRouteToConfig(team, escalationPolicy, service, orchestration, dynamicRouteToByNameInput), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyEventOrchestrationRouterExists("pagerduty_event_orchestration_router.router"), + testAccCheckPagerDutyEventOrchestrationRouterPathDynamicRouteToMatch("pagerduty_event_orchestration_router.router", dynamicRouteToByNameInput), + testAccCheckPagerDutyEventOrchestrationRouterPathRouteToMatch( + "pagerduty_event_orchestration_router.router", "unrouted", true), + ), + }, + // Update the Dynamic Routing rule added in the previous test case: + { + Config: testAccCheckPagerDutyEventOrchestrationRouterDynamicRouteToConfig(team, escalationPolicy, service, orchestration, dynamicRouteToByIDInput), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyEventOrchestrationRouterExists("pagerduty_event_orchestration_router.router"), + testAccCheckPagerDutyEventOrchestrationRouterPathDynamicRouteToMatch("pagerduty_event_orchestration_router.router", dynamicRouteToByIDInput), + testAccCheckPagerDutyEventOrchestrationRouterPathRouteToMatch( + "pagerduty_event_orchestration_router.router", "unrouted", true), + ), + }, + // Delete the Dynamic Routing rule added in the previous test cases: { Config: testAccCheckPagerDutyEventOrchestrationRouterConfigWithConditions(team, escalationPolicy, service, orchestration), Check: resource.ComposeTestCheckFunc( @@ -279,6 +312,42 @@ func testAccCheckPagerDutyEventOrchestrationRouterConfig(t, ep, s, o string) str `) } +func testAccCheckPagerDutyEventOrchestrationRouterDynamicRouteToConfig(t, ep, s, o string, dynamicRouteToByNameInput *pagerduty.EventOrchestrationPathDynamicRouteTo) string { + routerConfig := fmt.Sprintf( + `resource "pagerduty_event_orchestration_router" "router" { + event_orchestration = pagerduty_event_orchestration.orch.id + + catch_all { + actions { + route_to = "unrouted" + } + } + set { + id = "start" + rule { + disabled = false + label = "dynamic routing rule" + actions { + dynamic_route_to { + lookup_by = "%s" + regex = "%s" + source = "%s" + } + } + } + rule { + label = "static routing rule" + actions { + route_to = pagerduty_service.bar.id + } + } + } + } + `, dynamicRouteToByNameInput.LookupBy, dynamicRouteToByNameInput.Regex, dynamicRouteToByNameInput.Source) + + return fmt.Sprintf("%s%s", createBaseConfig(t, ep, s, o), routerConfig) +} + func testAccCheckPagerDutyEventOrchestrationRouterConfigWithConditions(t, ep, s, o string) string { return fmt.Sprintf("%s%s", createBaseConfig(t, ep, s, o), `resource "pagerduty_event_orchestration_router" "router" { @@ -510,3 +579,28 @@ func testAccCheckPagerDutyEventOrchestrationRouterPathRouteToMatch(router, servi return nil } } + +func testAccCheckPagerDutyEventOrchestrationRouterPathDynamicRouteToMatch(router string, expectedDynamicRouteTo *pagerduty.EventOrchestrationPathDynamicRouteTo) resource.TestCheckFunc { + return func(s *terraform.State) error { + r, rOk := s.RootModule().Resources[router] + if !rOk { + return fmt.Errorf("Not found: %s", router) + } + + rLookupBy := r.Primary.Attributes["set.0.rule.0.actions.0.dynamic_route_to.0.lookup_by"] + rRegex := r.Primary.Attributes["set.0.rule.0.actions.0.dynamic_route_to.0.regex"] + rSource := r.Primary.Attributes["set.0.rule.0.actions.0.dynamic_route_to.0.source"] + + if rLookupBy != expectedDynamicRouteTo.LookupBy { + return fmt.Errorf("Event Orchestration Router `dynamic_route_to.lookup_by` (%v) does not match expected value: %v", rLookupBy, expectedDynamicRouteTo.LookupBy) + } + if rRegex != expectedDynamicRouteTo.Regex { + return fmt.Errorf("Event Orchestration Router `dynamic_route_to.regex` (%v) does not match expected value: %v", rRegex, expectedDynamicRouteTo.Regex) + } + if rSource != expectedDynamicRouteTo.Source { + return fmt.Errorf("Event Orchestration Router `dynamic_route_to.source` (%v) does not match expected value: %v", rSource, expectedDynamicRouteTo.Source) + } + + return nil + } +} diff --git a/vendor/github.com/heimweh/go-pagerduty/pagerduty/event_orchestration_path.go b/vendor/github.com/heimweh/go-pagerduty/pagerduty/event_orchestration_path.go index 72b60e0f4..9760a6702 100644 --- a/vendor/github.com/heimweh/go-pagerduty/pagerduty/event_orchestration_path.go +++ b/vendor/github.com/heimweh/go-pagerduty/pagerduty/event_orchestration_path.go @@ -53,6 +53,7 @@ type EventOrchestrationPathRuleCondition struct { type EventOrchestrationPathRuleActions struct { DropEvent bool `json:"drop_event"` RouteTo string `json:"route_to"` + DynamicRouteTo *EventOrchestrationPathDynamicRouteTo `json:"dynamic_route_to"` Suppress bool `json:"suppress"` Suspend *int `json:"suspend"` Priority string `json:"priority"` @@ -66,6 +67,12 @@ type EventOrchestrationPathRuleActions struct { Extractions []*EventOrchestrationPathActionExtractions `json:"extractions"` } +type EventOrchestrationPathDynamicRouteTo struct { + Source string `json:"source,omitempty"` + Regex string `json:"regex,omitempty"` + LookupBy string `json:"lookup_by,omitempty"` +} + type EventOrchestrationPathIncidentCustomFieldUpdate struct { ID string `json:"id,omitempty"` Value string `json:"value,omitempty"` diff --git a/vendor/modules.txt b/vendor/modules.txt index fb52ea944..9cfa72738 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -257,7 +257,7 @@ github.com/hashicorp/terraform-svchost # github.com/hashicorp/yamux v0.1.1 ## explicit; go 1.15 github.com/hashicorp/yamux -# github.com/heimweh/go-pagerduty v0.0.0-20240503143637-3459408ac715 +# github.com/heimweh/go-pagerduty v0.0.0-20240503143637-3459408ac715 => github.com/alexzakabluk/go-pagerduty v0.0.0-20240607142119-ac9a64bba6da ## explicit; go 1.17 github.com/heimweh/go-pagerduty/pagerduty github.com/heimweh/go-pagerduty/persistentconfig @@ -558,3 +558,4 @@ google.golang.org/protobuf/types/known/timestamppb # gopkg.in/ini.v1 v1.67.0 ## explicit gopkg.in/ini.v1 +# github.com/heimweh/go-pagerduty => github.com/alexzakabluk/go-pagerduty v0.0.0-20240607142119-ac9a64bba6da