Skip to content

Commit

Permalink
Merge pull request #198 from sleuth-io/ziga/fea-322-add-rootly-suppor…
Browse files Browse the repository at this point in the history
…t-to-terraform-provider

FEA-322: Add support for Rootly as incident impact source
  • Loading branch information
zigomir authored Sep 26, 2024
2 parents abf9d6f + b51bc42 commit 5aef486
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.6.2 (Sep 26, 2024)
ENHANCEMENTS:
- [#198](https://github.com/sleuth-io/terraform-provider-sleuth/issues/198) Add support for Rootly

## 0.6.1 (Sep 26, 2024)
ENHANCEMENTS:
- [#196](https://github.com/sleuth-io/terraform-provider-sleuth/pull/196) Fix crash for creating new code change source
Expand Down
31 changes: 30 additions & 1 deletion docs/resources/incident_impact_source.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,21 @@ resource "sleuth_incident_impact_source" "clubhouse" {
integration_slug = "optional_integration_slug"
}
}
resource "sleuth_incident_impact_source" "rootly" {
project_slug = "project_slug"
name = "Rootly TF incident impact"
environment_name = "environment_name"
provider_name = "rootly"
rootly_input = {
remote_severity = "ALL" # or "CRITICAL", "HIGH", "MEDIUM", "LOW"
remote_incident_type = "remote_incident_type_id"
remote_environment = "remote_environment_id"
remote_service = "remote_service_id"
remote_team = "remote_team_id"
integration_slug = "optional_integration_slug"
}
}
```

<!-- schema generated by tfplugindocs -->
Expand All @@ -118,7 +133,7 @@ resource "sleuth_incident_impact_source" "clubhouse" {
- `environment_name` (String) Impact source environment name
- `name` (String) Impact source name
- `project_slug` (String) The slug of the project that this incident impact source belongs to.
- `provider_name` (String) Impact source provider in lowercase (options: pagerduty, datadog, jira, blameless, statuspage, opsgenie, firehydrant, clubhouse)
- `provider_name` (String) Impact source provider in lowercase (options: pagerduty, datadog, jira, blameless, statuspage, opsgenie, firehydrant, clubhouse, rootly)

### Optional

Expand All @@ -129,6 +144,7 @@ resource "sleuth_incident_impact_source" "clubhouse" {
- `jira_input` (Attributes) JIRA input (see [below for nested schema](#nestedatt--jira_input))
- `opsgenie_input` (Attributes) OpsGenie input (see [below for nested schema](#nestedatt--opsgenie_input))
- `pagerduty_input` (Attributes) PagerDuty input (see [below for nested schema](#nestedatt--pagerduty_input))
- `rootly_input` (Attributes) Rootly input (see [below for nested schema](#nestedatt--rootly_input))
- `statuspage_input` (Attributes) Statuspage input (see [below for nested schema](#nestedatt--statuspage_input))

### Read-Only
Expand Down Expand Up @@ -212,6 +228,19 @@ Optional:
- `remote_urgency` (String) PagerDuty remote urgency, options: HIGH, LOW, ANY


<a id="nestedatt--rootly_input"></a>
### Nested Schema for `rootly_input`

Optional:

- `integration_slug` (String) IntegrationAuthentication slug used
- `remote_environment` (String) Environment ID (environments are defined within Rootly)
- `remote_incident_type` (String) Incident type ID (incident types are defined within Rootly)
- `remote_service` (String) Service ID (services are defined within Rootly)
- `remote_severity` (String) Rootly’s severity values are configurable, but ultimately they always map to 4 levels: ALL, CRITICAL, HIGH, MEDIUM and LOW. Check out your current [severities configuration in Rootly](https://rootly.com/account/severities).
- `remote_team` (String) Team ID (teams are defined within Rootly)


<a id="nestedatt--statuspage_input"></a>
### Nested Schema for `statuspage_input`

Expand Down
15 changes: 15 additions & 0 deletions examples/resources/sleuth_incident_impact_source/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,18 @@ resource "sleuth_incident_impact_source" "clubhouse" {
integration_slug = "optional_integration_slug"
}
}

resource "sleuth_incident_impact_source" "rootly" {
project_slug = "project_slug"
name = "Rootly TF incident impact"
environment_name = "environment_name"
provider_name = "rootly"
rootly_input = {
remote_severity = "ALL" # or "CRITICAL", "HIGH", "MEDIUM", "LOW"
remote_incident_type = "remote_incident_type_id"
remote_environment = "remote_environment_id"
remote_service = "remote_service_id"
remote_team = "remote_team_id"
integration_slug = "optional_integration_slug"
}
}
15 changes: 15 additions & 0 deletions internal/gqlclient/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,14 @@ type ClubhouseProviderData struct {
RemoteQuery string `json:"remoteQuery"`
}

type RootlyProviderData struct {
RemoteSeverity string `json:"remoteSeverity"`
RemoteIncidentType string `json:"remoteIncidentType"`
RemoteEnvironment string `json:"remoteEnvironment"`
RemoteService string `json:"remoteService"`
RemoteTeam string `json:"remoteTeam"`
}

type ProviderData struct {
PagerDutyProviderData PagerDutyProviderData `json:"pagerDutyProviderData" graphql:"... on PagerDutyProviderData"`
DataDogProviderData DataDogProviderData `json:"dataDogProviderData" graphql:"... on DataDogProviderData"`
Expand All @@ -297,6 +305,7 @@ type ProviderData struct {
OpsGenieProviderData OpsGenieProviderData `json:"opsgenieProviderData" graphql:"... on OpsgenieProviderData"`
FireHydrantProviderData FireHydrantProviderData `json:"firehydrantProviderData" graphql:"... on FireHydrantProviderData"`
ClubhouseProviderData ClubhouseProviderData `json:"ClubhouseProviderData" graphql:"... on ClubhouseProviderData"`
RootlyProviderData RootlyProviderData `json:"RootlyProviderData" graphql:"... on RootlyProviderData"`
}

type IncidentImpactSource struct {
Expand Down Expand Up @@ -343,6 +352,11 @@ type ClubhouseInputType struct {
IntegrationSlug string `json:"integrationSlug"`
}

type RootlyInputType struct {
RootlyProviderData
IntegrationSlug string `json:"integrationSlug"`
}

type OpsGenieInputType struct {
OpsGenieProviderData
IntegrationSlug string `json:"integrationSlug"`
Expand All @@ -361,6 +375,7 @@ type IncidentImpactSourceInputType struct {
OpsGenieInputType *OpsGenieInputType `json:"opsgenieInput"`
FireHydrantInputType *FireHydrantInputType `json:"firehydrantInput"`
ClubhouseInputType *ClubhouseInputType `json:"clubhouseInput"`
RootlyInputType *RootlyInputType `json:"rootlyInput"`
}

type IncidentImpactSourceInputUpdateType struct {
Expand Down
74 changes: 73 additions & 1 deletion internal/sleuth/incident_impact_source_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type incidentImpactResourceModel struct {
OpsGenieInput *opsgenieInputResourceModel `tfsdk:"opsgenie_input"`
FireHydrantInput *firehydrantInputResourceModel `tfsdk:"firehydrant_input"`
ClubhouseInput *clubhouseInputResourceModel `tfsdk:"clubhouse_input"`
RootlyInput *rootlyInputResourceModel `tfsdk:"rootly_input"`
}

type pagerDutyInputResourceModel struct {
Expand Down Expand Up @@ -98,6 +99,15 @@ type clubhouseInputResourceModel struct {
IntegrationSlug types.String `tfsdk:"integration_slug"`
}

type rootlyInputResourceModel struct {
RemoteSeverity types.String `tfsdk:"remote_severity"`
RemoteIncidentType types.String `tfsdk:"remote_incident_type"`
RemoteEnvironment types.String `tfsdk:"remote_environment"`
RemoteService types.String `tfsdk:"remote_service"`
RemoteTeam types.String `tfsdk:"remote_team"`
IntegrationSlug types.String `tfsdk:"integration_slug"`
}

type incidentImpactSourceResource struct {
c *gqlclient.Client
}
Expand Down Expand Up @@ -134,7 +144,7 @@ func (iisr *incidentImpactSourceResource) Schema(_ context.Context, _ resource.S
Required: true,
},
"provider_name": schema.StringAttribute{
MarkdownDescription: "Impact source provider in lowercase (options: pagerduty, datadog, jira, blameless, statuspage, opsgenie, firehydrant, clubhouse)",
MarkdownDescription: "Impact source provider in lowercase (options: pagerduty, datadog, jira, blameless, statuspage, opsgenie, firehydrant, clubhouse, rootly)",
Required: true,
},
"environment_name": schema.StringAttribute{
Expand Down Expand Up @@ -312,6 +322,36 @@ Options: ALL, P1, P2, P3, P4, P5. Defaults to ALL`,
},
},
},
"rootly_input": schema.SingleNestedAttribute{
Optional: true,
MarkdownDescription: "Rootly input",
Attributes: map[string]schema.Attribute{
"remote_severity": schema.StringAttribute{
Optional: true,
MarkdownDescription: "Rootly’s severity values are configurable, but ultimately they always map to 4 levels: ALL, CRITICAL, HIGH, MEDIUM and LOW. Check out your current [severities configuration in Rootly](https://rootly.com/account/severities).",
},
"remote_incident_type": schema.StringAttribute{
Optional: true,
MarkdownDescription: "Incident type ID (incident types are defined within Rootly)",
},
"remote_environment": schema.StringAttribute{
Optional: true,
MarkdownDescription: "Environment ID (environments are defined within Rootly)",
},
"remote_service": schema.StringAttribute{
Optional: true,
MarkdownDescription: "Service ID (services are defined within Rootly)",
},
"remote_team": schema.StringAttribute{
Optional: true,
MarkdownDescription: "Team ID (teams are defined within Rootly)",
},
"integration_slug": schema.StringAttribute{
Optional: true,
MarkdownDescription: "IntegrationAuthentication slug used",
},
},
},
},
}
}
Expand All @@ -337,6 +377,7 @@ type providerData struct {
clubhouse *clubhouseInputResourceModel
firehydrant *firehydrantInputResourceModel
opsgenie *opsgenieInputResourceModel
rootly *rootlyInputResourceModel
}

// we have to manually parse the provider data because the TF protocol v5 doesn't support nested objects
Expand All @@ -350,6 +391,7 @@ func parseProviderData(ctx context.Context, plan incidentImpactResourceModel) pr
opsgenie: plan.OpsGenieInput,
firehydrant: plan.FireHydrantInput,
clubhouse: plan.ClubhouseInput,
rootly: plan.RootlyInput,
}

}
Expand Down Expand Up @@ -522,6 +564,7 @@ func getNewStateFromIncidentImpactSource(ctx context.Context, iis *gqlclient.Inc
OpsGenieInput: nil,
FireHydrantInput: nil,
ClubhouseInput: nil,
RootlyInput: nil,
}

return getProviderSpecificStateValue(ctx, iis, iirm, data)
Expand Down Expand Up @@ -609,6 +652,18 @@ func getProviderSpecificStateValue(ctx context.Context, iis *gqlclient.IncidentI
clubhouse.IntegrationSlug = types.StringValue(iis.IntegrationAuthSlug)
}

rootly := &rootlyInputResourceModel{
RemoteSeverity: types.StringValue(iis.ProviderData.RootlyProviderData.RemoteSeverity),
RemoteIncidentType: types.StringValue(iis.ProviderData.RootlyProviderData.RemoteIncidentType),
RemoteEnvironment: types.StringValue(iis.ProviderData.RootlyProviderData.RemoteEnvironment),
RemoteService: types.StringValue(iis.ProviderData.RootlyProviderData.RemoteService),
RemoteTeam: types.StringValue(iis.ProviderData.RootlyProviderData.RemoteTeam),
IntegrationSlug: types.StringNull(),
}
if iis.IntegrationAuthSlug != "" {
rootly.IntegrationSlug = types.StringValue(iis.IntegrationAuthSlug)
}

if data.pagerduty != nil {
stateObj.PagerDutyInput = pd
}
Expand All @@ -633,6 +688,9 @@ func getProviderSpecificStateValue(ctx context.Context, iis *gqlclient.IncidentI
if data.clubhouse != nil {
stateObj.ClubhouseInput = clubhouse
}
if data.rootly != nil {
stateObj.RootlyInput = rootly
}

return stateObj, diags

Expand All @@ -652,6 +710,7 @@ func getMutableIncidentImpactSourceStruct(ctx context.Context, plan incidentImpa
OpsGenieInputType: nil,
FireHydrantInputType: nil,
ClubhouseInputType: nil,
RootlyInputType: nil,
}

return getProviderSpecificData(ctx, input, data)
Expand Down Expand Up @@ -743,5 +802,18 @@ func getProviderSpecificData(ctx context.Context, input gqlclient.IncidentImpact
}
}

if data.rootly != nil {
input.RootlyInputType = &gqlclient.RootlyInputType{
RootlyProviderData: gqlclient.RootlyProviderData{
RemoteSeverity: data.rootly.RemoteSeverity.ValueString(),
RemoteIncidentType: data.rootly.RemoteIncidentType.ValueString(),
RemoteEnvironment: data.rootly.RemoteEnvironment.ValueString(),
RemoteService: data.rootly.RemoteService.ValueString(),
RemoteTeam: data.rootly.RemoteTeam.ValueString(),
},
IntegrationSlug: data.rootly.IntegrationSlug.ValueString(),
}
}

return input, diags
}

0 comments on commit 5aef486

Please sign in to comment.