Files
cloudfox/aws/sdk/codebuild.go

157 lines
5.0 KiB
Go

package sdk
import (
"context"
"encoding/gob"
"fmt"
"github.com/BishopFox/cloudfox/internal"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/codebuild"
codeBuildTypes "github.com/aws/aws-sdk-go-v2/service/codebuild/types"
"github.com/patrickmn/go-cache"
"github.com/sirupsen/logrus"
)
type CodeBuildClientInterface interface {
ListProjects(ctx context.Context, params *codebuild.ListProjectsInput, optFns ...func(*codebuild.Options)) (*codebuild.ListProjectsOutput, error)
BatchGetProjects(ctx context.Context, params *codebuild.BatchGetProjectsInput, optFns ...func(*codebuild.Options)) (*codebuild.BatchGetProjectsOutput, error)
GetResourcePolicy(ctx context.Context, params *codebuild.GetResourcePolicyInput, optFns ...func(*codebuild.Options)) (*codebuild.GetResourcePolicyOutput, error)
}
func init() {
gob.Register(codeBuildTypes.Project{})
gob.Register([]codeBuildTypes.Project{})
}
// create a CachedCodeBuildListProjects function that accepts a codebuild client, account id, and region. Make sure it handles the region option and pagination
func CachedCodeBuildListProjects(CodeBuildClient CodeBuildClientInterface, accountID string, region string) ([]string, error) {
var PaginationControl *string
var projects []string
cacheKey := fmt.Sprintf("%s-codebuild-ListProjects", accountID)
cached, found := internal.Cache.Get(cacheKey)
if found {
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:ListProjects",
"account": accountID,
"region": region,
"cache": "hit",
}).Info("AWS API call")
return cached.([]string), nil
}
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:ListProjects",
"account": accountID,
"region": region,
"cache": "miss",
}).Info("AWS API call")
for {
ListProjects, err := CodeBuildClient.ListProjects(
context.TODO(),
&codebuild.ListProjectsInput{
NextToken: PaginationControl,
},
func(o *codebuild.Options) {
o.Region = region
},
)
if err != nil {
sharedLogger.Error(err.Error())
break
}
projects = append(projects, ListProjects.Projects...)
// Pagination control.
if ListProjects.NextToken != nil {
PaginationControl = ListProjects.NextToken
} else {
PaginationControl = nil
break
}
}
internal.Cache.Set(cacheKey, projects, cache.DefaultExpiration)
return projects, nil
}
// create a CachedCodeBuildBatchGetProjects function that accepts a codebuild client, account id, region, and a single projectId. Make sure it handles the region option and pagination
func CachedCodeBuildBatchGetProjects(CodeBuildClient CodeBuildClientInterface, accountID string, region string, projectID string) (codeBuildTypes.Project, error) {
project := codeBuildTypes.Project{}
cacheKey := fmt.Sprintf("%s-codebuild-BatchGetProjects-%s-%s", accountID, region, projectID)
cached, found := internal.Cache.Get(cacheKey)
if found {
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:BatchGetProjects",
"account": accountID,
"region": region,
"cache": "hit",
}).Info("AWS API call")
return cached.(codeBuildTypes.Project), nil
}
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:BatchGetProjects",
"account": accountID,
"region": region,
"cache": "miss",
}).Info("AWS API call")
BatchGetProjects, err := CodeBuildClient.BatchGetProjects(
context.TODO(),
&codebuild.BatchGetProjectsInput{
Names: []string{projectID},
},
func(o *codebuild.Options) {
o.Region = region
},
)
if err != nil {
sharedLogger.Error(err.Error())
return project, err
}
internal.Cache.Set(cacheKey, BatchGetProjects.Projects, cache.DefaultExpiration)
return BatchGetProjects.Projects[0], nil
}
// create a CachedCodeBuildGetResourcePolicy function that accepts a codebuild client, account id, region, and a single projectId. Make sure it handles the region option and pagination
func CachedCodeBuildGetResourcePolicy(CodeBuildClient CodeBuildClientInterface, accountID string, region string, projectID string) (string, error) {
cacheKey := fmt.Sprintf("%s-codebuild-GetResourcePolicy-%s-%s", accountID, region, projectID)
cached, found := internal.Cache.Get(cacheKey)
if found {
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:GetResourcePolicy",
"account": accountID,
"region": region,
"cache": "hit",
}).Info("AWS API call")
return cached.(string), nil
}
sharedLogger.WithFields(logrus.Fields{
"api": "codebuild:GetResourcePolicy",
"account": accountID,
"region": region,
"cache": "miss",
}).Info("AWS API call")
GetResourcePolicy, err := CodeBuildClient.GetResourcePolicy(
context.TODO(),
&codebuild.GetResourcePolicyInput{
ResourceArn: aws.String("arn:aws:codebuild:" + region + ":" + accountID + ":project/" + projectID),
},
func(o *codebuild.Options) {
o.Region = region
},
)
if err != nil {
sharedLogger.Error(err.Error())
return "", err
}
internal.Cache.Set(cacheKey, GetResourcePolicy, cache.DefaultExpiration)
return aws.ToString(GetResourcePolicy.Policy), nil
}