Skip to content

Commit

Permalink
transact empty result for no-data
Browse files Browse the repository at this point in the history
  • Loading branch information
chrispatrick authored and Paul Norton committed Jan 8, 2024
1 parent 3030721 commit a963f0f
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 20 deletions.
15 changes: 10 additions & 5 deletions policy/goals/differ.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import (
// It returns the storage id for the current query results.
func GoalResultsDiffer(log skill.Logger, queryResults []GoalEvaluationQueryResult, digest string, goal Goal, previousStorageId string) (bool, string, error) {
log.Infof("Generating storage id for goal %s, image %s", goal.Definition, digest)
hash, err := hashstructure.Hash(queryResults, hashstructure.FormatV2, nil)
if err != nil {
return false, "", fmt.Errorf("failed to generate storage id for goal %s, image %s: %s", goal.Definition, digest, err)
}

storageId := fmt.Sprint(hash)
storageId := "no-data"

if queryResults != nil {
hash, err := hashstructure.Hash(queryResults, hashstructure.FormatV2, nil)
if err != nil {
return false, "", fmt.Errorf("failed to generate storage id for goal %s, image %s: %s", goal.Definition, digest, err)
}

storageId = fmt.Sprint(hash)
}

differ := storageId != previousStorageId

Expand Down
23 changes: 15 additions & 8 deletions policy/goals/entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ package goals
import "time"

func CreateEntitiesFromResults(results []GoalEvaluationQueryResult, goalDefinition string, goalConfiguration string, image string, storageId string, configHash string, evaluationTs time.Time, tx int64) GoalEvaluationResultEntity {
return GoalEvaluationResultEntity{
Definition: goalDefinition,
Configuration: goalConfiguration,
Subject: DockerImageEntity{Digest: image},
DeviationCount: len(results),
StorageId: storageId,
ConfigHash: configHash,
CreatedAt: evaluationTs,
entity := GoalEvaluationResultEntity{
Definition: goalDefinition,
Configuration: goalConfiguration,
Subject: DockerImageEntity{Digest: image},
ConfigHash: configHash,
CreatedAt: evaluationTs,
TransactionCondition: TransactionConditionEntity{
Args: map[string]interface{}{"tx-arg": tx},
Where: []byte(`[[?entity :goal.result/created-at _ ?tx true]
[(< ?tx ?tx-arg)]]`),
},
}

if storageId != "no-data" {
deviationCount := len(results)

entity.DeviationCount = &deviationCount
entity.StorageId = &storageId
}

return entity
}
20 changes: 18 additions & 2 deletions policy/goals/entities_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,27 @@ func TestCreateEntitiesFromResult(t *testing.T) {

entity := CreateEntitiesFromResults(resultModel, "test-definition", "test-configuration", "test-image", "storage-id", "config-hash", evaluationTs, 123)

if entity.Definition != "test-definition" || entity.Configuration != "test-configuration" || entity.StorageId != "storage-id" || entity.CreatedAt.Format("2006-01-02T15:04:05.000Z") != "2023-07-10T20:01:41.000Z" {
if entity.Definition != "test-definition" || entity.Configuration != "test-configuration" || *entity.StorageId != "storage-id" || entity.CreatedAt.Format("2006-01-02T15:04:05.000Z") != "2023-07-10T20:01:41.000Z" {
t.Errorf("metadata not set correctly")
}

if entity.DeviationCount != 1 {
if *entity.DeviationCount != 1 {
t.Errorf("incorrect number of deviations, expected %d, got %d", 1, entity.DeviationCount)
}
}

func TestNoDataDoesntSetFields(t *testing.T) {
result := `[{:name "CVE-2023-2650", :details {:purl "pkg:alpine/[email protected]?os_name=alpine&os_version=3.18", :cve "CVE-2023-2650", :severity "HIGH", :fixed-by "3.1.1-r0"} }]`

resultModel := []GoalEvaluationQueryResult{}

edn.Unmarshal([]byte(result), &resultModel)

evaluationTs := time.Date(2023, 7, 10, 20, 1, 41, 0, time.UTC)

entity := CreateEntitiesFromResults(resultModel, "test-definition", "test-configuration", "test-image", "no-data", "config-hash", evaluationTs, 123)

if entity.StorageId != nil || entity.DeviationCount != nil {
t.Errorf("metadata not set correctly")
}
}
4 changes: 2 additions & 2 deletions policy/goals/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ type (
Definition string `edn:"goal.definition/name"`
Configuration string `edn:"goal.configuration/name"`
Subject DockerImageEntity `edn:"goal.result/subject"`
DeviationCount int `edn:"goal.result/deviation-count"`
StorageId string `edn:"goal.result/storage-id"`
DeviationCount *int `edn:"goal.result/deviation-count"`
StorageId *string `edn:"goal.result/storage-id"`
ConfigHash string `edn:"goal.result/config-hash"`
CreatedAt time.Time `edn:"goal.result/created-at"`
TransactionCondition TransactionConditionEntity `edn:"atomist/tx-iff"`
Expand Down
5 changes: 2 additions & 3 deletions policy/policy_handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ func transact(
configHash := storageTuple[1]

if goalResults == nil {
req.Log.Infof("goal %s returned no data for digest %s, skipping storing results", goal.Definition, digest)
return skill.NewCompletedStatus(fmt.Sprintf("Goal %s evaluated - no data found", goalName))
req.Log.Infof("goal %s returned no data for digest %s", goal.Definition, digest)
}

es, err := storage.NewEvaluationStorage(ctx)
Expand All @@ -217,7 +216,7 @@ func transact(
differ = true
}

if differ {
if differ && goalResults != nil {
if err := es.Store(ctx, goalResults, storageId, req.Event.Environment, req.Log); err != nil {
return skill.NewFailedStatus(fmt.Sprintf("Failed to store evaluation results for digest %s: %s", digest, err.Error()))
}
Expand Down

0 comments on commit a963f0f

Please sign in to comment.