github.com/khulnasoft-lab/tunnel-db@v0.0.0-20231117205118-74e1113bd007/pkg/db/advisory_detail.go (about)

     1  package db
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	bolt "go.etcd.io/bbolt"
     7  	"golang.org/x/xerrors"
     8  )
     9  
    10  const (
    11  	advisoryDetailBucket = "advisory-detail"
    12  )
    13  
    14  func (dbc Config) PutAdvisoryDetail(tx *bolt.Tx, vulnID, pkgName string, nestedBktNames []string, advisory interface{}) error {
    15  	bktNames := append([]string{advisoryDetailBucket, vulnID}, nestedBktNames...)
    16  	if err := dbc.put(tx, bktNames, pkgName, advisory); err != nil {
    17  		return xerrors.Errorf("failed to put advisory detail: %w", err)
    18  	}
    19  	return nil
    20  }
    21  
    22  // SaveAdvisoryDetails Extract advisories from 'advisory-detail' bucket and copy them in each
    23  func (dbc Config) SaveAdvisoryDetails(tx *bolt.Tx, vulnID string) error {
    24  	root := tx.Bucket([]byte(advisoryDetailBucket))
    25  	if root == nil {
    26  		return nil
    27  	}
    28  
    29  	cveBucket := root.Bucket([]byte(vulnID))
    30  	if cveBucket == nil {
    31  		return nil
    32  	}
    33  
    34  	if err := dbc.saveAdvisories(tx, cveBucket, []string{}, vulnID); err != nil {
    35  		return xerrors.Errorf("walk advisories error: %w", err)
    36  	}
    37  
    38  	return nil
    39  }
    40  
    41  // saveAdvisories walks all key-values under the 'advisory-detail' bucket and copy them in each vendor's bucket.
    42  func (dbc Config) saveAdvisories(tx *bolt.Tx, bkt *bolt.Bucket, bktNames []string, vulnID string) error {
    43  	if bkt == nil {
    44  		return nil
    45  	}
    46  
    47  	err := bkt.ForEach(func(k, v []byte) error {
    48  		// When the key is a bucket, it walks recursively.
    49  		if v == nil {
    50  			bkts := append(bktNames, string(k))
    51  			if err := dbc.saveAdvisories(tx, bkt.Bucket(k), bkts, vulnID); err != nil {
    52  				return xerrors.Errorf("walk advisories error: %w", err)
    53  			}
    54  		} else {
    55  			detail := map[string]interface{}{}
    56  			if err := json.Unmarshal(v, &detail); err != nil {
    57  				return xerrors.Errorf("failed to unmarshall the advisory detail: %w", err)
    58  			}
    59  
    60  			// Put the advisory in vendor's bucket such as Debian and Ubuntu
    61  			bkts := append(bktNames, string(k))
    62  			if err := dbc.put(tx, bkts, vulnID, detail); err != nil {
    63  				return xerrors.Errorf("database put error: %w", err)
    64  			}
    65  		}
    66  
    67  		return nil
    68  	})
    69  	if err != nil {
    70  		return xerrors.Errorf("foreach error: %w", err)
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  func (dbc Config) DeleteAdvisoryDetailBucket() error {
    77  	return dbc.deleteBucket(advisoryDetailBucket)
    78  }