github.com/google/osv-scalibr@v0.4.1/plugin/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 provides a functions for accessing SCALIBR-specific plugins from their respective type-specific lists. 16 package list 17 18 import ( 19 "fmt" 20 21 "github.com/google/osv-scalibr/annotator" 22 al "github.com/google/osv-scalibr/annotator/list" 23 "github.com/google/osv-scalibr/detector" 24 dl "github.com/google/osv-scalibr/detector/list" 25 "github.com/google/osv-scalibr/enricher" 26 el "github.com/google/osv-scalibr/enricher/enricherlist" 27 "github.com/google/osv-scalibr/extractor/filesystem" 28 fl "github.com/google/osv-scalibr/extractor/filesystem/list" 29 "github.com/google/osv-scalibr/extractor/standalone" 30 sl "github.com/google/osv-scalibr/extractor/standalone/list" 31 "github.com/google/osv-scalibr/plugin" 32 33 cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" 34 ) 35 36 // FromCapabilities returns all plugins that can run under the specified 37 // capabilities (OS, direct filesystem access, network access, etc.) of the 38 // scanning environment. 39 func FromCapabilities(capabs *plugin.Capabilities, cfg *cpb.PluginConfig) []plugin.Plugin { 40 return plugin.FilterByCapabilities(All(cfg), capabs) 41 } 42 43 // FromNames returns a deduplicated list of plugins from a list of names. 44 func FromNames(names []string, cfg *cpb.PluginConfig) ([]plugin.Plugin, error) { 45 if cfg == nil { 46 // Do the nil check here instead of in individual plugin initers. 47 cfg = &cpb.PluginConfig{} 48 } 49 resultMap := make(map[string]plugin.Plugin) 50 for _, name := range names { 51 fsex, ferr := fl.ExtractorsFromName(name, cfg) 52 stex, serr := sl.ExtractorsFromName(name, cfg) 53 det, derr := dl.DetectorsFromName(name, cfg) 54 ann, aerr := al.AnnotatorsFromName(name, cfg) 55 enr, eerr := el.EnrichersFromName(name, cfg) 56 57 // Report an error if none of the type-specific lists were able to resolve the name. 58 if ferr != nil && serr != nil && derr != nil && aerr != nil && eerr != nil { 59 return nil, fmt.Errorf("unknown plugin %q", name) 60 } 61 62 for _, p := range fsex { 63 resultMap[p.Name()] = p 64 } 65 for _, p := range stex { 66 resultMap[p.Name()] = p 67 } 68 for _, p := range det { 69 resultMap[p.Name()] = p 70 } 71 for _, p := range ann { 72 resultMap[p.Name()] = p 73 } 74 for _, p := range enr { 75 resultMap[p.Name()] = p 76 } 77 } 78 79 result := make([]plugin.Plugin, 0, len(resultMap)) 80 for _, e := range resultMap { 81 result = append(result, e) 82 } 83 return result, nil 84 } 85 86 // FromName returns a single plugin based on its exact name. 87 func FromName(name string, cfg *cpb.PluginConfig) (plugin.Plugin, error) { 88 plugins, err := FromNames([]string{name}, cfg) 89 if err != nil { 90 return nil, err 91 } 92 if len(plugins) != 1 { 93 return nil, fmt.Errorf("not an exact name for a plugin: %q", name) 94 } 95 return plugins[0], nil 96 } 97 98 // All returns all plugins defined in their type-specific list files. 99 // Note that these plugins have different capability Requirements and can't all 100 // be run on the same host (e.g. some are Linux-only while others are Windows-only) 101 // Prefer using FromCapabilities instead. 102 func All(cfg *cpb.PluginConfig) []plugin.Plugin { 103 if cfg == nil { 104 // Do the nil check here instead of in individual plugin initers. 105 cfg = &cpb.PluginConfig{} 106 } 107 all := []plugin.Plugin{} 108 for _, initers := range fl.All { 109 for _, initer := range initers { 110 all = append(all, initer(cfg)) 111 } 112 } 113 for _, initers := range sl.All { 114 for _, initer := range initers { 115 all = append(all, initer(cfg)) 116 } 117 } 118 for _, initers := range dl.All { 119 for _, initer := range initers { 120 all = append(all, initer(cfg)) 121 } 122 } 123 for _, initers := range al.All { 124 for _, initer := range initers { 125 all = append(all, initer(cfg)) 126 } 127 } 128 for _, initers := range el.All { 129 for _, initer := range initers { 130 all = append(all, initer(cfg)) 131 } 132 } 133 return all 134 } 135 136 // FilesystemExtractors returns the plugins from a list which are filesystem Extractors. 137 func FilesystemExtractors(plugins []plugin.Plugin) []filesystem.Extractor { 138 result := []filesystem.Extractor{} 139 for _, p := range plugins { 140 if p, ok := p.(filesystem.Extractor); ok { 141 result = append(result, p) 142 } 143 } 144 return result 145 } 146 147 // StandaloneExtractors returns the plugins from a list which are standalone Extractors. 148 func StandaloneExtractors(plugins []plugin.Plugin) []standalone.Extractor { 149 result := []standalone.Extractor{} 150 for _, p := range plugins { 151 if p, ok := p.(standalone.Extractor); ok { 152 result = append(result, p) 153 } 154 } 155 return result 156 } 157 158 // Detectors returns the plugins from a list which are Detectors. 159 func Detectors(plugins []plugin.Plugin) []detector.Detector { 160 result := []detector.Detector{} 161 for _, p := range plugins { 162 if p, ok := p.(detector.Detector); ok { 163 result = append(result, p) 164 } 165 } 166 return result 167 } 168 169 // Annotators returns the plugins from a list which are Annotators. 170 func Annotators(plugins []plugin.Plugin) []annotator.Annotator { 171 result := []annotator.Annotator{} 172 for _, p := range plugins { 173 if p, ok := p.(annotator.Annotator); ok { 174 result = append(result, p) 175 } 176 } 177 return result 178 } 179 180 // Enrichers returns the plugins from a list which are Enrichers. 181 func Enrichers(plugins []plugin.Plugin) []enricher.Enricher { 182 result := []enricher.Enricher{} 183 for _, p := range plugins { 184 if p, ok := p.(enricher.Enricher); ok { 185 result = append(result, p) 186 } 187 } 188 return result 189 }