Skip to content

Commit

Permalink
Add nodes for attestations, artifacts and builders
Browse files Browse the repository at this point in the history
Implements most of guacsec#11.

Still working on the testing interface for this as I also want to be
able to write and read subgraphs from DB (guacsec#10/guacsec#12/guacsec#14).

Signed-off-by: Mihai Maruseac <mihaimaruseac@google.com>
  • Loading branch information
mihaimaruseac authored and cpendery committed Aug 31, 2022
1 parent 7a43d0b commit 05e7263
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 23 deletions.
61 changes: 42 additions & 19 deletions pkg/assembler/assembler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,66 @@ package assembler

type assembler struct{} //nolint: unused

// Identifiable implements the ability to retrieve a set of
// attributes such that a graph query is able to identify a
// GuacNode or GuacEdge uniquely (or as a GuacHyperNode).
type Identifiable interface {
// Identifiers returns a map of fields and values which
// can be used to identify an object in the graph.
Identifiers() map[string]interface{}
}

// GuacNode represents a node in the GUAC graph
type GuacNode interface {
Identifiable

// Type returns the type of node
Type() string

// Properties returns the list of properties of the node
Properties() map[string]interface{}

// Attributes returns the names of the properties of the node.
//
// If a string `s` is in the list returned by `Attributes` then it
// should also be a key in the map returned by `Properties`.
Attributes() []string

// IdentifiableAttributes returns a list of tuples of property names
// that can uniquely specify a GuacNode.
//
// Any string found in a tuple returned by `IdentifiableAttributes`
// must also be returned by `Attributes`.
IdentifiableAttributes() [][]string
}

// GuacEdge represents an edge in the GUAC graph
type GuacEdge interface {
Identifiable
// Type returns the type of edge
Type() string

// Nodes returns the (v,u) nodes of the edge
// where v--edge-->u for directional edges.
//
// For directional edges: v-[edge]->u.
// For non-directional edges there is no guaranteed order.
Nodes() (v, u GuacNode)

// Type returns the type of edge
Type() string

// Properties returns the list of properties of the node
// Properties returns the list of properties of the edge
Properties() map[string]interface{}

// Attributes returns the names of the properties of the edge.
//
// If a string `s` is in the list returned by `Attributes` then it
// should also be a key in the map returned by `Properties`.
Attributes() []string

// IdentifiableAttributes returns a list of tuples of property names
// that can uniquely specify a GuacEdge, as an alternative to the two
// node endpoints.
//
// Any string found in a tuple returned by `IdentifiableAttributes`
// must also be returned by `Attributes`.
//
// TODO(mihaimaruseac): We might not need this?
IdentifiableAttributes() [][]string
}

// AssemblerInput represents the inputs to add to the graph
type AssemblerInput struct {
// Subgraph represents a subgraph read from the database or written to it.
type Subgraph struct {
V []GuacNode
E []GuacEdge
}

// TODO(mihaimaruseac): Write queries to write/read subgraphs from DB?

// AssemblerInput represents the inputs to add to the graph
type AssemblerInput = Subgraph
79 changes: 75 additions & 4 deletions pkg/assembler/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,80 @@
package assembler

// ArtifactNode is a node that represents an artifact
// TODO: implement GuacNode
type ArtifactNode struct{}
type ArtifactNode struct{
Name string
Checksum string
}

func (an* ArtifactNode) Type() string {
return "Artifact"
}

func (an *ArtifactNode) Properties() map[string]interface{} {
properties := make(map[string]interface{})
properties["name"] = an.Name
properties["checksum"] = an.Checksum
return properties
}

func (an *ArtifactNode) Attributes() []string {
return []string{"name", "checksum"}
}

func (an *ArtifactNode) IdentifiableAttributes() [][]string {
// An artifact can be uniquely identified by checksum
return [][]string{{"checksum"}}
}

// AttestationNode is a node that represents an attestation
// TODO: implement GuacNode
type AttestationNode struct{}
type AttestationNode struct{
// TODO(mihaimaruseac): Unsure what fields to store here
File string
Checksum string
}

func (an* AttestationNode) Type() string {
return "Attestation"
}

func (an *AttestationNode) Properties() map[string]interface{} {
properties := make(map[string]interface{})
properties["file"] = an.File
properties["checksum"] = an.Checksum
return properties
}

func (an *AttestationNode) Attributes() []string {
return []string{"file", "checksum"}
}

func (an *AttestationNode) IdentifiableAttributes() [][]string {
// An attestation can be uniquely identified by filename?
return [][]string{{"file"}}
}

// BuilderNode is a node that represents an attestation
type BuilderNode struct{
BuilderType string
BuilderId string
}

func (bn* BuilderNode) Type() string {
return "Builder"
}

func (bn *BuilderNode) Properties() map[string]interface{} {
properties := make(map[string]interface{})
properties["type"] = bn.BuilderType
properties["id"] = bn.BuilderId
return properties
}

func (bn *BuilderNode) Attributes() []string {
return []string{"type", "id"}
}

func (bn *BuilderNode) IdentifiableAttributes() [][]string {
// A builder needs both type and id to be identified
return [][]string{{"type", "id"}}
}

0 comments on commit 05e7263

Please sign in to comment.