Skip to content

Commit

Permalink
feat!: plain text image ref, instead of json payload in generic handl…
Browse files Browse the repository at this point in the history
…er (#25)

* feat!: accept plain text image ref, instead of json payload in generic handler

Signed-off-by: Nico Braun <rainbowstack@gmail.com>

* test: add more test cases to generic handler

Signed-off-by: Nico Braun <rainbowstack@gmail.com>

* docs: add remark about the generic plain text endpoint

Signed-off-by: Nico Braun <rainbowstack@gmail.com>

* test(e2e): fix generic event in testdata

Signed-off-by: Nico Braun <rainbowstack@gmail.com>

---------

Signed-off-by: Nico Braun <rainbowstack@gmail.com>
  • Loading branch information
bluebrown authored Jul 27, 2023
1 parent d9d064f commit 3b7dccc
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 128 deletions.
4 changes: 2 additions & 2 deletions docs/src/configuration/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ endpoints:
## Types
Currently supported endpoint types are `acr`, `dockerhub` and `generic`. The
generic type can be used if you want to dispatch events manually, perhaps via
pipeline.
generic type expects the image reference in plain text. It can be used if you
want to dispatch events manually, perhaps via pipeline.

> **Note** If there is no type for your registry of choice, please open an issue
so that we can add it to the codebase.
9 changes: 2 additions & 7 deletions e2e/testdata/events/generic.http
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
POST /generic HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Content-Type: text/plain

{
"registry": "index.docker.io",
"repository": "bluebrown/busybox",
"tag": "latest",
"digest": "sha256:82becede498899ec668628e7cb0ad87b6e1c371cb8a1e597d83a47fac21d6af3"
}
index.docker.io/bluebrown/busybox:latest@sha256:82becede498899ec668628e7cb0ad87b6e1c371cb8a1e597d83a47fac21d6af3
40 changes: 40 additions & 0 deletions internal/events/generic/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package generic

import (
"errors"
"fmt"
"strings"

"github.com/bluebrown/kobold/internal/events"
"github.com/google/go-containerregistry/pkg/name"
)

type payloadHandler struct {
}

func NewPayloadHandler() events.PayloadHandler {
return payloadHandler{}
}

func (ph payloadHandler) Validate(b []byte) error {
_, err := ph.Decode(b)
return err
}

func (ph payloadHandler) Decode(b []byte) (events.PushData, error) {
rawRef, digest, found := strings.Cut(string(b), "@")
if !found {
return events.PushData{}, errors.New("missing digest")
}

tag, err := name.NewTag(rawRef, name.StrictValidation)
if err != nil {
return events.PushData{}, err
}

return events.PushData{
Image: fmt.Sprintf("%s/%s", tag.RegistryStr(), tag.RepositoryStr()),
Tag: tag.TagStr(),
Digest: digest,
}, nil
}
89 changes: 89 additions & 0 deletions internal/events/generic/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package generic

import (
_ "embed"
"reflect"
"testing"

"github.com/bluebrown/kobold/internal/events"
)

func Test_payloadHandler_Validate(t *testing.T) {
type args struct {
b []byte
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "valid ref",
args: args{b: []byte(`index.docker.io/foo/bar:v1@sha256:220611111e8c9bbe242e9dc1367c0fa89eef83f26203ee3f7c3764046e02b248`)},
wantErr: false,
},
{
name: "no registry",
args: args{b: []byte(`yum/yam:latest@sha256:82becede498899ec668628e7cb0ad87b6e1c371cb8a1e597d83a47fac21d6af3`)},
wantErr: true,
},
{
name: "no tag",
args: args{b: []byte(`azurecr.io/some/thing@sha256:220611111e8c9bbe242e9dc1367c0fa89eef83f26203ee3f7c3764046e02b248`)},
wantErr: true,
},
{
name: "no digest",
args: args{b: []byte(`index.docker.io/library/busybox:123`)},
wantErr: true,
},
{
name: "no namespace",
args: args{b: []byte(`index.docker.io/redis:7.4@sha256:220611111e8c9bbe242e9dc1367c0fa89eef83f26203ee3f7c3764046e02b248`)},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ph := NewPayloadHandler()
if err := ph.Validate(tt.args.b); (err != nil) != tt.wantErr {
t.Errorf("payloadHandler.Validate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func Test_payloadHandler_Decode(t *testing.T) {
type args struct {
b []byte
}
tests := []struct {
name string
args args
want events.PushData
wantErr bool
}{
{
name: "simple",
args: args{b: []byte(`index.docker.io/foo/bar:v1@sha256:220611111e8c9bbe242e9dc1367c0fa89eef83f26203ee3f7c3764046e02b248`)},
want: events.PushData{
Image: "index.docker.io/foo/bar",
Tag: "v1",
Digest: "sha256:220611111e8c9bbe242e9dc1367c0fa89eef83f26203ee3f7c3764046e02b248",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ph := NewPayloadHandler()
got, err := ph.Decode(tt.args.b)
if (err != nil) != tt.wantErr {
t.Errorf("payloadHandler.Decode() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("payloadHandler.Decode() = %v, want %v", got, tt.want)
}
})
}
}
26 changes: 0 additions & 26 deletions internal/events/generic/schema.json

This file was deleted.

32 changes: 0 additions & 32 deletions internal/events/generic/schema_test.go

This file was deleted.

61 changes: 0 additions & 61 deletions internal/events/generic/types.go

This file was deleted.

0 comments on commit 3b7dccc

Please sign in to comment.