Skip to content

Commit

Permalink
feat: add custom tags for ECR object
Browse files Browse the repository at this point in the history
  • Loading branch information
darkweaver87 committed May 3, 2022
1 parent 9463137 commit 970eddc
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 41 deletions.
5 changes: 2 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"

"os"

"github.com/estahn/k8s-image-swapper/pkg/config"
"github.com/estahn/k8s-image-swapper/pkg/registry"
"github.com/estahn/k8s-image-swapper/pkg/secrets"
Expand Down Expand Up @@ -64,7 +63,7 @@ A mutating webhook for Kubernetes, pointing the images to a new location.`,
//metricsRec := metrics.NewPrometheus(promReg)
log.Trace().Interface("config", cfg).Msg("config")

rClient, err := registry.NewECRClient(cfg.Target.AWS.Region, cfg.Target.AWS.EcrDomain())
rClient, err := registry.NewECRClient(cfg.Target.AWS.Region, cfg.Target.AWS.EcrDomain(), cfg.RepositoryCustomTags)
if err != nil {
log.Err(err).Msg("error connecting to registry client")
os.Exit(1)
Expand Down
16 changes: 11 additions & 5 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ type Config struct {

ListenAddress string

DryRun bool `yaml:"dryRun"`
ImageSwapPolicy string `yaml:"imageSwapPolicy" validate:"oneof=always exists"`
ImageCopyPolicy string `yaml:"imageCopyPolicy" validate:"oneof=delayed immediate force"`
Source Source `yaml:"source"`
Target Target `yaml:"target"`
DryRun bool `yaml:"dryRun"`
ImageSwapPolicy string `yaml:"imageSwapPolicy" validate:"oneof=always exists"`
ImageCopyPolicy string `yaml:"imageCopyPolicy" validate:"oneof=delayed immediate force"`
Source Source `yaml:"source"`
Target Target `yaml:"target"`
RepositoryCustomTags []CustomTag `yaml:"repositoryCustomTags"`

TLSCertFile string
TLSKeyFile string
Expand All @@ -49,6 +50,11 @@ type JMESPathFilter struct {
JMESPath string `yaml:"jmespath"`
}

type CustomTag struct {
Name string `yaml:"name"`
Value string `yaml:"value"`
}

type Target struct {
AWS AWS `yaml:"aws"`
}
Expand Down
13 changes: 13 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ source:
},
},
},
{
name: "should render custom tags config",
cfg: `
repositoryCustomTags:
- name: A
value: b
`,
expCfg: Config{
RepositoryCustomTags: []CustomTag{
{Name: "A", Value: "b"},
},
},
},
}

for _, test := range tests {
Expand Down
57 changes: 36 additions & 21 deletions pkg/registry/ecr.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ import (
"github.com/aws/aws-sdk-go/service/ecr"
"github.com/aws/aws-sdk-go/service/ecr/ecriface"
"github.com/dgraph-io/ristretto"
"github.com/estahn/k8s-image-swapper/pkg/config"
"github.com/go-co-op/gocron"
"github.com/rs/zerolog/log"
)

var execCommand = exec.Command

type ECRClient struct {
client ecriface.ECRAPI
ecrDomain string
authToken []byte
cache *ristretto.Cache
scheduler *gocron.Scheduler
client ecriface.ECRAPI
ecrDomain string
authToken []byte
cache *ristretto.Cache
scheduler *gocron.Scheduler
customTags []config.CustomTag
}

func (e *ECRClient) Credentials() string {
Expand All @@ -41,12 +43,7 @@ func (e *ECRClient) CreateRepository(name string) error {
ScanOnPush: aws.Bool(true),
},
ImageTagMutability: aws.String(ecr.ImageTagMutabilityMutable),
Tags: []*ecr.Tag{
{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
},
},
Tags: e.buildEcrTags(),
})
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
Expand All @@ -68,6 +65,22 @@ func (e *ECRClient) CreateRepository(name string) error {
return nil
}

func (e *ECRClient) buildEcrTags() []*ecr.Tag {
ecrTags := []*ecr.Tag{
{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
},
}

for _, t := range e.customTags {
tag := ecr.Tag{Key: &t.Name, Value: &t.Value}
ecrTags = append(ecrTags, &tag)
}

return ecrTags
}

func (e *ECRClient) RepositoryExists() bool {
panic("implement me")
}
Expand Down Expand Up @@ -146,7 +159,7 @@ func (e *ECRClient) scheduleTokenRenewal() error {
return nil
}

func NewECRClient(region string, ecrDomain string) (*ECRClient, error) {
func NewECRClient(region string, ecrDomain string, ecrCustomTags []config.CustomTag) (*ECRClient, error) {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
Expand All @@ -173,10 +186,11 @@ func NewECRClient(region string, ecrDomain string) (*ECRClient, error) {
scheduler.StartAsync()

client := &ECRClient{
client: ecrClient,
ecrDomain: ecrDomain,
cache: cache,
scheduler: scheduler,
client: ecrClient,
ecrDomain: ecrDomain,
cache: cache,
scheduler: scheduler,
customTags: ecrCustomTags,
}

if err := client.scheduleTokenRenewal(); err != nil {
Expand All @@ -188,11 +202,12 @@ func NewECRClient(region string, ecrDomain string) (*ECRClient, error) {

func NewMockECRClient(ecrClient ecriface.ECRAPI, region string, ecrDomain string) (*ECRClient, error) {
client := &ECRClient{
client: ecrClient,
ecrDomain: ecrDomain,
cache: nil,
scheduler: nil,
authToken: []byte("mock-ecr-client-fake-auth-token"),
client: ecrClient,
ecrDomain: ecrDomain,
cache: nil,
scheduler: nil,
authToken: []byte("mock-ecr-client-fake-auth-token"),
customTags: []config.CustomTag{{Name: "Mock", Value: "mocked-tag"}},
}

return client, nil
Expand Down
42 changes: 30 additions & 12 deletions pkg/webhook/image_swapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,16 @@ func TestImageSwapper_Mutate(t *testing.T) {
},
ImageTagMutability: aws.String("MUTABLE"),
RepositoryName: aws.String("docker.io/library/init-container"),
Tags: []*ecr.Tag{{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
}},
Tags: []*ecr.Tag{
{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
},
{
Key: aws.String("Mock"),
Value: aws.String("mocked-tag"),
},
},
}).Return(mock.Anything)
ecrClient.On(
"CreateRepository",
Expand All @@ -258,10 +264,16 @@ func TestImageSwapper_Mutate(t *testing.T) {
},
ImageTagMutability: aws.String("MUTABLE"),
RepositoryName: aws.String("docker.io/library/nginx"),
Tags: []*ecr.Tag{{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
}},
Tags: []*ecr.Tag{
{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
},
{
Key: aws.String("Mock"),
Value: aws.String("mocked-tag"),
},
},
}).Return(mock.Anything)

registryClient, _ := registry.NewMockECRClient(ecrClient, "ap-southeast-2", "123456789.dkr.ecr.ap-southeast-2.amazonaws.com")
Expand Down Expand Up @@ -310,10 +322,16 @@ func TestImageSwapper_MutateWithImagePullSecrets(t *testing.T) {
},
ImageTagMutability: aws.String("MUTABLE"),
RepositoryName: aws.String("docker.io/library/nginx"),
Tags: []*ecr.Tag{{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
}},
Tags: []*ecr.Tag{
{
Key: aws.String("CreatedBy"),
Value: aws.String("k8s-image-swapper"),
},
{
Key: aws.String("Mock"),
Value: aws.String("mocked-tag"),
},
},
}).Return(mock.Anything)

registryClient, _ := registry.NewMockECRClient(ecrClient, "ap-southeast-2", "123456789.dkr.ecr.ap-southeast-2.amazonaws.com")
Expand Down

0 comments on commit 970eddc

Please sign in to comment.