Skip to content

Commit

Permalink
Support for deleting Snapshot (#39)
Browse files Browse the repository at this point in the history
* Deleting snapshot by ID

* Work in progress

* Unit test

* fix comments
  • Loading branch information
nvnyale authored Jun 30, 2022
1 parent dad96e2 commit 31091b3
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 1 deletion.
33 changes: 33 additions & 0 deletions api/handlers_snapshots.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,36 @@ func (s *server) SnapshotCreateHandler(w http.ResponseWriter, r *http.Request) {

handleResponseOk(w, out)
}

func (s *server) SnapshotDeleteHandler(w http.ResponseWriter, r *http.Request) {
w = LogWriter{w}
vars := mux.Vars(r)
account := s.mapAccountNumber(vars["account"])
id := vars["id"]

policy, err := generatePolicy([]string{"ec2:DeleteSnapshot"})
if err != nil {
handleError(w, err)
return
}

orch, err := s.newEc2Orchestrator(r.Context(), &sessionParams{
role: fmt.Sprintf("arn:aws:iam::%s:role/%s", account, s.session.RoleName),
inlinePolicy: policy,
policyArns: []string{
"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",
},
})
if err != nil {
handleError(w, err)
return
}

err = orch.deleteSnapshot(r.Context(), id)
if err != nil {
handleError(w, err)
return
}

handleResponseOk(w, nil)
}
17 changes: 17 additions & 0 deletions api/orchestration_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,20 @@ func (o *ec2Orchestrator) createSnapshot(ctx context.Context, req *Ec2SnapshotCr

return snapshotId, nil
}

func (o *ec2Orchestrator) deleteSnapshot(ctx context.Context, id string) error {
if id == "" {
return apierror.New(apierror.ErrBadRequest, "invalid input", nil)
}
log.Debugf("got request to delete snapshot %s", id)

input := &ec2.DeleteSnapshotInput{
SnapshotId: aws.String(id),
}

if err := o.ec2Client.DeleteSnapshot(ctx, input); err != nil {
return err
}

return nil
}
2 changes: 1 addition & 1 deletion api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ func (s *server) routes() {
api.HandleFunc("/{account}/instanceprofiles/{name}", s.ProxyRequestHandler).Methods(http.MethodDelete)
api.HandleFunc("/{account}/sgs/{id}", s.SecurityGroupDeleteHandler).Methods(http.MethodDelete)
api.HandleFunc("/{account}/volumes/{id}", s.VolumeDeleteHandler).Methods(http.MethodDelete)
api.HandleFunc("/{account}/snapshots/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete)
api.HandleFunc("/{account}/snapshots/{id}", s.SnapshotDeleteHandler).Methods(http.MethodDelete)
api.HandleFunc("/{account}/images/{id}", s.ProxyRequestHandler).Methods(http.MethodDelete)
}
14 changes: 14 additions & 0 deletions ec2/snapshots.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,17 @@ func (e *Ec2) CreateSnapshot(ctx context.Context, input *ec2.CreateSnapshotInput

return aws.StringValue(out.SnapshotId), nil
}

func (e *Ec2) DeleteSnapshot(ctx context.Context, input *ec2.DeleteSnapshotInput) error {
if input == nil {
return apierror.New(apierror.ErrBadRequest, "invalid input", nil)
}

log.Infof("deleting snapshot %s", *input.SnapshotId)

_, err := e.Service.DeleteSnapshotWithContext(ctx, input)
if err != nil {
return common.ErrCode("failed to delete snapshot", err)
}
return nil
}
55 changes: 55 additions & 0 deletions ec2/snapshots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ func (m mockEC2Client) CreateSnapshotWithContext(ctx aws.Context, input *ec2.Cre
}
return &ec2.Snapshot{SnapshotId: aws.String("1234")}, nil
}

func (m mockEC2Client) DeleteSnapshotWithContext(aws.Context, *ec2.DeleteSnapshotInput, ...request.Option) (*ec2.DeleteSnapshotOutput, error) {
if m.err != nil {
return nil, m.err
}
return &ec2.DeleteSnapshotOutput{}, nil
}

func TestEc2_CreateSnapshot(t *testing.T) {
type fields struct {
Service ec2iface.EC2API
Expand Down Expand Up @@ -69,3 +77,50 @@ func TestEc2_CreateSnapshot(t *testing.T) {
})
}
}

func TestEc2_DeleteSnapshot(t *testing.T) {
type fields struct {
Service ec2iface.EC2API
}
type args struct {
ctx context.Context
input *ec2.DeleteSnapshotInput
}
tests := []struct {
name string
fields fields
e *Ec2
args args
wantErr bool
}{
{
name: "success case",
args: args{ctx: context.TODO(), input: &ec2.DeleteSnapshotInput{
SnapshotId: aws.String("3514")}},
fields: fields{Service: newmockEC2Client(t, nil)},
wantErr: false,
},
{
name: "aws error",
args: args{ctx: context.TODO(), input: &ec2.DeleteSnapshotInput{SnapshotId: aws.String("1234")}},
fields: fields{Service: newmockEC2Client(t, awserr.New("Bad Request", "boom.", nil))},
wantErr: true,
},
{
name: "nil input",
args: args{ctx: context.TODO()},
fields: fields{Service: newmockEC2Client(t, nil)},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &Ec2{
Service: tt.fields.Service,
}
if err := e.DeleteSnapshot(tt.args.ctx, tt.args.input); (err != nil) != tt.wantErr {
t.Errorf("Ec2.DeleteSnapshot() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

0 comments on commit 31091b3

Please sign in to comment.