From d543ac61519cf35c1adce7519a0190f735f73c00 Mon Sep 17 00:00:00 2001 From: E Camden Fisher Date: Thu, 22 Jul 2021 07:43:51 -0400 Subject: [PATCH] Get image list with name query (#7) * get image list with name query * add missing routes --- api/handlers_images.go | 3 +- api/role.go | 2 +- api/routes.go | 4 ++ ec2/images.go | 11 +++++- ec2/images_test.go | 86 +++++++++++++++++++++++++++++++----------- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/api/handlers_images.go b/api/handlers_images.go index 11d0f6a..e4ca22e 100644 --- a/api/handlers_images.go +++ b/api/handlers_images.go @@ -14,6 +14,7 @@ func (s *server) ImageListHandler(w http.ResponseWriter, r *http.Request) { w = LogWriter{w} vars := mux.Vars(r) account := s.mapAccountNumber(vars["account"]) + name := vars["name"] role := fmt.Sprintf("arn:aws:iam::%s:role/%s", account, s.session.RoleName) @@ -36,7 +37,7 @@ func (s *server) ImageListHandler(w http.ResponseWriter, r *http.Request) { ) // TODO only return images from our org, current EC2-API returns all (needed for managed) - out, err := service.ListImages(r.Context(), "") + out, err := service.ListImages(r.Context(), "", name) if err != nil { handleError(w, err) return diff --git a/api/role.go b/api/role.go index 5f572e7..61a7750 100644 --- a/api/role.go +++ b/api/role.go @@ -70,7 +70,7 @@ func (s *server) assumeRole(ctx context.Context, externalId, roleArn, inlinePoli item, expire, found := s.sessionCache.GetWithExpiration(cacheKey) if found { if sess, ok := item.(*session.Session); ok { - log.Debugf("using cached session (expire: %s)", expire.String()) + log.Infof("using cached session (expire: %s)", expire.String()) return sess, nil } } diff --git a/api/routes.go b/api/routes.go index 473d2a9..6046fa9 100644 --- a/api/routes.go +++ b/api/routes.go @@ -50,6 +50,7 @@ func (s *server) routes() { api.HandleFunc("/{account}/snapshots", s.SnapshotListHandler).Methods(http.MethodGet) api.HandleFunc("/{account}/snapshots/{id}", s.SnapshotGetHandler).Methods(http.MethodGet) api.HandleFunc("/{account}/subnets", s.ProxyRequestHandler).Methods(http.MethodGet) + api.HandleFunc("/{account}/images", s.ImageListHandler).Methods(http.MethodGet).Queries("name", "{name}") api.HandleFunc("/{account}/images", s.ImageListHandler).Methods(http.MethodGet) api.HandleFunc("/{account}/images/{id}", s.ImageGetHandler).Methods(http.MethodGet) api.HandleFunc("/{account}/vpcs", s.ProxyRequestHandler).Methods(http.MethodGet) @@ -62,6 +63,7 @@ func (s *server) routes() { api.HandleFunc("/{account}/snapshots", s.ProxyRequestHandler).Methods(http.MethodPost) api.HandleFunc("/{account}/images", s.ProxyRequestHandler).Methods(http.MethodPost) + api.HandleFunc("/{account}/images/{id}/tags", s.ProxyRequestHandler).Methods(http.MethodPut) api.HandleFunc("/{account}/instances/{id}", s.ProxyRequestHandler).Methods(http.MethodPut) api.HandleFunc("/{account}/instances/{id}/power", s.ProxyRequestHandler).Methods(http.MethodPut) api.HandleFunc("/{account}/instances/{id}/ssm/command", s.ProxyRequestHandler).Methods(http.MethodPut) @@ -75,7 +77,9 @@ func (s *server) routes() { api.HandleFunc("/{account}/instances/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete) api.HandleFunc("/{account}/instances/{id}/volumes/{vid}", s.ProxyRequestHandler).Methods(http.MethodDelete) + api.HandleFunc("/{account}/instanceprofiles/{name}", s.ProxyRequestHandler).Methods(http.MethodDelete) api.HandleFunc("/{account}/sgs/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete) api.HandleFunc("/{account}/volumes/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete) api.HandleFunc("/{account}/snapshots/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete) + api.HandleFunc("/{account}/images/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete) } diff --git a/ec2/images.go b/ec2/images.go index c9be606..85a67c8 100644 --- a/ec2/images.go +++ b/ec2/images.go @@ -9,8 +9,8 @@ import ( log "github.com/sirupsen/logrus" ) -func (e *Ec2) ListImages(ctx context.Context, org string) ([]map[string]*string, error) { - log.Infof("listing ec2 images") +func (e *Ec2) ListImages(ctx context.Context, org, name string) ([]map[string]*string, error) { + log.Infof("listing ec2 images (name: '%s', org: '%s')", name, org) filters := []*ec2.Filter{ { @@ -27,6 +27,13 @@ func (e *Ec2) ListImages(ctx context.Context, org string) ([]map[string]*string, filters = append(filters, inOrg(org)) } + if name != "" { + filters = append(filters, &ec2.Filter{ + Name: aws.String("name"), + Values: aws.StringSlice([]string{name}), + }) + } + out, err := e.Service.DescribeImagesWithContext(ctx, &ec2.DescribeImagesInput{ Owners: aws.StringSlice([]string{"self"}), Filters: filters, diff --git a/ec2/images_test.go b/ec2/images_test.go index a6204a8..b2162f4 100644 --- a/ec2/images_test.go +++ b/ec2/images_test.go @@ -16,7 +16,7 @@ import ( var images = []*ec2.Image{ { ImageId: aws.String("i-00000001"), - Name: aws.String("Image 00000001"), + Name: aws.String("Image_00000001"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -29,7 +29,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000002"), - Name: aws.String("Image 00000002"), + Name: aws.String("Image_00000002"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -42,7 +42,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000003"), - Name: aws.String("Image 00000003"), + Name: aws.String("Image_00000003"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -55,7 +55,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000004"), - Name: aws.String("Image 00000004"), + Name: aws.String("Image_00000004"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -68,7 +68,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000005"), - Name: aws.String("Image 00000005"), + Name: aws.String("Image_00000005"), OwnerId: aws.String("aws"), Public: aws.Bool(false), State: aws.String("available"), @@ -81,7 +81,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000006"), - Name: aws.String("Image 00000006"), + Name: aws.String("Image_00000006"), OwnerId: aws.String("self"), Public: aws.Bool(true), State: aws.String("available"), @@ -94,7 +94,7 @@ var images = []*ec2.Image{ }, { ImageId: aws.String("i-00000007"), - Name: aws.String("Image 00000007"), + Name: aws.String("Image_00000007"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("pending"), @@ -155,6 +155,18 @@ func (m mockEC2Client) DescribeImagesWithContext(ctx context.Context, input *ec2 m.t.Logf("checking passed image filter %+v", f) switch aws.StringValue(f.Name) { + case "name": + var filterMatch bool + for _, v := range f.Values { + if aws.StringValue(v) == aws.StringValue(i.Name) { + filterMatch = true + break + } + } + + if !filterMatch { + match = false + } case "is-public": var filterMatch bool for _, v := range f.Values { @@ -231,8 +243,9 @@ func TestEc2_ListImages(t *testing.T) { org string } type args struct { - ctx context.Context - org string + ctx context.Context + org string + name string } tests := []struct { name string @@ -251,19 +264,19 @@ func TestEc2_ListImages(t *testing.T) { want: []map[string]*string{ { "id": aws.String("i-00000001"), - "name": aws.String("Image 00000001"), + "name": aws.String("Image_00000001"), }, { "id": aws.String("i-00000002"), - "name": aws.String("Image 00000002"), + "name": aws.String("Image_00000002"), }, { "id": aws.String("i-00000003"), - "name": aws.String("Image 00000003"), + "name": aws.String("Image_00000003"), }, { "id": aws.String("i-00000004"), - "name": aws.String("Image 00000004"), + "name": aws.String("Image_00000004"), }, }, }, @@ -277,11 +290,40 @@ func TestEc2_ListImages(t *testing.T) { want: []map[string]*string{ { "id": aws.String("i-00000001"), - "name": aws.String("Image 00000001"), + "name": aws.String("Image_00000001"), }, { "id": aws.String("i-00000002"), - "name": aws.String("Image 00000002"), + "name": aws.String("Image_00000002"), + }, + }, + }, + { + name: "name Image_00000002", + fields: fields{Service: newmockEC2Client(t, nil)}, + args: args{ + ctx: context.TODO(), + name: "Image_00000002", + }, + want: []map[string]*string{ + { + "id": aws.String("i-00000002"), + "name": aws.String("Image_00000002"), + }, + }, + }, + { + name: "dev org with name Image_00000001", + fields: fields{Service: newmockEC2Client(t, nil)}, + args: args{ + ctx: context.TODO(), + org: "dev", + name: "Image_00000001", + }, + want: []map[string]*string{ + { + "id": aws.String("i-00000001"), + "name": aws.String("Image_00000001"), }, }, }, @@ -296,7 +338,7 @@ func TestEc2_ListImages(t *testing.T) { DefaultSubnets: tt.fields.DefaultSubnets, org: tt.fields.org, } - got, err := e.ListImages(tt.args.ctx, tt.args.org) + got, err := e.ListImages(tt.args.ctx, tt.args.org, tt.args.name) if (err != nil) != tt.wantErr { t.Errorf("Ec2.ListImages() error = %v, wantErr %v", err, tt.wantErr) return @@ -353,7 +395,7 @@ func TestEc2_GetImage(t *testing.T) { want: []*ec2.Image{ { ImageId: aws.String("i-00000007"), - Name: aws.String("Image 00000007"), + Name: aws.String("Image_00000007"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("pending"), @@ -389,7 +431,7 @@ func TestEc2_GetImage(t *testing.T) { want: []*ec2.Image{ { ImageId: aws.String("i-00000002"), - Name: aws.String("Image 00000002"), + Name: aws.String("Image_00000002"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -402,7 +444,7 @@ func TestEc2_GetImage(t *testing.T) { }, { ImageId: aws.String("i-00000003"), - Name: aws.String("Image 00000003"), + Name: aws.String("Image_00000003"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -415,7 +457,7 @@ func TestEc2_GetImage(t *testing.T) { }, { ImageId: aws.String("i-00000004"), - Name: aws.String("Image 00000004"), + Name: aws.String("Image_00000004"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -442,7 +484,7 @@ func TestEc2_GetImage(t *testing.T) { want: []*ec2.Image{ { ImageId: aws.String("i-00000003"), - Name: aws.String("Image 00000003"), + Name: aws.String("Image_00000003"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"), @@ -455,7 +497,7 @@ func TestEc2_GetImage(t *testing.T) { }, { ImageId: aws.String("i-00000004"), - Name: aws.String("Image 00000004"), + Name: aws.String("Image_00000004"), OwnerId: aws.String("self"), Public: aws.Bool(false), State: aws.String("available"),