Skip to content

Commit

Permalink
Resource to manage sentry plugins (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
johanneswuerbach authored and jianyuan committed Oct 31, 2016
1 parent 90aa787 commit 8e39cc8
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,37 @@ The following attributes are exported:

* `id` - The ID of the created project.

#### `sentry_plugin`

##### Example Usage

```
# Create a plugin
resource "sentry_plugin" "default" {
organization = "my-organization"
project = "web-app"
plugin = "slack"
config = {
webhook = "slack://webhook"
}
}
```

##### Argument Reference

The following arguments are supported:

* `organization` - (Required) The slug of the organization the plugin should be enabled for.
* `project` - (Required) The slug of the project the plugin should be enabled for.
* `plugin` - (Required) Identifier of the plugin.
* `config` - (Optional) Configuration of the plugin.

##### Attributes Reference

The following attributes are exported:

* `id` - The ID of the created plugin.

### Import

You can import existing resources using [terraform import](https://www.terraform.io/docs/import/index.html).
Expand Down
50 changes: 50 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,53 @@ func (c *Client) DeleteKey(organizationSlug, projectSlug, keyID string) (*http.R
resp, err := c.sling.New().Delete(path).Receive(nil, &apiErr)
return resp, relevantError(err, apiErr)
}

type PluginConfigEntry struct {
Name string `json:"name"`
Value string `json:"value"`
}

type Plugin struct {
ID string `json:"id"`
Enabled bool `json:"enabled"`
Config []PluginConfigEntry `json:"config,omitempty"`
}

func (c *Client) GetPlugin(organizationSlug, projectSlug, id string) (*Plugin, *http.Response, error) {
var plugin Plugin
apiErr := make(APIError)
path := fmt.Sprintf("0/projects/%s/%s/plugins/%s/", organizationSlug, projectSlug, id)
resp, err := c.sling.New().Get(path).Receive(&plugin, &apiErr)

log.Printf("[DEBUG] Client.GetPlugin %s\n%v", path, resp)

return &plugin, resp, relevantError(err, apiErr)
}

func (c *Client) UpdatePlugin(organizationSlug, projectSlug, id string, params map[string]interface{}) (*Plugin, *http.Response, error) {
var plugin Plugin
apiErr := make(APIError)
path := fmt.Sprintf("0/projects/%s/%s/plugins/%s/", organizationSlug, projectSlug, id)
resp, err := c.sling.New().Put(path).BodyJSON(params).Receive(&plugin, &apiErr)

log.Printf("[DEBUG] Client.UpdatePlugin %s\n%v", path, resp)

return &plugin, resp, relevantError(err, apiErr)
}

func (c *Client) EnablePlugin(organizationSlug, projectSlug, id string) (*http.Response, error) {
apiErr := make(APIError)
path := fmt.Sprintf("0/projects/%s/%s/plugins/%s/", organizationSlug, projectSlug, id)
resp, err := c.sling.New().Post(path).Receive(nil, &apiErr)

log.Printf("[DEBUG] Client.EnablePlugin %s\n%v", path, resp)

return resp, relevantError(err, apiErr)
}

func (c *Client) DisablePlugin(organizationSlug, projectSlug, id string) (*http.Response, error) {
apiErr := make(APIError)
path := fmt.Sprintf("0/projects/%s/%s/plugins/%s/", organizationSlug, projectSlug, id)
resp, err := c.sling.New().Delete(path).Receive(nil, &apiErr)
return resp, relevantError(err, apiErr)
}
1 change: 1 addition & 0 deletions provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func Provider() terraform.ResourceProvider {
"sentry_team": resourceSentryTeam(),
"sentry_project": resourceSentryProject(),
"sentry_key": resourceSentryKey(),
"sentry_plugin": resourceSentryPlugin(),
},

ConfigureFunc: providerConfigure,
Expand Down
141 changes: 141 additions & 0 deletions resource_sentry_plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package main

import (
"errors"
"log"
"strings"

"github.com/hashicorp/terraform/helper/schema"
)

func resourceSentryPlugin() *schema.Resource {
return &schema.Resource{
Create: resourceSentryPluginCreate,
Read: resourceSentryPluginRead,
Update: resourceSentryPluginUpdate,
Delete: resourceSentryPluginDelete,
Importer: &schema.ResourceImporter{
State: resourceSentryPluginImporter,
},

Schema: map[string]*schema.Schema{
"organization": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The slug of the organization the project belongs to",
},
"project": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The slug of the project to create the plugin for",
},
"plugin": &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The id of the plugin",
},
"config": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
Description: "Plugin config",
},
},
}
}

func resourceSentryPluginCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)

plugin := d.Get("plugin").(string)
org := d.Get("organization").(string)
project := d.Get("project").(string)

log.Printf("%v, %v, %v", plugin, org, project)

if _, err := client.EnablePlugin(org, project, plugin); err != nil {
return err
}

d.SetId(plugin)

params := d.Get("config").(map[string]interface{})
if _, _, err := client.UpdatePlugin(org, project, plugin, params); err != nil {
return err
}

return resourceSentryPluginRead(d, meta)
}

func resourceSentryPluginRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)

id := d.Id()
org := d.Get("organization").(string)
project := d.Get("project").(string)

plugin, _, err := client.GetPlugin(org, project, id)
if err != nil {
d.SetId("")
return nil
}

d.SetId(plugin.ID)

pluginConfig := make(map[string]string)
for _, entry := range plugin.Config {
pluginConfig[entry.Name] = entry.Value
}

config := make(map[string]string)
for k := range d.Get("config").(map[string]interface{}) {
config[k] = pluginConfig[k]
}

d.Set("config", config)

return nil
}

func resourceSentryPluginUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)

id := d.Id()
org := d.Get("organization").(string)
project := d.Get("project").(string)

params := d.Get("config").(map[string]interface{})
if _, _, err := client.UpdatePlugin(org, project, id, params); err != nil {
return err
}

return resourceSentryPluginRead(d, meta)
}

func resourceSentryPluginDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*Client)

id := d.Id()
org := d.Get("organization").(string)
project := d.Get("project").(string)

_, err := client.DisablePlugin(org, project, id)
return err
}

func resourceSentryPluginImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
addrID := d.Id()

log.Printf("[DEBUG] Importing key using ADDR ID %s", addrID)

parts := strings.Split(addrID, "/")

if len(parts) != 3 {
return nil, errors.New("Project import requires an ADDR ID of the following schema org-slug/project-slug/plugin-id")
}

d.Set("organization", parts[0])
d.Set("project", parts[1])
d.SetId(parts[2])

return []*schema.ResourceData{d}, nil
}

0 comments on commit 8e39cc8

Please sign in to comment.