Skip to content

Commit

Permalink
fix: ensure correct handling for missing anchore account
Browse files Browse the repository at this point in the history
Signed-off-by: Bradley Jones <[email protected]>
bradleyjones committed May 16, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 5627a3e commit 02ebaf5
Showing 3 changed files with 61 additions and 5 deletions.
17 changes: 16 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package cmd

import (
"errors"
"fmt"
"os"
"runtime/pprof"

"github.com/anchore/k8s-inventory/pkg/mode"
"github.com/anchore/k8s-inventory/pkg/reporter"

"github.com/spf13/cobra"
"github.com/spf13/viper"
@@ -55,13 +57,26 @@ var rootCmd = &cobra.Command{
log.Errorf("Failed to get Image Results: %+v", err)
os.Exit(1)
}
anErrorOccurred := false
for account, report := range reports {
err = pkg.HandleReport(report, appConfig, account)
if errors.Is(err, reporter.ErrAnchoreAccountDoesNotExist) {
// Retry with default account
retryAccount := appConfig.AnchoreDetails.Account
if appConfig.AccountRouteByNamespaceLabel.DefaultAccount != "" {
retryAccount = appConfig.AccountRouteByNamespaceLabel.DefaultAccount
}
log.Warnf("Anchore Account %s does not exist, sending to default account", account)
err = pkg.HandleReport(report, appConfig, retryAccount)
}
if err != nil {
log.Errorf("Failed to handle Image Results: %+v", err)
os.Exit(1)
anErrorOccurred = true
}
}
if anErrorOccurred {
os.Exit(1)
}
}
},
}
13 changes: 13 additions & 0 deletions pkg/lib.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ k8s go SDK

import (
"encoding/json"
"errors"
"fmt"
"os"
"regexp"
@@ -75,6 +76,9 @@ func HandleReport(report inventory.Report, cfg *config.Application, account stri

if anchoreDetails.IsValid() {
if err := reporter.Post(report, anchoreDetails); err != nil {
if errors.Is(err, reporter.ErrAnchoreAccountDoesNotExist) {
return err
}
return fmt.Errorf("unable to report Inventory to Anchore account %s: %w", account, err)
}
log.Infof("Inventory report sent to Anchore account %s", account)
@@ -97,6 +101,15 @@ func PeriodicallyGetInventoryReport(cfg *config.Application) {
} else {
for account, report := range reports {
err := HandleReport(report, cfg, account)
if errors.Is(err, reporter.ErrAnchoreAccountDoesNotExist) {
// Retry with default account
retryAccount := cfg.AnchoreDetails.Account
if cfg.AccountRouteByNamespaceLabel.DefaultAccount != "" {
retryAccount = cfg.AccountRouteByNamespaceLabel.DefaultAccount
}
log.Warnf("Anchore Account %s does not exist, sending to default account", account)
err = HandleReport(report, cfg, retryAccount)
}
if err != nil {
log.Errorf("Failed to handle Inventory Report: %w", err)
}
36 changes: 32 additions & 4 deletions pkg/reporter/reporter.go
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import (
"io"
"net/http"
"net/url"
"strings"
"time"

"github.com/anchore/k8s-inventory/internal/config"
@@ -19,13 +20,26 @@ import (
)

const (
reportAPIPathV1 = "v1/enterprise/kubernetes-inventory"
reportAPIPathV2 = "v2/kubernetes-inventory"
reportAPIPathV1 = "v1/enterprise/kubernetes-inventory"
reportAPIPathV2 = "v2/kubernetes-inventory"
AnchoreAccountMissingError = "User account not found"
)

var enterpriseEndpoint = reportAPIPathV2
var (
ErrAnchoreAccountDoesNotExist = fmt.Errorf("user account not found")
enterpriseEndpoint = reportAPIPathV2
)

type AnchoreResponse struct {
Message string `json:"message"`
Httpcode int `json:"httpcode"`
Detail interface{} `json:"detail"`
AnchoreRequestID string `json:"anchore_request_id"`
}

// This method does the actual Reporting (via HTTP) to Anchore
//
//nolint:funlen
func Post(report inventory.Report, anchoreDetails config.AnchoreInfo) error {
defer tracker.TrackFunctionTime(time.Now(), "Reporting results to Anchore for cluster: "+report.ClusterName+"")
log.Debug("Validating and normalizing report before sending to Anchore")
@@ -78,7 +92,21 @@ func Post(report inventory.Report, anchoreDetails config.AnchoreInfo) error {
log.Info("Retrying inventory report with new endpoint: ", enterpriseEndpoint)
return Post(report, anchoreDetails)
}
return fmt.Errorf("failed to report data to Anchore: %+v", resp)

// Check if account is correct
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response from Anchore: %w", err)
}
anchoreResponse := &AnchoreResponse{}
err = json.Unmarshal(respBody, anchoreResponse)
if err != nil {
return fmt.Errorf("failed to parse response from Anchore: %w", err)
}
if strings.Contains(anchoreResponse.Message, AnchoreAccountMissingError) {
return ErrAnchoreAccountDoesNotExist
}
return fmt.Errorf("failed to report data to Anchore: %s", string(respBody))
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return fmt.Errorf("failed to report data to Anchore: %+v", resp)

0 comments on commit 02ebaf5

Please sign in to comment.