Skip to content

Commit d7cfda5

Browse files
support api tokens for service accounts
1 parent 5429310 commit d7cfda5

File tree

4 files changed

+164
-31
lines changed

4 files changed

+164
-31
lines changed

codefresh/cfclient/api_key.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,95 @@ func (client *Client) GetApiKeysList() ([]ApiKey, error) {
245245
return apiKeys, nil
246246
}
247247

248+
func (client *Client) GetAPIKeyServiceUser(keyID string, serviceUserId string) (*ApiKey, error) {
249+
250+
opts := RequestOptions{
251+
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
252+
Method: "GET",
253+
}
254+
255+
resp, err := client.RequestAPI(&opts)
256+
257+
if err != nil {
258+
return nil, err
259+
}
260+
261+
var apiKey ApiKey
262+
263+
err = DecodeResponseInto(resp, &apiKey)
264+
if err != nil {
265+
return nil, err
266+
}
267+
268+
return &apiKey, nil
269+
}
270+
271+
func (client *Client) DeleteAPIKeyServiceUser(keyID string, serviceUserId string) error {
272+
273+
opts := RequestOptions{
274+
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
275+
Method: "DELETE",
276+
}
277+
278+
resp, err := client.RequestAPI(&opts)
279+
if err != nil {
280+
fmt.Println(string(resp))
281+
return err
282+
}
283+
284+
return nil
285+
}
286+
287+
func (client *Client) UpdateAPIKeyServiceUser(key *ApiKey, serviceUserId string) error {
288+
289+
keyID := key.ID
290+
if keyID == "" {
291+
return errors.New("[ERROR] Key ID is empty")
292+
}
293+
294+
body, err := EncodeToJSON(key)
295+
if err != nil {
296+
return err
297+
}
298+
299+
opts := RequestOptions{
300+
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
301+
Method: "PATCH",
302+
Body: body,
303+
}
304+
305+
resp, err := client.RequestAPI(&opts)
306+
307+
if err != nil {
308+
fmt.Println(string(resp))
309+
return err
310+
}
311+
312+
return nil
313+
}
314+
315+
func (client *Client) CreateApiKeyServiceUser(serviceUserId string, apiKey *ApiKey) (string, error) {
316+
317+
body, err := EncodeToJSON(apiKey)
318+
if err != nil {
319+
return "", err
320+
}
321+
322+
opts := RequestOptions{
323+
Path: fmt.Sprintf("/auth/key/service-user/%s", serviceUserId),
324+
Method: "POST",
325+
Body: body,
326+
}
327+
328+
resp, err := client.RequestAPI(&opts)
329+
330+
if err != nil {
331+
return "", err
332+
}
333+
334+
return string(resp), nil
335+
}
336+
248337
func (client *Client) createRandomUser(accountId string) (string, error) {
249338
// add user
250339
userPrefix := acctest.RandString(10)

codefresh/cfclient/service_user.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ package cfclient
33
import (
44
"fmt"
55
"golang.org/x/exp/slices"
6-
76
)
87

98
type ServiceUser struct {
10-
ID string `json:"_id,omitempty"`
11-
Name string `json:"userName,omitempty"`
12-
Teams []Team `json:"teams,omitempty"`
13-
Roles []string `json:"roles,omitempty"`
9+
ID string `json:"_id,omitempty"`
10+
Name string `json:"userName,omitempty"`
11+
Teams []Team `json:"teams,omitempty"`
12+
Roles []string `json:"roles,omitempty"`
1413
}
1514

1615
type ServiceUserCreateUpdate struct {
17-
ID string `json:"_id,omitempty"`
18-
Name string `json:"userName,omitempty"`
19-
TeamIDs []string `json:"teamIds,omitempty"`
20-
AssignAdminRole bool `json:"assignAdminRole,omitempty"`
16+
ID string `json:"_id,omitempty"`
17+
Name string `json:"userName,omitempty"`
18+
TeamIDs []string `json:"teamIds,omitempty"`
19+
AssignAdminRole bool `json:"assignAdminRole,omitempty"`
2120
}
2221

2322
// GetID implement CodefreshObject interface
@@ -104,7 +103,7 @@ func (client *Client) CreateServiceUser(serviceUserCreateUpdate *ServiceUserCrea
104103
opts := RequestOptions{
105104
Path: fullPath,
106105
Method: "POST",
107-
Body: body,
106+
Body: body,
108107
}
109108

110109
resp, err := client.RequestAPI(&opts)
@@ -135,7 +134,7 @@ func (client *Client) UpdateServiceUser(serviceUserCreateUpdate *ServiceUserCrea
135134
opts := RequestOptions{
136135
Path: fullPath,
137136
Method: "PATCH",
138-
Body: body,
137+
Body: body,
139138
}
140139

141140
resp, err := client.RequestAPI(&opts)

codefresh/resource_api_key.go

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,26 @@ func resourceApiKey() *schema.Resource {
3030
Required: true,
3131
},
3232
"account_id": {
33-
Description: "The ID of account in which the API key will be created.",
34-
Type: schema.TypeString,
35-
Required: true,
33+
Description: "The ID of account in which the API key will be created. Required if user_id is set.",
34+
Type: schema.TypeString,
35+
Optional: true,
36+
RequiredWith: []string{"user_id", "account_id"},
37+
ForceNew: true,
3638
},
3739
"user_id": {
38-
Description: "The ID of a user within the referenced `account_id` that will own the API key.",
39-
Type: schema.TypeString,
40-
Required: true,
40+
Description: "The ID of a user within the referenced `account_id` that will own the API key. Requires a Codefresh admin token and can be used only in Codefresh on-premises installations.",
41+
Type: schema.TypeString,
42+
Optional: true,
43+
ExactlyOneOf: []string{"user_id", "service_account_id"},
44+
RequiredWith: []string{"user_id", "account_id"},
45+
ForceNew: true,
46+
},
47+
"service_account_id": {
48+
Description: "The ID of the service account to create the API key for.",
49+
Type: schema.TypeString,
50+
Optional: true,
51+
ExactlyOneOf: []string{"user_id", "service_account_id"},
52+
ForceNew: true,
4153
},
4254
"token": {
4355
Description: "The resulting API key.",
@@ -79,12 +91,22 @@ A list of access scopes for the API key. The possible values:
7991

8092
func resourceApiKeyCreate(d *schema.ResourceData, meta interface{}) error {
8193
client := meta.(*cfclient.Client)
82-
8394
apiKey := *mapResourceToApiKey(d)
84-
accountID := d.Get("account_id").(string)
85-
userID := d.Get("user_id").(string)
8695

87-
resp, err := client.CreateApiKey(userID, accountID, &apiKey)
96+
var (
97+
resp string
98+
err error
99+
)
100+
101+
if serviceAccountId := d.Get("service_account_id").(string); serviceAccountId != "" {
102+
resp, err = client.CreateApiKeyServiceUser(serviceAccountId, &apiKey)
103+
} else {
104+
accountID := d.Get("account_id").(string)
105+
userID := d.Get("user_id").(string)
106+
107+
resp, err = client.CreateApiKey(userID, accountID, &apiKey)
108+
}
109+
88110
if err != nil {
89111
fmt.Println(string(resp))
90112
return err
@@ -117,7 +139,17 @@ func resourceApiKeyRead(d *schema.ResourceData, meta interface{}) error {
117139
return errors.New("[ERROR] Can't read API Key. Token is empty.")
118140
}
119141

120-
apiKey, err := client.GetAPIKey(keyID)
142+
var (
143+
apiKey *cfclient.ApiKey
144+
err error
145+
)
146+
147+
if serviceAccountId := d.Get("service_account_id").(string); serviceAccountId != "" {
148+
apiKey, err = client.GetAPIKeyServiceUser(keyID, serviceAccountId)
149+
} else {
150+
apiKey, err = client.GetAPIKey(keyID)
151+
}
152+
121153
if err != nil {
122154
return err
123155
}
@@ -140,7 +172,15 @@ func resourceApiKeyUpdate(d *schema.ResourceData, meta interface{}) error {
140172
return errors.New("[ERROR] Can't read API Key. Token is empty.")
141173
}
142174

143-
err := client.UpdateAPIKey(&apiKey)
175+
var err error
176+
177+
if serviceAccountId := d.Get("service_account_id").(string); serviceAccountId != "" {
178+
err = client.UpdateAPIKeyServiceUser(&apiKey, serviceAccountId)
179+
} else {
180+
err = client.UpdateAPIKey(&apiKey)
181+
182+
}
183+
144184
if err != nil {
145185
return err
146186
}
@@ -156,7 +196,13 @@ func resourceApiKeyDelete(d *schema.ResourceData, meta interface{}) error {
156196
return errors.New("[ERROR] Can't read API Key. Token is empty.")
157197
}
158198

159-
err := client.DeleteAPIKey(d.Id())
199+
var err error
200+
if serviceAccountId := d.Get("service_account_id").(string); serviceAccountId != "" {
201+
err = client.DeleteAPIKeyServiceUser(d.Id(), serviceAccountId)
202+
} else {
203+
err = client.DeleteAPIKey(d.Id())
204+
}
205+
160206
if err != nil {
161207
return err
162208
}

codefresh/resource_service_user.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ func resourceServiceAccount() *schema.Resource {
2626
},
2727
"assign_admin_role": {
2828
Description: "Whether or not to assign account admin role to the service account",
29-
Type: schema.TypeBool,
30-
Optional: true,
31-
Default: false,
29+
Type: schema.TypeBool,
30+
Optional: true,
31+
Default: false,
3232
},
3333
"assigned_teams": {
3434
Description: "A list of team IDs the service account is be assigned to",
@@ -87,7 +87,6 @@ func resourceServiceAccountUpdate(d *schema.ResourceData, meta interface{}) erro
8787

8888
updateServiceAccount := *mapResourceToServiceAccount(d)
8989

90-
9190
_, err := client.UpdateServiceUser(&updateServiceAccount)
9291

9392
if err != nil {
@@ -152,9 +151,9 @@ func flattenServiceAccountTeams(users []cfclient.TeamUser) []string {
152151
func mapResourceToServiceAccount(d *schema.ResourceData) *cfclient.ServiceUserCreateUpdate {
153152

154153
return &cfclient.ServiceUserCreateUpdate{
155-
ID: d.Id(),
156-
Name: d.Get("name").(string),
157-
TeamIDs: datautil.ConvertStringArr(d.Get("assigned_teams").(*schema.Set).List()),
154+
ID: d.Id(),
155+
Name: d.Get("name").(string),
156+
TeamIDs: datautil.ConvertStringArr(d.Get("assigned_teams").(*schema.Set).List()),
158157
AssignAdminRole: d.Get("assign_admin_role").(bool),
159158
}
160159
}

0 commit comments

Comments
 (0)