diff --git a/k8s/harbor-adapter-anchore-skaffold.yaml b/k8s/harbor-adapter-anchore-skaffold.yaml index 80aeed2..202768e 100644 --- a/k8s/harbor-adapter-anchore-skaffold.yaml +++ b/k8s/harbor-adapter-anchore-skaffold.yaml @@ -42,6 +42,8 @@ spec: value: "debug" - name: SCANNER_ADAPTER_REGISTRY_TLS_VERIFY value: "false" + - name: SCANNER_ADAPTER_IGNORE_HARBOR_CREDS + value: "false" # To enable api authentication, uncomment this and set it to a good randomized value. Use that same value in the scanner config in Harbor UI with "Bearer" type # - name: "SCANNER_ADAPTER_APIKEY" # value: "apikey123" diff --git a/pkg/adapter/anchore/adapter.go b/pkg/adapter/anchore/adapter.go index b8b0290..0b8addd 100644 --- a/pkg/adapter/anchore/adapter.go +++ b/pkg/adapter/anchore/adapter.go @@ -513,7 +513,15 @@ func (s *HarborScannerAdapter) GetRawVulnerabilityReport(scanID string) (harbor. rawScanID := fmt.Sprintf("%s-raw", scanID) // Used to store just the raw report results in the rawResult store rawResult, _ := resultStore.PopResult(rawScanID) - result := resultStore.GetResult(scanID) + result, resultFound := resultStore.GetResult(scanID) + + // If there is no entry in the cache for the base scanID (harbor formatted report) and the raw ScanCreated is false + // then the original create scan request was unsuccessful, likely due to the image being unable to be added to Anchore + // so we need to fail fast. + if !resultFound && !rawResult.ScanCreated { + log.WithFields(log.Fields{"scanId": scanID}).Debug("scan creation failed, no result found in store for scanId") + return nil, fmt.Errorf("create scan unsuccessful") + } // Check Scan has been created for the non-report report. This ensures the image is in Anchore Enterprise and submitted for analysis. if !rawResult.ScanCreated && !result.ScanCreated { diff --git a/pkg/adapter/anchore/result_store.go b/pkg/adapter/anchore/result_store.go index 075766b..1a2bf84 100644 --- a/pkg/adapter/anchore/result_store.go +++ b/pkg/adapter/anchore/result_store.go @@ -39,7 +39,7 @@ type ResultStore interface { ) // Update a result in the store GetResult( scanID string, - ) VulnerabilityResult // Get a result if it exists + ) (VulnerabilityResult, bool) // Get a result if it exists PopResult( scanID string, ) (VulnerabilityResult, bool) // Returns a result and true if found, false if not (e.g. like hash map interface) @@ -80,16 +80,22 @@ func (m *MemoryResultStore) HasResult(scanID string) bool { return ok && found.IsComplete } -func (m *MemoryResultStore) GetResult(scanID string) VulnerabilityResult { +func (m *MemoryResultStore) GetResult(scanID string) (VulnerabilityResult, bool) { m.mu.Lock() defer m.mu.Unlock() - found := m.Results[scanID] - return found + found, ok := m.Results[scanID] + return found, ok } func (m *MemoryResultStore) PopResult(scanID string) (VulnerabilityResult, bool) { m.mu.Lock() - defer m.mu.Unlock() + defer func() { + m.mu.Unlock() + log.WithField("CacheSize", len(m.Results)).Debug("Cache size - after pop") + }() + + log.WithField("CacheSize", len(m.Results)).Debug("Cache size - before pop") + found, ok := m.Results[scanID] if found.IsComplete { log.WithField("scanId", scanID).Debug("found completed result and removing from store to return to caller") diff --git a/pkg/adapter/anchore/result_store_test.go b/pkg/adapter/anchore/result_store_test.go index cbd4099..7073d43 100644 --- a/pkg/adapter/anchore/result_store_test.go +++ b/pkg/adapter/anchore/result_store_test.go @@ -372,3 +372,44 @@ func TestMemoryResultStore_RequestResult(t *testing.T) { }) } } + +func TestMemoryResultStore_GetResult(t *testing.T) { + type fields struct { + Results map[string]VulnerabilityResult + } + type args struct { + scanID string + } + tests := []struct { + name string + fields fields + args args + want VulnerabilityResult + expectedResult bool + }{ + { + name: "result found", + fields: fields{Results: map[string]VulnerabilityResult{"test1": {ScanID: "test1"}}}, + args: args{"test1"}, + want: VulnerabilityResult{ScanID: "test1"}, + expectedResult: true, + }, + { + name: "no result found", + fields: fields{Results: map[string]VulnerabilityResult{}}, + args: args{"test1"}, + want: VulnerabilityResult{}, + expectedResult: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &MemoryResultStore{ + Results: tt.fields.Results, + } + got, ok := m.GetResult(tt.args.scanID) + assert.Equal(t, tt.want, got) + assert.Equal(t, tt.expectedResult, ok) + }) + } +}