diff --git a/CHANGELOG.md b/CHANGELOG.md index 23189493..ea2ab5e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.4.8 (September 4, 2020) +NEW RESOURCE: +* Notification rule implemented (#121) + + ## 0.4.7 (August 26, 2020) IMPROVEMENTS: diff --git a/go.sum b/go.sum index 01f2a0e6..8f4358fa 100644 --- a/go.sum +++ b/go.sum @@ -169,10 +169,6 @@ github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY7 github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.1-0.20200814082615-0451657a72bb h1:jrc1HVw4t8jZxd4LhiRCF9zp+NUsufZ5+KbLZ76ENOg= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.1-0.20200814082615-0451657a72bb/go.mod h1:VOkJ7STzYj+nXRhMcBTcmt8uZZ17KZKJdZtJpgHLbT8= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.2-0.20200818092809-258635176b1d h1:FXSBAW4+IgVlSt9Fo3Kq7aK8v2F8eBYLm4BiDOzdKLI= -github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.2-0.20200818092809-258635176b1d/go.mod h1:VOkJ7STzYj+nXRhMcBTcmt8uZZ17KZKJdZtJpgHLbT8= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.2-0.20200820123717-3bcc8ea32b68 h1:aeMcivVe6oeKG+2eIml82VULDUIRLXfqEDNmfjesf5o= github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.2-0.20200820123717-3bcc8ea32b68/go.mod h1:VOkJ7STzYj+nXRhMcBTcmt8uZZ17KZKJdZtJpgHLbT8= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= diff --git a/opsgenie/provider.go b/opsgenie/provider.go index 3971df9f..e5d66c78 100644 --- a/opsgenie/provider.go +++ b/opsgenie/provider.go @@ -23,12 +23,12 @@ func Provider() terraform.ResourceProvider { }, ResourcesMap: map[string]*schema.Resource{ - "opsgenie_team": resourceOpsGenieTeam(), "opsgenie_team_routing_rule": resourceOpsGenieTeamRoutingRule(), "opsgenie_user": resourceOpsGenieUser(), "opsgenie_user_contact": resourceOpsGenieUserContact(), "opsgenie_notification_policy": resourceOpsGenieNotificationPolicy(), + "opsgenie_notification_rule": resourceOpsGenieNotificationRule(), "opsgenie_escalation": resourceOpsgenieEscalation(), "opsgenie_api_integration": resourceOpsgenieApiIntegration(), "opsgenie_email_integration": resourceOpsgenieEmailIntegration(), diff --git a/opsgenie/resource_opsgenie_notification_policy.go b/opsgenie/resource_opsgenie_notification_policy.go index 9ec1c072..f8acbacb 100644 --- a/opsgenie/resource_opsgenie_notification_policy.go +++ b/opsgenie/resource_opsgenie_notification_policy.go @@ -518,8 +518,8 @@ func expandOpsGenieNotificationPolicyDelayAction(input []interface{}) *policy.De config := v.(map[string]interface{}) action.DelayOption = policy.DelayType(config["delay_option"].(string)) untilMinute := config["until_minute"].(int) - action.UntilMinute = &untilMinute untilHour := config["until_hour"].(int) + action.UntilMinute = &untilMinute action.UntilHour = &untilHour if len(config["duration"].([]interface{})) > 0 { action.Duration = expandOpsGenieNotificationPolicyDuration(config["duration"].([]interface{})) diff --git a/opsgenie/resource_opsgenie_notification_rule.go b/opsgenie/resource_opsgenie_notification_rule.go new file mode 100644 index 00000000..84364010 --- /dev/null +++ b/opsgenie/resource_opsgenie_notification_rule.go @@ -0,0 +1,567 @@ +package opsgenie + +import ( + "context" + "fmt" + "log" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ogClient "github.com/opsgenie/opsgenie-go-sdk-v2/client" + "github.com/opsgenie/opsgenie-go-sdk-v2/notification" + "github.com/opsgenie/opsgenie-go-sdk-v2/og" +) + +func resourceOpsGenieNotificationRule() *schema.Resource { + return &schema.Resource{ + Create: resourceOpsGenieNotificationRuleCreate, + Read: resourceOpsGenieNotificationRuleRead, + Update: resourceOpsGenieNotificationRuleUpdate, + Delete: resourceOpsGenieNotificationRuleDelete, + Importer: &schema.ResourceImporter{ + State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + idParts := strings.Split(d.Id(), "/") + if len(idParts) != 2 || idParts[0] == "" || idParts[1] == "" { + return nil, fmt.Errorf("Unexpected format of ID (%q), expected username/notification_rule_id", d.Id()) + } + d.Set("username", idParts[0]) + d.SetId(idParts[1]) + return []*schema.ResourceData{d}, nil + }, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 512), + ForceNew: true, + }, + "username": { + Type: schema.TypeString, + Required: true, + }, + "action_type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + "create-alert", "acknowledged-alert", "closed-alert", "assigned-alert", "add-note", + "schedule-start", "schedule-end", "incoming-call-routing", + }, false), + ForceNew: true, + }, + "notification_time": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "just-before", "15-minutes-ago", "1-hour-ago", "1-day-ago", + }, false), + }, + }, + "steps": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "send_after": { + Type: schema.TypeInt, + Optional: true, + }, + "contact": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "method": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"email", "sms", "voice", "mobile"}, false), + }, + "to": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "order": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + "repeat": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "loop_after": { + Type: schema.TypeInt, + Required: true, + }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + }, + }, + }, + "time_restriction": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + }, + "restrictions": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_day": { + Type: schema.TypeString, + Required: true, + }, + "end_day": { + Type: schema.TypeString, + Required: true, + }, + "start_hour": { + Type: schema.TypeInt, + Required: true, + }, + "start_min": { + Type: schema.TypeInt, + Required: true, + }, + "end_hour": { + Type: schema.TypeInt, + Required: true, + }, + "end_min": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + "restriction": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_hour": { + Type: schema.TypeInt, + Required: true, + }, + "start_min": { + Type: schema.TypeInt, + Required: true, + }, + "end_hour": { + Type: schema.TypeInt, + Required: true, + }, + "end_min": { + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + "schedules": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Default: true, + }, + }, + }, + }, + "criteria": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + }, + "conditions": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "field": { + Type: schema.TypeString, + Required: true, + }, + "key": { + Type: schema.TypeString, + Optional: true, + }, + "not": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "operation": { + Type: schema.TypeString, + Required: true, + }, + "expected_value": { + Type: schema.TypeString, + Optional: true, + }, + "order": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func resourceOpsGenieNotificationRuleCreate(d *schema.ResourceData, meta interface{}) error { + client, err := notification.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + + enabled := d.Get("enabled").(bool) + timeRestriction := d.Get("time_restriction").([]interface{}) + criteria := d.Get("criteria").([]interface{}) + + createRequest := ¬ification.CreateRuleRequest{ + UserIdentifier: d.Get("username").(string), + Name: d.Get("name").(string), + ActionType: notification.ActionType(d.Get("action_type").(string)), + NotificationTime: expandOpsGenieNotificationRuleNotificationTime(d.Get("notification_time").(*schema.Set)), + Enabled: &enabled, + Order: uint32(d.Get("order").(int)), + Repeat: expandOpsGenieNotificationRuleRepeat(d), + Criteria: expandOpsgenieNotificationRuleCriteria(criteria), + } + + if len(d.Get("schedules").([]interface{})) > 0 { + createRequest.Schedules = expandOpsGenieNotificationRuleSchedules(d.Get("schedules").([]interface{})) + } + + if len(d.Get("steps").([]interface{})) > 0 { + createRequest.Steps = expandOpsGenieNotificationRuleSteps(d.Get("steps").([]interface{})) + } + + if len(timeRestriction) > 0 { + createRequest.TimeRestriction = expandTimeRestrictions(timeRestriction) + } + + log.Printf("[INFO] Creating Notification Rule '%s' for User: '%s'", d.Get("name").(string), d.Get("username").(string)) + result, err := client.CreateRule(context.Background(), createRequest) + if err != nil { + return err + } + + d.SetId(result.SimpleNotificationRule.Id) + + return resourceOpsGenieNotificationRuleRead(d, meta) +} + +func resourceOpsGenieNotificationRuleRead(d *schema.ResourceData, meta interface{}) error { + client, err := notification.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + name := d.Get("name").(string) + username := d.Get("username").(string) + + log.Printf("[INFO] Reading OpsGenie Notification Rule '%s' for user '%s'", name, username) + + rule, err := client.GetRule(context.Background(), ¬ification.GetRuleRequest{ + UserIdentifier: username, + RuleId: d.Id(), + }) + if err != nil { + x := err.(*ogClient.ApiError) + if x.StatusCode == 404 { + log.Printf("[WARN] Removing Notification Rule because it's gone %s", name) + d.SetId("") + return nil + } + } + d.Set("name", rule.Name) + d.Set("action_type", rule.ActionType) + d.Set("notification_time", rule.NotificationTime) + d.Set("enabled", rule.Enabled) + d.Set("order", rule.Order) + d.Set("time_restriction", flattenOpsgenieNotificationRuleTimeRestriction(rule.TimeRestriction)) + d.Set("schedules", rule.Schedules) + + if rule.Steps != nil { + d.Set("steps", flattenOpsGenieNotificationRuleSteps(rule.Steps)) + } else { + d.Set("steps", nil) + } + + return nil +} + +func resourceOpsGenieNotificationRuleUpdate(d *schema.ResourceData, meta interface{}) error { + client, err := notification.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + + enabled := d.Get("enabled").(bool) + timeRestriction := d.Get("time_restriction").([]interface{}) + criteria := d.Get("criteria").([]interface{}) + + updateRequest := ¬ification.UpdateRuleRequest{ + UserIdentifier: d.Get("username").(string), + RuleId: d.Id(), + NotificationTime: expandOpsGenieNotificationRuleNotificationTime(d.Get("notification_time").(*schema.Set)), + Enabled: &enabled, + Order: uint32(d.Get("order").(int)), + Repeat: expandOpsGenieNotificationRuleRepeat(d), + Criteria: expandOpsgenieNotificationRuleCriteria(criteria), + } + + if len(d.Get("schedules").([]interface{})) > 0 { + updateRequest.Schedules = expandOpsGenieNotificationRuleSchedules(d.Get("schedules").([]interface{})) + } + + if len(d.Get("steps").([]interface{})) > 0 { + updateRequest.Steps = expandOpsGenieNotificationRuleSteps(d.Get("steps").([]interface{})) + } + + if len(timeRestriction) > 0 { + updateRequest.TimeRestriction = expandTimeRestrictions(timeRestriction) + } + + log.Printf("[INFO] Updating Notification Rule '%s' for User: '%s'", d.Get("name").(string), d.Get("username").(string)) + result, err := client.UpdateRule(context.Background(), updateRequest) + if err != nil { + return err + } + + d.SetId(result.SimpleNotificationRule.Id) + + return resourceOpsGenieNotificationRuleRead(d, meta) +} + +func resourceOpsGenieNotificationRuleDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Deleting OpsGenie Notification Rule '%s' for user '%s'", d.Get("name").(string), d.Get("username").(string)) + client, err := notification.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + deleteRequest := ¬ification.DeleteRuleRequest{ + UserIdentifier: d.Get("username").(string), + RuleId: d.Id(), + } + + _, err = client.DeleteRule(context.Background(), deleteRequest) + if err != nil { + return err + } + return nil +} + +func expandOpsGenieNotificationRuleNotificationTime(input *schema.Set) []notification.NotificationTimeType { + output := make([]notification.NotificationTimeType, 0) + + if input == nil { + return output + } + + for _, v := range input.List() { + output = append(output, notification.NotificationTimeType(v.(string))) + } + return output +} + +func expandOpsGenieNotificationRuleSteps(input []interface{}) []*og.Step { + output := make([]*og.Step, 0) + if input == nil { + return output + } + for _, v := range input { + config := v.(map[string]interface{}) + enabled := config["enabled"].(bool) + element := og.Step{} + element.Enabled = &enabled + element.Contact = expandOpsGenieNotificationRuleStepsContact(config["contact"].([]interface{})) + if config["send_after"].(int) > 0 { + element.SendAfter = &og.SendAfter{ + TimeUnit: "minute", + TimeAmount: uint32(config["send_after"].(int)), + } + } + output = append(output, &element) + } + return output +} + +func expandOpsGenieNotificationRuleStepsContact(input []interface{}) og.Contact { + output := og.Contact{} + if input == nil { + return output + } + for _, v := range input { + config := v.(map[string]interface{}) + output.To = config["to"].(string) + output.MethodOfContact = og.MethodType(config["method"].(string)) + } + return output +} + +func flattenOpsGenieNotificationRuleSteps(input []*notification.StepResult) []map[string]interface{} { + output := make([]map[string]interface{}, 0, len(input)) + for _, v := range input { + element := make(map[string]interface{}) + element["enabled"] = v.Enabled + element["contact"] = flattenOpsGenieNotificationRuleStepsContact(v.Contact) + if v.SendAfter != nil { + element["send_after"] = v.SendAfter.TimeAmount + } + output = append(output, element) + } + return output +} + +func flattenOpsGenieNotificationRuleStepsContact(input og.Contact) []map[string]interface{} { + output := make([]map[string]interface{}, 0, 1) + element := make(map[string]interface{}) + element["to"] = input.To + element["method"] = input.MethodOfContact + output = append(output, element) + return output +} + +func expandOpsGenieNotificationRuleRepeat(d *schema.ResourceData) *notification.Repeat { + input := d.Get("repeat").([]interface{}) + repeat := notification.Repeat{} + for _, r := range input { + repeatMap := r.(map[string]interface{}) + repeatEnabled := repeatMap["enabled"].(bool) + repeat.LoopAfter = uint32(repeatMap["loop_after"].(int)) + repeat.Enabled = &repeatEnabled + } + return &repeat +} + +func flattenOpsgenieNotificationRuleTimeRestriction(input *og.TimeRestriction) []map[string]interface{} { + rules := make([]map[string]interface{}, 0, 1) + out := make(map[string]interface{}) + out["type"] = input.Type + + if len(input.RestrictionList) > 0 { + restrictions := make([]map[string]interface{}, 0, len(input.RestrictionList)) + for _, r := range input.RestrictionList { + restrictionMap := make(map[string]interface{}) + restrictionMap["start_min"] = r.StartMin + restrictionMap["start_hour"] = r.StartHour + restrictionMap["start_day"] = r.StartDay + restrictionMap["end_min"] = r.EndMin + restrictionMap["end_hour"] = r.EndHour + restrictionMap["end_day"] = r.EndDay + restrictions = append(restrictions, restrictionMap) + } + return restrictions + } else { + restriction := make(map[string]interface{}) + //IF RESTRICTION + restriction["end_day"] = input.Restriction.EndDay + restriction["end_hour"] = input.Restriction.EndHour + restriction["end_min"] = input.Restriction.EndMin + restriction["start_day"] = input.Restriction.StartDay + restriction["start_hour"] = input.Restriction.StartHour + restriction["start_min"] = input.Restriction.StartMin + + //IF restrictions + rules = append(rules, restriction) + return rules + } +} + +func expandOpsGenieNotificationRuleSchedules(input []interface{}) []notification.Schedule { + output := make([]notification.Schedule, 0) + if input != nil { + for _, v := range input { + scheduleMap := v.(map[string]interface{}) + scheduleName := scheduleMap["name"] + scheduleType := scheduleMap["type"] + output = append(output, notification.Schedule{ + TypeOfSchedule: scheduleType.(string), + Name: scheduleName.(string)}) + } + } + return output +} + +func expandOpsgenieNotificationRuleCriteria(input []interface{}) *og.Criteria { + criteria := og.Criteria{} + for _, r := range input { + inputMap := r.(map[string]interface{}) + criteriaType := inputMap["type"].(string) + conditions := expandOpsgenieNotificationRuleCriteriaConditions(inputMap["conditions"].([]interface{})) + criteria.Conditions = conditions + criteria.CriteriaType = og.ConditionMatchType(criteriaType) + } + return &criteria +} + +func expandOpsgenieNotificationRuleCriteriaConditions(input []interface{}) []og.Condition { + conditions := make([]og.Condition, 0, len(input)) + if input != nil { + for _, v := range input { + inputMap := v.(map[string]interface{}) + condition := og.Condition{} + condition.Field = og.ConditionFieldType(inputMap["field"].(string)) + isNot := inputMap["not"].(bool) + condition.IsNot = &isNot + condition.Operation = og.ConditionOperation(inputMap["operation"].(string)) + condition.ExpectedValue = inputMap["expected_value"].(string) + key := inputMap["key"].(string) + if key != "" { + condition.Key = inputMap["key"].(string) + } + order := inputMap["order"].(int) + condition.Order = &order + conditions = append(conditions, condition) + } + } + return conditions +} diff --git a/opsgenie/resource_opsgenie_notification_rule_test.go b/opsgenie/resource_opsgenie_notification_rule_test.go new file mode 100644 index 00000000..f869992f --- /dev/null +++ b/opsgenie/resource_opsgenie_notification_rule_test.go @@ -0,0 +1,199 @@ +package opsgenie + +import ( + "context" + "errors" + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + ogClient "github.com/opsgenie/opsgenie-go-sdk-v2/client" + "github.com/opsgenie/opsgenie-go-sdk-v2/notification" + "github.com/opsgenie/opsgenie-go-sdk-v2/user" + "log" + "strings" + "testing" +) + +func init() { + resource.AddTestSweepers("opsgenie_notification_rule", &resource.Sweeper{ + Name: "opsgenie_notification_rule", + F: testSweepNotificationRule, + }) + +} + +func testSweepNotificationRule(region string) error { + meta, err := sharedConfigForRegion() + if err != nil { + return err + } + + client, err := notification.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + + userClient, err := user.NewClient(meta.(*OpsgenieClient).client.Config) + if err != nil { + return err + } + respUser, err := userClient.List(context.Background(), &user.ListRequest{}) + if err != nil { + return err + } + for _, u := range respUser.Users { + if strings.HasPrefix(u.Username, "genietest-") { + resp, err := client.ListRule(context.Background(), ¬ification.ListRuleRequest{ + UserIdentifier: u.Id, + }) + if err != nil { + return err + } + for _, r := range resp.SimpleNotificationRules { + deleteRequest := ¬ification.DeleteRuleRequest{ + UserIdentifier: u.Id, + RuleId: r.Id, + } + if _, err := client.DeleteRule(context.Background(), deleteRequest); err != nil { + return err + } + } + } + } + return nil +} + +func TestAccOpsGenieNotificationRule_basic(t *testing.T) { + randomName := acctest.RandString(6) + config := testAccOpsGenieNotificationRule_basic(randomName) + + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testCheckOpsGenieNotificationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckOpsGenieNotificationRuleExists("opsgenie_notification_rule.test", randomName), + ), + }, + }, + }) +} + +func testCheckOpsGenieNotificationRuleDestroy(s *terraform.State) error { + client, err := notification.NewClient(testAccProvider.Meta().(*OpsgenieClient).client.Config) + if err != nil { + return err + } + for _, rs := range s.RootModule().Resources { + if rs.Type != "opsgenie_notification_rule" { + continue + } + req := notification.GetRuleRequest{ + UserIdentifier: rs.Primary.Attributes["username"], + RuleId: rs.Primary.Attributes["id"], + } + _, err := client.GetRule(context.Background(), &req) + if err != nil { + x := err.(*ogClient.ApiError) + if x.StatusCode != 404 { + return errors.New(fmt.Sprintf("Notification rule still exists: %s", x.Error())) + } + } + } + + return nil +} + +func testCheckOpsGenieNotificationRuleExists(name, username string) resource.TestCheckFunc { + return func(s *terraform.State) error { + + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + client, err := notification.NewClient(testAccProvider.Meta().(*OpsgenieClient).client.Config) + if err != nil { + return err + } + req := notification.GetRuleRequest{ + RuleId: rs.Primary.Attributes["id"], + UserIdentifier: rs.Primary.Attributes["username"], + } + + _, err = client.GetRule(context.Background(), &req) + if err != nil { + return fmt.Errorf("Notification rule does not exist (and it should).") + } else { + log.Printf("Notification rule found.") + } + + return nil + } +} + +func testAccOpsGenieNotificationRule_basic(randomName string) string { + return fmt.Sprintf(` +resource "opsgenie_user" "test" { + username = "genieuser-%s@opsgenie.com" + full_name = "Acceptance Test User" + role = "User" +} +resource "opsgenie_team" "test" { + name = "genieteam-%s" + description = "This team deals with all the things" + member { + id = opsgenie_user.test.id + role = "admin" + } +} +resource "opsgenie_schedule" "test" { + name = "genieschedule-%s" + description = "schedule test" + timezone = "Europe/Rome" + enabled = false + owner_team_id = opsgenie_team.test.id +} +resource "opsgenie_notification_rule" "test" { + name = "genierule-%s" + username = opsgenie_user.test.username + action_type = "schedule-end" + notification_time = ["just-before", "15-minutes-ago"] + enabled = true + steps { + contact { + method = "email" + to = "genieuser-%s@opsgenie.com" + } + } + repeat { + loop_after = 2 + } + time_restriction { + type = "time-of-day" + restriction { + start_hour = 3 + start_min = 15 + end_hour = 5 + end_min = 30 + } + } + schedules { + name = opsgenie_schedule.test.name + type = "schedule" + } + criteria { + type = "match-any-condition" + conditions { + field = "message" + operation = "contains" + expected_value = "expected1" + not = false + } + } +} +`, randomName, randomName, randomName, randomName, randomName) +} diff --git a/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/notification.go b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/notification.go new file mode 100644 index 00000000..57676829 --- /dev/null +++ b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/notification.go @@ -0,0 +1,151 @@ +package notification + +import ( + "context" + "github.com/opsgenie/opsgenie-go-sdk-v2/client" +) + +type Client struct { + client *client.OpsGenieClient +} + +func NewClient(config *client.Config) (*Client, error) { + opsgenieClient, err := client.NewOpsGenieClient(config) + if err != nil { + return nil, err + } + return &Client{client: opsgenieClient}, nil +} +func (c *Client) CreateRuleStep(context context.Context, request *CreateRuleStepRequest) (*CreateRuleStepResult, error) { + result := &CreateRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) GetRuleStep(context context.Context, request *GetRuleStepRequest) (*GetRuleStepResult, error) { + result := &GetRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) UpdateRuleStep(context context.Context, request *UpdateRuleStepRequest) (*UpdateRuleStepResult, error) { + result := &UpdateRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) DeleteRuleStep(context context.Context, request *DeleteRuleStepRequest) (*DeleteRuleStepResult, error) { + result := &DeleteRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) ListRuleStep(context context.Context, request *ListRuleStepsRequest) (*ListRuleStepResult, error) { + result := &ListRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) EnableRuleStep(context context.Context, request *EnableRuleStepRequest) (*EnableRuleStepResult, error) { + result := &EnableRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) DisableRuleStep(context context.Context, request *DisableRuleStepRequest) (*DisableRuleStepResult, error) { + result := &DisableRuleStepResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) CreateRule(context context.Context, request *CreateRuleRequest) (*CreateRuleResult, error) { + result := &CreateRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} +func (c *Client) GetRule(context context.Context, request *GetRuleRequest) (*GetRuleResult, error) { + result := &GetRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) UpdateRule(context context.Context, request *UpdateRuleRequest) (*UpdateRuleResult, error) { + result := &UpdateRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) DeleteRule(context context.Context, request *DeleteRuleRequest) (*DeleteRuleResult, error) { + result := &DeleteRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) ListRule(context context.Context, request *ListRuleRequest) (*ListRuleResult, error) { + result := &ListRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) EnableRule(context context.Context, request *EnableRuleRequest) (*EnableRuleResult, error) { + result := &EnableRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) DisableRule(context context.Context, request *DisableRuleRequest) (*DisableRuleResult, error) { + result := &DisableRuleResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} + +func (c *Client) CopyRule(context context.Context, request *CopyNotificationRulesRequest) (*CopyNotificationRulesResult, error) { + result := &CopyNotificationRulesResult{} + err := c.client.Exec(context, request, result) + if err != nil { + return nil, err + } + return result, nil +} diff --git a/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/request.go b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/request.go new file mode 100644 index 00000000..5b4bf731 --- /dev/null +++ b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/request.go @@ -0,0 +1,590 @@ +package notification + +import ( + "net/http" + + "github.com/opsgenie/opsgenie-go-sdk-v2/client" + "github.com/opsgenie/opsgenie-go-sdk-v2/og" + "github.com/pkg/errors" +) + +type CreateRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + Contact og.Contact `json:"contact"` + SendAfter *og.SendAfter `json:"sendAfter,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func (r *CreateRuleStepRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + + err = validateContact(&r.Contact) + if err != nil { + return err + } + return nil +} + +func (r *CreateRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps" +} + +func (r *CreateRuleStepRequest) Method() string { + return http.MethodPost +} + +type GetRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + RuleStepId string +} + +func (r *GetRuleStepRequest) Validate() error { + err := validateRuleStepIdentifier(r.UserIdentifier, r.RuleId, r.RuleStepId) + if err != nil { + return err + } + return nil +} + +func (r *GetRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps/" + r.RuleStepId +} + +func (r *GetRuleStepRequest) Method() string { + return http.MethodGet +} + +type UpdateRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + RuleStepId string + Contact *og.Contact `json:"contact,omitempty"` + SendAfter *og.SendAfter `json:"sendAfter,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func (r *UpdateRuleStepRequest) Validate() error { + err := validateRuleStepIdentifier(r.UserIdentifier, r.RuleId, r.RuleStepId) + if err != nil { + return err + } + if r.Contact != nil { + err = validateContact(r.Contact) + if err != nil { + return err + } + } + + return nil +} + +func (r *UpdateRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps/" + r.RuleStepId +} + +func (r *UpdateRuleStepRequest) Method() string { + return http.MethodPatch +} + +type DeleteRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + RuleStepId string +} + +func (r *DeleteRuleStepRequest) Validate() error { + err := validateRuleStepIdentifier(r.UserIdentifier, r.RuleId, r.RuleStepId) + if err != nil { + return err + } + return nil +} + +func (r *DeleteRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps/" + r.RuleStepId +} + +func (r *DeleteRuleStepRequest) Method() string { + return http.MethodDelete +} + +type ListRuleStepsRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string +} + +func (r *ListRuleStepsRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + return nil +} + +func (r *ListRuleStepsRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps" +} + +func (r *ListRuleStepsRequest) Method() string { + return http.MethodGet +} + +type EnableRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + RuleStepId string +} + +func (r *EnableRuleStepRequest) Validate() error { + err := validateRuleStepIdentifier(r.UserIdentifier, r.RuleId, r.RuleStepId) + if err != nil { + return err + } + return nil +} + +func (r *EnableRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps/" + r.RuleStepId + "/enable" +} + +func (r *EnableRuleStepRequest) Method() string { + return http.MethodPost +} + +type DisableRuleStepRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + RuleStepId string +} + +func (r *DisableRuleStepRequest) Validate() error { + err := validateRuleStepIdentifier(r.UserIdentifier, r.RuleId, r.RuleStepId) + if err != nil { + return err + } + return nil +} + +func (r *DisableRuleStepRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/steps/" + r.RuleStepId + "/disable" +} + +func (r *DisableRuleStepRequest) Method() string { + return http.MethodPost +} + +type CreateRuleRequest struct { + client.BaseRequest + UserIdentifier string + Name string `json:"name"` + ActionType ActionType `json:"actionType"` + Criteria *og.Criteria `json:"criteria,omitempty"` + NotificationTime []NotificationTimeType `json:"notificationTime,omitempty"` + TimeRestriction *og.TimeRestriction `json:"timeRestriction,omitempty"` + Schedules []Schedule `json:"schedules,omitempty"` + Steps []*og.Step `json:"steps,omitempty"` + Order uint32 `json:"order,omitempty"` + Repeat *Repeat `json:"repeat,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func (r *CreateRuleRequest) Validate() error { + if r.UserIdentifier == "" { + return errors.New("User identifier cannot be empty.") + } + if r.Name == "" { + return errors.New("Name cannot be empty.") + } + if r.ActionType == "" { + return errors.New("Action type cannot be empty.") + } + if (r.ActionType == ScheduleStart || r.ActionType == ScheduleEnd) && len(r.NotificationTime) == 0 { + return errors.New("Notification time cannot be empty.") + } + if len(r.Schedules) != 0 { + for _, schedule := range r.Schedules { + err := validateSchedule(schedule) + if err != nil { + return err + } + } + } + if len(r.Steps) != 0 { + for _, step := range r.Steps { + err := validateStep(step, r.ActionType) + if err != nil { + return err + } + } + } + if r.Criteria != nil { + err := og.ValidateCriteria(*r.Criteria) + if err != nil { + return err + } + } + + if r.TimeRestriction != nil { + err := og.ValidateRestrictions(r.TimeRestriction) + if err != nil { + return err + } + } + + if r.Repeat != nil && r.Repeat.LoopAfter <= 0 { + return errors.New("Loop after must have a positive integer value.") + } + + return nil +} + +func (r *CreateRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules" +} + +func (r *CreateRuleRequest) Method() string { + return http.MethodPost +} + +type GetRuleRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string +} + +func (r *GetRuleRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + return nil +} + +func (r *GetRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId +} + +func (r *GetRuleRequest) Method() string { + return http.MethodGet +} + +type UpdateRuleRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string + Criteria *og.Criteria `json:"criteria,omitempty"` + NotificationTime []NotificationTimeType `json:"notificationTime,omitempty"` + TimeRestriction *og.TimeRestriction `json:"timeRestriction,omitempty"` + Schedules []Schedule `json:"schedules,omitempty"` + Steps []*og.Step `json:"steps,omitempty"` + Order uint32 `json:"order,omitempty"` + Repeat *Repeat `json:"repeat,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func (r *UpdateRuleRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + if len(r.Schedules) != 0 { + for _, schedule := range r.Schedules { + err := validateSchedule(schedule) + if err != nil { + return err + } + } + } + + if len(r.Steps) != 0 { + for _, step := range r.Steps { + err := validateStepWithoutActionTypeInfo(step) + if err != nil { + return err + } + } + } + if r.Criteria != nil { + err := og.ValidateCriteria(*r.Criteria) + if err != nil { + return err + } + } + + if r.TimeRestriction != nil { + err := og.ValidateRestrictions(r.TimeRestriction) + if err != nil { + return err + } + } + + if r.Repeat != nil && r.Repeat.LoopAfter <= 0 { + return errors.New("Loop after must have a positive integer value.") + } + return nil +} + +func (r *UpdateRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId +} + +func (r *UpdateRuleRequest) Method() string { + return http.MethodPatch +} + +type DeleteRuleRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string +} + +func (r *DeleteRuleRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + return nil +} + +func (r *DeleteRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId +} + +func (r *DeleteRuleRequest) Method() string { + return http.MethodDelete +} + +type ListRuleRequest struct { + client.BaseRequest + UserIdentifier string +} + +func (r *ListRuleRequest) Validate() error { + if r.UserIdentifier == "" { + return errors.New("User identifier cannot be empty.") + } + return nil +} + +func (r *ListRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules" +} + +func (r *ListRuleRequest) Method() string { + return http.MethodGet +} + +type EnableRuleRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string +} + +func (r *EnableRuleRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + return nil +} + +func (r *EnableRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/enable" +} + +func (r *EnableRuleRequest) Method() string { + return http.MethodPost +} + +type DisableRuleRequest struct { + client.BaseRequest + UserIdentifier string + RuleId string +} + +func (r *DisableRuleRequest) Validate() error { + err := validateRuleIdentifier(r.UserIdentifier, r.RuleId) + if err != nil { + return err + } + return nil +} + +func (r *DisableRuleRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/" + r.RuleId + "/disable" +} + +func (r *DisableRuleRequest) Method() string { + return http.MethodPost +} + +type CopyNotificationRulesRequest struct { + client.BaseRequest + UserIdentifier string + ToUsers []string `json:"toUsers"` + RuleTypes []RuleTypes `json:"ruleTypes"` +} + +func (r *CopyNotificationRulesRequest) Validate() error { + if r.UserIdentifier == "" { + return errors.New("User identifier cannot be empty.") + } + if len(r.ToUsers) == 0 { + return errors.New("You must specify a list of the users which you want to copy the rules to.") + } + if len(r.RuleTypes) == 0 { + return errors.New("Specify a list of the action types you want to copy the rules of.") + } + return nil +} + +func (r *CopyNotificationRulesRequest) ResourcePath() string { + + return "/v2/users/" + r.UserIdentifier + "/notification-rules/copy-to" +} + +func (r *CopyNotificationRulesRequest) Method() string { + return http.MethodPost +} + +func validateRuleIdentifier(userIdentifier string, ruleIdentifier string) error { + if userIdentifier == "" { + return errors.New("User identifier cannot be empty.") + } + if ruleIdentifier == "" { + return errors.New("Rule identifier cannot be empty.") + + } + return nil +} + +func validateRuleStepIdentifier(userIdentifier string, ruleIdentifier string, ruleStepId string) error { + err := validateRuleIdentifier(userIdentifier, ruleIdentifier) + if err != nil { + return err + } + if ruleStepId == "" { + return errors.New("Rule Step identifier cannot be empty.") + + } + return nil +} + +func validateContact(contact *og.Contact) error { + if contact == nil { + return errors.New("Contact cannot be empty.") + + } + if contact.To == "" { + return errors.New("To cannot be empty.") + } + if contact.MethodOfContact == "" { + return errors.New("Method cannot be empty.") + + } + return nil +} + +type ActionType string + +const ( + CreateAlert ActionType = "create-alert" + AcknowledgedAlert ActionType = "acknowledged-alert" + ClosedAlert ActionType = "closed-alert" + AssignedAlert ActionType = "assigned-alert" + AddNote ActionType = "add-note" + ScheduleStart ActionType = "schedule-start" + ScheduleEnd ActionType = "schedule-end" + IncomingCallRouting ActionType = "incoming-call-routing" +) + +type NotificationTimeType string + +const ( + JustBefore NotificationTimeType = "just-before" + FifteenMinutesAgo NotificationTimeType = "15-minutes-ago" + OneHourAgo NotificationTimeType = "1-hour-ago" + OneDayAgo NotificationTimeType = "1-day-ago" +) + +type Schedule struct { + TypeOfSchedule string `json:"type"` + Name string `json:"name,omitempty"` + Id string `json:"id,omitempty"` +} + +func validateSchedule(schedule Schedule) error { + if schedule.TypeOfSchedule != "schedule" { + return errors.New("Type of schedule must be schedule.") + } + return nil +} + +type Repeat struct { + LoopAfter uint32 `json:"loopAfter,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +func validateStep(step *og.Step, actionType ActionType) error { + if step.Contact.To == "" { + return errors.New("To cannot be empty.") + } + if step.Contact.MethodOfContact == "" { + return errors.New("Method cannot be empty.") + } + if (actionType == CreateAlert || actionType == AssignedAlert) && step.SendAfter == nil { + return errors.New("SendAfter cannot be empty.") + } + + return nil +} + +func validateStepWithoutActionTypeInfo(step *og.Step) error { + if step.Contact.To == "" { + return errors.New("To cannot be empty.") + } + if step.Contact.MethodOfContact == "" { + return errors.New("Method cannot be empty.") + } + + return nil +} + +type RuleTypes string + +const ( + All RuleTypes = "all" + AcknowledgedAlertRule RuleTypes = "acknowledged-alert" + RenotifiedAlertRule RuleTypes = "renotified-alert" + ClosedAlertRule RuleTypes = "closed-alert" + ScheduleStartRule RuleTypes = "schedule-start" + AssignedAlertRule RuleTypes = "assigned-alert" + AddNoteRule RuleTypes = "add-note" + NewAlertRule RuleTypes = "new-alert" +) diff --git a/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/result.go b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/result.go new file mode 100644 index 00000000..ea39527e --- /dev/null +++ b/vendor/github.com/opsgenie/opsgenie-go-sdk-v2/notification/result.go @@ -0,0 +1,114 @@ +package notification + +import ( + "github.com/opsgenie/opsgenie-go-sdk-v2/client" + "github.com/opsgenie/opsgenie-go-sdk-v2/og" +) + +type Parent struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` +} + +type RuleStep struct { + Parent Parent `json:"_parent,omitempty"` + Id string `json:"id,omitempty"` + SendAfter og.SendAfter `json:"sendAfter,omitempty"` + Contact og.Contact `json:"contact,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +type CreateRuleStepResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type GetRuleStepResult struct { + client.ResultMetadata + RuleStep RuleStep `json:"data,omitempty"` +} +type UpdateRuleStepResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type DeleteRuleStepResult struct { + client.ResultMetadata + Result string `json:"result,omitempty"` +} + +type ListRuleStepResult struct { + client.ResultMetadata + RuleSteps []RuleStep `json:"data,omitempty"` +} + +type EnableRuleStepResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type DisableRuleStepResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type SimpleNotificationRuleResult struct { + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + ActionType ActionType `json:"actionType,omitempty"` + Order uint32 `json:"order,omitempty"` + Enabled bool `json:"bool,omitempty"` +} + +type CreateRuleResult struct { + client.ResultMetadata + SimpleNotificationRule SimpleNotificationRuleResult `json:"data,omitempty"` +} + +type GetRuleResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + ActionType ActionType `json:"actionType,omitempty"` + Order uint32 `json:"order,omitempty"` + Enabled bool `json:"enabled,omitempty"` + NotificationTime []NotificationTimeType `json:"notificationTime,omitempty"` + TimeRestriction *og.TimeRestriction `json:"timeRestriction,omitempty"` + Steps []*StepResult `json:"steps,omitempty"` + Schedules []*Schedule `json:"schedules,omitempty"` +} + +type StepResult struct { + Contact og.Contact `json:"contact,omitempty"` + SendAfter *og.SendAfter `json:"sendAfter,omitempty"` + Enabled bool `json:"enabled,omitempty"` +} + +type UpdateRuleResult struct { + client.ResultMetadata + SimpleNotificationRule SimpleNotificationRuleResult `json:"data,omitempty"` +} +type DeleteRuleResult struct { + client.ResultMetadata + Result string `json:"result,omitempty"` +} + +type ListRuleResult struct { + client.ResultMetadata + SimpleNotificationRules []SimpleNotificationRuleResult `json:"data,omitempty"` +} + +type EnableRuleResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type DisableRuleResult struct { + client.ResultMetadata + Id string `json:"id,omitempty"` +} + +type CopyNotificationRulesResult struct { + client.ResultMetadata + Result string `json:"result,omitempty"` +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 15e76d7f..09c75df6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -224,6 +224,7 @@ github.com/opsgenie/opsgenie-go-sdk-v2/escalation github.com/opsgenie/opsgenie-go-sdk-v2/heartbeat github.com/opsgenie/opsgenie-go-sdk-v2/integration github.com/opsgenie/opsgenie-go-sdk-v2/maintenance +github.com/opsgenie/opsgenie-go-sdk-v2/notification github.com/opsgenie/opsgenie-go-sdk-v2/og github.com/opsgenie/opsgenie-go-sdk-v2/policy github.com/opsgenie/opsgenie-go-sdk-v2/schedule diff --git a/website/docs/r/notification_rule.html.markdown b/website/docs/r/notification_rule.html.markdown new file mode 100644 index 00000000..e77390f7 --- /dev/null +++ b/website/docs/r/notification_rule.html.markdown @@ -0,0 +1,83 @@ +--- +layout: "opsgenie" +page_title: "Opsgenie: opsgenie_notification_rule" +sidebar_current: "docs-opsgenie-resource-notification-rule" +description: |- + Manages a Notification Rule within Opsgenie. +--- + +# opsgenie\_notification\_rule + +Manages a Notification Rule within Opsgenie. + +## Example Usage + +```hcl +resource "opsgenie_user" "test" { + username = "Example user" + full_name = "Name Lastname" + role = "User" +} + +resource "opsgenie_notification_rule" "test" { + name = "Example notification rule" + username = opsgenie_user.test.username + action_type = "schedule-end" + notification_time = ["just-before", "15-minutes-ago"] + steps { + contact { + method = "email" + to = "example@user.com" + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Name of the notification policy + +* `username` - (Required) Username of user to which this notification rule belongs to. + +* `action_type` - (Required) Type of the action that notification rule will have. Allowed values: "create-alert", "acknowledged-alert", "closed-alert", "assigned-alert", "add-note", "schedule-start", "schedule-end", "incoming-call-routing" + +* `notification_time` - (Optional) List of Time Periods that notification for schedule start/end will be sent. Allowed values: "just-before", "15-minutes-ago", "1-hour-ago", "1-day-ago". If `action_type` is "schedule-start" or "schedule-end" then it is required. + +* `steps` - (Optional) Notification rule steps to take (eg. SMS or email message). This is a block, structure is documented below. + +* `enabled` - (Optional) If policy should be enabled. Default: true + +The `steps` block supports: + +* `enabled` - (Optional) Defined if this step is enabled. Default: true + +* `send_after` - (Optional) Minute time period notification will be sent after. + +* `contact` - (Required) Defines the contact that notification will be sent to. This is a block, structure is documented below. + +The `contact` block supports: + +* `method` - (Required) Contact method. Possible values: "email", "sms", "voice", "mobile" + +* `to` - (Required) Address of a given method (eg. phone number for sms/voice or email address for email) + + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the Opsgenie Notification Rule. + +## Import + +Notification policies can be imported using the `user id` and `id`, e.g. + +`$ terraform import opsgenie_notification_rule.test userId/Id` + +For this example: +- User Id = `c827c472-31f2-497b-9ec6-8ec855d7d94c` +- Notification Rule Id = `2d1a78d0-c13e-47d3-af0a-8b6d0cc2b7b1` + +`$ terraform import opsgenie_notification_rule.test c827c472-31f2-497b-9ec6-8ec855d7d94c/2d1a78d0-c13e-47d3-af0a-8b6d0cc2b7b1` diff --git a/website/opsgenie.erb b/website/opsgenie.erb index 281544d7..4c8851f1 100644 --- a/website/opsgenie.erb +++ b/website/opsgenie.erb @@ -79,6 +79,9 @@