ecrm

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 29, 2023 License: MIT Imports: 37 Imported by: 0

README

ecrm

A command line tool for managing ECR repositories.

ecrm can delete "unused" images safety.

"unused" means,

  • Images not specified in running tasks in ECS clusters.
  • Images not specified in avaliable ECS service deployments.
  • Images not specified in exists ECS task definitions.
  • Images not specified in using Lambda functions (PackageType=Image).

Usage

NAME:
   ecrm - A command line tool for managing ECR repositories

USAGE:
   ecrm [global options] command [command options] [arguments...]

COMMANDS:
   delete    Scan ECS/Lambda resources and delete unused ECR images.
   generate  Genarete ecrm.yaml
   plan      Scan ECS/Lambda resources and find unused ECR images to delete safety.
   help, h   Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config FILE, -c FILE  Load configuration from FILE (default: "ecrm.yaml") [$ECRM_CONFIG]
   --log-level value       Set log level (debug, info, notice, warn, error) (default: "info") [$ECRM_LOG_LEVEL]
   --no-color              Whether or not to color the output (default: false) [$ECRM_NO_COLOR]
   --help, -h              show help (default: false)

Configurations

Configuration file is YAML format. ecrm generate can generate a configuration file.

clusters:
  - name: my-cluster
  - name_pattern: "prod*"
  - name_pattern: "dev*"
task_definitions:
  - name: "*"
    keep_count: 3
lambda_funcions:
  - name: "*"
    keep_count: 3
repositories:
  - name_pattern: "prod/*"
    expires: 90days
    keep_tag_patterns:
      - latest
  - name_pattern: "dev/*"
    expires: 30days
generate command

ecrm generate scans ECS, Lambda and ECR resources in an AWS account and generate a configuration file.

$ ecrm generate --help
NAME:
   ecrm generate - Genarete ecrm.yaml

USAGE:
   ecrm generate [command options] [arguments...]

OPTIONS:
   --help, -h  show help (default: false)
plan command
$ ecrm plan --help
NAME:
   ecrm plan - Scan ECS/Lambda resources and find unused ECR images to delete safety.

USAGE:
   ecrm plan [command options] [arguments...]

OPTIONS:
   --format value                          plan output format (table, json) (default: table)
   --repository REPOSITORY, -r REPOSITORY  plan for only images in REPOSITORY [$ECRM_REPOSITORY]

ecrm plan shows summaries of unused images in ECR.

ecrm delete deletes these images (in EXPIRED columns) actually.

$ ecrm plan
       REPOSITORY      |    TOTAL     |    EXPIRED    |    KEEP      
-----------------------+--------------+---------------+--------------
      dev/app          | 732 (594 GB) | -707 (574 GB) | 25 (21 GB)   
      dev/nginx        | 720 (28 GB)  | -697 (27 GB)  | 23 (875 MB)  
      prod/app         | 97 (80 GB)   | -87 (72 GB)   | 10 (8.4 GB)  
      prod/nginx       | 95 (3.7 GB)  | -85 (3.3 GB)  | 10 (381 MB)  
delete command
$ ecrm delete --help
NAME:
   ecrm delete - scan ECS resources and delete unused ECR images.

USAGE:
   ecrm delete [command options] [arguments...]

OPTIONS:
   --force                                 force delete images without confirmation (default: false) [$ECRM_FORCE]
   --repository REPOSITORY, -r REPOSITORY  delete only images in REPOSITORY [$ECRM_REPOSITORY]
   --help, -h                              show help (default: false)

Notes

Support to image indexes and soci indexes.

ecrm supports image indexes and soci (Seekable OCI) indexes. ecrm deletes these images that are related to expired images safely.

  1. Scans ECR repositories.
    • Detect image type (Image, Image index, Soci index).
  2. Find expired images.
  3. Find expired image indexes related to expired images by the image tag (sha256-{digest of image}).
  4. Find soci indexes related to expired image indexes using ECR BatchGetImage API for expired images.

An example output is here.

  REPOSITORY |    TYPE     |   TOTAL    |   EXPIRED   |    KEEP     
-------------+-------------+------------+-------------+-------------
  xxx/app    | Image       | 30 (40 GB) | -27 (36 GB) | 3 (3.8 GB)  
  xxx/app    | Image index | 5 (163 MB) | -3 (98 MB)  | 2 (65 MB)   
  xxx/app    | Soci index  | 5 (163 MB) | -3 (98 MB)  | 2 (65 MB)  

See also

Author

Copyright (c) 2021 FUJIWARA Shunichiro

LICENSE

MIT

Documentation

Index

Constants

View Source
const (
	SummaryTypeImage      = "Image"
	SummaryTypeImageIndex = "Image index"
	SummaryTypeSociIndex  = "Soci index"
)
View Source
const (
	MediaTypeSociIndex = "application/vnd.amazon.soci.index.v1+json"
)

Variables

View Source
var (
	DefaultKeepCount       = 5
	DefaultExpiresStr      = "30d"
	DefaultKeepTagPatterns = []string{"latest"}
)
View Source
var LogLevelFilter = &logutils.LevelFilter{
	Levels: []logutils.LogLevel{"debug", "info", "notice", "warn", "error"},
	ModifierFuncs: []logutils.ModifierFunc{
		nil,
		logutils.Color(color.FgWhite),
		logutils.Color(color.FgHiBlue),
		logutils.Color(color.FgYellow),
		logutils.Color(color.FgRed, color.Bold),
	},
	Writer: os.Stderr,
}

Functions

func SetLogLevel added in v0.2.0

func SetLogLevel(level string)

Types

type App

type App struct {
	// contains filtered or unexported fields
}

func New

func New(ctx context.Context, region string) (*App, error)

func (*App) DeleteImages

func (app *App) DeleteImages(ctx context.Context, repo string, ids []ecrTypes.ImageIdentifier, opt Option) error

func (*App) GenerateConfig added in v0.2.0

func (app *App) GenerateConfig(ctx context.Context, configFile string, opt Option) error

func (*App) NewCLI added in v0.2.0

func (app *App) NewCLI() *cli.App

func (*App) NewDeleteCommand added in v0.2.0

func (app *App) NewDeleteCommand() *cli.Command

func (*App) NewGenerateCommand added in v0.2.0

func (app *App) NewGenerateCommand() *cli.Command

func (*App) NewLambdaAction added in v0.2.0

func (app *App) NewLambdaAction() func(c *cli.Context) error

func (*App) NewPlanCommand added in v0.2.0

func (app *App) NewPlanCommand() *cli.Command

func (*App) Run

func (app *App) Run(ctx context.Context, path string, opt Option) error

type ClusterConfig

type ClusterConfig struct {
	Name        string `yaml:"name,omitempty"`
	NamePattern string `yaml:"name_pattern,omitempty"`
}

func (*ClusterConfig) Match

func (c *ClusterConfig) Match(name string) bool

func (*ClusterConfig) Validate

func (c *ClusterConfig) Validate() error

type Config

type Config struct {
	Clusters        []*ClusterConfig    `yaml:"clusters"`
	TaskDefinitions []*TaskdefConfig    `yaml:"task_definitions"`
	LambdaFunctions []*LambdaConfig     `yaml:"lambda_functions"`
	Repositories    []*RepositoryConfig `yaml:"repositories"`
}

func LoadConfig

func LoadConfig(path string) (*Config, error)

func (*Config) Validate

func (c *Config) Validate() error

type LambdaConfig added in v0.1.0

type LambdaConfig struct {
	Name        string `yaml:"name,omitempty"`
	NamePattern string `yaml:"name_pattern,omitempty"`
	KeepCount   int64  `yaml:"keep_count,omitempty"`
	KeepAliase  bool   `yaml:"keep_aliase,omitempty"`
}

func (*LambdaConfig) Match added in v0.1.0

func (c *LambdaConfig) Match(name string) bool

func (*LambdaConfig) Validate added in v0.1.0

func (c *LambdaConfig) Validate() error

type Option

type Option struct {
	Delete     bool
	Force      bool
	Repository string
	NoColor    bool
	Format     outputFormat
}

type RepoSummary added in v0.4.0

type RepoSummary []*Summary

func NewRepoSummary added in v0.4.0

func NewRepoSummary(repo string) RepoSummary

func (RepoSummary) Add added in v0.4.0

func (s RepoSummary) Add(img ecrTypes.ImageDetail)

func (RepoSummary) Expire added in v0.4.0

func (s RepoSummary) Expire(img ecrTypes.ImageDetail)

type RepositoryConfig

type RepositoryConfig struct {
	Name            string   `yaml:"name,omitempty"`
	NamePattern     string   `yaml:"name_pattern,omitempty"`
	Expires         string   `yaml:"expires,omitempty"`
	KeepCount       int64    `yaml:"keep_count,omitempty"`
	KeepTagPatterns []string `yaml:"keep_tag_patterns,omitempty"`
	// contains filtered or unexported fields
}

func (*RepositoryConfig) IsExpired

func (r *RepositoryConfig) IsExpired(at time.Time) bool

func (*RepositoryConfig) MatchName

func (r *RepositoryConfig) MatchName(name string) bool

func (*RepositoryConfig) MatchTag

func (r *RepositoryConfig) MatchTag(tag string) bool

func (*RepositoryConfig) Validate

func (r *RepositoryConfig) Validate() error

type Summary added in v0.4.0

type Summary struct {
	Repo             string `json:"repository"`
	Type             string `json:"type"`
	ExpiredImages    int64  `json:"expired_images"`
	TotalImages      int64  `json:"total_images"`
	ExpiredImageSize int64  `json:"expired_image_size"`
	TotalImageSize   int64  `json:"total_image_size"`
}

type SummaryTable added in v0.4.0

type SummaryTable []*Summary

type TaskdefConfig added in v0.1.0

type TaskdefConfig struct {
	Name        string `yaml:"name,omitempty"`
	NamePattern string `yaml:"name_pattern,omitempty"`
	KeepCount   int64  `yaml:"keep_count,omitempty"`
}

func (*TaskdefConfig) Match added in v0.1.0

func (c *TaskdefConfig) Match(name string) bool

func (*TaskdefConfig) Validate added in v0.1.0

func (c *TaskdefConfig) Validate() error

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL