Skip to content

Commit

Permalink
Refactor entry and output data structures
Browse files Browse the repository at this point in the history
Fixes #8
  • Loading branch information
nsmith5 committed Jan 6, 2022
1 parent 601df9e commit f867448
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 64 deletions.
12 changes: 2 additions & 10 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (a *agent) run() error {
for _, p := range a.policies {
fmt.Printf("debug: iterating policies")

alert, err := p.Alert(entry)
alert, err := p.Alert(entry.Body)
if err != nil {
// huh... what to do here?
continue
Expand All @@ -102,15 +102,7 @@ func (a *agent) run() error {
if alert {
fmt.Println("debug: violation!")
for _, out := range a.outs {
// TODO: Populate the rekor URL!
e := outputs.Event{
Name: p.Name,
Description: p.Description,
RekorURL: `dunno...`,
}

// TODO: Do something on send failure
err = out.Send(e)
err = out.Send(outputs.Event{Policy: p, Entry: *entry})
if err != nil {
fmt.Println("debug: error sending output")
} else {
Expand Down
10 changes: 7 additions & 3 deletions outputs/interface.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package outputs

import (
"github.com/nsmith5/rekor-sidekick/policy"
"github.com/nsmith5/rekor-sidekick/rekor"
)

type Event struct {
Name string
Description string
RekorURL string
Policy policy.Policy
Entry rekor.LogEntry
}

type Output interface {
Expand Down
22 changes: 10 additions & 12 deletions outputs/stdout/stdout.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package stdout

import (
"fmt"
"encoding/json"
"os"

"github.com/nsmith5/rekor-sidekick/outputs"
)

type impl struct{}
type impl struct {
enc *json.Encoder
}

func (i impl) Send(e outputs.Event) error {
fmt.Printf(
`{"name": "%s", "description": "%s", rekorURL: "%s"}`,
e.Name,
e.Description,
e.RekorURL,
)
fmt.Println()
return nil
func (i *impl) Send(e outputs.Event) error {
return i.enc.Encode(e)
}

func New(map[string]interface{}) (outputs.Output, error) {
return &impl{}, nil
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", "\t")
return &impl{enc}, nil
}

func init() {
Expand Down
108 changes: 71 additions & 37 deletions rekor/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"net/http"
"strings"
"time"
)

var (
Expand All @@ -15,7 +16,12 @@ var (
)

// LogEntry is a Rekor log entry
type LogEntry map[string]interface{}
type LogEntry struct {
URL string
IntegratedAt time.Time
Index uint
Body map[string]interface{}
}

// treeState represents the current state of the transparency log (size
// etc)
Expand Down Expand Up @@ -56,59 +62,87 @@ func NewClient(baseURL string) (*Client, error) {
return &rc, nil
}

func (rc *Client) getLogEntry(index uint) (LogEntry, error) {
url := fmt.Sprintf("%s/api/v1/log/entries?logIndex=%d", rc.baseURL, index)
func (rc *Client) getLogEntry(index uint) (*LogEntry, error) {
var entry LogEntry

req, err := http.NewRequest(`GET`, url, nil)
if err != nil {
return nil, err
}
req.Header.Set(`Accept`, `application/json`)
resp, err := rc.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
entry.Index = index

if resp.StatusCode == http.StatusNotFound {
return nil, ErrEntryDoesntExist
}
entryMap := make(map[string]interface{})
{
url := fmt.Sprintf("%s/api/v1/log/entries?logIndex=%d", rc.baseURL, index)

m := make(map[string]interface{})
err = json.NewDecoder(resp.Body).Decode(&m)
if err != nil {
return nil, err
}
req, err := http.NewRequest(`GET`, url, nil)
if err != nil {
return nil, err
}
req.Header.Set(`Accept`, `application/json`)
resp, err := rc.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusNotFound {
return nil, ErrEntryDoesntExist
}

var body string
// The key is entry UUID, but we have no idea what that is apriori so we
// grab it by looping over key-value pairs and breaking after one
for _, v := range m {
m, ok := v.(map[string]interface{})
if !ok {
return nil, errors.New(`malformed rekor entry response`)
err = json.NewDecoder(resp.Body).Decode(&entryMap)
if err != nil {
return nil, err
}
body, ok = m["body"].(string)
if !ok {
return nil, errors.New(`malformed rekor entry response`)
}

var (
uuid string
unix float64
body string
)
{
// The key is entry UUID, but we have no idea what that is apriori so we
// grab it by looping over key-value pairs and breaking after one
for id, v := range entryMap {
uuid = id

m, ok := v.(map[string]interface{})
if !ok {
return nil, errors.New(`malformed rekor entry response`)
}

unix, ok = m[`integratedTime`].(float64)
if !ok {
return nil, errors.New(`malformed rekor integration time`)
}

body, ok = m["body"].(string)
if !ok {
return nil, errors.New(`malformed rekor entry response`)
}
break
}
break
}

var entry = make(LogEntry)
err = json.NewDecoder(
// (1) UUID -> URL
entry.URL = fmt.Sprintf("%s/api/v1/entries/%s", rc.baseURL, uuid)

// (2) Unix time -> created time
entry.IntegratedAt = time.Unix(int64(unix), 0)

// (3) Decode body
decodedBody := make(map[string]interface{})
err := json.NewDecoder(
base64.NewDecoder(base64.URLEncoding, strings.NewReader(body)),
).Decode(&entry)
).Decode(&decodedBody)
if err != nil {
return nil, err
}
entry.Body = decodedBody

return entry, nil
return &entry, nil
}

// GetNextLogEntry pulls the next entry in the Rekor log. If the
// next log doesn't exist yet ErrEntryDoesntExist is returned.
func (rc *Client) GetNextLogEntry() (LogEntry, error) {
func (rc *Client) GetNextLogEntry() (*LogEntry, error) {
entry, err := rc.getLogEntry(rc.currentIndex)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions rekor/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ func TestGetLogEntry(t *testing.T) {
t.Fatal(err)
}

if kind := entry["kind"].(string); kind != `rekord` {
if kind := entry.Body["kind"].(string); kind != `rekord` {
t.Error(`expected rekord type`)
}
if version := entry["apiVersion"].(string); version != `0.0.1` {
if version := entry.Body["apiVersion"].(string); version != `0.0.1` {
t.Error(`expected api version 0.0.1`)
}
}
Expand Down

0 comments on commit f867448

Please sign in to comment.