From 82b3c75764c3c4f30001d199bbbd389a5c573877 Mon Sep 17 00:00:00 2001 From: Nicolas Lamirault Date: Wed, 30 Oct 2019 16:31:15 +0100 Subject: [PATCH] Refactoring and new resources (#36) Adds the following resources: * pingdom_team * pingdom_user * pingdom_contact Adds parameters to existing resource: * pingdom_check: adds responsetime_threshold --- .gitignore | 6 + README.md | 84 +++++++++- examples/README.md | 1 + examples/main.tf | 65 ++++++++ examples/variables.tf | 7 + go.sum | 2 +- pingdom/data_source_pingdom_user.go | 42 +++++ pingdom/provider.go | 9 +- pingdom/resource_pingdom_check.go | 42 +++-- pingdom/resource_pingdom_contact.go | 198 ++++++++++++++++++++++++ pingdom/resource_pingdom_integration.go | 20 +++ pingdom/resource_pingdom_team.go | 130 ++++++++++++++++ pingdom/resource_pingdom_user.go | 113 ++++++++++++++ scripts/changelog-links.sh | 31 ++++ scripts/errcheck.sh | 24 +++ scripts/gofmtcheck.sh | 13 ++ scripts/gogetcookie.sh | 10 ++ 17 files changed, 780 insertions(+), 17 deletions(-) create mode 100644 .gitignore create mode 100644 examples/README.md create mode 100644 examples/main.tf create mode 100644 examples/variables.tf create mode 100644 pingdom/data_source_pingdom_user.go create mode 100644 pingdom/resource_pingdom_contact.go create mode 100644 pingdom/resource_pingdom_integration.go create mode 100644 pingdom/resource_pingdom_team.go create mode 100644 pingdom/resource_pingdom_user.go create mode 100755 scripts/changelog-links.sh create mode 100755 scripts/errcheck.sh create mode 100755 scripts/gofmtcheck.sh create mode 100755 scripts/gogetcookie.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ae93e4b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/terraform-provider-pingdom +/.terraform + +examples/*.tfstate* +examples/*.tfstate.backup +examples/*.tfvars diff --git a/README.md b/README.md index ccdba241..5774be7f 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,10 @@ resource "pingdom_check" "example_with_alert" { 12345678, 23456789 ] + userids = [ + 24680, + 13579 + ] } resource "pingdom_check" "ping_example" { @@ -71,6 +75,9 @@ resource "pingdom_check" "ping_example" { name = "my ping check" host = "example.com" resolution = 1 + userids = [ + 24680 + ] } ``` @@ -114,6 +121,56 @@ resource "pingdom_check" "example" { resolution = 5 } ``` + +**Teams** + +``` +resource "pingdom_team" "test" { + name = "The Test team" +} +``` + +**Users** + +``` +resource "pingdom_user" "first_user" { + username = "johndoe" +} + +resource "pingdom_user" "second_user" { + username = "janedoe" +} +``` + +**Contacts** + +``` + +resource "pingdom_contact" "first_user_contact_email_2" { + user_id = "${pingdom_user.first_user.id}" + email = "john.doe@doe.com" + severity_level = "LOW" +} + +resource "pingdom_contact" "first_user_contact_sms_1" { + user_id = "${pingdom_user.first_user.id}" + number = "700000000" + country_code = "33" + phone_provider = "nexmo" + severity_level = "HIGH" +} + +resource "pingdom_user" "second_user" { + username = "janedoe" +} + +resource "pingdom_contact" "second_user_contact_email_1" { + user_id = "${pingdom_user.second_user.id}" + email = "jane@doe.com" + severity_level = "high" +} +``` + ## Resources ## ### Pingdom Check ### @@ -176,10 +233,35 @@ For the TCP checks, you can set these attributes: **port** - Target port for TCP checks. -**stringtosend** - (optional) This string will be sent to the port +**stringtosend** - (optional) This string will be sent to the port **stringtoexpect** - (optional) This string must be returned by the remote host for the check to pass The following attributes are exported: **id** The ID of the Pingdom check + + +### Pingdom Team ### + +**name** - (Required) The name of the team + + +### Pingdom User ### + +**username** - (Required) The name of the user + + +### Pingdom Contact ### + +**user_id**: (Required) ID of the user linked to this contact + +**severity_level**: (Required) Severity level for target + +**email**: Email + +**number**: Cellphone number, without the country code part. (Requires countrycode) + +**country_code**: Cellphone country code (Requires number) + +**phone_provider**: SMS provider (Requires number and countrycode) \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..85702147 --- /dev/null +++ b/examples/README.md @@ -0,0 +1 @@ +# Pingdom Example diff --git a/examples/main.tf b/examples/main.tf new file mode 100644 index 00000000..e0da70b0 --- /dev/null +++ b/examples/main.tf @@ -0,0 +1,65 @@ +# Copyright (C) 2018-2019 Nicolas Lamirault + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_version = ">= 0.11.0" +} + +resource "pingdom_team" "test_one" { + name = "Team 1 (updated by Terraform)" +} + +provider "pingdom" { + user = "${var.pingdom_user}" + password = "${var.pingdom_password}" + api_key = "${var.pingdom_api_key}" +} + +resource "pingdom_team" "test" { + name = "Team for testing" +} + +resource "pingdom_user" "first_user" { + username = "johndoe" +} + +resource "pingdom_contact" "first_user_contact_email_1" { + user_id = "${pingdom_user.first_user.id}" + email = "john@doe.com" + severity_level = "HIGH" +} + +resource "pingdom_contact" "first_user_contact_email_2" { + user_id = "${pingdom_user.first_user.id}" + email = "john.doe@doe.com" + severity_level = "LOW" +} + +resource "pingdom_contact" "first_user_contact_sms_1" { + user_id = "${pingdom_user.first_user.id}" + number = "700000000" + country_code = "33" + phone_provider = "nexmo" + severity_level = "HIGH" +} + +resource "pingdom_user" "second_user" { + username = "janedoe" +} + +resource "pingdom_contact" "second_user_contact_email_1" { + user_id = "${pingdom_user.second_user.id}" + email = "jane@doe.com" + severity_level = "high" +} diff --git a/examples/variables.tf b/examples/variables.tf new file mode 100644 index 00000000..02a91b2c --- /dev/null +++ b/examples/variables.tf @@ -0,0 +1,7 @@ +variable "pingdom_user" {} + +variable "pingdom_password" {} + +variable "pingdom_api_key" { + description = "The API key to used" +} diff --git a/go.sum b/go.sum index a7efddb8..0910bbb3 100644 --- a/go.sum +++ b/go.sum @@ -483,4 +483,4 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= \ No newline at end of file diff --git a/pingdom/data_source_pingdom_user.go b/pingdom/data_source_pingdom_user.go new file mode 100644 index 00000000..80df6f4e --- /dev/null +++ b/pingdom/data_source_pingdom_user.go @@ -0,0 +1,42 @@ +package pingdom + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/russellcardullo/go-pingdom/pingdom" +) + +func dataSourcePingdomUser() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePingdomUserRead, + + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func dataSourcePingdomUserRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + username := d.Get("username").(string) + users, err := client.Users.List() + log.Printf("==== users : %v", users) + if err != nil { + return fmt.Errorf("Error retrieving user: %s", err) + } + var found pingdom.UsersResponse + for _, user := range users { + if user.Username == username { + log.Printf("User: %v", user) + found = user + } + } + d.Set("username", found.Username) + d.SetId(fmt.Sprintf("%d", found.Id)) + return nil +} diff --git a/pingdom/provider.go b/pingdom/provider.go index d3d2e099..7049cfb3 100644 --- a/pingdom/provider.go +++ b/pingdom/provider.go @@ -35,9 +35,14 @@ func Provider() terraform.ResourceProvider { }, }, ResourcesMap: map[string]*schema.Resource{ - "pingdom_check": resourcePingdomCheck(), + "pingdom_check": resourcePingdomCheck(), + "pingdom_team": resourcePingdomTeam(), + "pingdom_user": resourcePingdomUser(), + "pingdom_contact": resourcePingdomContact(), + }, + DataSourcesMap: map[string]*schema.Resource{ + "pingdom_user": dataSourcePingdomUser(), }, - ConfigureFunc: providerConfigure, } } diff --git a/pingdom/resource_pingdom_check.go b/pingdom/resource_pingdom_check.go index 451b2e10..7c8e94e0 100644 --- a/pingdom/resource_pingdom_check.go +++ b/pingdom/resource_pingdom_check.go @@ -45,6 +45,13 @@ func resourcePingdomCheck() *schema.Resource { ForceNew: false, }, + "responsetime_threshold": { + Type: schema.TypeInt, + Optional: true, + ForceNew: false, + Computed: true, + }, + "publicreport": { Type: schema.TypeBool, Optional: true, @@ -185,6 +192,7 @@ type commonCheckParams struct { Hostname string Resolution int Paused bool + ResponseTimeThreshold int SendNotificationWhenDown int NotifyAgainEvery int NotifyWhenBackup bool @@ -225,6 +233,10 @@ func checkForResource(d *schema.ResourceData) (pingdom.Check, error) { checkParams.Resolution = v.(int) } + if v, ok := d.GetOk("responsetime_threshold"); ok { + checkParams.ResponseTimeThreshold = v.(int) + } + if v, ok := d.GetOk("sendnotificationwhendown"); ok { checkParams.SendNotificationWhenDown = v.(int) } @@ -322,10 +334,11 @@ func checkForResource(d *schema.ResourceData) (pingdom.Check, error) { switch checkType { case "http": return &pingdom.HttpCheck{ - Name: checkParams.Name, - Hostname: checkParams.Hostname, - Resolution: checkParams.Resolution, - Paused: checkParams.Paused, + Name: checkParams.Name, + Hostname: checkParams.Hostname, + Resolution: checkParams.Resolution, + Paused: checkParams.Paused, + ResponseTimeThreshold: checkParams.ResponseTimeThreshold, SendNotificationWhenDown: checkParams.SendNotificationWhenDown, NotifyAgainEvery: checkParams.NotifyAgainEvery, NotifyWhenBackup: checkParams.NotifyWhenBackup, @@ -346,10 +359,11 @@ func checkForResource(d *schema.ResourceData) (pingdom.Check, error) { }, nil case "ping": return &pingdom.PingCheck{ - Name: checkParams.Name, - Hostname: checkParams.Hostname, - Resolution: checkParams.Resolution, - Paused: checkParams.Paused, + Name: checkParams.Name, + Hostname: checkParams.Hostname, + Resolution: checkParams.Resolution, + Paused: checkParams.Paused, + ResponseTimeThreshold: checkParams.ResponseTimeThreshold, SendNotificationWhenDown: checkParams.SendNotificationWhenDown, NotifyAgainEvery: checkParams.NotifyAgainEvery, NotifyWhenBackup: checkParams.NotifyWhenBackup, @@ -361,10 +375,10 @@ func checkForResource(d *schema.ResourceData) (pingdom.Check, error) { }, nil case "tcp": return &pingdom.TCPCheck{ - Name: checkParams.Name, - Hostname: checkParams.Hostname, - Resolution: checkParams.Resolution, - Paused: checkParams.Paused, + Name: checkParams.Name, + Hostname: checkParams.Hostname, + Resolution: checkParams.Resolution, + Paused: checkParams.Paused, SendNotificationWhenDown: checkParams.SendNotificationWhenDown, NotifyAgainEvery: checkParams.NotifyAgainEvery, NotifyWhenBackup: checkParams.NotifyWhenBackup, @@ -447,6 +461,7 @@ func resourcePingdomCheckRead(d *schema.ResourceData, meta interface{}) error { d.Set("host", ck.Hostname) d.Set("name", ck.Name) d.Set("resolution", ck.Resolution) + d.Set("responsetime_threshold", ck.ResponseTimeThreshold) d.Set("sendnotificationwhendown", ck.SendNotificationWhenDown) d.Set("notifyagainevery", ck.NotifyAgainEvery) d.Set("notifywhenbackup", ck.NotifyWhenBackup) @@ -458,7 +473,7 @@ func resourcePingdomCheckRead(d *schema.ResourceData, meta interface{}) error { } d.Set("tags", strings.Join(tags, ",")) - if ck.Status == "paused" { + if ck.Status == "paused" { d.Set("paused", true) } @@ -491,6 +506,7 @@ func resourcePingdomCheckRead(d *schema.ResourceData, meta interface{}) error { if ck.Type.HTTP != nil { d.Set("type", "http") + d.Set("responsetime_threshold", ck.ResponseTimeThreshold) d.Set("url", ck.Type.HTTP.Url) d.Set("encryption", ck.Type.HTTP.Encryption) d.Set("port", ck.Type.HTTP.Port) diff --git a/pingdom/resource_pingdom_contact.go b/pingdom/resource_pingdom_contact.go new file mode 100644 index 00000000..47d7ee4b --- /dev/null +++ b/pingdom/resource_pingdom_contact.go @@ -0,0 +1,198 @@ +package pingdom + +import ( + "fmt" + "log" + "strconv" + "strings" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/russellcardullo/go-pingdom/pingdom" +) + +func resourcePingdomContact() *schema.Resource { + return &schema.Resource{ + Create: resourcePingdomContactCreate, + Read: resourcePingdomContactRead, + Update: resourcePingdomContactUpdate, + Delete: resourcePingdomContactDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "user_id": { + Type: schema.TypeString, + Required: true, + }, + "severity_level": { + Type: schema.TypeString, + Required: true, + }, + "email": { + Type: schema.TypeString, + Optional: true, + }, + "number": { + Type: schema.TypeString, + Optional: true, + }, + "country_code": { + Type: schema.TypeString, + Optional: true, + }, + "phone_provider": { + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +type commonContactParams struct { + UserID string + Email string + Number string + PhoneProvider string + CountryCode string + Severity string +} + +func contactForResource(d *schema.ResourceData) (pingdom.Contact, error) { + contactParams := commonContactParams{} + + // required + if v, ok := d.GetOk("user_id"); ok { + contactParams.UserID = v.(string) + } + + if v, ok := d.GetOk("email"); ok { + contactParams.Email = v.(string) + } + + if v, ok := d.GetOk("number"); ok { + contactParams.Number = v.(string) + } + + if v, ok := d.GetOk("country_code"); ok { + contactParams.CountryCode = v.(string) + } + + if v, ok := d.GetOk("phone_provider"); ok { + contactParams.PhoneProvider = v.(string) + } + + if v, ok := d.GetOk("severity_level"); ok { + contactParams.Severity = strings.ToUpper(v.(string)) + } + + return pingdom.Contact{ + Severity: contactParams.Severity, + Email: contactParams.Email, + Number: contactParams.Number, + CountryCode: contactParams.CountryCode, + Provider: contactParams.PhoneProvider, + }, nil +} + +func resourcePingdomContactCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + contact, err := contactForResource(d) + if err != nil { + return err + } + + userID, err := strconv.Atoi(d.Get("user_id").(string)) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + log.Printf("[DEBUG] Contact create configuration: %#v", d.Get("Contactname")) + result, err := client.Users.CreateContact(userID, contact) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("%d", result.Id)) + return nil +} + +func resourcePingdomContactRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + userID, err := strconv.Atoi(d.Get("user_id").(string)) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + user, err := client.Users.Read(userID) + if err != nil { + return fmt.Errorf("Error retrieving Contact: %s", err) + } + + for _, contact := range user.Email { + if contact.Id == id { + d.Set("email", contact.Address) + d.Set("severity", contact.Severity) + return nil + } + } + for _, contact := range user.Sms { + if contact.Id == id { + d.Set("number", contact.Number) + d.Set("country_code", contact.CountryCode) + d.Set("phone_provider", contact.Provider) + d.Set("severity_level", contact.Severity) + return nil + } + } + return nil +} + +func resourcePingdomContactDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + userID, err := strconv.Atoi(d.Get("user_id").(string)) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + if _, err := client.Users.DeleteContact(userID, id); err != nil { + return fmt.Errorf("Error deleting Contact: %s", err) + } + return nil +} + +func resourcePingdomContactUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + contact, err := contactForResource(d) + if err != nil { + return err + } + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + userID, err := strconv.Atoi(d.Get("user_id").(string)) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + if _, err := client.Users.UpdateContact(userID, id, contact); err != nil { + return fmt.Errorf("Error updating Contact: %s", err) + } + return nil +} diff --git a/pingdom/resource_pingdom_integration.go b/pingdom/resource_pingdom_integration.go new file mode 100644 index 00000000..1e6e3ad0 --- /dev/null +++ b/pingdom/resource_pingdom_integration.go @@ -0,0 +1,20 @@ +package pingdom + +// func resourcePingdomIntegration() *schema.Resource { +// return &schema.Resource{ +// Create: resourcePingdomIntegrationCreate, +// Read: resourcePingdomIntegrationRead, +// Update: resourcePingdomIntegrationUpdate, +// Delete: resourcePingdomIntegrationDelete, +// Importer: &schema.ResourceImporter{ +// State: schema.ImportStatePassthrough, +// }, +// Schema: map[string]*schema.Schema{ +// "name": { +// Type: schema.TypeString, +// Required: true, +// ForceNew: false, +// }, +// }, +// } +// } diff --git a/pingdom/resource_pingdom_team.go b/pingdom/resource_pingdom_team.go new file mode 100644 index 00000000..c379b403 --- /dev/null +++ b/pingdom/resource_pingdom_team.go @@ -0,0 +1,130 @@ +package pingdom + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/russellcardullo/go-pingdom/pingdom" +) + +func resourcePingdomTeam() *schema.Resource { + return &schema.Resource{ + Create: resourcePingdomTeamCreate, + Read: resourcePingdomTeamRead, + Update: resourcePingdomTeamUpdate, + Delete: resourcePingdomTeamDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + }, + } +} + +type commonTeamParams struct { + Name string +} + +func teamForResource(d *schema.ResourceData) (*pingdom.TeamData, error) { + teamParams := commonTeamParams{} + + // required + if v, ok := d.GetOk("name"); ok { + teamParams.Name = v.(string) + } + + return &pingdom.TeamData{ + Name: teamParams.Name, + }, nil +} + +func resourcePingdomTeamCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + team, err := teamForResource(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] Team create configuration: %#v", d.Get("name")) + result, err := client.Teams.Create(team) + if err != nil { + return err + } + + d.SetId(result.ID) + return nil +} + +func resourcePingdomTeamRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + teams, err := client.Teams.List() + if err != nil { + return fmt.Errorf("Error retrieving list of teams: %s", err) + } + exists := false + for _, team := range teams { + if team.ID == d.Id() { + exists = true + break + } + } + if !exists { + d.SetId("") + return nil + } + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + team, err := client.Teams.Read(id) + if err != nil { + return fmt.Errorf("Error retrieving team: %s", err) + } + + d.Set("name", team.Name) + return nil +} + +func resourcePingdomTeamUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + + team, err := teamForResource(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] Team update configuration: %#v", d.Get("name")) + + if _, err = client.Teams.Update(id, team); err != nil { + return fmt.Errorf("Error updating team: %s", err) + } + return nil +} + +func resourcePingdomTeamDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + if _, err = client.Teams.Delete(id); err != nil { + return fmt.Errorf("Error deleting team: %s", err) + } + + return nil +} diff --git a/pingdom/resource_pingdom_user.go b/pingdom/resource_pingdom_user.go new file mode 100644 index 00000000..1fef5fab --- /dev/null +++ b/pingdom/resource_pingdom_user.go @@ -0,0 +1,113 @@ +package pingdom + +import ( + "fmt" + "log" + "strconv" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/russellcardullo/go-pingdom/pingdom" +) + +func resourcePingdomUser() *schema.Resource { + return &schema.Resource{ + Create: resourcePingdomUserCreate, + Read: resourcePingdomUserRead, + Update: resourcePingdomUserUpdate, + Delete: resourcePingdomUserDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +type commonUserParams struct { + Username string +} + +func userForResource(d *schema.ResourceData) (*pingdom.User, error) { + userParams := commonUserParams{} + + // required + if v, ok := d.GetOk("username"); ok { + userParams.Username = v.(string) + } + + return &pingdom.User{ + Username: userParams.Username, + }, nil +} + +func resourcePingdomUserCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + user, err := userForResource(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] User create configuration: %#v", d.Get("username")) + result, err := client.Users.Create(user) + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("%d", result.Id)) + return nil +} + +func resourcePingdomUserRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + user, err := client.Users.Read(id) + if err != nil { + return fmt.Errorf("Error retrieving user: %s", err) + } + + d.Set("username", user.Username) + return nil +} + +func resourcePingdomUserUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + user, err := userForResource(d) + if err != nil { + return err + } + + log.Printf("[DEBUG] User update configuration: %#v", d.Get("username")) + + if _, err = client.Users.Update(id, user); err != nil { + return fmt.Errorf("Error updating user: %s", err) + } + + return nil +} + +func resourcePingdomUserDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pingdom.Client) + + id, err := strconv.Atoi(d.Id()) + if err != nil { + return fmt.Errorf("Error retrieving id for resource: %s", err) + } + if _, err := client.Users.Delete(id); err != nil { + return fmt.Errorf("Error deleting user: %s", err) + } + return nil +} diff --git a/scripts/changelog-links.sh b/scripts/changelog-links.sh new file mode 100755 index 00000000..0233c157 --- /dev/null +++ b/scripts/changelog-links.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# This script rewrites [GH-nnnn]-style references in the CHANGELOG.md file to +# be Markdown links to the given github issues. +# +# This is run during releases so that the issue references in all of the +# released items are presented as clickable links, but we can just use the +# easy [GH-nnnn] shorthand for quickly adding items to the "Unrelease" section +# while merging things between releases. + +set -e + +if [[ ! -f CHANGELOG.md ]]; then + echo "ERROR: CHANGELOG.md not found in pwd." + echo "Please run this from the root of the terraform provider repository" + exit 1 +fi + +if [[ `uname` == "Darwin" ]]; then + echo "Using BSD sed" + SED="sed -i.bak -E -e" +else + echo "Using GNU sed" + SED="sed -i.bak -r -e" +fi + +PROVIDER_URL="https:\/\/github.com\/russellcardullo\/terraform-provider-pingdom\/issues" + +$SED "s/GH-([0-9]+)/\[#\1\]\($PROVIDER_URL\/\1\)/g" -e 's/\[\[#(.+)([0-9])\)]$/(\[#\1\2))/g' CHANGELOG.md + +rm CHANGELOG.md.bak diff --git a/scripts/errcheck.sh b/scripts/errcheck.sh new file mode 100755 index 00000000..15464f5a --- /dev/null +++ b/scripts/errcheck.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Check gofmt +echo "==> Checking for unchecked errors..." + +if ! which errcheck > /dev/null; then + echo "==> Installing errcheck..." + go get -u github.com/kisielk/errcheck +fi + +err_files=$(errcheck -ignoretests \ + -ignore 'github.com/hashicorp/terraform/helper/schema:Set' \ + -ignore 'bytes:.*' \ + -ignore 'io:Close|Write' \ + $(go list ./...| grep -v /vendor/)) + +if [[ -n ${err_files} ]]; then + echo 'Unchecked errors found in the following places:' + echo "${err_files}" + echo "Please handle returned errors. You can check directly with \`make errcheck\`" + exit 1 +fi + +exit 0 diff --git a/scripts/gofmtcheck.sh b/scripts/gofmtcheck.sh new file mode 100755 index 00000000..1c055815 --- /dev/null +++ b/scripts/gofmtcheck.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Check gofmt +echo "==> Checking that code complies with gofmt requirements..." +gofmt_files=$(gofmt -l `find . -name '*.go' | grep -v vendor`) +if [[ -n ${gofmt_files} ]]; then + echo 'gofmt needs running on the following files:' + echo "${gofmt_files}" + echo "You can use the command: \`make fmt\` to reformat code." + exit 1 +fi + +exit 0 diff --git a/scripts/gogetcookie.sh b/scripts/gogetcookie.sh new file mode 100755 index 00000000..26c63a64 --- /dev/null +++ b/scripts/gogetcookie.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +touch ~/.gitcookies +chmod 0600 ~/.gitcookies + +git config --global http.cookiefile ~/.gitcookies + +tr , \\t <<\__END__ >>~/.gitcookies +.googlesource.com,TRUE,/,TRUE,2147483647,o,git-paul.hashicorp.com=1/z7s05EYPudQ9qoe6dMVfmAVwgZopEkZBb1a2mA5QtHE +__END__