Skip to content

Commit

Permalink
Merge pull request #123 from firehydrant/add-auto-team-assignment-to-…
Browse files Browse the repository at this point in the history
…services

Update support for external resources on services
  • Loading branch information
sofuture committed Jul 20, 2023
2 parents d933e54 + f190163 commit 0134a60
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 40 deletions.
19 changes: 10 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
## 0.3.2

ENHANCEMENTS:
ENHANCEMENTS:

* Bump golang from 1.16 to 1.18
* resource/service: Added `auto_add_responding_team` attribute to service ([#117](https://github.com/firehydrant/terraform-provider-firehydrant/pull/117))
* data_source/service: Added `auto_add_responding_team` attribute to service ([#117](https://github.com/firehydrant/terraform-provider-firehydrant/pull/117))
* data_source/services: Added `auto_add_responding_team` attribute to service ([#117](https://github.com/firehydrant/terraform-provider-firehydrant/pull/117))
* resource/service: Added `external_resources` attribute to service ([#123](https://github.com/firehydrant/terraform-provider-firehydrant/pull/123))
* resource/team: Add the ability to attach memberships to teams ([#116](https://github.com/firehydrant/terraform-provider-firehydrant/pull/116))

## 0.3.1
Expand Down Expand Up @@ -70,12 +71,12 @@ ENHANCEMENTS:

NOTES:

* resource/functionality: The deprecated `services` attribute has been removed. See the ["Notes" section in 0.2.0](#020)
* resource/functionality: The deprecated `services` attribute has been removed. See the ["Notes" section in 0.2.0](#020)
or the [original deprecation PR](https://github.com/firehydrant/terraform-provider-firehydrant/pull/49) for more information.
* resource/runbook: There are a number of breaking changes for the runbook resource. The `steps` attribute is now required,
the `steps` `config` attribute is now a JSON string, and the `type` and `severities` attribute have been removed. In order
to upgrade to 0.3.0, you will need to destroy your existing runbooks and recreate them after changing your configuration to
account for the breaking changes.
* resource/runbook: There are a number of breaking changes for the runbook resource. The `steps` attribute is now required,
the `steps` `config` attribute is now a JSON string, and the `type` and `severities` attribute have been removed. In order
to upgrade to 0.3.0, you will need to destroy your existing runbooks and recreate them after changing your configuration to
account for the breaking changes.
As an example, the configuration below was valid in 0.2.1
```hcl
# An example of a valid 0.2.1 configuration
Expand All @@ -86,7 +87,7 @@ NOTES:
steps {
name = "Send me an email"
action_id = data.firehydrant_runbook_action.firehydrant_email_notification.id
config = {
email_address = "test@example.com"
email_subject = "Incident opened on FireHydrant"
Expand All @@ -104,7 +105,7 @@ NOTES:
steps {
name = "Send me an email"
action_id = data.firehydrant_runbook_action.firehydrant_email_notification.id
config = jsonencode({
email_address = "test@example.com"
email_subject = "Incident opened on FireHydrant"
Expand All @@ -122,7 +123,7 @@ ENHANCEMENTS:

## 0.2.0

BREAKING CHANGES:
BREAKING CHANGES:

* resource/team: Removed `services` attribute. Use resource/service to associate teams with a service. See "Notes" for more information ([#54](https://github.com/firehydrant/terraform-provider-firehydrant/pull/54))

Expand Down
6 changes: 6 additions & 0 deletions docs/resources/service.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ The following arguments are supported:
active incident. Defaults to `false`.
* `auto_add_responding_team` - (Optional) Indicates if FireHydrant should automatically add
the responding team if this service is added to an active incident. Defaults to `false`.
* `external_resources` - (Optional) External resources associated with the service
* `description` - (Optional) A description for the service.
* `labels` - (Optional) Key-value pairs associated with the service. Useful for
supporting searching and filtering of the service catalog.
Expand All @@ -77,6 +78,11 @@ The `links` block supports:
* `href_url` - (Required) The URL to use for the link.
* `name` - (Required) The name of the link.

The `exteral_resources` block supports:

* `remote_id` - (Required) The ID of the resource in the remote provider
* `connection_type` - (Required) The connection type configured in FireHydrant (`pager_duty` for example)

## Attributes Reference

In addition to all arguments above, the following attributes are exported:
Expand Down
1 change: 1 addition & 0 deletions firehydrant/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package firehydrant

import (
"context"

"github.com/dghubble/sling"
"github.com/pkg/errors"
)
Expand Down
72 changes: 41 additions & 31 deletions firehydrant/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ type PingResponse struct {
// CreateServiceRequest is the payload for creating a service
// URL: POST https://api.firehydrant.io/v1/services
type CreateServiceRequest struct {
AlertOnAdd bool `json:"alert_on_add,omitempty"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team,omitempty"`
Description string `json:"description"`
Labels map[string]string `json:"labels,omitempty"`
Links []ServiceLink `json:"links,omitempty"`
Name string `json:"name"`
Owner *ServiceTeam `json:"owner,omitempty"`
ServiceTier int `json:"service_tier,int,omitempty"`
Teams []ServiceTeam `json:"teams,omitempty"`
AlertOnAdd bool `json:"alert_on_add,omitempty"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team,omitempty"`
Description string `json:"description"`
Labels map[string]string `json:"labels,omitempty"`
Links []ServiceLink `json:"links,omitempty"`
Name string `json:"name"`
Owner *ServiceTeam `json:"owner,omitempty"`
ServiceTier int `json:"service_tier,int,omitempty"`
Teams []ServiceTeam `json:"teams,omitempty"`
ExternalResources []ExternalResource `json:"external_resources,omitempty"`
}

// ExternalResource is a nested object to link services to things like PagerDuty services
type ExternalResource struct {
RemoteID string `json:"remote_id"`
ConnectionType string `json:"connection_type,omitempty"`
}

// RunbookTeam represents a team when creating a runbook
Expand Down Expand Up @@ -70,33 +77,36 @@ type ServiceLink struct {
// UpdateServiceRequest is the payload for updating a service
// URL: PATCH https://api.firehydrant.io/v1/services/{id}
type UpdateServiceRequest struct {
AlertOnAdd bool `json:"alert_on_add"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team"`
Description string `json:"description"`
Labels map[string]string `json:"labels"`
Links []ServiceLink `json:"links"`
Name string `json:"name,omitempty"`
Owner *ServiceTeam `json:"owner"`
RemoveOwner bool `json:"remove_owner,omitempty"`
RemoveRemainingTeams bool `json:"remove_remaining_teams,omitempty"`
ServiceTier int `json:"service_tier,int"`
Teams []ServiceTeam `json:"teams"`
AlertOnAdd bool `json:"alert_on_add"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team"`
Description string `json:"description"`
Labels map[string]string `json:"labels"`
Links []ServiceLink `json:"links"`
Name string `json:"name,omitempty"`
Owner *ServiceTeam `json:"owner"`
RemoveOwner bool `json:"remove_owner,omitempty"`
RemoveRemainingTeams bool `json:"remove_remaining_teams,omitempty"`
RemoveRemainingExternalResources bool `json:"remove_remaining_external_resources,omitempty"`
ServiceTier int `json:"service_tier,int"`
Teams []ServiceTeam `json:"teams"`
ExternalResources []ExternalResource `json:"external_resources,omitempty"`
}

// ServiceResponse is the payload for retrieving a service
// URL: GET https://api.firehydrant.io/v1/services/{id}
type ServiceResponse struct {
ID string `json:"id"`
AlertOnAdd bool `json:"alert_on_add"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team"`
Description string `json:"description"`
Labels map[string]string `json:"labels"`
Links []ServiceLink `json:"links"`
Name string `json:"name"`
Owner *ServiceTeam `json:"owner"`
ServiceTier int `json:"service_tier"`
Slug string `json:"slug"`
Teams []ServiceTeam `json:"teams"`
ID string `json:"id"`
AlertOnAdd bool `json:"alert_on_add"`
AutoAddRespondingTeam bool `json:"auto_add_responding_team"`
Description string `json:"description"`
Labels map[string]string `json:"labels"`
Links []ServiceLink `json:"links"`
Name string `json:"name"`
Owner *ServiceTeam `json:"owner"`
ServiceTier int `json:"service_tier"`
Slug string `json:"slug"`
Teams []ServiceTeam `json:"teams"`
ExternalResources []ExternalResource `json:"external_resources"`

CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Expand Down
48 changes: 48 additions & 0 deletions provider/service_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,23 @@ func resourceService() *schema.Resource {
Type: schema.TypeString,
},
},
"external_resources": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// Required
"remote_id": {
Type: schema.TypeString,
Required: true,
},
"connection_type": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
}
}
Expand Down Expand Up @@ -125,6 +142,16 @@ func readResourceFireHydrantService(ctx context.Context, d *schema.ResourceData,
}
attributes["links"] = links

// Process any attributes that could be nil
ers := make([]map[string]interface{}, len(serviceResponse.ExternalResources))
for index, currentER := range serviceResponse.ExternalResources {
ers[index] = map[string]interface{}{
"remote_id": currentER.RemoteID,
"connection_type": currentER.ConnectionType,
}
}
attributes["external_resources"] = ers

var ownerID string
if serviceResponse.Owner != nil {
ownerID = serviceResponse.Owner.ID
Expand Down Expand Up @@ -180,6 +207,16 @@ func createResourceFireHydrantService(ctx context.Context, d *schema.ResourceDat
createRequest.Teams = append(createRequest.Teams, firehydrant.ServiceTeam{ID: teamID.(string)})
}

externalResources := d.Get("external_resources").(*schema.Set).List()
for _, currentER := range externalResources {
er := currentER.(map[string]interface{})

createRequest.ExternalResources = append(createRequest.ExternalResources, firehydrant.ExternalResource{
RemoteID: er["remote_id"].(string),
ConnectionType: er["connection_type"].(string),
})
}

// Create the new service
tflog.Debug(ctx, fmt.Sprintf("Create service: %s", createRequest.Name), map[string]interface{}{
"name": createRequest.Name,
Expand Down Expand Up @@ -237,6 +274,17 @@ func updateResourceFireHydrantService(ctx context.Context, d *schema.ResourceDat
// This will force the update request to replace the teams with the ones we send
updateRequest.RemoveRemainingTeams = true

externalResources := d.Get("external_resources").(*schema.Set).List()
for _, currentER := range externalResources {
er := currentER.(map[string]interface{})

updateRequest.ExternalResources = append(updateRequest.ExternalResources, firehydrant.ExternalResource{
RemoteID: er["remote_id"].(string),
ConnectionType: er["connection_type"].(string),
})
}
updateRequest.RemoveRemainingExternalResources = true

// Update the service
tflog.Debug(ctx, fmt.Sprintf("Update service: %s", d.Id()), map[string]interface{}{
"id": d.Id(),
Expand Down

0 comments on commit 0134a60

Please sign in to comment.