Skip to content

feat: Add codefresh_service_account resource and datasource #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 12, 2025
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
89 changes: 89 additions & 0 deletions codefresh/cfclient/api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,95 @@ func (client *Client) GetApiKeysList() ([]ApiKey, error) {
return apiKeys, nil
}

func (client *Client) GetAPIKeyServiceUser(keyID string, serviceUserId string) (*ApiKey, error) {

opts := RequestOptions{
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
Method: "GET",
}

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

if err != nil {
return nil, err
}

var apiKey ApiKey

err = DecodeResponseInto(resp, &apiKey)
if err != nil {
return nil, err
}

return &apiKey, nil
}

func (client *Client) DeleteAPIKeyServiceUser(keyID string, serviceUserId string) error {

opts := RequestOptions{
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
Method: "DELETE",
}

resp, err := client.RequestAPI(&opts)
if err != nil {
fmt.Println(string(resp))
return err
}

return nil
}

func (client *Client) UpdateAPIKeyServiceUser(key *ApiKey, serviceUserId string) error {

keyID := key.ID
if keyID == "" {
return errors.New("[ERROR] Key ID is empty")
}

body, err := EncodeToJSON(key)
if err != nil {
return err
}

opts := RequestOptions{
Path: fmt.Sprintf("/auth/key/service-user/%s/%s", serviceUserId, keyID),
Method: "PATCH",
Body: body,
}

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

if err != nil {
fmt.Println(string(resp))
return err
}

return nil
}

func (client *Client) CreateApiKeyServiceUser(serviceUserId string, apiKey *ApiKey) (string, error) {

body, err := EncodeToJSON(apiKey)
if err != nil {
return "", err
}

opts := RequestOptions{
Path: fmt.Sprintf("/auth/key/service-user/%s", serviceUserId),
Method: "POST",
Body: body,
}

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

if err != nil {
return "", err
}

return string(resp), nil
}

func (client *Client) createRandomUser(accountId string) (string, error) {
// add user
userPrefix := acctest.RandString(10)
Expand Down
174 changes: 174 additions & 0 deletions codefresh/cfclient/service_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package cfclient

import (
"fmt"
"golang.org/x/exp/slices"
)

type ServiceUserTeam struct {
ID string `json:"_id,omitempty"`
}

type ServiceUser struct {
ID string `json:"_id,omitempty"`
Name string `json:"userName,omitempty"`
Teams []ServiceUserTeam `json:"teams,omitempty"`
Roles []string `json:"roles,omitempty"`
}

type ServiceUserCreateUpdate struct {
ID string `json:"_id,omitempty"`
Name string `json:"userName,omitempty"`
TeamIDs []string `json:"teamIds,omitempty"`
AssignAdminRole bool `json:"assignAdminRole,omitempty"`
}

// GetID implement CodefreshObject interface
func (serviceuser *ServiceUser) GetID() string {
return serviceuser.ID
}

func (serviceuser *ServiceUser) HasAdminRole() bool {
return slices.Contains(serviceuser.Roles, "Admin")
}

func (client *Client) GetServiceUserList() ([]ServiceUser, error) {
fullPath := "/service-users"
opts := RequestOptions{
Path: fullPath,
Method: "GET",
}

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

if err != nil {
return nil, err
}

var serviceusers []ServiceUser

err = DecodeResponseInto(resp, &serviceusers)
if err != nil {
return nil, err
}

return serviceusers, nil
}

func (client *Client) GetServiceUserByName(name string) (*ServiceUser, error) {

serviceusers, err := client.GetServiceUserList()
if err != nil {
return nil, err
}

for _, serviceuser := range serviceusers {
if serviceuser.Name == name {
return &serviceuser, nil
}
}

return nil, nil
}

func (client *Client) GetServiceUserByID(id string) (*ServiceUser, error) {

fullPath := fmt.Sprintf("/service-users/%s", id)
opts := RequestOptions{
Path: fullPath,
Method: "GET",
}

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

if err != nil {
return nil, err
}

var serviceuser ServiceUser

err = DecodeResponseInto(resp, &serviceuser)
if err != nil {
return nil, err
}

return &serviceuser, nil
}

func (client *Client) CreateServiceUser(serviceUserCreateUpdate *ServiceUserCreateUpdate) (*ServiceUser, error) {

fullPath := "/service-users"
body, err := EncodeToJSON(serviceUserCreateUpdate)

if err != nil {
return nil, err
}

opts := RequestOptions{
Path: fullPath,
Method: "POST",
Body: body,
}

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

if err != nil {
return nil, err
}

var serviceuser ServiceUser

err = DecodeResponseInto(resp, &serviceuser)
if err != nil {
return nil, err
}

return &serviceuser, nil
}

func (client *Client) UpdateServiceUser(serviceUserCreateUpdate *ServiceUserCreateUpdate) (*ServiceUser, error) {

fullPath := fmt.Sprintf("/service-users/%s", serviceUserCreateUpdate.ID)
body, err := EncodeToJSON(serviceUserCreateUpdate)

if err != nil {
return nil, err
}

opts := RequestOptions{
Path: fullPath,
Method: "PATCH",
Body: body,
}

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

if err != nil {
return nil, err
}

var serviceuser ServiceUser

err = DecodeResponseInto(resp, &serviceuser)
if err != nil {
return nil, err
}

return &serviceuser, nil
}

func (client *Client) DeleteServiceUser(id string) error {
fullPath := fmt.Sprintf("/service-users/%s", id)
opts := RequestOptions{
Path: fullPath,
Method: "DELETE",
}

_, err := client.RequestAPI(&opts)

if err != nil {
return err
}

return nil
}
85 changes: 85 additions & 0 deletions codefresh/data_service_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package codefresh

import (
"fmt"

cfClient "github.com/codefresh-io/terraform-provider-codefresh/codefresh/cfclient"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceServiceAccount() *schema.Resource {
return &schema.Resource{
Description: "This data source retrieves a Codefresh service account by its ID or name.",
Read: dataSourceServiceAccountRead,
Schema: map[string]*schema.Schema{
"_id": {
Type: schema.TypeString,
Optional: true,
},
"name": {
Description: "Service account name",
Type: schema.TypeString,
Optional: true,
AtLeastOneOf: []string{"_id", "name"},
},
"assign_admin_role": {
Description: "Whether or not account admin role is assigned to the service account",
Type: schema.TypeBool,
Optional: true,
},
"assigned_teams": {
Description: "A list of team IDs the service account is be assigned to",
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func dataSourceServiceAccountRead(d *schema.ResourceData, meta interface{}) error {

client := meta.(*cfClient.Client)
var serviceAccount *cfClient.ServiceUser
var err error

if _id, _idOk := d.GetOk("_id"); _idOk {
serviceAccount, err = client.GetServiceUserByID(_id.(string))
} else if name, nameOk := d.GetOk("name"); nameOk {
serviceAccount, err = client.GetServiceUserByName(name.(string))
}

if err != nil {
return err
}

if serviceAccount == nil {
return fmt.Errorf("data.codefresh_service_account - cannot find service account")
}

return mapDataServiceAccountToResource(serviceAccount, d)

}

func mapDataServiceAccountToResource(serviceAccount *cfClient.ServiceUser, d *schema.ResourceData) error {

if serviceAccount == nil || serviceAccount.ID == "" {
return fmt.Errorf("data.codefresh_service_account - failed to mapDataServiceAccountToResource")
}

d.SetId(serviceAccount.ID)
d.Set("name", serviceAccount.Name)
d.Set("assign_admin_role", serviceAccount.HasAdminRole())

teamIds := []string{}

for _, team := range serviceAccount.Teams {
teamIds = append(teamIds, team.ID)
}

d.Set("assigned_teams", teamIds)

return nil
}
2 changes: 2 additions & 0 deletions codefresh/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func Provider() *schema.Provider {
"codefresh_account_idp": dataSourceAccountIdp(),
"codefresh_project": dataSourceProject(),
"codefresh_account_gitops_settings": dataSourceAccountGitopsSettings(),
"codefresh_service_account": dataSourceServiceAccount(),
},
ResourcesMap: map[string]*schema.Resource{
"codefresh_account": resourceAccount(),
Expand All @@ -73,6 +74,7 @@ func Provider() *schema.Provider {
"codefresh_idp": resourceIdp(),
"codefresh_account_idp": resourceAccountIdp(),
"codefresh_account_gitops_settings": resourceAccountGitopsSettings(),
"codefresh_service_account": resourceServiceAccount(),
},
ConfigureFunc: configureProvider,
}
Expand Down
Loading
Loading