Skip to content

Commit

Permalink
Add request id flag
Browse files Browse the repository at this point in the history
  • Loading branch information
ckluy31 committed Aug 30, 2024
1 parent 6ab8e5a commit 1542361
Showing 1 changed file with 100 additions and 42 deletions.
142 changes: 100 additions & 42 deletions pkg/granted/request/close.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"fmt"

"connectrpc.com/connect"
"github.com/common-fate/cli/printdiags"
"github.com/common-fate/clio"
"github.com/common-fate/grab"
"github.com/common-fate/granted/pkg/cfaws"
"github.com/common-fate/granted/pkg/cfcfg"
"github.com/common-fate/sdk/config"
"github.com/common-fate/sdk/eid"
accessv1alpha1 "github.com/common-fate/sdk/gen/commonfate/access/v1alpha1"
"github.com/common-fate/sdk/service/access/grants"
Expand All @@ -21,7 +23,7 @@ var closeCommand = cli.Command{
Name: "close",
Usage: "Close an active Just-In-Time access to a particular entitlement",
Flags: []cli.Flag{
&cli.StringFlag{Name: "aws-profile", Required: true, Usage: "Close a JIT access for a particular AWS profile"},
&cli.StringFlag{Name: "aws-profile", Required: false, Usage: "Close a JIT access for a particular AWS profile"},
&cli.StringFlag{Name: "request-id", Required: false, Usage: "Close a JIT access for a particular access request ID"},
},
Action: func(c *cli.Context) error {
Expand All @@ -30,63 +32,119 @@ var closeCommand = cli.Command{
return err
}

profileName := c.String("aws-profile")
accessRequestID := c.String("request-id")

profile, err := profiles.LoadInitialisedProfile(c.Context, profileName)
if err != nil {
return err
}
if accessRequestID != "" {
ctx := c.Context

cfg, err := cfcfg.Load(c.Context, profile)
if err != nil {
return fmt.Errorf("failed to load cfconfig, cannot check for active grants, %w", err)
}
cfg, err := config.LoadDefault(ctx)
if err != nil {
return err
}

grantsClient := grants.NewFromConfig(cfg)
idClient := identitysvc.NewFromConfig(cfg)
callerID, err := idClient.GetCallerIdentity(c.Context, connect.NewRequest(&accessv1alpha1.GetCallerIdentityRequest{}))
if err != nil {
return err
}
target := eid.New("AWS::Account", profile.AWSConfig.SSOAccountID)

grants, err := grab.AllPages(c.Context, func(ctx context.Context, nextToken *string) ([]*accessv1alpha1.Grant, *string, error) {
grants, err := grantsClient.QueryGrants(c.Context, connect.NewRequest(&accessv1alpha1.QueryGrantsRequest{
Principal: callerID.Msg.Principal.Eid,
Target: target.ToAPI(),
// This API needs to be updated to use specifiers, for now, fetch all active grants and check for a match on the role name
// Role: eid.New("AWS::Account", profile.AWSConfig.SSOAccountID).ToAPI(),
Status: accessv1alpha1.GrantStatus_GRANT_STATUS_ACTIVE.Enum(),
client := request.NewFromConfig(cfg)

getRes, err := client.GetAccessRequest(ctx, connect.NewRequest(&accessv1alpha1.GetAccessRequestRequest{
Id: accessRequestID,
}))
clio.Debugw("result", "getAccessRequest", getRes)
if err != nil {
return nil, nil, err
return fmt.Errorf("failed to get access request: , %w", err)
}
return grants.Msg.Grants, &grants.Msg.NextPageToken, nil
})

if err != nil {
clearCacheProfileIfExists(profileName)
return fmt.Errorf("failed to query for active grants: %w", err)
// check if access request has grants that need to be closed
grants := getRes.Msg.AccessRequest.Grants

needsDeprovisioning := false
for _, grant := range grants {

if grant.Status == accessv1alpha1.GrantStatus_GRANT_STATUS_ACTIVE && grant.ProvisioningStatus != accessv1alpha1.ProvisioningStatus(accessv1alpha1.ProvisioningStatus_PROVISIONING_STATUS_ATTEMPTING) {
needsDeprovisioning = true
break
}
}

if !needsDeprovisioning {
return fmt.Errorf("access request %s has no grants that need to be closed", accessRequestID)
}

closeRes, err := client.CloseAccessRequest(ctx, connect.NewRequest(&accessv1alpha1.CloseAccessRequestRequest{
Id: accessRequestID,
}))
clio.Debugw("result", "closeAccessRequest", closeRes)
if err != nil {
return fmt.Errorf("failed to close access request: , %w", err)
}

haserrors := printdiags.Print(closeRes.Msg.Diagnostics, nil)
if !haserrors {
clio.Successf("access request %s is now closed", accessRequestID)
}

return nil
}

accessClient := request.NewFromConfig(cfg)
profileName := c.String("aws-profile")

for _, grant := range grants {
if grant.Role.Name == profile.AWSConfig.SSORoleName {
clio.Debugw("found active grant matching the profile, attempting to close grant", "grant", grant)
if profileName != "" {
profile, err := profiles.LoadInitialisedProfile(c.Context, profileName)
if err != nil {
return err
}

res, err := accessClient.CloseAccessRequest(c.Context, connect.NewRequest(&accessv1alpha1.CloseAccessRequestRequest{
Id: grant.AccessRequestId,
cfg, err := cfcfg.Load(c.Context, profile)
if err != nil {
return fmt.Errorf("failed to load cfconfig, cannot check for active grants, %w", err)
}

grantsClient := grants.NewFromConfig(cfg)
idClient := identitysvc.NewFromConfig(cfg)
callerID, err := idClient.GetCallerIdentity(c.Context, connect.NewRequest(&accessv1alpha1.GetCallerIdentityRequest{}))
if err != nil {
return err
}
target := eid.New("AWS::Account", profile.AWSConfig.SSOAccountID)

grants, err := grab.AllPages(c.Context, func(ctx context.Context, nextToken *string) ([]*accessv1alpha1.Grant, *string, error) {
grants, err := grantsClient.QueryGrants(c.Context, connect.NewRequest(&accessv1alpha1.QueryGrantsRequest{
Principal: callerID.Msg.Principal.Eid,
Target: target.ToAPI(),
// This API needs to be updated to use specifiers, for now, fetch all active grants and check for a match on the role name
// Role: eid.New("AWS::Account", profile.AWSConfig.SSOAccountID).ToAPI(),
Status: accessv1alpha1.GrantStatus_GRANT_STATUS_ACTIVE.Enum(),
}))
clio.Debugw("result", "res", res)
if err != nil {
return err
return nil, nil, err
}
return grants.Msg.Grants, &grants.Msg.NextPageToken, nil
})

if err != nil {
clearCacheProfileIfExists(profileName)
return fmt.Errorf("failed to query for active grants: %w", err)
}

accessClient := request.NewFromConfig(cfg)

for _, grant := range grants {
if grant.Role.Name == profile.AWSConfig.SSORoleName {
clio.Debugw("found active grant matching the profile, attempting to close grant", "grant", grant)

res, err := accessClient.CloseAccessRequest(c.Context, connect.NewRequest(&accessv1alpha1.CloseAccessRequestRequest{
Id: grant.AccessRequestId,
}))
clio.Debugw("result", "res", res)
if err != nil {
return err
}
clio.Successf("access to target %s and role %s is now closed", target, profile.AWSConfig.SSORoleName)
return nil
}
clio.Successf("access to target %s and role %s is now closed", target, profile.AWSConfig.SSORoleName)
return nil
}

return fmt.Errorf("no active Access Request found for target %s and role %s", target, profile.AWSConfig.SSORoleName)
}

return fmt.Errorf("no active Access Request found for target %s and role %s", target, profile.AWSConfig.SSORoleName)
return nil
},
}

0 comments on commit 1542361

Please sign in to comment.