github.com/wolfi-dev/wolfictl@v0.16.11/pkg/cli/advisory_alias_discover.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"os"
     7  
     8  	"github.com/spf13/cobra"
     9  	"github.com/wolfi-dev/wolfictl/pkg/advisory"
    10  	v2 "github.com/wolfi-dev/wolfictl/pkg/configs/advisory/v2"
    11  	rwos "github.com/wolfi-dev/wolfictl/pkg/configs/rwfs/os"
    12  	"github.com/wolfi-dev/wolfictl/pkg/distro"
    13  )
    14  
    15  func cmdAdvisoryAliasDiscover() *cobra.Command {
    16  	p := &aliasDiscoverParams{}
    17  	cmd := &cobra.Command{
    18  		Use:   "discover",
    19  		Short: "Discover new aliases for vulnerabilities in the advisory data",
    20  		Long: `Discover new aliases for vulnerabilities in the advisory data.
    21  
    22  This command reads the advisory data and searches for new aliases for the ID
    23  and aliases of each advisory. For any new aliases found, the advisory data is
    24  updated to include the new alias.
    25  
    26  This command uses the GitHub API to query GHSA information. Note that GitHub
    27  enforces a stricter rate limit against unauthenticated API calls. You can
    28  authenticate this command's API calls by setting the environment variable
    29  GITHUB_TOKEN to a personal access token, or by setting up the "gh" CLI.
    30  When performing alias discovery across the entire data set, authenticating
    31  these API calls is highly recommended.
    32  
    33  You may pass one or more instances of -p/--package to have the command operate
    34  on only one or more packages, rather than on the entire advisory data set.
    35  
    36  Where possible, this command also normalizes advisories to use the relevant CVE
    37  ID as the advisory ID instead of an ID from another vulnerability namespace.
    38  This means, for example, that a non-CVE ID (e.g. a GHSA ID) that was previously
    39  the advisory ID will be moved to the advisory's aliases if a canonical CVE ID
    40  is discovered, since the CVE ID will become the advisory's new ID.
    41  
    42  In cases where an advisory's ID is updated, the advisory document will be
    43  re-sorted by advisory ID so that the resulting advisories are still sorted
    44  correctly. Also, if updating an advisory ID results in an advisory document
    45  having two or more advisories with the same ID, the command errors out rather
    46  than attempting any kind of merge of the separate advisories.
    47  `,
    48  		SilenceErrors: true,
    49  		Args:          cobra.NoArgs,
    50  		RunE: func(cmd *cobra.Command, _ []string) error {
    51  			advisoriesRepoDir := resolveAdvisoriesDirInput(p.advisoriesRepoDir)
    52  			if advisoriesRepoDir == "" {
    53  				if p.doNotDetectDistro {
    54  					return fmt.Errorf("no advisories repo dir specified")
    55  				}
    56  
    57  				d, err := distro.Detect()
    58  				if err != nil {
    59  					return fmt.Errorf("no advisories repo dir specified, and distro auto-detection failed: %w", err)
    60  				}
    61  
    62  				advisoriesRepoDir = d.Local.AdvisoriesRepo.Dir
    63  				_, _ = fmt.Fprint(os.Stderr, renderDetectedDistro(d))
    64  			}
    65  
    66  			advisoriesFsys := rwos.DirFS(advisoriesRepoDir)
    67  			advisoryDocs, err := v2.NewIndex(cmd.Context(), advisoriesFsys)
    68  			if err != nil {
    69  				return err
    70  			}
    71  
    72  			selectedPackageSet := make(map[string]struct{})
    73  			for _, pkg := range p.packages {
    74  				selectedPackageSet[pkg] = struct{}{}
    75  			}
    76  
    77  			opts := advisory.DiscoverAliasesOptions{
    78  				AdvisoryDocs:     advisoryDocs,
    79  				AliasFinder:      advisory.NewHTTPAliasFinder(http.DefaultClient),
    80  				SelectedPackages: selectedPackageSet,
    81  			}
    82  
    83  			return advisory.DiscoverAliases(cmd.Context(), opts)
    84  		},
    85  	}
    86  
    87  	p.addFlagsTo(cmd)
    88  	return cmd
    89  }
    90  
    91  type aliasDiscoverParams struct {
    92  	advisoriesRepoDir string
    93  	doNotDetectDistro bool
    94  
    95  	packages []string
    96  }
    97  
    98  func (p *aliasDiscoverParams) addFlagsTo(cmd *cobra.Command) {
    99  	addAdvisoriesDirFlag(&p.advisoriesRepoDir, cmd)
   100  	addNoDistroDetectionFlag(&p.doNotDetectDistro, cmd)
   101  
   102  	cmd.Flags().StringSliceVarP(&p.packages, flagNamePackage, "p", nil, "packages to operate on")
   103  }