Skip to content

Commit

Permalink
Added project id as mandatory filter.
Browse files Browse the repository at this point in the history
  • Loading branch information
blkt committed Jul 9, 2024
1 parent baf75c1 commit 4f9a857
Show file tree
Hide file tree
Showing 8 changed files with 479 additions and 26 deletions.
14 changes: 9 additions & 5 deletions database/query/eval_history.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,12 @@ SELECT s.id::uuid AS evaluation_id,
WHEN ere.pull_request_id IS NOT NULL THEN pr.id
WHEN ere.artifact_id IS NOT NULL THEN a.id
END AS entity_id,
-- entity name
CASE WHEN ere.repository_id IS NOT NULL THEN r.repo_name
WHEN ere.pull_request_id IS NOT NULL THEN pr.pr_number::text
WHEN ere.artifact_id IS NOT NULL THEN a.artifact_name
END AS entity_name,
-- raw fields for entity names
r.repo_owner,
r.repo_name,
pr.pr_number,
a.artifact_name,
j.id as project_id,
-- rule type, name, and profile
rt.name AS rule_type,
ri.name AS rule_name,
Expand All @@ -135,6 +136,7 @@ SELECT s.id::uuid AS evaluation_id,
LEFT JOIN artifacts a ON ere.artifact_id = a.id
LEFT JOIN remediation_events re ON re.evaluation_id = s.id
LEFT JOIN alert_events ae ON ae.evaluation_id = s.id
LEFT JOIN projects j ON r.project_id = j.id
WHERE (sqlc.narg(next)::timestamp without time zone IS NULL OR sqlc.narg(next) > s.most_recent_evaluation)
AND (sqlc.narg(prev)::timestamp without time zone IS NULL OR sqlc.narg(prev) < s.most_recent_evaluation)
-- inclusion filters
Expand All @@ -159,5 +161,7 @@ SELECT s.id::uuid AS evaluation_id,
AND (sqlc.narg(fromts)::timestamp without time zone IS NULL
OR sqlc.narg(tots)::timestamp without time zone IS NULL
OR s.most_recent_evaluation BETWEEN sqlc.narg(fromts) AND sqlc.narg(tots))
-- implicit filter by project id
AND j.id = sqlc.arg(projectId)
ORDER BY s.most_recent_evaluation DESC
LIMIT sqlc.arg(size)::integer;
53 changes: 49 additions & 4 deletions internal/controlplane/handlers_evalstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ func (s *Server) ListEvaluationHistory(
opts = append(opts, history.WithTo(in.GetTo().AsTime()))
}

// we always filter by project id
opts = append(opts, history.WithProjectIDStr(in.GetContext().GetProject()))

filter, err := history.NewListEvaluationFilter(opts...)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid filter")
Expand Down Expand Up @@ -138,10 +141,9 @@ func fromEvaluationHistoryRow(
return nil, errors.New("internal error")
}
entityType := dbEntityToEntity(dbEntityType)

entityName, ok := row.EntityName.(string)
if !ok {
return nil, errors.New("internal error")
entityName, err := getEntityName(dbEntityType, row)
if err != nil {
return nil, err
}

var alert *minderv1.EvaluationHistoryAlert
Expand Down Expand Up @@ -589,3 +591,46 @@ func dbEntityToEntity(dbEnt db.Entities) minderv1.Entity {
return minderv1.Entity_ENTITY_UNSPECIFIED
}
}

func getEntityName(
dbEnt db.Entities,
row db.ListEvaluationHistoryRow,
) (string, error) {
switch dbEnt {
case db.EntitiesPullRequest:
if !row.RepoOwner.Valid {
return "", errors.New("repo_owner is missing")
}
if !row.RepoName.Valid {
return "", errors.New("repo_name is missing")
}
if !row.PrNumber.Valid {
return "", errors.New("pr_number is missing")
}
return fmt.Sprintf("%s/%s#%d",
row.RepoOwner.String,
row.RepoName.String,
row.PrNumber.Int64,
), nil
case db.EntitiesArtifact:
if !row.ArtifactName.Valid {
return "", errors.New("artifact_name is missing")
}
return row.ArtifactName.String, nil
case db.EntitiesRepository:
if !row.RepoOwner.Valid {
return "", errors.New("repo_owner is missing")
}
if !row.RepoName.Valid {
return "", errors.New("repo_name is missing")
}
return fmt.Sprintf("%s/%s",
row.RepoOwner.String,
row.RepoName.String,
), nil
case db.EntitiesBuildEnvironment:
return "", errors.New("invalid entity type")
default:
return "", errors.New("invalid entity type")
}
}
197 changes: 197 additions & 0 deletions internal/controlplane/handlers_evalstatus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,200 @@ func TestBuildEvalResultAlertFromLRERow(t *testing.T) {
})
}
}

func TestDBEntityToEntity(t *testing.T) {
t.Parallel()

tests := []struct {
name string
input db.Entities
output minderv1.Entity
}{
{
name: "pull request",
input: db.EntitiesPullRequest,
output: minderv1.Entity_ENTITY_PULL_REQUESTS,
},
{
name: "artifact",
input: db.EntitiesArtifact,
output: minderv1.Entity_ENTITY_ARTIFACTS,
},
{
name: "repository",
input: db.EntitiesRepository,
output: minderv1.Entity_ENTITY_REPOSITORIES,
},
{
name: "build environments",
input: db.EntitiesBuildEnvironment,
output: minderv1.Entity_ENTITY_BUILD_ENVIRONMENTS,
},
{
name: "default",
input: db.Entities("whatever"),
output: minderv1.Entity_ENTITY_UNSPECIFIED,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
res := dbEntityToEntity(tt.input)
require.Equal(t, tt.output, res)
})
}
}

func TestGetEntityName(t *testing.T) {
t.Parallel()

tests := []struct {
name string
dbEnt db.Entities
row db.ListEvaluationHistoryRow
output string
err bool
}{
{
name: "pull request",
dbEnt: db.EntitiesPullRequest,
row: db.ListEvaluationHistoryRow{
RepoOwner: sql.NullString{
Valid: true,
String: "stacklok",
},
RepoName: sql.NullString{
Valid: true,
String: "minder",
},
PrNumber: sql.NullInt64{
Valid: true,
Int64: 12345,
},
},
output: "stacklok/minder#12345",
},
{
name: "pull request no repo owner",
dbEnt: db.EntitiesPullRequest,
row: db.ListEvaluationHistoryRow{
RepoName: sql.NullString{
Valid: true,
String: "minder",
},
PrNumber: sql.NullInt64{
Valid: true,
Int64: 12345,
},
},
err: true,
},
{
name: "pull request no repo name",
dbEnt: db.EntitiesPullRequest,
row: db.ListEvaluationHistoryRow{
RepoOwner: sql.NullString{
Valid: true,
String: "stacklok",
},
PrNumber: sql.NullInt64{
Valid: true,
Int64: 12345,
},
},
err: true,
},
{
name: "pull request no pr number",
dbEnt: db.EntitiesPullRequest,
row: db.ListEvaluationHistoryRow{
RepoOwner: sql.NullString{
Valid: true,
String: "stacklok",
},
RepoName: sql.NullString{
Valid: true,
String: "minder",
},
},
err: true,
},
{
name: "artifact",
dbEnt: db.EntitiesArtifact,
row: db.ListEvaluationHistoryRow{
ArtifactName: sql.NullString{
Valid: true,
String: "artifact name",
},
},
output: "artifact name",
},
{
name: "repository",
dbEnt: db.EntitiesRepository,
row: db.ListEvaluationHistoryRow{
RepoOwner: sql.NullString{
Valid: true,
String: "stacklok",
},
RepoName: sql.NullString{
Valid: true,
String: "minder",
},
},
output: "stacklok/minder",
},
{
name: "repository no repo owner",
dbEnt: db.EntitiesRepository,
row: db.ListEvaluationHistoryRow{
RepoName: sql.NullString{
Valid: true,
String: "minder",
},
},
err: true,
},
{
name: "repository no repo name",
dbEnt: db.EntitiesRepository,
row: db.ListEvaluationHistoryRow{
RepoOwner: sql.NullString{
Valid: true,
String: "stacklok",
},
},
err: true,
},
{
name: "build environments",
dbEnt: db.EntitiesBuildEnvironment,
row: db.ListEvaluationHistoryRow{},
err: true,
},
{
name: "default",
dbEnt: db.Entities("whatever"),
row: db.ListEvaluationHistoryRow{},
err: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
res, err := getEntityName(tt.dbEnt, tt.row)

if tt.err {
require.Error(t, err)
require.Equal(t, "", res)
return
}

require.NoError(t, err)
require.Equal(t, tt.output, res)
})
}
}
30 changes: 22 additions & 8 deletions internal/db/eval_history.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4f9a857

Please sign in to comment.