Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions entities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package linodego

import "context"

// LinodeEntity is anything in Linode with IAM Permissions
type LinodeEntity struct {
ID int `json:"id"`
Label string `json:"label"`
Type string `json:"type"`
}

// ListEntities returns a paginated list of all entities
func (c *Client) ListEntities(ctx context.Context, opts *ListOptions) ([]LinodeEntity, error) {
return getPaginatedResults[LinodeEntity](ctx, c, "entities", opts)
}

// GetEntityRoles returns a list of roles for the entity and user
func (c *Client) GetEntityRoles(ctx context.Context, username string, entityType string, entityID int) ([]string, error) {
perms, err := doGETRequest[[]string](ctx, c,
formatAPIPath("iam/users/%s/permissions/%s/%d", username, entityType, entityID))
if err != nil || perms == nil {
return nil, err
}

return (*perms), err
}
80 changes: 80 additions & 0 deletions iam.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package linodego

import "context"

// UserRolePermissions are the account and entity permissions for the User
type UserRolePermissions struct {
AccountAccess []string `json:"account_access"`
EntityAccess []UserAccess `json:"entity_access"`
}

// GetUpdateOptions converts UserRolePermissions for use in UpdateUserRolePermissions
func (p *UserRolePermissions) GetUpdateOptions() UserRolePermissionsUpdateOptions {
return UserRolePermissionsUpdateOptions{
AccountAccess: p.AccountAccess,
EntityAccess: p.EntityAccess,
}
}

// UserRolePermissionsUpdateOptions are fields accepted by UpdateUserRolePermissions
type UserRolePermissionsUpdateOptions struct {
AccountAccess []string `json:"account_access"`
EntityAccess []UserAccess `json:"entity_access"`
}

// UserAccess is the breakdown of entities Roles
type UserAccess struct {
ID int `json:"id"`
Type string `json:"type"`
Roles []string `json:"roles"`
}

// AccountRolePermissions are the account and entity roles for the Account
type AccountRolePermissions struct {
AccountAccess []AccountAccess `json:"account_access"`
EntityAccess []AccountAccess `json:"entity_access"`
}

// AccountAccess is the Roles for each Type for the Account
type AccountAccess struct {
Type string `json:"type"`
Roles []Role `json:"roles"`
}

// Role is the IAM Role and its Permissions
type Role struct {
Name string `json:"name"`
Description string `json:"description"`
Permissions []string `json:"permissions"`
}

// GetUserRolePermissions returns any role permissions for username
func (c *Client) GetUserRolePermissions(ctx context.Context, username string) (*UserRolePermissions, error) {
return doGETRequest[UserRolePermissions](ctx, c,
formatAPIPath("iam/users/%s/role-permissions", username),
)
}

// UpdateUserRolePermissions updates any role permissions for username
func (c *Client) UpdateUserRolePermissions(ctx context.Context, username string, opts UserRolePermissionsUpdateOptions) (*UserRolePermissions, error) {
return doPUTRequest[UserRolePermissions](ctx, c,
formatAPIPath("iam/users/%s/role-permissions", username),
opts,
)
}

// GetAccountRolePermissions returns the role permissions for this Account
func (c *Client) GetAccountRolePermissions(ctx context.Context) (*AccountRolePermissions, error) {
return doGETRequest[AccountRolePermissions](ctx, c, "iam/role-permissions")
}

// GetUserAccountPermissions returns the account permissions for username
func (c *Client) GetUserAccountPermissions(ctx context.Context, username string) ([]string, error) {
perms, err := doGETRequest[[]string](ctx, c,
formatAPIPath("iam/users/%s/permissions/account", username))
if err != nil || perms == nil {
return nil, err
}

return (*perms), err
}
41 changes: 41 additions & 0 deletions test/unit/entities_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package unit

import (
"context"
"testing"

"github.com/linode/linodego"
"github.com/stretchr/testify/assert"
)

func TestEntities_List(t *testing.T) {
fixtureData, err := fixtures.GetFixture("entities_list")
assert.NoError(t, err)

var base ClientBaseCase
base.SetUp(t)
defer base.TearDown(t)

base.MockGet(formatMockAPIPath("entities"), fixtureData)

entities, err := base.Client.ListEntities(context.Background(), &linodego.ListOptions{})
assert.NoError(t, err)

assert.Equal(t, 7, entities[0].ID)
}

func TestEntitiesPermissions_Get(t *testing.T) {
fixtureData, err := fixtures.GetFixture("entities_permissions")
assert.NoError(t, err)

var base ClientBaseCase
base.SetUp(t)
defer base.TearDown(t)

base.MockGet(formatMockAPIPath("iam/users/Linode/permissions/linode/123"), fixtureData)

perms, err := base.Client.GetEntityRoles(context.Background(), "Linode", "linode", 123)
assert.NoError(t, err)

assert.Equal(t, "rebuild_linode", perms[1])
}
27 changes: 27 additions & 0 deletions test/unit/fixtures/entities_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"data": [
{
"id": 7,
"label": "linode7",
"type": "linode"
},
{
"id": 10,
"label": "linode10",
"type": "linode"
},
{
"id": 1,
"label": "no_devices",
"type": "firewall"
},
{
"id": 2,
"label": "active_with_nodebalancer",
"type": "firewall"
}
],
"page": 1,
"pages": 1,
"results": 4
}
5 changes: 5 additions & 0 deletions test/unit/fixtures/entities_permissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"generate_linode_lish_token_remote",
"rebuild_linode",
"shutdown_linode"
]
81 changes: 81 additions & 0 deletions test/unit/fixtures/iam_account_get.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"account_access": [
{
"type": "account",
"roles": [
{
"name": "account_admin",
"description": "Access to perform any supported action on all entities of the account",
"permissions": [
"create_linode",
"update_linode",
"update_firewall"
]
}
]
},
{
"type": "linode",
"roles": [
{
"name": "account_linode_admin",
"description": "Access to perform any supported action on all linode instances of the account",
"permissions": [
"create_linode",
"update_linode",
"delete_linode"
]
}
]
},
{
"type": "firewall",
"roles": [
{
"name": "firewall_creator",
"description": "Access to create a firewall instance",
"permissions": [
"update_linode",
"view_linode"
]
}
]
}
],
"entity_access": [
{
"type": "linode",
"roles": [
{
"name": "linode_contributor",
"description": "Access to update a linode instance",
"permissions": [
"update_linode",
"view_linode"
]
}
]
},
{
"type": "firewall",
"roles": [
{
"name": "firewall_viewer",
"description": "Access to view a firewall instance",
"permissions": [
"update_linode",
"view_linode"
]
},
{
"name": "firewall_admin",
"description": "Access to perform any supported action on a firewall instance",
"permissions": [
"update_linode",
"view_linode"
]
}
]
}
]
}
5 changes: 5 additions & 0 deletions test/unit/fixtures/iam_user_account_permissions_get.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
"list_events",
"view_account_settings",
"cancel_account"
]
23 changes: 23 additions & 0 deletions test/unit/fixtures/iam_user_get.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"account_access": [
"account_linode_admin",
"linode_creator",
"firewall_creator"
],
"entity_access": [
{
"id": 1,
"type": "linode",
"roles": [
"linode_contributor"
]
},
{
"id": 1,
"type": "firewall",
"roles": [
"firewall_admin"
]
}
]
}
24 changes: 24 additions & 0 deletions test/unit/fixtures/iam_user_update.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"account_access": [
"account_linode_admin",
"linode_creator",
"firewall_creator",
"test_admin"
],
"entity_access": [
{
"id": 1,
"type": "linode",
"roles": [
"linode_contributor"
]
},
{
"id": 1,
"type": "firewall",
"roles": [
"firewall_admin"
]
}
]
}
3 changes: 2 additions & 1 deletion test/unit/fixtures/volume_get.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"hardware_type": "",
"linode_label": "",
"encryption": "",
"io_ready": true,
"created": "2025-01-01T12:00:00",
"updated": "2025-01-10T12:00:00"
}

Loading