Skip to content
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

feat: new explain commands for debugging and informational purposes #86

Merged
merged 3 commits into from
Feb 23, 2024
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
14 changes: 13 additions & 1 deletion docs/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@

This is not a comprehensive list of options, but rather a list of features that I think are worth highlighting.

## Cloud Control API

`--cloud-control` will allow you to use the Cloud Control API for specific resource types. This is useful if you want to use the Cloud Control API for specific resource types.

## Skip Alias Checks

`--no-alias-check` will skip the check for the AWS account alias. This is useful if you are running in an account that does not have an alias.

## Skip Prompts

`--no-prompt` will skip the prompt to verify you want to run the command. This is useful if you are running in a CI/CD environment.
`--no-prompt` will skip the prompt to verify you want to run the command. This is useful if you are running in a CI/CD environment.
`--prompt-delay` will set the delay before the command runs. This is useful if you want to give yourself time to cancel the command.

## Logging

- `--log-level` will set the log level. This is useful if you want to see more or less information in the logs.
- `--log-caller` will log the caller (aka line number and file). This is useful if you are debugging.
- `--log-disable-color` will disable log coloring. This is useful if you are running in an environment that does not support color.
- `--log-full-timestamp` will force log output to always show full timestamp. This is useful if you want to see the full timestamp in the logs.
105 changes: 103 additions & 2 deletions docs/cli-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ USAGE:
aws-nuke [global options] command [command options]

VERSION:
3.0.0-beta.2
3.0.0-dev

AUTHOR:
Erik Kristensen <[email protected]>

COMMANDS:
run, nuke run nuke against an aws account and remove everything from it
account-details, account list details about the AWS account that the tool is authenticated to
config-details explain the configuration file and the resources that will be nuked
resource-types, list-resources list available resources to nuke
help, h Shows a list of commands or help for one command

Expand Down Expand Up @@ -50,4 +52,103 @@ OPTIONS:
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```
```

## aws-nuke explain-account

This command shows you details of how you are authenticated to AWS.

```console
NAME:
aws-nuke explain-account - explain the account and authentication method used to authenticate against AWS

USAGE:
aws-nuke explain-account [command options] [arguments...]

DESCRIPTION:
explain the account and authentication method used to authenticate against AWS

OPTIONS:
--config value, -c value path to config file (default: "config.yaml")
--default-region value the default aws region to use when setting up the aws auth session [$AWS_DEFAULT_REGION]
--access-key-id value the aws access key id to use when setting up the aws auth session [$AWS_ACCESS_KEY_ID]
--secret-access-key value the aws secret access key to use when setting up the aws auth session [$AWS_SECRET_ACCESS_KEY]
--session-token value the aws session token to use when setting up the aws auth session, typically used for temporary credentials [$AWS_SESSION_TOKEN]
--profile value the aws profile to use when setting up the aws auth session, typically used for shared credentials files [$AWS_PROFILE]
--assume-role-arn value the role arn to assume using the credentials provided in the profile or statically set [$AWS_ASSUME_ROLE_ARN]
--assume-role-session-name value the session name to provide for the assumed role [$AWS_ASSUME_ROLE_SESSION_NAME]
--assume-role-external-id value the external id to provide for the assumed role [$AWS_ASSUME_ROLE_EXTERNAL_ID]
--log-level value, -l value Log Level (default: "info") [$LOGLEVEL]
--log-caller log the caller (aka line number and file) (default: false)
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```

### explain-account example output

```console
Overview:
> Account ID: 123456789012
> Account ARN: arn:aws:iam::123456789012:root
> Account UserID: AKIAIOSFODNN7EXAMPLE:root
> Account Alias: no-alias-123456789012
> Default Region: us-east-2
> Enabled Regions: [global ap-south-1 ca-central-1 eu-central-1 us-west-1 us-west-2 eu-north-1 eu-west-3 eu-west-2 eu-west-1 ap-northeast-3 ap-northeast-2 ap-northeast-1 sa-east-1 ap-southeast-1 ap-southeast-2 us-east-1 us-east-2]

Authentication:
> Method: Static Keys
> Access Key ID: AKIAIOSFODNN7EXAMPLE
```

## aws-nuke explain-config

This command will explain the configuration file and the resources that will be nuked for the targeted account.

```console
NAME:
aws-nuke explain-config - explain the configuration file and the resources that will be nuked for an account

USAGE:
aws-nuke explain-config [command options] [arguments...]

DESCRIPTION:
explain the configuration file and the resources that will be nuked for an account that
is defined within the configuration. You may either specific an account using the --account-id flag or
leave it empty to use the default account that can be authenticated against. If you want to see the
resource types that will be nuked, use the --with-resource-types flag. If you want to see the resources
that have filters defined, use the --with-resource-filters flag.

OPTIONS:
--config value, -c value path to config file (default: "config.yaml")
--account-id value the account id to check against the configuration file, if empty, it will use whatever account
can be authenticated against
--with-resource-filters include resource with filters defined in the output (default: false)
--with-resource-types include resource types defined in the output (default: false)
--default-region value the default aws region to use when setting up the aws auth session [$AWS_DEFAULT_REGION]
--access-key-id value the aws access key id to use when setting up the aws auth session [$AWS_ACCESS_KEY_ID]
--secret-access-key value the aws secret access key to use when setting up the aws auth session [$AWS_SECRET_ACCESS_KEY]
--session-token value the aws session token to use when setting up the aws auth session, typically used for temporary credentials [$AWS_SESSION_TOKEN]
--profile value the aws profile to use when setting up the aws auth session, typically used for shared credentials files [$AWS_PROFILE]
--assume-role-arn value the role arn to assume using the credentials provided in the profile or statically set [$AWS_ASSUME_ROLE_ARN]
--assume-role-session-name value the session name to provide for the assumed role [$AWS_ASSUME_ROLE_SESSION_NAME]
--assume-role-external-id value the external id to provide for the assumed role [$AWS_ASSUME_ROLE_EXTERNAL_ID]
--log-level value, -l value Log Level (default: "info") [$LOGLEVEL]
--log-caller log the caller (aka line number and file) (default: false)
--log-disable-color disable log coloring (default: false)
--log-full-timestamp force log output to always show full timestamp (default: false)
--help, -h show help
```

### explain-config example output

```console
Configuration Details

Resource Types: 426
Filter Presets: 2
Resource Filters: 24

Note: use --with-resource-filters to see resources with filters defined
Note: use --with-resource-types to see included resource types that will be nuked
```
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/ekristen/aws-nuke/pkg/common"

_ "github.com/ekristen/aws-nuke/pkg/commands/account"
_ "github.com/ekristen/aws-nuke/pkg/commands/config"
_ "github.com/ekristen/aws-nuke/pkg/commands/list"
_ "github.com/ekristen/aws-nuke/pkg/commands/nuke"

Expand Down
1 change: 0 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ nav:
- Usage: cli-usage.md
- Options: cli-options.md
- Experimental: cli-experimental.md
- Feature Flags: cli-feature-flags.md
- Examples: cli-examples.md
- Config:
- Overview: config.md
Expand Down
14 changes: 14 additions & 0 deletions pkg/awsutil/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type Account struct {
Credentials

id string
arn string
userID string
aliases []string
regions []string
disabledRegions []string
Expand Down Expand Up @@ -92,6 +94,8 @@ func NewAccount(creds Credentials, endpoints config.CustomEndpoints) (*Account,
}

account.id = ptr.ToString(identityOutput.Account)
account.arn = ptr.ToString(identityOutput.Arn)
account.userID = ptr.ToString(identityOutput.UserId)
account.aliases = aliases
account.regions = regions
account.disabledRegions = disabledRegions
Expand All @@ -104,6 +108,16 @@ func (a *Account) ID() string {
return a.id
}

// ARN returns the STS Authenticated ARN for the account
func (a *Account) ARN() string {
return a.arn
}

// UserID returns the authenticated user ID
func (a *Account) UserID() string {
return a.userID
}

// Alias returns the first alias for the account
func (a *Account) Alias() string {
if len(a.aliases) == 0 {
Expand Down
152 changes: 152 additions & 0 deletions pkg/commands/account/account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package account

import (
"fmt"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/ekristen/aws-nuke/pkg/awsutil"
"github.com/ekristen/aws-nuke/pkg/config"
libconfig "github.com/ekristen/libnuke/pkg/config"
"github.com/ekristen/libnuke/pkg/registry"
"github.com/sirupsen/logrus"

"github.com/urfave/cli/v2"

"github.com/ekristen/aws-nuke/pkg/commands/global"
"github.com/ekristen/aws-nuke/pkg/commands/nuke"
"github.com/ekristen/aws-nuke/pkg/common"
)

func execute(c *cli.Context) error {
defaultRegion := c.String("default-region")
creds := nuke.ConfigureCreds(c)

if err := creds.Validate(); err != nil {
return err
}

// Parse the user supplied configuration file to pass in part to configure the nuke process.
parsedConfig, err := config.New(libconfig.Options{
Path: c.Path("config"),
Deprecations: registry.GetDeprecatedResourceTypeMapping(),
})
if err != nil {
logrus.Errorf("Failed to parse config file %s", c.Path("config"))
return err
}

// Set the default region for the AWS SDK to use.
if defaultRegion != "" {
awsutil.DefaultRegionID = defaultRegion
switch defaultRegion {
case endpoints.UsEast1RegionID, endpoints.UsEast2RegionID, endpoints.UsWest1RegionID, endpoints.UsWest2RegionID:
awsutil.DefaultAWSPartitionID = endpoints.AwsPartitionID
case endpoints.UsGovEast1RegionID, endpoints.UsGovWest1RegionID:
awsutil.DefaultAWSPartitionID = endpoints.AwsUsGovPartitionID
default:
if parsedConfig.CustomEndpoints.GetRegion(defaultRegion) == nil {
err = fmt.Errorf("the custom region '%s' must be specified in the configuration 'endpoints'", defaultRegion)
logrus.Error(err.Error())
return err
}
}
}

// Create the AWS Account object. This will be used to get the account ID and aliases for the account.
account, err := awsutil.NewAccount(creds, parsedConfig.CustomEndpoints)
if err != nil {
return err
}

fmt.Println("Overview:")
fmt.Println("> Account ID: ", account.ID())
fmt.Println("> Account ARN: ", account.ARN())
fmt.Println("> Account UserID: ", account.UserID())
fmt.Println("> Account Alias: ", account.Alias())
fmt.Println("> Default Region: ", defaultRegion)
fmt.Println("> Enabled Regions: ", account.Regions())

fmt.Println("")
fmt.Println("Authentication:")
if creds.HasKeys() {
fmt.Println("> Method: Static Keys")
fmt.Println("> Access Key ID: ", creds.AccessKeyID)
}
if creds.HasProfile() {
fmt.Println("> Method: Shared Credentials")
fmt.Println("> Profile: ", creds.Profile)
}
if creds.AssumeRoleArn != "" {
fmt.Println("> Method: Assume Role")
fmt.Println("> Role ARN: ", creds.AssumeRoleArn)
if creds.RoleSessionName != "" {
fmt.Println("> Session Name: ", creds.RoleSessionName)
}
if creds.ExternalId != "" {
fmt.Println("> External ID: ", creds.ExternalId)
}
}

return nil
}

func init() {
flags := []cli.Flag{
&cli.PathFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "path to config file",
Value: "config.yaml",
},
&cli.StringFlag{
Name: "default-region",
EnvVars: []string{"AWS_DEFAULT_REGION"},
Usage: "the default aws region to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "access-key-id",
EnvVars: []string{"AWS_ACCESS_KEY_ID"},
Usage: "the aws access key id to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "secret-access-key",
EnvVars: []string{"AWS_SECRET_ACCESS_KEY"},
Usage: "the aws secret access key to use when setting up the aws auth session",
},
&cli.StringFlag{
Name: "session-token",
EnvVars: []string{"AWS_SESSION_TOKEN"},
Usage: "the aws session token to use when setting up the aws auth session, typically used for temporary credentials",
},
&cli.StringFlag{
Name: "profile",
EnvVars: []string{"AWS_PROFILE"},
Usage: "the aws profile to use when setting up the aws auth session, typically used for shared credentials files",
},
&cli.StringFlag{
Name: "assume-role-arn",
EnvVars: []string{"AWS_ASSUME_ROLE_ARN"},
Usage: "the role arn to assume using the credentials provided in the profile or statically set",
},
&cli.StringFlag{
Name: "assume-role-session-name",
EnvVars: []string{"AWS_ASSUME_ROLE_SESSION_NAME"},
Usage: "the session name to provide for the assumed role",
},
&cli.StringFlag{
Name: "assume-role-external-id",
EnvVars: []string{"AWS_ASSUME_ROLE_EXTERNAL_ID"},
Usage: "the external id to provide for the assumed role",
},
}

cmd := &cli.Command{
Name: "explain-account",
Usage: "explain the account and authentication method used to authenticate against AWS",
Description: `explain the account and authentication method used to authenticate against AWS`,
Flags: append(flags, global.Flags()...),
Before: global.Before,
Action: execute,
}

common.RegisterCommand(cmd)
}
Loading