Skip to content

Commit 94cb953

Browse files
Support for Entities and IAM endpoints (#754)
## 📝 Description **What does this PR do and why is this change necessary?** Implements: - **GET** /entities - **GET** /iam/role-permissions - **GET** /iam/users/{username}/role-permissions - **PUT** /iam/users/{username}/role-permissions ## ✔️ How to Test **How do I run the relevant unit/integration tests?** ```bash make TEST_ARGS='-run TestIAM' test-unit ``` ```bash make TEST_ARGS='-run TestEntities' test-unit ```
1 parent 3236713 commit 94cb953

File tree

8 files changed

+315
-0
lines changed

8 files changed

+315
-0
lines changed

entities.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package linodego
2+
3+
import "context"
4+
5+
type LinodeEntity struct {
6+
ID int `json:"id"`
7+
Label string `json:"label"`
8+
Type string `json:"type"`
9+
}
10+
11+
func (c *Client) ListEntities(ctx context.Context, opts *ListOptions) ([]LinodeEntity, error) {
12+
return getPaginatedResults[LinodeEntity](ctx, c, "entities", opts)
13+
}

iam.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package linodego
2+
3+
import "context"
4+
5+
type UserRolePermissions struct {
6+
AccountAccess []string `json:"account_access"`
7+
EntityAccess []UserAccess `json:"entity_access"`
8+
}
9+
10+
func (p *UserRolePermissions) GetUpdateOptions() UserRolePermissionsUpdateOptions {
11+
return UserRolePermissionsUpdateOptions{
12+
AccountAccess: p.AccountAccess,
13+
EntityAccess: p.EntityAccess,
14+
}
15+
}
16+
17+
type UserRolePermissionsUpdateOptions struct {
18+
AccountAccess []string `json:"account_access"`
19+
EntityAccess []UserAccess `json:"entity_access"`
20+
}
21+
22+
type UserAccess struct {
23+
ID int `json:"id"`
24+
Type string `json:"type"`
25+
Roles []string `json:"roles"`
26+
}
27+
28+
type AccountRolePermissions struct {
29+
AccountAccess []AccountAccess `json:"account_access"`
30+
EntityAccess []AccountAccess `json:"entity_access"`
31+
}
32+
33+
type AccountAccess struct {
34+
Type string `json:"type"`
35+
Roles []Role `json:"roles"`
36+
}
37+
38+
type Role struct {
39+
Name string `json:"name"`
40+
Description string `json:"description"`
41+
Permissions []string `json:"permissions"`
42+
}
43+
44+
func (c *Client) GetUserRolePermissions(ctx context.Context, username string) (*UserRolePermissions, error) {
45+
return doGETRequest[UserRolePermissions](ctx, c,
46+
formatAPIPath("iam/users/%s/role-permissions", username),
47+
)
48+
}
49+
50+
func (c *Client) UpdateUserRolePermissions(ctx context.Context, username string, opts UserRolePermissionsUpdateOptions) (*UserRolePermissions, error) {
51+
return doPUTRequest[UserRolePermissions](ctx, c,
52+
formatAPIPath("iam/users/%s/role-permissions", username),
53+
opts,
54+
)
55+
}
56+
57+
func (c *Client) GetAccountRolePermissions(ctx context.Context) (*AccountRolePermissions, error) {
58+
return doGETRequest[AccountRolePermissions](ctx, c, "iam/role-permissions")
59+
}

test/unit/entities_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package unit
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/linode/linodego"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestEntities_List(t *testing.T) {
12+
fixtureData, err := fixtures.GetFixture("entities_list")
13+
assert.NoError(t, err)
14+
15+
var base ClientBaseCase
16+
base.SetUp(t)
17+
defer base.TearDown(t)
18+
19+
base.MockGet(formatMockAPIPath("entities"), fixtureData)
20+
21+
entities, err := base.Client.ListEntities(context.Background(), &linodego.ListOptions{})
22+
assert.NoError(t, err)
23+
24+
assert.Equal(t, 7, entities[0].ID)
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"data": [
3+
{
4+
"id": 7,
5+
"label": "linode7",
6+
"type": "linode"
7+
},
8+
{
9+
"id": 10,
10+
"label": "linode10",
11+
"type": "linode"
12+
},
13+
{
14+
"id": 1,
15+
"label": "no_devices",
16+
"type": "firewall"
17+
},
18+
{
19+
"id": 2,
20+
"label": "active_with_nodebalancer",
21+
"type": "firewall"
22+
}
23+
],
24+
"page": 1,
25+
"pages": 1,
26+
"results": 4
27+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"account_access": [
3+
{
4+
"type": "account",
5+
"roles": [
6+
{
7+
"name": "account_admin",
8+
"description": "Access to perform any supported action on all entities of the account",
9+
"permissions": [
10+
"create_linode",
11+
"update_linode",
12+
"update_firewall"
13+
]
14+
}
15+
]
16+
},
17+
{
18+
"type": "linode",
19+
"roles": [
20+
{
21+
"name": "account_linode_admin",
22+
"description": "Access to perform any supported action on all linode instances of the account",
23+
"permissions": [
24+
"create_linode",
25+
"update_linode",
26+
"delete_linode"
27+
]
28+
}
29+
]
30+
},
31+
{
32+
"type": "firewall",
33+
"roles": [
34+
{
35+
"name": "firewall_creator",
36+
"description": "Access to create a firewall instance",
37+
"permissions": [
38+
"update_linode",
39+
"view_linode"
40+
]
41+
}
42+
]
43+
}
44+
],
45+
"entity_access": [
46+
{
47+
"type": "linode",
48+
"roles": [
49+
{
50+
"name": "linode_contributor",
51+
"description": "Access to update a linode instance",
52+
"permissions": [
53+
"update_linode",
54+
"view_linode"
55+
]
56+
}
57+
]
58+
},
59+
{
60+
"type": "firewall",
61+
"roles": [
62+
{
63+
"name": "firewall_viewer",
64+
"description": "Access to view a firewall instance",
65+
"permissions": [
66+
"update_linode",
67+
"view_linode"
68+
]
69+
},
70+
{
71+
"name": "firewall_admin",
72+
"description": "Access to perform any supported action on a firewall instance",
73+
"permissions": [
74+
"update_linode",
75+
"view_linode"
76+
]
77+
}
78+
]
79+
}
80+
]
81+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"account_access": [
3+
"account_linode_admin",
4+
"linode_creator",
5+
"firewall_creator"
6+
],
7+
"entity_access": [
8+
{
9+
"id": 1,
10+
"type": "linode",
11+
"roles": [
12+
"linode_contributor"
13+
]
14+
},
15+
{
16+
"id": 1,
17+
"type": "firewall",
18+
"roles": [
19+
"firewall_admin"
20+
]
21+
}
22+
]
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"account_access": [
3+
"account_linode_admin",
4+
"linode_creator",
5+
"firewall_creator",
6+
"test_admin"
7+
],
8+
"entity_access": [
9+
{
10+
"id": 1,
11+
"type": "linode",
12+
"roles": [
13+
"linode_contributor"
14+
]
15+
},
16+
{
17+
"id": 1,
18+
"type": "firewall",
19+
"roles": [
20+
"firewall_admin"
21+
]
22+
}
23+
]
24+
}

test/unit/iam_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package unit
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestIAMAccountRolerPermissions_Get(t *testing.T) {
11+
fixtureData, err := fixtures.GetFixture("iam_account_get")
12+
assert.NoError(t, err)
13+
14+
var base ClientBaseCase
15+
base.SetUp(t)
16+
defer base.TearDown(t)
17+
18+
base.MockGet(formatMockAPIPath("iam/role-permissions"), fixtureData)
19+
20+
perms, err := base.Client.GetAccountRolePermissions(context.Background())
21+
assert.NoError(t, err)
22+
23+
assert.Equal(t, "linode", perms.EntityAccess[0].Type)
24+
}
25+
26+
func TestIAMUserRolePermissions_Get(t *testing.T) {
27+
fixtureData, err := fixtures.GetFixture("iam_user_get")
28+
assert.NoError(t, err)
29+
30+
var base ClientBaseCase
31+
base.SetUp(t)
32+
defer base.TearDown(t)
33+
34+
base.MockGet(formatMockAPIPath("iam/users/Linode/role-permissions"), fixtureData)
35+
36+
perms, err := base.Client.GetUserRolePermissions(context.Background(), "Linode")
37+
assert.NoError(t, err)
38+
39+
assert.Equal(t, 1, perms.EntityAccess[0].ID)
40+
}
41+
42+
func TestIAMUserRolePermissions_Update(t *testing.T) {
43+
updateFixtureData, err := fixtures.GetFixture("iam_user_update")
44+
assert.NoError(t, err)
45+
getFixtureData, err := fixtures.GetFixture("iam_user_get")
46+
assert.NoError(t, err)
47+
48+
var base ClientBaseCase
49+
base.SetUp(t)
50+
defer base.TearDown(t)
51+
52+
base.MockGet(formatMockAPIPath("iam/users/Linode/role-permissions"), getFixtureData)
53+
base.MockPut(formatMockAPIPath("iam/users/Linode/role-permissions"), updateFixtureData)
54+
55+
before, err := base.Client.GetUserRolePermissions(context.Background(), "Linode")
56+
opts := before.GetUpdateOptions()
57+
opts.AccountAccess = append(opts.AccountAccess, "test_admin")
58+
after, err := base.Client.UpdateUserRolePermissions(context.Background(), "Linode", opts)
59+
assert.NoError(t, err)
60+
61+
assert.Equal(t, 1, after.EntityAccess[0].ID)
62+
assert.NotEqual(t, before.AccountAccess, after.AccountAccess)
63+
}

0 commit comments

Comments
 (0)