Skip to content

Commit 3720134

Browse files
authored
Add sysdig_user resource (#12)
* Add sysdig_user resource Signed-off-by: Hiroki Suezawa <[email protected]> * Improve names for sysdig_user resource Signed-off-by: Hiroki Suezawa <[email protected]>
1 parent 95f6139 commit 3720134

File tree

7 files changed

+314
-0
lines changed

7 files changed

+314
-0
lines changed

examples/user.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resource "sysdig_user" "sample" {
2+
3+
system_role = "ROLE_CUSTOMER"
4+
first_name = "John"
5+
last_name = "Smith"
6+
}

sysdig/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ func Provider() terraform.ResourceProvider {
4343
"sysdig_secure_rule_process": resourceSysdigSecureRuleProcess(),
4444
"sysdig_secure_rule_syscall": resourceSysdigSecureRuleSyscall(),
4545
"sysdig_secure_rule_falco": resourceSysdigSecureRuleFalco(),
46+
"sysdig_user": resourceSysdigUser(),
4647

4748
"sysdig_monitor_alert_downtime": resourceSysdigMonitorAlertDowntime(),
4849
"sysdig_monitor_alert_metric": resourceSysdigMonitorAlertMetric(),

sysdig/resource_sysdig_user.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package sysdig
2+
3+
import (
4+
"github.com/draios/terraform-provider-sysdig/sysdig/secure"
5+
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
6+
"strconv"
7+
"time"
8+
)
9+
10+
func resourceSysdigUser() *schema.Resource {
11+
timeout := 30 * time.Second
12+
13+
return &schema.Resource{
14+
Create: resourceSysdigUserCreate,
15+
Update: resourceSysdigUserUpdate,
16+
Read: resourceSysdigUserRead,
17+
Delete: resourceSysdigUserDelete,
18+
19+
Timeouts: &schema.ResourceTimeout{
20+
Create: schema.DefaultTimeout(timeout),
21+
},
22+
23+
Schema: map[string]*schema.Schema{
24+
"email": {
25+
Type: schema.TypeString,
26+
Required: true,
27+
},
28+
"system_role": {
29+
Type: schema.TypeString,
30+
Optional: true,
31+
Default: "ROLE_USER",
32+
},
33+
"first_name": {
34+
Type: schema.TypeString,
35+
Optional: true,
36+
},
37+
"last_name": {
38+
Type: schema.TypeString,
39+
Optional: true,
40+
},
41+
"version": {
42+
Type: schema.TypeInt,
43+
Computed: true,
44+
},
45+
},
46+
}
47+
}
48+
49+
func resourceSysdigUserCreate(d *schema.ResourceData, meta interface{}) error {
50+
client := meta.(*SysdigClients).sysdigSecureClient
51+
52+
user := userFromResourceData(d)
53+
54+
user, err := client.CreateUser(user)
55+
if err != nil {
56+
return err
57+
}
58+
59+
d.SetId(strconv.Itoa(user.ID))
60+
d.Set("version", user.Version)
61+
62+
return nil
63+
}
64+
65+
// Retrieves the information of a resource form the file and loads it in Terraform
66+
func resourceSysdigUserRead(d *schema.ResourceData, meta interface{}) error {
67+
client := meta.(*SysdigClients).sysdigSecureClient
68+
69+
id, _ := strconv.Atoi(d.Id())
70+
u, err := client.GetUserById(id)
71+
72+
if err != nil {
73+
d.SetId("")
74+
return err
75+
}
76+
77+
d.Set("version", u.Version)
78+
d.Set("system_role", u.SystemRole)
79+
d.Set("email", u.Email)
80+
d.Set("first_name", u.FirstName)
81+
d.Set("last_name", u.LastName)
82+
83+
return nil
84+
}
85+
86+
func resourceSysdigUserUpdate(d *schema.ResourceData, meta interface{}) error {
87+
client := meta.(*SysdigClients).sysdigSecureClient
88+
89+
u := userFromResourceData(d)
90+
91+
u.Version = d.Get("version").(int)
92+
u.ID, _ = strconv.Atoi(d.Id())
93+
94+
_, err := client.UpdateUser(u)
95+
96+
return err
97+
}
98+
99+
func resourceSysdigUserDelete(d *schema.ResourceData, meta interface{}) error {
100+
client := meta.(*SysdigClients).sysdigSecureClient
101+
102+
id, _ := strconv.Atoi(d.Id())
103+
104+
return client.DeleteUser(id)
105+
}
106+
107+
func userFromResourceData(d *schema.ResourceData) (u secure.User) {
108+
u = secure.User{
109+
SystemRole: d.Get("system_role").(string),
110+
Email: d.Get("email").(string),
111+
FirstName: d.Get("first_name").(string),
112+
LastName: d.Get("last_name").(string),
113+
}
114+
return u
115+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package sysdig_test
2+
3+
import (
4+
"fmt"
5+
"github.com/draios/terraform-provider-sysdig/sysdig"
6+
"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
7+
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/terraform"
9+
"os"
10+
"testing"
11+
)
12+
13+
func TestAccUser(t *testing.T) {
14+
rText := func() string { return acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) }
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() {
18+
if v := os.Getenv("SYSDIG_SECURE_API_TOKEN"); v == "" {
19+
t.Fatal("SYSDIG_SECURE_API_TOKEN must be set for acceptance tests")
20+
}
21+
},
22+
Providers: map[string]terraform.ResourceProvider{
23+
"sysdig": sysdig.Provider(),
24+
},
25+
Steps: []resource.TestStep{
26+
{
27+
Config: userWithName(rText()),
28+
},
29+
{
30+
Config: userWithSystemRole(rText()),
31+
},
32+
{
33+
Config: userWithoutSystemRole(rText()),
34+
},
35+
{
36+
Config: userMinimumConfiguration(rText()),
37+
},
38+
},
39+
})
40+
}
41+
42+
func userWithName(name string) string {
43+
return fmt.Sprintf(`
44+
resource "sysdig_user" "sample" {
45+
email = "terraform-test+with-name-%[email protected]"
46+
system_role = "ROLE_USER"
47+
first_name = "%s"
48+
last_name = "%s"
49+
}`, name, name, name)
50+
}
51+
52+
func userWithSystemRole(name string) string {
53+
return fmt.Sprintf(`
54+
resource "sysdig_user" "sample" {
55+
email = "terraform-test+with-systemrole-%[email protected]"
56+
system_role = "ROLE_CUSTOMER"
57+
first_name = "%s"
58+
last_name = "%s"
59+
}`, name, name, name)
60+
}
61+
62+
func userWithoutSystemRole(name string) string {
63+
return fmt.Sprintf(`
64+
resource "sysdig_user" "sample" {
65+
email = "terraform-test+without-systemrole-%[email protected]"
66+
first_name = "%s"
67+
last_name = "%s"
68+
}`, name, name, name)
69+
}
70+
71+
func userMinimumConfiguration(name string) string {
72+
return fmt.Sprintf(`
73+
resource "sysdig_user" "sample" {
74+
email = "terraform-test+minimum-%[email protected]"
75+
}`, name)
76+
}

sysdig/secure/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ type SysdigSecureClient interface {
2020
GetNotificationChannelById(int) (NotificationChannel, error)
2121
DeleteNotificationChannel(int) error
2222
UpdateNotificationChannel(NotificationChannel) (NotificationChannel, error)
23+
24+
CreateUser(User) (User, error)
25+
GetUserById(int) (User, error)
26+
DeleteUser(int) error
27+
UpdateUser(User) (User, error)
2328
}
2429

2530
func NewSysdigSecureClient(sysdigSecureAPIToken string, url string) SysdigSecureClient {

sysdig/secure/models.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,29 @@ func RuleFromJSON(body []byte) (rule Rule, err error) {
194194
err = json.Unmarshal(body, &rule)
195195
return
196196
}
197+
198+
// -------- User --------
199+
type User struct {
200+
ID int `json:"id,omitempty"`
201+
Version int `json:"version,omitempty"`
202+
SystemRole string `json:"systemRole,omitempty"`
203+
Email string `json:"username"`
204+
FirstName string `json:"firstName,omitempty"`
205+
LastName string `json:"lastName,omitempty"`
206+
}
207+
208+
func (u *User) ToJSON() io.Reader {
209+
payload, _ := json.Marshal(*u)
210+
return bytes.NewBuffer(payload)
211+
}
212+
213+
func UserFromJSON(body []byte) User {
214+
var result userWrapper
215+
json.Unmarshal(body, &result)
216+
217+
return result.User
218+
}
219+
220+
type userWrapper struct {
221+
User User `json:"user"`
222+
}

sysdig/secure/users.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package secure
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"io/ioutil"
7+
"net/http"
8+
)
9+
10+
func (client *sysdigSecureClient) GetUserById(id int) (u User, err error) {
11+
response, err := client.doSysdigSecureRequest(http.MethodGet, client.GetUserUrl(id), nil)
12+
if err != nil {
13+
return
14+
}
15+
defer response.Body.Close()
16+
17+
body, _ := ioutil.ReadAll(response.Body)
18+
19+
if response.StatusCode != http.StatusOK {
20+
err = errors.New(response.Status)
21+
return
22+
}
23+
24+
u = UserFromJSON(body)
25+
26+
return
27+
}
28+
29+
func (client *sysdigSecureClient) CreateUser(uRequest User) (u User, err error) {
30+
response, err := client.doSysdigSecureRequest(http.MethodPost, client.GetUsersUrl(), uRequest.ToJSON())
31+
32+
if err != nil {
33+
return
34+
}
35+
defer response.Body.Close()
36+
37+
body, _ := ioutil.ReadAll(response.Body)
38+
39+
if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusCreated {
40+
err = errors.New(response.Status)
41+
return
42+
}
43+
44+
u = UserFromJSON(body)
45+
return
46+
}
47+
48+
func (client *sysdigSecureClient) UpdateUser(uRequest User) (u User, err error) {
49+
response, err := client.doSysdigSecureRequest(http.MethodPut, client.GetUserUrl(uRequest.ID), uRequest.ToJSON())
50+
if err != nil {
51+
return
52+
}
53+
defer response.Body.Close()
54+
55+
body, _ := ioutil.ReadAll(response.Body)
56+
57+
if response.StatusCode != http.StatusOK {
58+
err = errors.New(response.Status)
59+
return
60+
}
61+
62+
u = UserFromJSON(body)
63+
return
64+
}
65+
66+
func (client *sysdigSecureClient) DeleteUser(id int) error {
67+
response, err := client.doSysdigSecureRequest(http.MethodDelete, client.GetUserUrl(id), nil)
68+
if err != nil {
69+
return err
70+
}
71+
defer response.Body.Close()
72+
73+
if response.StatusCode != http.StatusNoContent && response.StatusCode != http.StatusOK {
74+
return errors.New(response.Status)
75+
}
76+
return nil
77+
}
78+
79+
func (client *sysdigSecureClient) GetUsersUrl() string {
80+
return fmt.Sprintf("%s/api/users", client.URL)
81+
}
82+
83+
func (client *sysdigSecureClient) GetUserUrl(id int) string {
84+
return fmt.Sprintf("%s/api/users/%d", client.URL, id)
85+
}

0 commit comments

Comments
 (0)