Skip to content

Commit

Permalink
fix(gcp-iam): add pagination support
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminch committed Nov 29, 2024
1 parent 7fad475 commit d21f2f1
Showing 1 changed file with 61 additions and 45 deletions.
106 changes: 61 additions & 45 deletions pkg/gcp/iam_service_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,74 @@ import (
)

func DeleteExpiredServiceAccounts(sessions GCPSessions, options GCPOptions) {
serviceAccountsListResponse, err := sessions.IAM.Projects.ServiceAccounts.List("projects/" + options.ProjectID).Do()
if err != nil {
log.Error(fmt.Sprintf("Error listing service accounts, error: %s", err))
return
}

for _, serviceAccount := range serviceAccountsListResponse.Accounts {
resourceTags := common.ResourceTags{}
if err = json.Unmarshal([]byte(serviceAccount.Description), &resourceTags); err != nil {
log.Info(fmt.Sprintf("No resource tags found in description field, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}
ttlStr := ""
if resourceTags.TTL != nil {
ttlStr = resourceTags.TTL.String()
} else {
log.Info(fmt.Sprintf("No ttl value found, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}
ttl, err := strconv.ParseInt(ttlStr, 10, 64)
nextPageToken := ""
for {
serviceAccountsListResponse, err := sessions.IAM.Projects.ServiceAccounts.List("projects/" + options.ProjectID).
PageToken(nextPageToken).PageSize(100).Do()
if err != nil {
log.Warn(fmt.Sprintf("ttl label value `%s` is not parsable to int64, ignoring this service account (`%s`)", ttlStr, serviceAccount.Name))
continue
log.Error(fmt.Sprintf("Error listing service accounts, error: %s", err))
return
}
creationTimeStr := ""
if resourceTags.CreationUnixTimestamp != nil {
creationTimeStr = resourceTags.CreationUnixTimestamp.String()
} else {
log.Info(fmt.Sprintf("No creation time value found, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}
creationTimeInt64, err := strconv.ParseInt(creationTimeStr, 10, 64)
if err != nil {
log.Warn(fmt.Sprintf("creation_date label value `%s` is not parsable to int64, ignoring this service account (`%s`)", creationTimeStr, serviceAccount.Name))
continue
}
creationTime := time.Unix(creationTimeInt64, 0).UTC()

// Service account is not expired (or is protected TTL = 0)
if ttl == 0 || creationTimeInt64 == 0 || time.Now().UTC().Before(creationTime.Add(time.Second*time.Duration(ttl))) {
continue
}
for _, serviceAccount := range serviceAccountsListResponse.Accounts {
resourceTags := common.ResourceTags{}
if err = json.Unmarshal([]byte(serviceAccount.Description), &resourceTags); err != nil {
log.Info(fmt.Sprintf("No resource tags found in description field, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}

ttlStr := ""
if resourceTags.TTL != nil {
ttlStr = resourceTags.TTL.String()
} else {
log.Info(fmt.Sprintf("No ttl value found, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}

ttl, err := strconv.ParseInt(ttlStr, 10, 64)
if err != nil {
log.Warn(fmt.Sprintf("ttl label value `%s` is not parsable to int64, ignoring this service account (`%s`)", ttlStr, serviceAccount.Name))
continue
}

creationTimeStr := ""
if resourceTags.CreationUnixTimestamp != nil {
creationTimeStr = resourceTags.CreationUnixTimestamp.String()
} else {
log.Info(fmt.Sprintf("No creation time value found, ignoring this service account (`%s`)", serviceAccount.Name))
continue
}

creationTimeInt64, err := strconv.ParseInt(creationTimeStr, 10, 64)
if err != nil {
log.Warn(fmt.Sprintf("creation_date label value `%s` is not parsable to int64, ignoring this service account (`%s`)", creationTimeStr, serviceAccount.Name))
continue
}

creationTime := time.Unix(creationTimeInt64, 0).UTC()

// Service account is not expired (or is protected TTL = 0)
if ttl == 0 || creationTimeInt64 == 0 || time.Now().UTC().Before(creationTime.Add(time.Second*time.Duration(ttl))) {
continue
}

if options.DryRun {
log.Info(fmt.Sprintf("Service account `%s` will be deleted", serviceAccount.Name))
continue
}

log.Info(fmt.Sprintf("Deleting service account `%s`", serviceAccount.Name))

if options.DryRun {
log.Info(fmt.Sprintf("Service account `%s will be deleted`", serviceAccount.Name))
continue
if _, err = sessions.IAM.Projects.ServiceAccounts.Delete(serviceAccount.Name).Do(); err != nil {
log.Error(fmt.Sprintf("Error deleting service account `%s`, error: %s", serviceAccount.Name, err))
}
}

log.Info(fmt.Sprintf("Deleting service account `%s`", serviceAccount.Name))
nextPageToken = serviceAccountsListResponse.NextPageToken

if _, err = sessions.IAM.Projects.ServiceAccounts.Delete(serviceAccount.Name).Do(); err != nil {
log.Error(fmt.Sprintf("Error deleting service account `%s`, error: %s", serviceAccount.Name, err))
// Break if there are no more pages
if serviceAccountsListResponse.NextPageToken == "" {
break
}
}
}

0 comments on commit d21f2f1

Please sign in to comment.