github.com/google/osv-scalibr@v0.4.1/extractor/standalone/list/list.go (about)

     1  // Copyright 2025 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package list contains the list of all standalone extractors.
    16  package list
    17  
    18  import (
    19  	"fmt"
    20  	"maps"
    21  	"slices"
    22  
    23  	"github.com/google/osv-scalibr/extractor/standalone"
    24  	"github.com/google/osv-scalibr/extractor/standalone/containers/containerd"
    25  	"github.com/google/osv-scalibr/extractor/standalone/containers/docker"
    26  	"github.com/google/osv-scalibr/extractor/standalone/os/netports"
    27  	"github.com/google/osv-scalibr/extractor/standalone/windows/dismpatch"
    28  	"github.com/google/osv-scalibr/extractor/standalone/windows/ospackages"
    29  	"github.com/google/osv-scalibr/extractor/standalone/windows/regosversion"
    30  	"github.com/google/osv-scalibr/extractor/standalone/windows/regpatchlevel"
    31  
    32  	cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto"
    33  )
    34  
    35  // InitFn is the extractor initializer function.
    36  type InitFn func(cfg *cpb.PluginConfig) standalone.Extractor
    37  
    38  // InitMap is a map of extractor names to their initers.
    39  type InitMap map[string][]InitFn
    40  
    41  var (
    42  	// Windows standalone extractors.
    43  	Windows = InitMap{dismpatch.Name: {noCFG(dismpatch.New)}}
    44  
    45  	// WindowsExperimental defines experimental extractors. Note that experimental does not mean
    46  	// dangerous.
    47  	WindowsExperimental = InitMap{
    48  		ospackages.Name:    {noCFG(ospackages.NewDefault)},
    49  		regosversion.Name:  {noCFG(regosversion.NewDefault)},
    50  		regpatchlevel.Name: {noCFG(regpatchlevel.NewDefault)},
    51  	}
    52  
    53  	// OSExperimental defines experimental OS extractors.
    54  	OSExperimental = InitMap{
    55  		netports.Name: {noCFG(netports.New)},
    56  	}
    57  
    58  	// Containers standalone extractors.
    59  	Containers = InitMap{
    60  		containerd.Name: {noCFG(containerd.NewDefault)},
    61  		docker.Name:     {noCFG(docker.New)},
    62  	}
    63  
    64  	// Default standalone extractors.
    65  	Default = Windows
    66  	// All standalone extractors.
    67  	All = concat(Windows, WindowsExperimental, Containers, OSExperimental)
    68  
    69  	extractorNames = concat(All, InitMap{
    70  		// Windows
    71  		"windows": vals(Windows),
    72  
    73  		// Collections.
    74  		"extractors/default": vals(Default),
    75  		"default":            vals(Default),
    76  		"extractors/all":     vals(All),
    77  		"all":                vals(All),
    78  		"containers":         vals(Containers),
    79  	})
    80  )
    81  
    82  func concat(initMaps ...InitMap) InitMap {
    83  	result := InitMap{}
    84  	for _, m := range initMaps {
    85  		maps.Copy(result, m)
    86  	}
    87  	return result
    88  }
    89  
    90  func vals(initMap InitMap) []InitFn {
    91  	return slices.Concat(slices.Collect(maps.Values(initMap))...)
    92  }
    93  
    94  // Wraps initer functions that don't take any config value to initer functions that do.
    95  // TODO(b/400910349): Remove once all plugins take config values.
    96  func noCFG(f func() standalone.Extractor) InitFn {
    97  	return func(_ *cpb.PluginConfig) standalone.Extractor { return f() }
    98  }
    99  
   100  // ExtractorsFromName returns a list of extractors from a name.
   101  func ExtractorsFromName(name string, cfg *cpb.PluginConfig) ([]standalone.Extractor, error) {
   102  	if initers, ok := extractorNames[name]; ok {
   103  		result := []standalone.Extractor{}
   104  		for _, initer := range initers {
   105  			result = append(result, initer(cfg))
   106  		}
   107  		return result, nil
   108  	}
   109  	return nil, fmt.Errorf("unknown extractor %q", name)
   110  }