Skip to content

Commit ab7b4c2

Browse files
committed
Store importer authentication configuration in DB.
This avoids restarting the server when we want to add a new importer. Also cleanup some dead code and fix some linting issues.
1 parent 161d587 commit ab7b4c2

File tree

11 files changed

+156
-106
lines changed

11 files changed

+156
-106
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ and results can be visualized in the UI as shown below.
1313
Run the following commands
1414

1515
# Spin up GraphKB in few seconds with (wait 15 seconds for mariadb to start).
16-
docker-compose up -d
16+
source bootstrap.sh && docker-compose up -d
1717

1818
# Insert the example data available in examples/ directory
1919
# with the following command:

cmd/go-graphkb/config.yml

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
listen: :8080
2-
# tls_key: cmd/go-graphkb/keys/server.key
3-
# tls_cert: cmd/go-graphkb/keys/server.crt
1+
server_listen: :8080
2+
# server_tls_key: cmd/go-graphkb/keys/server.key
3+
# server_tls_cert: cmd/go-graphkb/keys/server.crt
44

5-
mariadb:
6-
username: graphkb
7-
password: password
8-
host: db
9-
database: graphkb
10-
11-
sources:
12-
csv-employees: token_auth_for_csv_importer
5+
mariadb_username: graphkb
6+
mariadb_password: password
7+
mariadb_host: db
8+
mariadb_database: graphkb

cmd/go-graphkb/main.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ func onInit() {
8080

8181
fmt.Println("Using config file:", viper.ConfigFileUsed())
8282

83-
dbName := viper.GetString("mariadb.database")
83+
dbName := viper.GetString("mariadb_database")
8484
if dbName == "" {
8585
log.Fatal("Please provide database_name option in your configuration file")
8686
}
8787
Database = database.NewMariaDB(
88-
viper.GetString("mariadb.username"),
89-
viper.GetString("mariadb.password"),
90-
viper.GetString("mariadb.host"),
88+
viper.GetString("mariadb_username"),
89+
viper.GetString("mariadb_password"),
90+
viper.GetString("mariadb_host"),
9191
dbName)
9292
}
9393

@@ -121,9 +121,9 @@ func listen(cmd *cobra.Command, args []string) {
121121
log.Fatal(err)
122122
}
123123

124-
listenInterface := viper.GetString("listen")
124+
listenInterface := viper.GetString("server_listen")
125125

126-
server.StartServer(listenInterface, Database, Database, eventBus)
126+
server.StartServer(listenInterface, Database, Database, Database, eventBus)
127127

128128
close(eventBus)
129129
}

cmd/importer-csv/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
graphkb:
22
url: "http://localhost:8080"
3-
auth_token: "token_auth_for_csv_importer"
3+
auth_token: "importer-csv"
44
skip_verify: true
55

6-
path: "./examples/example-data.csv"
6+
path: "example.csv"

graphkb/importer.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ package graphkb
33
import (
44
"fmt"
55

6+
"github.com/clems4ever/go-graphkb/internal/importers"
67
"github.com/clems4ever/go-graphkb/internal/knowledge"
78
"github.com/clems4ever/go-graphkb/internal/schema"
8-
"github.com/clems4ever/go-graphkb/internal/sources"
99
)
1010

11+
// ImporterOptions options for configuring importer
1112
type ImporterOptions struct {
1213
URL string
1314
AuthToken string
1415
SkipVerify bool
1516
}
1617

17-
func Start(source sources.Source, options ImporterOptions) error {
18+
// Start the importer with provided options
19+
func Start(source importers.Importer, options ImporterOptions) error {
1820
if options.URL == "" {
1921
return fmt.Errorf("Please provide graphkb URL in configuration file")
2022
}
@@ -32,6 +34,7 @@ func Start(source sources.Source, options ImporterOptions) error {
3234
return nil
3335
}
3436

37+
// CreateRelation helper function for creating a relation
3538
func CreateRelation(fromType schema.AssetType, relation, toType schema.AssetType) RelationType {
3639
return schema.RelationType{
3740
FromType: fromType,
@@ -40,6 +43,7 @@ func CreateRelation(fromType schema.AssetType, relation, toType schema.AssetType
4043
}
4144
}
4245

46+
// CreateAsset helper function for creating an asset
4347
func CreateAsset(fromType string) AssetType {
4448
return schema.AssetType(fromType)
4549
}

internal/database/mariadb.go

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,44 @@ CREATE TABLE IF NOT EXISTS relations (
8787
q, err = m.db.QueryContext(context.Background(), `
8888
CREATE TABLE IF NOT EXISTS graph_schema (
8989
id INTEGER AUTO_INCREMENT NOT NULL,
90-
source_name VARCHAR(64) NOT NULL,
90+
importer VARCHAR(64) NOT NULL,
9191
graph TEXT NOT NULL,
9292
timestamp TIMESTAMP,
93-
CONSTRAINT pk_schema PRIMARY KEY (id))`)
93+
94+
CONSTRAINT pk_schema PRIMARY KEY (id))`)
95+
if err != nil {
96+
return err
97+
}
98+
defer q.Close()
99+
100+
// Create the table storing importers tokens
101+
q, err = m.db.QueryContext(context.Background(), `
102+
CREATE TABLE IF NOT EXISTS importers (
103+
id INTEGER AUTO_INCREMENT NOT NULL,
104+
name VARCHAR(64) NOT NULL,
105+
auth_token VARCHAR(64) NOT NULL,
106+
107+
CONSTRAINT pk_importer PRIMARY KEY (id),
108+
UNIQUE unique_importer_idx (name, auth_token)
109+
)`)
94110
if err != nil {
95111
return err
96112
}
97113
defer q.Close()
98114
return nil
99115
}
100116

101-
// AssetIDResolver store ID assets in a cache
117+
// AssetRegistry store ID of assets in a cache
102118
type AssetRegistry struct {
103119
cache map[knowledge.AssetKey]int64
104120
}
105121

122+
// Set id of an asset
106123
func (ar *AssetRegistry) Set(a knowledge.AssetKey, idx int64) {
107124
ar.cache[a] = idx
108125
}
109126

127+
// Get id of an asset
110128
func (ar *AssetRegistry) Get(a knowledge.AssetKey) (int64, bool) {
111129
idx, ok := ar.cache[a]
112130
return idx, ok
@@ -286,19 +304,15 @@ func (m *MariaDB) removeRelations(source string, relations []knowledge.Relation)
286304
DELETE r FROM relations r
287305
INNER JOIN assets a ON r.from_id = a.id
288306
INNER JOIN assets b ON r.to_id = b.id
289-
WHERE a.type = ? AND a.value = ? AND b.type = ? AND b.value = ? AND r.type = ?`)
307+
WHERE a.type = ? AND a.value = ? AND b.type = ? AND b.value = ? AND r.type = ? AND r.source = ?`)
290308
if err != nil {
291309
return 0, 0, err
292310
}
293311
defer stmt.Close()
294312

295313
for _, r := range relations {
296-
rel := SourceRelation{
297-
Relation: r,
298-
Source: source,
299-
}
300314
res, err := stmt.ExecContext(context.Background(),
301-
rel.From.Type, rel.From.Key, rel.To.Type, rel.To.Key, rel.Type)
315+
r.From.Type, r.From.Key, r.To.Type, r.To.Key, r.Type, source)
302316
if err != nil {
303317
return 0, 0, fmt.Errorf("Unable to detete relation %v: %v", r, err)
304318
}
@@ -508,6 +522,7 @@ func (m *MariaDB) Query(ctx context.Context, query *query.QueryIL) (*knowledge.G
508522
return res, nil
509523
}
510524

525+
// SaveSchema save the schema graph in database
511526
func (m *MariaDB) SaveSchema(ctx context.Context, sourceName string, schema schema.SchemaGraph) error {
512527
b, err := json.Marshal(schema)
513528
if err != nil {
@@ -523,55 +538,60 @@ func (m *MariaDB) SaveSchema(ctx context.Context, sourceName string, schema sche
523538
return nil
524539
}
525540

541+
// LoadSchema load the schema graph of the source from DB
526542
func (m *MariaDB) LoadSchema(ctx context.Context, sourceName string) (schema.SchemaGraph, error) {
527543
row := m.db.QueryRowContext(ctx, "SELECT graph FROM graph_schema WHERE source_name = ? ORDER BY id DESC LIMIT 1", sourceName)
528-
var rawJson string
529-
if err := row.Scan(&rawJson); err != nil {
544+
var rawJSON string
545+
if err := row.Scan(&rawJSON); err != nil {
530546
if err == sql.ErrNoRows {
531547
return schema.NewSchemaGraph(), nil
532-
} else {
533-
return schema.NewSchemaGraph(), err
534548
}
549+
return schema.NewSchemaGraph(), err
535550
}
536551

537552
graph := schema.NewSchemaGraph()
538-
err := json.Unmarshal([]byte(rawJson), &graph)
553+
err := json.Unmarshal([]byte(rawJSON), &graph)
539554
if err != nil {
540555
return schema.NewSchemaGraph(), err
541556
}
542557

543558
return graph, nil
544559
}
545560

546-
func (m *MariaDB) ListSources(ctx context.Context) ([]string, error) {
547-
rows, err := m.db.QueryContext(ctx, "SELECT DISTINCT source_name FROM graph_schema")
561+
// ListImporters list importers with their authentication tokens
562+
func (m *MariaDB) ListImporters(ctx context.Context) (map[string]string, error) {
563+
rows, err := m.db.QueryContext(ctx, "SELECT name, auth_token FROM importers")
548564

549565
if err != nil {
550566
return nil, fmt.Errorf("Unable to read sources from database: %v", err)
551567
}
552568
defer rows.Close()
553569

554-
sources := make([]string, 0)
570+
importers := make(map[string]string)
555571
for rows.Next() {
556-
var source string
557-
if err := rows.Scan(&source); err != nil {
572+
var importerName string
573+
var authToken string
574+
if err := rows.Scan(&importerName, &authToken); err != nil {
558575
return nil, err
559576
}
560-
sources = append(sources, source)
577+
importers[importerName] = authToken
561578
}
562-
return sources, nil
579+
return importers, nil
563580
}
564581

582+
// MariaDBCursor is a cursor of data retrieved by MariaDB
565583
type MariaDBCursor struct {
566584
*sql.Rows
567585

568586
Projections []knowledge.Projection
569587
}
570588

589+
// HasMore tells whether there are more data to retrieve from the cursor
571590
func (mc *MariaDBCursor) HasMore() bool {
572591
return mc.Rows.Next()
573592
}
574593

594+
// Read read one more item from the cursor
575595
func (mc *MariaDBCursor) Read(ctx context.Context, doc interface{}) error {
576596
var err error
577597
var fArr []string
@@ -650,6 +670,7 @@ func (mc *MariaDBCursor) Read(ctx context.Context, doc interface{}) error {
650670
return nil
651671
}
652672

673+
// Close the cursor
653674
func (mc *MariaDBCursor) Close() error {
654675
return mc.Rows.Close()
655676
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package sources
1+
package importers
22

33
import "github.com/clems4ever/go-graphkb/internal/knowledge"
44

5-
// Source represent a source of data
6-
type Source interface {
5+
// Importer represent an importer of data
6+
type Importer interface {
77
Start(emitter *knowledge.GraphImporter) error
88
Stop() error
99
}

internal/importers/registry.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package importers
2+
3+
import "context"
4+
5+
// Registry is a regostry of importers with their auth tokens
6+
type Registry interface {
7+
// List importers with their authentication tokens
8+
ListImporters(ctx context.Context) (map[string]string, error)
9+
}

internal/schema/graph.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,24 +82,26 @@ func (sg *SchemaGraph) Equal(other SchemaGraph) bool {
8282
return true
8383
}
8484

85+
// MarshalJSON marshal the schema graph into json format
8586
func (sg *SchemaGraph) MarshalJSON() ([]byte, error) {
86-
schemaJson := SchemaGraphJSON{}
87-
schemaJson.Vertices = []AssetType{}
88-
schemaJson.Edges = []RelationType{}
87+
schemaJSON := SchemaGraphJSON{}
88+
schemaJSON.Vertices = []AssetType{}
89+
schemaJSON.Edges = []RelationType{}
8990

9091
for v := range sg.Vertices.Iter() {
9192
vertice := v.(AssetType)
92-
schemaJson.Vertices = append(schemaJson.Vertices, vertice)
93+
schemaJSON.Vertices = append(schemaJSON.Vertices, vertice)
9394
}
9495

9596
for e := range sg.Edges.Iter() {
9697
edge := e.(RelationType)
97-
schemaJson.Edges = append(schemaJson.Edges, edge)
98+
schemaJSON.Edges = append(schemaJSON.Edges, edge)
9899
}
99100

100-
return json.Marshal(schemaJson)
101+
return json.Marshal(schemaJSON)
101102
}
102103

104+
// UnmarshalJSON unmarshal the schema graph from json payload
103105
func (sg *SchemaGraph) UnmarshalJSON(b []byte) error {
104106
j := SchemaGraphJSON{}
105107
if err := json.Unmarshal(b, &j); err != nil {

internal/schema/persistor.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ package schema
22

33
import "context"
44

5+
// Persistor is a persistor of schema
56
type Persistor interface {
6-
ListSources(ctx context.Context) ([]string, error)
7-
87
SaveSchema(ctx context.Context, sourceName string, sg SchemaGraph) error
98
LoadSchema(ctx context.Context, sourceName string) (SchemaGraph, error)
109
}

0 commit comments

Comments
 (0)