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 }