diff --git a/README.md b/README.md index 8c33ca2..36dd13d 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ Here are the GCP resources currently searchable through the workflow: | 🏃‍♂️ Cloud Run | Functions (Gen1), Services (Gen2) | | 📋 Cloud Tasks | Queues | | 📊 Monitoring | Dashboards | -| 🔐 IAM | Role | +| 🔐 IAM | Role, Service Accounts | ## Contributing diff --git a/gcloud/roleslist.go b/gcloud/roleslist.go index 8361f9e..08a47fe 100644 --- a/gcloud/roleslist.go +++ b/gcloud/roleslist.go @@ -10,3 +10,14 @@ func ListIAMRoles(config *Config) ([]IAMRole, error) { return runGCloudCmd[[]IAMRole](config, "iam", "roles", "list", "--format=json(description,name,title)") } + +type IAMServiceAccount struct { + DisplayName string `json:"displayName"` + Email string `json:"email"` + UniqueID string `json:"uniqueId"` +} + +func ListIAMServiceAccounts(config *Config) ([]IAMServiceAccount, error) { + return runGCloudCmd[[]IAMServiceAccount](config, + "iam", "service-accounts", "list", "--format=json(displayName,email,uniqueId)") +} diff --git a/searchers/iam/dto.go b/searchers/iam/dto.go index dda69d3..da7ef6a 100644 --- a/searchers/iam/dto.go +++ b/searchers/iam/dto.go @@ -41,3 +41,33 @@ func FromGCloudIAMRoles(roles *gcloud.IAMRole) Role { DisplayTitle: roles.Title, } } + +type ServiceAccount struct { + DisplayName string + Email string + UniqueID string +} + +func (a ServiceAccount) Title() string { + return a.DisplayName +} + +func (a ServiceAccount) Subtitle() string { + return a.Email +} + +func (a ServiceAccount) UID() string { + return a.UniqueID +} + +func (a ServiceAccount) URL(config *gcloud.Config) string { + return "https://console.cloud.google.com/iam-admin/serviceaccounts/details/" + a.UID() + "?project=" + config.Project +} + +func FromGCloudIAMServiceAccount(account *gcloud.IAMServiceAccount) ServiceAccount { + return ServiceAccount{ + DisplayName: account.DisplayName, + Email: account.Email, + UniqueID: account.UniqueID, + } +} diff --git a/searchers/iam/serviceaccount.go b/searchers/iam/serviceaccount.go new file mode 100644 index 0000000..d05f9f8 --- /dev/null +++ b/searchers/iam/serviceaccount.go @@ -0,0 +1,30 @@ +package iam + +import ( + aw "github.com/deanishe/awgo" + + gc "github.com/dineshgowda24/alfred-gcp-workflow/gcloud" + "github.com/dineshgowda24/alfred-gcp-workflow/parser" + "github.com/dineshgowda24/alfred-gcp-workflow/services" + "github.com/dineshgowda24/alfred-gcp-workflow/workflow/resource" +) + +type ServiceAccountSearcher struct{} + +func (s *ServiceAccountSearcher) Search( + wf *aw.Workflow, svc *services.Service, cfg *gc.Config, q *parser.Result, +) error { + builder := resource.NewBuilder( + "iam_service_accounts", + wf, + cfg, + q, + gc.ListIAMServiceAccounts, + func(wf *aw.Workflow, account gc.IAMServiceAccount) { + sb := FromGCloudIAMServiceAccount(&account) + resource.NewItem(wf, cfg, sb, svc.Icon()) + }, + ) + + return builder.Build() +} diff --git a/searchers/searcher.go b/searchers/searcher.go index 17ed2fc..b69bb03 100644 --- a/searchers/searcher.go +++ b/searchers/searcher.go @@ -80,6 +80,7 @@ func GetDefaultRegistry() *Registry { "vpc/networks": &vpc.NetworkSearcher{}, "vpc/routes": &vpc.RouteSearcher{}, "iam/roles": &iam.RoleSearcher{}, + "iam/serviceaccounts": &iam.ServiceAccountSearcher{}, }, } }