From a9b3aa057839ee9125bdd0457fdd6ed271227181 Mon Sep 17 00:00:00 2001 From: Stephen Jung Date: Wed, 28 Feb 2018 16:56:33 -0800 Subject: [PATCH] Add resource for integrations We only use Slack and PagerDuty here, but adding support for others should be straightforward. --- docs/index.md | 1 + docs/resources/integration.md | 27 ++++ .../signalform/integration.go | 116 ++++++++++++++++++ .../signalform/provider.go | 1 + 4 files changed, 145 insertions(+) create mode 100644 docs/resources/integration.md create mode 100644 src/terraform-provider-signalform/signalform/integration.go diff --git a/docs/index.md b/docs/index.md index 4eafad5..a3bdc9a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,6 +25,7 @@ Changelog is available [here](https://github.com/Yelp/terraform-provider-signalf * [Text Note](https://yelp.github.io/terraform-provider-signalform/resources/text_note.html) * [Dashboard](https://yelp.github.io/terraform-provider-signalform/resources/dashboard.html) * [Dashboard Group](https://yelp.github.io/terraform-provider-signalform/resources/dashboard_group.html) + * [Integration](https://yelp.github.io/terraform-provider-signalform/resources/integration.html) * [Build And Install](#build-and-install) * [Build binary from source](#build-binary-from-source) * [Build debian package from source](#build-debian-package-from-source) diff --git a/docs/resources/integration.md b/docs/resources/integration.md new file mode 100644 index 0000000..6725091 --- /dev/null +++ b/docs/resources/integration.md @@ -0,0 +1,27 @@ +# Integration + +SignalFx supports integrations to ingest metrics from other monitoring systems, connect to Single Sign-On providers, and to report notifications for messaging and incident management. Note that your SignalForm API key must have admin permissions to use the SignalFx integration API. + +## Example Usage + +```terraform +resource "signalform_integration" "pagerduty_myteam" { + provider = "signalform" + name = "PD - My Team" + enabled = true + type = "PagerDuty" + api_key = "1234567890" +} +``` + +## Argument Reference + +* `name` - (Required) Name of the integration. +* `enabled` - (Required) Whether the integration is enabled. +* `type` - (Required) Type of the integration. See the full list at . +* `api_key` - (Required for `PagerDuty`) PagerDuty API key. +* `webhook_url` - (Required for `Slack`) Slack incoming webhook URL. + +**Notes** + +This resource does not support all known types of integration. Contributions are welcome to implement more types. diff --git a/src/terraform-provider-signalform/signalform/integration.go b/src/terraform-provider-signalform/signalform/integration.go new file mode 100644 index 0000000..547af8c --- /dev/null +++ b/src/terraform-provider-signalform/signalform/integration.go @@ -0,0 +1,116 @@ +package signalform + +import ( + "encoding/json" + "fmt" + "github.com/hashicorp/terraform/helper/schema" + "strings" +) + +const ( + INTEGRATION_API_URL = "https://api.signalfx.com/v2/integration" +) + +func integrationResource() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Name of the integration", + }, + "enabled": &schema.Schema{ + Type: schema.TypeBool, + Required: true, + Description: "Whether the integration is enabled or not", + }, + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + Description: "Type of the integration", + ValidateFunc: validateIntegrationType, + }, + "api_key": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "PagerDuty API key", + Sensitive: true, + }, + "webhook_url": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "Slack Incoming Webhook URL", + Sensitive: true, + }, + }, + + Create: integrationCreate, + Read: integrationRead, + Update: integrationUpdate, + Delete: integrationDelete, + } +} + +func validateIntegrationType(v interface{}, k string) (we []string, errors []error) { + value := v.(string) + allowedWords := []string{"PagerDuty", "Slack"} + for _, word := range allowedWords { + if value == word { + return + } + } + errors = append(errors, fmt.Errorf("%s not allowed; must be one of: %s", value, strings.Join(allowedWords, ", "))) + return +} + +func getPayloadIntegration(d *schema.ResourceData) ([]byte, error) { + integrationType := d.Get("type").(string) + payload := map[string]interface{}{ + "name": d.Get("name").(string), + "enabled": d.Get("enabled").(bool), + "type": integrationType, + } + + switch integrationType { + case "PagerDuty": + payload["apiKey"] = d.Get("api_key").(string) + case "Slack": + payload["webhookUrl"] = d.Get("webhook_url").(string) + } + + return json.Marshal(payload) +} + +func integrationCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*signalformConfig) + payload, err := getPayloadIntegration(d) + if err != nil { + return fmt.Errorf("Failed creating json payload: %s", err.Error()) + } + + return resourceCreate(INTEGRATION_API_URL, config.AuthToken, payload, d) +} + +func integrationRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*signalformConfig) + url := fmt.Sprintf("%s/%s", INTEGRATION_API_URL, d.Id()) + + return resourceRead(url, config.AuthToken, d) +} + +func integrationUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*signalformConfig) + payload, err := getPayloadIntegration(d) + if err != nil { + return fmt.Errorf("Failed creating json payload: %s", err.Error()) + } + url := fmt.Sprintf("%s/%s", INTEGRATION_API_URL, d.Id()) + + return resourceUpdate(url, config.AuthToken, payload, d) +} + +func integrationDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*signalformConfig) + url := fmt.Sprintf("%s/%s", INTEGRATION_API_URL, d.Id()) + return resourceDelete(url, config.AuthToken, d) +} diff --git a/src/terraform-provider-signalform/signalform/provider.go b/src/terraform-provider-signalform/signalform/provider.go index e9e9f32..910fb98 100644 --- a/src/terraform-provider-signalform/signalform/provider.go +++ b/src/terraform-provider-signalform/signalform/provider.go @@ -40,6 +40,7 @@ func Provider() terraform.ResourceProvider { "signalform_text_chart": textChartResource(), "signalform_dashboard": dashboardResource(), "signalform_dashboard_group": dashboardGroupResource(), + "signalform_integration": integrationResource(), }, ConfigureFunc: signalformConfigure, }