Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): expose go api for third party apps #282

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ fmt :
$(GO_FMT) -s -w ./

test :
go test -race -coverprofile=coverage.txt -covermode=atomic ./router ./msgservice ./dbservice ./formatting ./data ./regoservice ./routes
go test -timeout 30s -race -coverprofile=coverage.txt -covermode=atomic ./router ./msgservice ./dbservice ./formatting ./data ./regoservice ./routes

lint :
golangci-lint run

cover :
go test ./msgservice ./dbservice ./router ./formatting ./data ./regoservice ./routes -v -coverprofile=cover.out
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,14 +464,15 @@ See [Postee UI](PosteeUI.md) for details how to setup the Postee UI.
### Data Persistency
The Postee container uses BoltDB to store information about previously scanned images.
This is used to prevent resending messages that were already sent before.
The size of the database can grow over time. Every image that is saved in the database uses 20K of storage.

Postee supports ‘PATH_TO_DB’ environment variable to change the database directory. To use, set the ‘PATH_TO_DB’ environment variable to point to the database file, for example: PATH_TO_DB="./database/webhook.db". By default, the directory for the database file is “/server/database/webhook.db”.
The size of the database can grow over time. Every image that is saved in the Bolt database uses 20K of storage.
The default Postee Database is BoltDb.

Postee supports ‘PATH_TO_DB’ environment variable to change the bolt database directory. To use, set the ‘PATH_TO_DB’ environment variable to point to the bolt database file, for example: PATH_TO_DB="./database/webhook.db". By default, the directory for the bolt database file is “/server/database/webhook.db”.

If you would like to persist the database file between restarts of the Postee container, then you should
use a persistent storage option to mount the "/server/database" directory of the container.
The "deploy/kubernetes" directory in this project contains an example deployment that includes a basic Host Persistency.

### Using environment variables in Postee Configuration File
Postee supports use of environment variables for *Output* fields: **User**, **Password** and **Token**. Add preffix `$` to the environment variable name in the configuration file, for example:
```
Expand Down
2 changes: 1 addition & 1 deletion router/integrations.go → data/integrations.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package router
package data

type OutputSettings struct {
Name string `json:"name,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion router/template.go → data/template.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package router
package data

type Template struct {
Name string `json:"name"`
Expand Down
3 changes: 2 additions & 1 deletion router/tenants.go → data/tenants.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package router
package data

import (
"github.com/aquasecurity/postee/v2/routes"
)

type TenantSettings struct {
Name string `json:"name,omitempty"`
AquaServer string `json:"aqua-server,omitempty"`
DBMaxSize int `json:"max-db-size,omitempty"`
DBRemoveOldData int `json:"delete-old-data,omitempty"`
Expand Down
6 changes: 6 additions & 0 deletions data/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ func ClearField(source string) string {
re := regexp.MustCompile(`[[:cntrl:]]|[\x{FFFD}]`)
return re.ReplaceAllString(source, "")
}

func CopyStringArray(src []string) []string {
dst := make([]string, len(src))
copy(dst, src)
return dst
}
10 changes: 10 additions & 0 deletions data/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package data

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestClearField(t *testing.T) {
Expand All @@ -19,3 +21,11 @@ func TestClearField(t *testing.T) {
}
}
}

func TestCopyStringArray(t *testing.T) {
src := []string{"a", "b", "c"}
dst := CopyStringArray(src)
dst[0] = "x"
assert.Equal(t, "a", src[0], "TestCopyStringArray")
assert.Equal(t, "x", dst[0], "TestCopyStringArray")
}
48 changes: 0 additions & 48 deletions dbservice/actions.go

This file was deleted.

44 changes: 44 additions & 0 deletions dbservice/boltdb/actions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package boltdb

import (
"time"

"github.com/aquasecurity/postee/v2/dbservice/dbparam"
)

func (boltDb *BoltDb) MayBeStoreMessage(message []byte, messageKey string, expired *time.Time) (wasStored bool, err error) {
boltDb.mu.Lock()
defer boltDb.mu.Unlock()

db := boltDb.db

if err = Init(db, dbparam.DbBucketName); err != nil {
return false, err
}
if err = Init(db, dbparam.DbBucketExpiryDates); err != nil {
return false, err
}

currentValue, err := dbSelect(db, dbparam.DbBucketName, messageKey)
if err != nil {
return false, err
}

if currentValue != nil {
return false, nil
} else {
bMessageKey := []byte(messageKey)
err = dbInsert(db, dbparam.DbBucketName, bMessageKey, message)
if err != nil {
return false, err
}
if expired != nil {
err = dbInsert(db, dbparam.DbBucketExpiryDates, []byte(expired.Format(dbparam.DateFmt)), bMessageKey)
if err != nil {
return false, err
}
}
return true, nil
}

}
76 changes: 76 additions & 0 deletions dbservice/boltdb/boltdb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package boltdb

import (
"fmt"
"os"
"path/filepath"
"sync"

"github.com/aquasecurity/postee/v2/log"
bolt "go.etcd.io/bbolt"
)

const (
DefaultPath = "/server/database/webhooks.db"
)

type BoltDb struct {
mu sync.Mutex
DbPath string
db *bolt.DB
}

func NewBoltDb(paths ...string) (*BoltDb, error) {
dbPath := DefaultPath
if len(paths) > 0 {
if paths[0] != "" {
dbPath = paths[0]
}
}

log.Logger.Infof("Open Bolt DB at %s", dbPath)
dbConn, err := open(dbPath)
if err != nil {
return nil, fmt.Errorf("failed to open bolt DB file: (%s) %w", dbPath, err)
}

return &BoltDb{
db: dbConn,
DbPath: dbPath,
}, nil
}

var open = func(path string) (*bolt.DB, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
err = os.MkdirAll(filepath.Dir(path), os.ModePerm)
if err != nil {
return nil, err
}
}

return bolt.Open(path, 0666, nil)
}

func (boltDb *BoltDb) ChangeDbPath(newPath string) error {
boltDb.mu.Lock()
defer boltDb.mu.Unlock()
boltDb.DbPath = newPath

if boltDb.db != nil {
boltDb.db.Close()
}

dbConn, err := bolt.Open(newPath, 0666, nil)
if err != nil {
return fmt.Errorf("failed to open bolt DB file: (%s) %w", newPath, err)
}

boltDb.db = dbConn
return nil
}

func (boltDb *BoltDb) Close() error {
boltDb.mu.Lock()
defer boltDb.mu.Unlock()
return boltDb.db.Close()
}
46 changes: 46 additions & 0 deletions dbservice/boltdb/boltdb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package boltdb

import (
"os"
"testing"

bolt "go.etcd.io/bbolt"
)

func TestConfigureBoltDb(t *testing.T) {
tests := []struct {
name string
dbPath string
expectedPath string
}{
{"happy configuration BoltDB with dbPath", "database/webhooks.db", "database/webhooks.db"},
{"happy configuration BoltDB with empty dbPath", "", "/server/database/webhooks.db"},
}

savedOpen := open

open = func(path string) (*bolt.DB, error) {
return nil, nil
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {

boltdb, err := NewBoltDb(test.dbPath)
if err != nil {
t.Errorf("Unexpected error: %v", err)
return
}

configuredPath := boltdb.DbPath

if test.expectedPath != configuredPath {
t.Errorf("paths do not match, expected: %s, got: %s", test.expectedPath, configuredPath)
}
})
}
defer func() {
os.RemoveAll("database/")
open = savedOpen
}()
}
23 changes: 23 additions & 0 deletions dbservice/boltdb/changedbpath_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package boltdb

import (
"testing"
)

func TestChangeDbPath(t *testing.T) {
boltDb, err := NewBoltDb("test_webhooks.db")
if err != nil {
t.Fatal(err)
}

defer boltDb.Close()
testPath := "/tmp/test.db"
storedPath := boltDb.DbPath
_ = boltDb.ChangeDbPath(testPath)
defer func() {
_ = boltDb.ChangeDbPath(storedPath)
}()
if boltDb.DbPath != testPath {
t.Errorf("path is not configured correctly, expected: %s, got %s", testPath, boltDb.DbPath)
}
}
Loading