Skip to content

Commit 8c78c1d

Browse files
authored
Add membership resource (#6)
1 parent 4bd6b38 commit 8c78c1d

File tree

8 files changed

+301
-15
lines changed

8 files changed

+301
-15
lines changed

README.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ then create an `.env` file with:
6363

6464
TF_ACC=on
6565
HIREFIRE_API_KEY=your-key
66-
67-
If testing the user data source also append this to the `.env` file:
68-
66+
# The following variables are optional.
67+
# For user data source:
6968
HIREFIRE_TEST_USER_ID=user-id
7069
HIREFIRE_TEST_USER_EMAIL=user-email
70+
# For membership resource:
71+
HIREFIRE_TEST_MEMBERSHIP_USER_ID=another-user-id
7172

7273
and run with:
7374

client/client.go

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Client struct {
1717
TimeRange *TimeRangeResource
1818
Recipient *RecipientResource
1919
User *UserResource
20+
Membership *MembershipResource
2021
}
2122

2223
const DefaultURL = "https://api.hirefire.io/"
@@ -40,6 +41,7 @@ func New(apiKey string) *Client {
4041
client.TimeRange = &TimeRangeResource{client: client}
4142
client.Recipient = &RecipientResource{client: client}
4243
client.User = &UserResource{client: client}
44+
client.Membership = &MembershipResource{client: client}
4345

4446
return client
4547
}

client/membership.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package client
2+
3+
type MembershipResource struct {
4+
client *Client
5+
}
6+
7+
type Membership struct {
8+
Id string `json:"id"`
9+
OrganizationId string `json:"organization_id"`
10+
UserId string `json:"user_id"`
11+
Owner bool `json:"owner"`
12+
}
13+
14+
type wrappedMembership struct {
15+
Membership Membership `json:"membership"`
16+
}
17+
18+
func (r *MembershipResource) Get(id string) (*Membership, error) {
19+
wrapped := &wrappedMembership{}
20+
err := r.client.getResource("memberships", id, wrapped)
21+
return &wrapped.Membership, err
22+
}
23+
24+
func (r *MembershipResource) Create(create Membership) (*Membership, error) {
25+
wrapped := &wrappedMembership{Membership: create}
26+
err := r.client.createResource("memberships", wrapped)
27+
return &wrapped.Membership, err
28+
}
29+
30+
func (r *MembershipResource) Update(update Membership) (*Membership, error) {
31+
wrapped := &wrappedMembership{Membership: update}
32+
err := r.client.updateResource("memberships", update.Id, wrapped)
33+
return &wrapped.Membership, err
34+
}
35+
36+
func (r *MembershipResource) Delete(id string) error {
37+
err := r.client.deleteResource("memberships", id)
38+
return err
39+
}

client/membership_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package client
2+
3+
import (
4+
"github.com/carwow/terraform-provider-hirefire/testing/assert"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
)
9+
10+
func TestGetMembership(t *testing.T) {
11+
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
12+
assert.Equals(t, req.URL.String(), "/memberships/ID-123")
13+
rw.Write([]byte(`{
14+
"membership": {
15+
"id": "ID-123",
16+
"organization_id": "ID-999",
17+
"user_id": "ID-888",
18+
"owner": true
19+
}
20+
}`))
21+
}))
22+
defer server.Close()
23+
24+
client := New("secret")
25+
client.URL = server.URL + "/"
26+
27+
membership, err := client.Membership.Get("ID-123")
28+
assert.Ok(t, err)
29+
30+
expected := &Membership{
31+
Id: "ID-123",
32+
OrganizationId: "ID-999",
33+
UserId: "ID-888",
34+
Owner: true,
35+
}
36+
assert.Equals(t, expected, membership)
37+
}

provider/provider.go

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/carwow/terraform-provider-hirefire/resources/account"
66
"github.com/carwow/terraform-provider-hirefire/resources/application"
77
"github.com/carwow/terraform-provider-hirefire/resources/manager"
8+
"github.com/carwow/terraform-provider-hirefire/resources/membership"
89
"github.com/carwow/terraform-provider-hirefire/resources/organization"
910
"github.com/carwow/terraform-provider-hirefire/resources/recipient"
1011
"github.com/carwow/terraform-provider-hirefire/resources/time_range"
@@ -29,6 +30,7 @@ func Provider() *schema.Provider {
2930
"hirefire_manager": manager.Resource(),
3031
"hirefire_time_range": time_range.Resource(),
3132
"hirefire_recipient": recipient.Resource(),
33+
"hirefire_membership": membership.Resource(),
3234
},
3335

3436
DataSourcesMap: map[string]*schema.Resource{

resources/account/resource.go

-12
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,6 @@ func read(d *schema.ResourceData, m interface{}) error {
5757
return nil
5858
}
5959

60-
func update(d *schema.ResourceData, m interface{}) error {
61-
d.Partial(true)
62-
63-
_, err := config.Client(m).Account.Update(getAttributes(d))
64-
if err != nil {
65-
return err
66-
}
67-
68-
d.Partial(false)
69-
return nil
70-
}
71-
7260
func delete(d *schema.ResourceData, m interface{}) error {
7361
err := config.Client(m).Account.Delete(d.Id())
7462
return err

resources/membership/resource.go

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package membership
2+
3+
import (
4+
"github.com/carwow/terraform-provider-hirefire/client"
5+
"github.com/carwow/terraform-provider-hirefire/config"
6+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
7+
)
8+
9+
func Resource() *schema.Resource {
10+
return &schema.Resource{
11+
Create: create,
12+
Read: read,
13+
Update: update,
14+
Delete: delete,
15+
16+
Importer: &schema.ResourceImporter{
17+
State: importer,
18+
},
19+
20+
Schema: map[string]*schema.Schema{
21+
"organization_id": &schema.Schema{
22+
Type: schema.TypeString,
23+
Required: true,
24+
ForceNew: true,
25+
},
26+
"user_id": &schema.Schema{
27+
Type: schema.TypeString,
28+
Required: true,
29+
ForceNew: true,
30+
},
31+
"owner": &schema.Schema{
32+
Type: schema.TypeBool,
33+
Optional: true,
34+
},
35+
},
36+
}
37+
}
38+
39+
func setAttributes(d *schema.ResourceData, mem *client.Membership) {
40+
d.Set("organization_id", mem.OrganizationId)
41+
d.Set("user_id", mem.UserId)
42+
d.Set("owner", mem.Owner)
43+
}
44+
45+
func getAttributes(d *schema.ResourceData) client.Membership {
46+
return client.Membership{
47+
Id: d.Id(),
48+
OrganizationId: d.Get("organization_id").(string),
49+
UserId: d.Get("user_id").(string),
50+
Owner: d.Get("owner").(bool),
51+
}
52+
}
53+
54+
func create(d *schema.ResourceData, m interface{}) error {
55+
mem, err := config.Client(m).Membership.Create(getAttributes(d))
56+
if err != nil {
57+
return err
58+
}
59+
60+
d.SetId(mem.Id)
61+
setAttributes(d, mem)
62+
return nil
63+
}
64+
65+
func read(d *schema.ResourceData, m interface{}) error {
66+
mem, err := config.Client(m).Membership.Get(d.Id())
67+
if err != nil {
68+
return err
69+
}
70+
71+
setAttributes(d, mem)
72+
return nil
73+
}
74+
75+
func update(d *schema.ResourceData, m interface{}) error {
76+
d.Partial(true)
77+
78+
_, err := config.Client(m).Membership.Update(getAttributes(d))
79+
if err != nil {
80+
return err
81+
}
82+
83+
d.Partial(false)
84+
return nil
85+
}
86+
87+
func delete(d *schema.ResourceData, m interface{}) error {
88+
err := config.Client(m).Membership.Delete(d.Id())
89+
return err
90+
}
91+
92+
func importer(d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) {
93+
err := read(d, m)
94+
if err != nil {
95+
return nil, err
96+
}
97+
98+
return []*schema.ResourceData{d}, nil
99+
}

resources/membership/resource_test.go

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package membership_test
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strconv"
7+
"testing"
8+
9+
"github.com/carwow/terraform-provider-hirefire/client"
10+
"github.com/carwow/terraform-provider-hirefire/testing/helper"
11+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
13+
)
14+
15+
const resourceName = "hirefire_membership.foobar"
16+
17+
func TestAccMembership(t *testing.T) {
18+
orgName := fmt.Sprintf("test-%s", helper.RandString(10))
19+
mem := &client.Membership{
20+
UserId: os.Getenv("HIREFIRE_TEST_MEMBERSHIP_USER_ID"),
21+
}
22+
23+
if mem.UserId == "" {
24+
t.Skip("Membership resource test skipped unless env " +
25+
"'HIREFIRE_TEST_MEMBERSHIP_USER_ID' is set")
26+
}
27+
28+
resource.Test(t, resource.TestCase{
29+
PreCheck: helper.PreCheck(t),
30+
Providers: helper.Providers(),
31+
CheckDestroy: checkDestroy,
32+
Steps: []resource.TestStep{
33+
{
34+
Config: func(orgName string, mem *client.Membership) string {
35+
*mem = client.Membership{
36+
UserId: mem.UserId,
37+
Owner: helper.RandBool(),
38+
}
39+
return config(orgName, mem)
40+
}(orgName, mem),
41+
Check: checks(*mem),
42+
},
43+
{
44+
Config: func(orgName string, mem *client.Membership) string {
45+
*mem = client.Membership{
46+
UserId: mem.UserId,
47+
Owner: helper.RandBool(),
48+
}
49+
return config(orgName, mem)
50+
}(orgName, mem),
51+
Check: checks(*mem),
52+
},
53+
{
54+
ResourceName: resourceName,
55+
ImportState: true,
56+
ImportStateVerify: true,
57+
},
58+
},
59+
})
60+
}
61+
62+
func config(orgName string, mem *client.Membership) string {
63+
return fmt.Sprintf(`
64+
resource "hirefire_organization" "foobar" {
65+
name = "%s"
66+
time_zone = "UTC"
67+
}
68+
69+
resource "hirefire_membership" "foobar" {
70+
organization_id = hirefire_organization.foobar.id
71+
user_id = "%s"
72+
owner = %t
73+
}`, orgName, mem.UserId, mem.Owner)
74+
}
75+
76+
func checks(mem client.Membership) resource.TestCheckFunc {
77+
return resource.ComposeAggregateTestCheckFunc(
78+
checkAttributes(mem),
79+
checkExists(mem),
80+
)
81+
}
82+
83+
func checkAttributes(mem client.Membership) resource.TestCheckFunc {
84+
return helper.CheckResourceAttributes(resourceName, map[string]string{
85+
"owner": strconv.FormatBool(mem.Owner),
86+
})
87+
}
88+
89+
func checkExists(mem client.Membership) resource.TestCheckFunc {
90+
return func(state *terraform.State) error {
91+
id, err := helper.GetResourceID(state, resourceName)
92+
if err != nil {
93+
return err
94+
}
95+
96+
actualMembership, err := helper.Client().Membership.Get(id)
97+
if err != nil {
98+
return err
99+
}
100+
101+
mem.Id = actualMembership.Id
102+
mem.OrganizationId = actualMembership.OrganizationId
103+
return helper.Equals(mem, *actualMembership)
104+
}
105+
}
106+
107+
func checkDestroy(state *terraform.State) error {
108+
id, err := helper.GetResourceID(state, resourceName)
109+
if err != nil {
110+
return err
111+
}
112+
113+
_, err = helper.Client().Membership.Get(id)
114+
if err == nil {
115+
return fmt.Errorf("Not destroyed: %s", resourceName)
116+
}
117+
return nil
118+
}

0 commit comments

Comments
 (0)