@@ -47,6 +47,13 @@ var AdminCmd = &cli.Command{
4747 Usage : "create `idx_manifest_layer_layer_id` index in the `indexer` database" ,
4848 Action : adminPre473 ,
4949 },
50+ {
51+ Name : "v4.8.0" ,
52+ Aliases : []string {"4.8.0" },
53+ Description : "This task sets the matcher migration version to 13 to avert the migration deleting RHEL OVAL vulnerabilities." ,
54+ Usage : "set matcher migration version to 13" ,
55+ Action : adminPre480 ,
56+ },
5057 },
5158 Before : otherVersion ,
5259 },
@@ -64,6 +71,14 @@ var AdminCmd = &cli.Command{
6471 Usage : "delete pyupio vulns in from the matcher DB" ,
6572 Action : adminPost470 ,
6673 },
74+ {
75+ Name : "v4.8.0" ,
76+ Aliases : []string {"4.8.0" },
77+ Description : "This task deletes RHEL OVALv2 vulnerabilities from the database.\n " +
78+ "This could take a while so this command allows an operator to delete the vulnerabilities outside of migrations.\n " ,
79+ Usage : "delete RHEL OVALv2 vulnerabilities" ,
80+ Action : adminPost480 ,
81+ },
6782 },
6883 Before : otherVersion ,
6984 },
@@ -476,3 +491,131 @@ func fromSemver(v *semver.Version) (out claircore.Version) {
476491 out .V [3 ] = int32 (v .Patch ())
477492 return out
478493}
494+
495+ // Set matcher migration version to 13.
496+ func adminPre480 (c * cli.Context ) error {
497+ ctx := c .Context
498+ fi , err := os .Stat (c .Path ("config" ))
499+ switch {
500+ case ! errors .Is (err , nil ):
501+ return fmt .Errorf ("bad config: %w" , err )
502+ case fi .IsDir ():
503+ return fmt .Errorf ("bad config: is a directory" )
504+ }
505+ cfg , err := loadConfig (c .Path ("config" ))
506+ if err != nil {
507+ return fmt .Errorf ("error loading config: %w" , err )
508+ }
509+ dsn := cfg .Matcher .ConnString
510+
511+ pgcfg , err := pgxpool .ParseConfig (dsn )
512+ if err != nil {
513+ return fmt .Errorf ("error parsing dsn: %w" , err )
514+ }
515+ zlog .Info (ctx ).
516+ Str ("host" , pgcfg .ConnConfig .Host ).
517+ Str ("database" , pgcfg .ConnConfig .Database ).
518+ Str ("user" , pgcfg .ConnConfig .User ).
519+ Uint16 ("port" , pgcfg .ConnConfig .Port ).
520+ Msg ("using discovered connection params" )
521+
522+ zlog .Debug (ctx ).
523+ Msg ("resizing pool to 1 connections" )
524+ pgcfg .MaxConns = 1
525+ pool , err := pgxpool .ConnectConfig (ctx , pgcfg )
526+ if err != nil {
527+ return fmt .Errorf ("error creating pool: %w" , err )
528+ }
529+ defer pool .Close ()
530+ if err := pool .Ping (ctx ); err != nil {
531+ return fmt .Errorf ("error connecting to database: %w" , err )
532+ }
533+
534+ return pool .AcquireFunc (ctx , func (conn * pgxpool.Conn ) error {
535+ const (
536+ setMatcherMigration = `INSERT INTO libvuln_migrations ("version") VALUES (13) ON CONFLICT DO NOTHING;`
537+ )
538+ if _ , err := conn .Exec (ctx , setMatcherMigration ); err != nil {
539+ return fmt .Errorf ("error setting matcher migration: %w" , err )
540+ }
541+ zlog .Debug (ctx ).Msg ("Set migration version done" )
542+ zlog .Info (ctx ).Msg ("pre v4.8.0 admin done" )
543+ return nil
544+ })
545+ }
546+
547+ // Attempt to remove RHEL OVALv2 vulnerabilities before v4.8.0 (where vulnerabilities come from VEX).
548+ func adminPost480 (c * cli.Context ) error {
549+ ctx := c .Context
550+ fi , err := os .Stat (c .Path ("config" ))
551+ switch {
552+ case ! errors .Is (err , nil ):
553+ return fmt .Errorf ("bad config: %w" , err )
554+ case fi .IsDir ():
555+ return fmt .Errorf ("bad config: is a directory" )
556+ }
557+ cfg , err := loadConfig (c .Path ("config" ))
558+ if err != nil {
559+ return fmt .Errorf ("error loading config: %w" , err )
560+ }
561+ dsn := cfg .Matcher .ConnString
562+
563+ pgcfg , err := pgxpool .ParseConfig (dsn )
564+ if err != nil {
565+ return fmt .Errorf ("error parsing dsn: %w" , err )
566+ }
567+ zlog .Info (ctx ).
568+ Str ("host" , pgcfg .ConnConfig .Host ).
569+ Str ("database" , pgcfg .ConnConfig .Database ).
570+ Str ("user" , pgcfg .ConnConfig .User ).
571+ Uint16 ("port" , pgcfg .ConnConfig .Port ).
572+ Msg ("using discovered connection params" )
573+
574+ zlog .Debug (ctx ).
575+ Msg ("resizing pool to 2 connections" )
576+ pgcfg .MaxConns = 2
577+ pool , err := pgxpool .ConnectConfig (ctx , pgcfg )
578+ if err != nil {
579+ return fmt .Errorf ("error creating pool: %w" , err )
580+ }
581+ defer pool .Close ()
582+ if err := pool .Ping (ctx ); err != nil {
583+ return fmt .Errorf ("error connecting to database: %w" , err )
584+ }
585+
586+ return pool .AcquireFunc (ctx , func (conn * pgxpool.Conn ) error {
587+ const (
588+ selectUpdateOperations = `SELECT DISTINCT(updater) FROM update_operation WHERE updater ~ 'RHEL[5-9]-*'; `
589+ deleteOVALUO = `DELETE FROM update_operation WHERE updater = ANY($1::TEXT[]);`
590+ deleteOVALVulns = `DELETE FROM vuln where updater = ANY($1::TEXT[]);`
591+ )
592+ updaters := []string {}
593+ rows , err := conn .Query (ctx , selectUpdateOperations )
594+ if err != nil {
595+ return err
596+ }
597+ defer rows .Close ()
598+
599+ var updater string
600+ for rows .Next () {
601+ if err := rows .Scan (& updater ); err != nil {
602+ return err
603+ }
604+ updaters = append (updaters , updater )
605+ }
606+ if err := rows .Err (); err != nil {
607+ return err
608+ }
609+ zlog .Debug (ctx ).Strs ("updaters" , updaters ).Msg ("Got updaters" )
610+ if _ , err := conn .Exec (ctx , deleteOVALUO , updaters ); err != nil {
611+ return fmt .Errorf ("error deleting OVAL update_operations: %w" , err )
612+ }
613+ zlog .Debug (ctx ).Msg ("Delete update_operations done" )
614+ if _ , err := conn .Exec (ctx , deleteOVALVulns , updaters ); err != nil {
615+ return fmt .Errorf ("error deleting OVAL vulns: %w" , err )
616+ }
617+ zlog .Debug (ctx ).Msg ("Delete vulns done" )
618+ zlog .Info (ctx ).Msg ("post v4.8.0 admin done" )
619+ return nil
620+ })
621+ }
0 commit comments