diff --git a/internal/handler/FactDataTransformer_test.go b/internal/handler/FactDataTransformer_test.go index ddb1036..48dbe3d 100644 --- a/internal/handler/FactDataTransformer_test.go +++ b/internal/handler/FactDataTransformer_test.go @@ -17,6 +17,7 @@ func TestFactProcessor_TestMultipleFilters(t *testing.T) { KeyFact: false, Type: "", Category: "", + Service: "", } fp1 := FactProcessor{ @@ -69,6 +70,7 @@ func TestFactProcessor_ProcessLagoonFactAgainstRegisteredFilters(t *testing.T) { KeyFact: false, Type: "", Category: "", + Service: "", } poppedFactFilters := KeyFactFilters @@ -181,6 +183,7 @@ func TestFactProcessor_TestSetFriendlyName(t *testing.T) { KeyFact: false, Type: "", Category: "", + Service: "", }, InsightsData: EnvironmentVariable{ Key: "testkey", @@ -213,6 +216,7 @@ func TestFactProcessor_TestExactMatchLookup(t *testing.T) { KeyFact: false, Type: "", Category: "", + Service: "", }, InsightsData: EnvironmentVariable{ Key: "testkey", diff --git a/internal/handler/imageInspectParserFilter.go b/internal/handler/imageInspectParserFilter.go index 3b24a92..c65e1c7 100644 --- a/internal/handler/imageInspectParserFilter.go +++ b/internal/handler/imageInspectParserFilter.go @@ -25,6 +25,7 @@ type ImageData struct { func processImageInspectInsightsData(h *Messaging, insights InsightsData, v string, apiClient graphql.Client, resource ResourceDestination) ([]LagoonFact, string, error) { source := fmt.Sprintf("insights:image:%s", resource.Service) + service := resource.Service logger := slog.With("ProjectName", resource.Project, "EnvironmentName", resource.Environment, "Source", source) if insights.InsightsType == Image { @@ -34,12 +35,12 @@ func processImageInspectInsightsData(h *Messaging, insights InsightsData, v stri } environmentId := environment.Id - return ProcessImageInspectData(v, logger, environmentId, source) + return ProcessImageInspectData(v, logger, environmentId, source, service) } return []LagoonFact{}, "", nil } -func ProcessImageInspectData(v string, logger *slog.Logger, environmentId int, source string) ([]LagoonFact, string, error) { +func ProcessImageInspectData(v string, logger *slog.Logger, environmentId int, source string, service string) ([]LagoonFact, string, error) { decoded, err := decodeGzipString(v) if err != nil { return nil, "", err @@ -53,7 +54,7 @@ func ProcessImageInspectData(v string, logger *slog.Logger, environmentId int, s return nil, "", err } - facts, err := processFactsFromImageInspect(logger, imageInspect, environmentId, source) + facts, err := processFactsFromImageInspect(logger, imageInspect, environmentId, source, service) if err != nil { return nil, "", err } @@ -66,7 +67,7 @@ func ProcessImageInspectData(v string, logger *slog.Logger, environmentId int, s return facts, source, nil } -func processFactsFromImageInspect(logger *slog.Logger, imageInspectData ImageData, id int, source string) ([]LagoonFact, error) { +func processFactsFromImageInspect(logger *slog.Logger, imageInspectData ImageData, id int, source string, service string) ([]LagoonFact, error) { var factsInput []LagoonFact @@ -101,6 +102,7 @@ func processFactsFromImageInspect(logger *slog.Logger, imageInspectData ImageDat Description: "Environment Variable", KeyFact: false, Type: FactTypeText, + Service: service, } logger.Debug("Processing environment fact", "name", f.Key, "value", f.Value) diff --git a/internal/handler/imageInspectParserFilter_test.go b/internal/handler/imageInspectParserFilter_test.go index 52e6747..50c49ca 100644 --- a/internal/handler/imageInspectParserFilter_test.go +++ b/internal/handler/imageInspectParserFilter_test.go @@ -14,6 +14,7 @@ func Test_processFactsFromImageInspect(t *testing.T) { imageInspectDataSource string id int source string + service string } tests := []struct { name string @@ -54,7 +55,7 @@ func Test_processFactsFromImageInspect(t *testing.T) { panic(1) } - got, err := processFactsFromImageInspect(tt.args.logger, imageInspectData, tt.args.id, tt.args.source) + got, err := processFactsFromImageInspect(tt.args.logger, imageInspectData, tt.args.id, tt.args.source, tt.args.service) if (err != nil) != tt.wantErr { t.Errorf("processFactsFromImageInspect() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/internal/handler/insightsParserFilter.go b/internal/handler/insightsParserFilter.go index 27b9878..bd5943b 100644 --- a/internal/handler/insightsParserFilter.go +++ b/internal/handler/insightsParserFilter.go @@ -11,7 +11,7 @@ func processSbomInsightsData(h *Messaging, insights InsightsData, v string, apiC source := fmt.Sprintf("insights:sbom:%s", resource.Service) logger := slog.With("ProjectName", resource.Project, "EnvironmentName", resource.Environment, "Source", source) - + service := resource.Service if insights.InsightsType != Sbom { return []LagoonFact{}, "", nil } @@ -45,7 +45,7 @@ func processSbomInsightsData(h *Messaging, insights InsightsData, v string, apiC } // Process SBOM into facts - facts := processFactsFromSBOM(logger, bom.Components, environment.Id, source) + facts := processFactsFromSBOM(logger, bom.Components, environment.Id, source, service) facts, err = KeyFactsFilter(facts) if err != nil { @@ -66,7 +66,7 @@ func processSbomInsightsData(h *Messaging, insights InsightsData, v string, apiC return facts, source, nil } -func processFactsFromSBOM(logger *slog.Logger, facts *[]cdx.Component, environmentId int, source string) []LagoonFact { +func processFactsFromSBOM(logger *slog.Logger, facts *[]cdx.Component, environmentId int, source string, service string) []LagoonFact { var factsInput []LagoonFact if facts == nil || len(*facts) == 0 { return factsInput @@ -92,6 +92,7 @@ func processFactsFromSBOM(logger *slog.Logger, facts *[]cdx.Component, environme Description: f.PackageURL, KeyFact: false, Type: FactTypeText, + Service: service, } //if EnableDebug { // log.Println("[DEBUG] processing fact name " + f.Name) diff --git a/internal/handler/main.go b/internal/handler/main.go index 1bf13a4..db5bd7b 100644 --- a/internal/handler/main.go +++ b/internal/handler/main.go @@ -67,6 +67,9 @@ type InsightsMessage struct { Annotations map[string]string `json:"annotations"` Labels map[string]string `json:"labels"` Type string `json:"type,omitempty"` + Environment string `json:"environment"` + Project string `json:"project"` + Service string `json:"service"` } type PayloadInput struct { @@ -135,6 +138,7 @@ type LagoonFact struct { KeyFact bool `json:"keyFact"` Type string `json:"type"` Category string `json:"category"` + Service string `json:"service"` } const ( @@ -573,6 +577,7 @@ func (h *Messaging) pushFactsToLagoonApi(facts []LagoonFact, resource ResourceDe KeyFact: fact.KeyFact, Type: lagoonclient.FactType(fact.Type), Category: fact.Category, + Service: fact.Service, } } diff --git a/internal/handler/main_test.go b/internal/handler/main_test.go index 2fa92f4..71b6516 100644 --- a/internal/handler/main_test.go +++ b/internal/handler/main_test.go @@ -140,6 +140,7 @@ func Test_processFactsFromSBOM(t *testing.T) { bom *[]cdx.Component environmentId int source string + service string } testResponse, err := ioutil.ReadFile("./testassets/testSbomPayload.json") @@ -201,7 +202,7 @@ func Test_processFactsFromSBOM(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := processFactsFromSBOM(slog.Default(), tt.args.bom, tt.args.environmentId, tt.args.source) + got := processFactsFromSBOM(slog.Default(), tt.args.bom, tt.args.environmentId, tt.args.source, tt.args.service) if len(got) != len(tt.want) { t.Errorf("processFactsFromSBOM() returned %d results, want %d", len(got), len(tt.want)) } @@ -224,6 +225,7 @@ func Test_processFactsFromSBOMWithNoComponents(t *testing.T) { bom *[]cdx.Component environmentId int source string + service string } testResponse, err := ioutil.ReadFile("./testassets/testSbomPayloadNoComponents.json") @@ -266,7 +268,7 @@ func Test_processFactsFromSBOMWithNoComponents(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := processFactsFromSBOM(slog.Default(), tt.args.bom, tt.args.environmentId, tt.args.source) + got := processFactsFromSBOM(slog.Default(), tt.args.bom, tt.args.environmentId, tt.args.source, tt.args.service) if len(got) != len(tt.want) { t.Errorf("processFactsFromSBOM() returned %d results, want %d", len(got), len(tt.want)) } diff --git a/internal/handler/messaging.go b/internal/handler/messaging.go index 836877a..7009d72 100644 --- a/internal/handler/messaging.go +++ b/internal/handler/messaging.go @@ -171,6 +171,34 @@ func preprocessIncomingMessageData(incoming *InsightsMessage) (ResourceDestinati OutputFileMIMEType: "application/json", } + // Prioritize the insights data over labels + if incoming.Project != "" { + resource.Project = incoming.Project + } else if label, ok := incoming.Labels["lagoon.sh/project"]; ok { + resource.Project = label + } + + if incoming.Environment != "" { + resource.Environment = incoming.Environment + } else if label, ok := incoming.Labels["lagoon.sh/environment"]; ok { + resource.Environment = label + } + + if incoming.Service != "" { + resource.Service = incoming.Service + } else if label, ok := incoming.Labels["lagoon.sh/service"]; ok { + resource.Service = label + } + + if incoming.Type != "" { + insights.InputType = incoming.Type + } else if label, ok := incoming.Labels["lagoon.sh/insightsType"]; ok { + insights.InputType = label + if label == "image-gz" { + insights.LagoonType = ImageFacts + } + } + // Check labels for insights data from message if incoming.Labels != nil { labelKeys := make([]string, 0, len(incoming.Labels)) @@ -181,17 +209,6 @@ func preprocessIncomingMessageData(incoming *InsightsMessage) (ResourceDestinati for _, label := range labelKeys { switch label { - case "lagoon.sh/project": - resource.Project = incoming.Labels["lagoon.sh/project"] - case "lagoon.sh/environment": - resource.Environment = incoming.Labels["lagoon.sh/environment"] - case "lagoon.sh/service": - resource.Service = incoming.Labels["lagoon.sh/service"] - case "lagoon.sh/insightsType": - insights.InputType = incoming.Labels["lagoon.sh/insightsType"] - if incoming.Labels["lagoon.sh/insightsType"] == "image-gz" { - insights.LagoonType = ImageFacts - } case "lagoon.sh/insightsOutputCompressed": compressed, _ := strconv.ParseBool(incoming.Labels["lagoon.sh/insightsOutputCompressed"]) insights.OutputCompressed = compressed diff --git a/internal/handler/processing.go b/internal/handler/processing.go index deb8413..7d20b7a 100644 --- a/internal/handler/processing.go +++ b/internal/handler/processing.go @@ -57,6 +57,7 @@ func processFactsDirectly(message mq.Message, h *Messaging) string { KeyFact: false, Type: lagoonclient.FactType(vartypeString), Category: fact.Category, + Service: fact.Service, } factSources[fact.Source] = fact.Source } diff --git a/internal/lagoonclient/generated.go b/internal/lagoonclient/generated.go index 3069239..07fec9d 100644 --- a/internal/lagoonclient/generated.go +++ b/internal/lagoonclient/generated.go @@ -18,6 +18,7 @@ type AddFactInput struct { KeyFact bool `json:"keyFact"` Type FactType `json:"type"` Category string `json:"category"` + Service string `json:"service"` } // GetId returns AddFactInput.Id, and is useful for accessing the field via an interface. @@ -47,6 +48,9 @@ func (v *AddFactInput) GetType() FactType { return v.Type } // GetCategory returns AddFactInput.Category, and is useful for accessing the field via an interface. func (v *AddFactInput) GetCategory() string { return v.Category } +// GetService returns AddFactInput.Service, and is useful for accessing the field via an interface. +func (v *AddFactInput) GetService() string { return v.Service } + type FactType string const ( @@ -55,6 +59,12 @@ const ( FactTypeSemver FactType = "SEMVER" ) +var AllFactType = []FactType{ + FactTypeText, + FactTypeUrl, + FactTypeSemver, +} + type ProblemSeverityRating string const ( @@ -67,6 +77,16 @@ const ( ProblemSeverityRatingCritical ProblemSeverityRating = "CRITICAL" ) +var AllProblemSeverityRating = []ProblemSeverityRating{ + ProblemSeverityRatingNone, + ProblemSeverityRatingUnknown, + ProblemSeverityRatingNegligible, + ProblemSeverityRatingLow, + ProblemSeverityRatingMedium, + ProblemSeverityRatingHigh, + ProblemSeverityRatingCritical, +} + // __addFactsInput is used internally by genqlient type __addFactsInput struct { Facts []AddFactInput `json:"facts"` @@ -317,7 +337,7 @@ func (v *getProjectByNameResponse) GetProjectByName() getProjectByNameProjectByN return v.ProjectByName } -// The query or mutation executed by addFacts. +// The mutation executed by addFacts. const addFacts_Operation = ` mutation addFacts ($facts: [AddFactInput]!) { addFacts(input: {facts:$facts}) { @@ -327,32 +347,31 @@ mutation addFacts ($facts: [AddFactInput]!) { ` func addFacts( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, facts []AddFactInput, -) (*addFactsResponse, error) { - req := &graphql.Request{ +) (data_ *addFactsResponse, err_ error) { + req_ := &graphql.Request{ OpName: "addFacts", Query: addFacts_Operation, Variables: &__addFactsInput{ Facts: facts, }, } - var err error - var data addFactsResponse - resp := &graphql.Response{Data: &data} + data_ = &addFactsResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by addProblem. +// The mutation executed by addProblem. const addProblem_Operation = ` mutation addProblem ($environment: Int!, $severity: ProblemSeverityRating, $severityScore: SeverityScore, $identifier: String!, $service: String!, $source: String!, $associatedPackage: String, $description: String, $links: String, $verstion: String, $fixedVersion: String, $dataString: String!) { addProblem(input: {environment:$environment,severity:$severity,severityScore:$severityScore,identifier:$identifier,service:$service,source:$source,associatedPackage:$associatedPackage,description:$description,links:$links,version:$verstion,fixedVersion:$fixedVersion,data:$dataString}) { @@ -362,8 +381,8 @@ mutation addProblem ($environment: Int!, $severity: ProblemSeverityRating, $seve ` func addProblem( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, environment int, severity ProblemSeverityRating, severityScore float64, @@ -376,8 +395,8 @@ func addProblem( verstion string, fixedVersion string, dataString string, -) (*addProblemResponse, error) { - req := &graphql.Request{ +) (data_ *addProblemResponse, err_ error) { + req_ := &graphql.Request{ OpName: "addProblem", Query: addProblem_Operation, Variables: &__addProblemInput{ @@ -395,21 +414,20 @@ func addProblem( DataString: dataString, }, } - var err error - var data addProblemResponse - resp := &graphql.Response{Data: &data} + data_ = &addProblemResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by deleteFactsFromSource. +// The mutation executed by deleteFactsFromSource. const deleteFactsFromSource_Operation = ` mutation deleteFactsFromSource ($environment: Int!, $source: String!) { deleteFactsFromSource(input: {environment:$environment,source:$source}) @@ -417,12 +435,12 @@ mutation deleteFactsFromSource ($environment: Int!, $source: String!) { ` func deleteFactsFromSource( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, environment int, source string, -) (*deleteFactsFromSourceResponse, error) { - req := &graphql.Request{ +) (data_ *deleteFactsFromSourceResponse, err_ error) { + req_ := &graphql.Request{ OpName: "deleteFactsFromSource", Query: deleteFactsFromSource_Operation, Variables: &__deleteFactsFromSourceInput{ @@ -430,21 +448,20 @@ func deleteFactsFromSource( Source: source, }, } - var err error - var data deleteFactsFromSourceResponse - resp := &graphql.Response{Data: &data} + data_ = &deleteFactsFromSourceResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by deleteProblemsFromSource. +// The mutation executed by deleteProblemsFromSource. const deleteProblemsFromSource_Operation = ` mutation deleteProblemsFromSource ($environment: Int!, $source: String!, $service: String!) { deleteProblemsFromSource(input: {environment:$environment,source:$source,service:$service}) @@ -452,13 +469,13 @@ mutation deleteProblemsFromSource ($environment: Int!, $source: String!, $servic ` func deleteProblemsFromSource( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, environment int, source string, service string, -) (*deleteProblemsFromSourceResponse, error) { - req := &graphql.Request{ +) (data_ *deleteProblemsFromSourceResponse, err_ error) { + req_ := &graphql.Request{ OpName: "deleteProblemsFromSource", Query: deleteProblemsFromSource_Operation, Variables: &__deleteProblemsFromSourceInput{ @@ -467,21 +484,20 @@ func deleteProblemsFromSource( Service: service, }, } - var err error - var data deleteProblemsFromSourceResponse - resp := &graphql.Response{Data: &data} + data_ = &deleteProblemsFromSourceResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by getEnvironmentByName. +// The query executed by getEnvironmentByName. const getEnvironmentByName_Operation = ` query getEnvironmentByName ($name: String!, $project: Int!) { environmentByName(name: $name, project: $project) { @@ -492,12 +508,12 @@ query getEnvironmentByName ($name: String!, $project: Int!) { ` func getEnvironmentByName( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, name string, project int, -) (*getEnvironmentByNameResponse, error) { - req := &graphql.Request{ +) (data_ *getEnvironmentByNameResponse, err_ error) { + req_ := &graphql.Request{ OpName: "getEnvironmentByName", Query: getEnvironmentByName_Operation, Variables: &__getEnvironmentByNameInput{ @@ -505,21 +521,20 @@ func getEnvironmentByName( Project: project, }, } - var err error - var data getEnvironmentByNameResponse - resp := &graphql.Response{Data: &data} + data_ = &getEnvironmentByNameResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by getEnvironmentFromId. +// The query executed by getEnvironmentFromId. const getEnvironmentFromId_Operation = ` query getEnvironmentFromId ($environment: Int!) { environmentById(id: $environment) { @@ -530,32 +545,31 @@ query getEnvironmentFromId ($environment: Int!) { ` func getEnvironmentFromId( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, environment int, -) (*getEnvironmentFromIdResponse, error) { - req := &graphql.Request{ +) (data_ *getEnvironmentFromIdResponse, err_ error) { + req_ := &graphql.Request{ OpName: "getEnvironmentFromId", Query: getEnvironmentFromId_Operation, Variables: &__getEnvironmentFromIdInput{ Environment: environment, }, } - var err error - var data getEnvironmentFromIdResponse - resp := &graphql.Response{Data: &data} + data_ = &getEnvironmentFromIdResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } -// The query or mutation executed by getProjectByName. +// The query executed by getProjectByName. const getProjectByName_Operation = ` query getProjectByName ($project: String!) { projectByName(name: $project) { @@ -566,27 +580,26 @@ query getProjectByName ($project: String!) { ` func getProjectByName( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, project string, -) (*getProjectByNameResponse, error) { - req := &graphql.Request{ +) (data_ *getProjectByNameResponse, err_ error) { + req_ := &graphql.Request{ OpName: "getProjectByName", Query: getProjectByName_Operation, Variables: &__getProjectByNameInput{ Project: project, }, } - var err error - var data getProjectByNameResponse - resp := &graphql.Response{Data: &data} + data_ = &getProjectByNameResponse{} + resp_ := &graphql.Response{Data: data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return data_, err_ } diff --git a/internal/lagoonclient/schema.graphql b/internal/lagoonclient/schema.graphql index 23d5b1f..fdd3845 100644 --- a/internal/lagoonclient/schema.graphql +++ b/internal/lagoonclient/schema.graphql @@ -116,6 +116,7 @@ input AddFactInput { keyFact: Boolean type: FactType category: String + service: String } input AddFactReferenceInput {