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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Unreleased

FEATURES:
* Added optional description for user token roles to provide a description in HCPTF UI: https://github.com/hashicorp/vault-plugin-secrets-terraform/pull/84

## 0.11.0
### FEb 7, 2025
IMPROVEMENTS:
Expand Down
4 changes: 3 additions & 1 deletion backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type testEnv struct {
Organization string
TeamID string
UserID string
Description string

Backend logical.Backend
Context context.Context
Expand Down Expand Up @@ -160,7 +161,8 @@ func (e *testEnv) AddUserTokenRole(t *testing.T) {
Path: "role/test-user-token",
Storage: e.Storage,
Data: map[string]interface{}{
"user_id": e.UserID,
"user_id": e.UserID,
"description": e.Description,
},
}
resp, err := e.Backend.HandleRequest(e.Context, req)
Expand Down
16 changes: 13 additions & 3 deletions path_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func (b *tfBackend) pathCredentialsRead(ctx context.Context, req *logical.Reques
"role": roleEntry.Name,
},
}

if roleEntry.Description != "" {
resp.Data["description"] = roleEntry.Description
}
return resp, nil
}

Expand All @@ -94,10 +98,16 @@ func (b *tfBackend) createUserCreds(ctx context.Context, req *logical.Request, r
return nil, err
}

resp := b.Secret(terraformTokenType).Response(map[string]interface{}{
data := map[string]interface{}{
"token": token.Token,
"token_id": token.ID,
}, map[string]interface{}{
}

if role.Description != "" {
data["description"] = role.Description
}

resp := b.Secret(terraformTokenType).Response(data, map[string]interface{}{
"token_id": token.ID,
"role": role.Name,
})
Expand Down Expand Up @@ -127,7 +137,7 @@ func (b *tfBackend) createToken(ctx context.Context, s logical.Storage, roleEntr
case isTeamToken(roleEntry.TeamID):
token, err = createTeamToken(ctx, client, roleEntry.TeamID)
default:
token, err = createUserToken(ctx, client, roleEntry.UserID)
token, err = createUserToken(ctx, client, roleEntry.UserID, roleEntry.Description)
}

if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions path_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type terraformRoleEntry struct {
Organization string `json:"organization,omitempty"`
TeamID string `json:"team_id,omitempty"`
UserID string `json:"user_id,omitempty"`
Description string `json:"description,omitempty"`
TTL time.Duration `json:"ttl"`
MaxTTL time.Duration `json:"max_ttl"`
Token string `json:"token,omitempty"`
Expand All @@ -30,6 +31,9 @@ func (r *terraformRoleEntry) toResponseData() map[string]interface{} {
"ttl": r.TTL.Seconds(),
"max_ttl": r.MaxTTL.Seconds(),
}
if r.Description != "" {
respData["description"] = r.Description
}
if r.Organization != "" {
respData["organization"] = r.Organization
}
Expand Down Expand Up @@ -58,6 +62,10 @@ func pathRole(b *tfBackend) []*framework.Path {
Description: "Name of the role",
Required: true,
},
"description": {
Type: framework.TypeString,
Description: "Description of the token created by the role",
},
"organization": {
Type: framework.TypeString,
Description: "Name of the Terraform Cloud or Enterprise organization",
Expand Down Expand Up @@ -166,6 +174,10 @@ func (b *tfBackend) pathRolesWrite(ctx context.Context, req *logical.Request, d
roleEntry.UserID = userID.(string)
}

if description, ok := d.GetOk("description"); ok {
roleEntry.Description = description.(string)
}

if roleEntry.UserID != "" && (roleEntry.Organization != "" || roleEntry.TeamID != "") {
return logical.ErrorResponse("cannot provide a user_id in combination with organization or team_id"), nil
}
Expand Down
14 changes: 10 additions & 4 deletions path_roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ func TestUserRole(t *testing.T) {
organization := checkEnvVars(t, envVarTerraformOrganization)
teamID := checkEnvVars(t, envVarTerraformTeamID)
userID := checkEnvVars(t, envVarTerraformUserID)
descriptionOriginal := "description1"
descriptionUpdated := "description2"

t.Run("Create User Role - fail", func(t *testing.T) {
resp, err := testTokenRoleCreate(t, b, s, roleName, map[string]interface{}{
Expand All @@ -147,8 +149,9 @@ func TestUserRole(t *testing.T) {
})
t.Run("Create User Role - pass", func(t *testing.T) {
resp, err := testTokenRoleCreate(t, b, s, roleName, map[string]interface{}{
"user_id": userID,
"max_ttl": "3600",
"user_id": userID,
"max_ttl": "3600",
"description": descriptionOriginal,
})

require.Nil(t, err)
Expand All @@ -162,11 +165,13 @@ func TestUserRole(t *testing.T) {
require.Nil(t, resp.Error())
require.NotNil(t, resp)
require.Equal(t, resp.Data["user_id"], userID)
require.Equal(t, resp.Data["description"], descriptionOriginal)
})
t.Run("Update User Role", func(t *testing.T) {
resp, err := testTokenRoleUpdate(t, b, s, map[string]interface{}{
"ttl": "1m",
"max_ttl": "5h",
"ttl": "1m",
"max_ttl": "5h",
"description": descriptionUpdated,
})

require.Nil(t, err)
Expand All @@ -180,6 +185,7 @@ func TestUserRole(t *testing.T) {
require.Nil(t, resp.Error())
require.NotNil(t, resp)
require.Equal(t, resp.Data["user_id"], userID)
require.Equal(t, resp.Data["description"], descriptionUpdated)
})
}

Expand Down
6 changes: 4 additions & 2 deletions terraform_token.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ func createTeamToken(ctx context.Context, c *client, teamID string) (*terraformT
}, nil
}

func createUserToken(ctx context.Context, c *client, userID string) (*terraformToken, error) {
token, err := c.UserTokens.Create(ctx, userID, tfe.UserTokenCreateOptions{})
func createUserToken(ctx context.Context, c *client, userID string, description string) (*terraformToken, error) {
token, err := c.UserTokens.Create(ctx, userID, tfe.UserTokenCreateOptions{
Description: description,
})
if err != nil {
return nil, err
}
Expand Down