diff --git a/binary/cli/cli.go b/binary/cli/cli.go index 565209e6f..586233666 100644 --- a/binary/cli/cli.go +++ b/binary/cli/cli.go @@ -27,27 +27,23 @@ import ( "github.com/google/go-containerregistry/pkg/authn" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" + scalibr "github.com/google/osv-scalibr" scalibrimage "github.com/google/osv-scalibr/artifact/image" "github.com/google/osv-scalibr/binary/cdx" "github.com/google/osv-scalibr/binary/platform" "github.com/google/osv-scalibr/binary/proto" cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" binspdx "github.com/google/osv-scalibr/binary/spdx" - "github.com/google/osv-scalibr/clients/resolution" "github.com/google/osv-scalibr/converter" convspdx "github.com/google/osv-scalibr/converter/spdx" "github.com/google/osv-scalibr/detector" - "github.com/spdx/tools-golang/spdx/v2/common" - "google.golang.org/protobuf/encoding/prototext" - - scalibr "github.com/google/osv-scalibr" - "github.com/google/osv-scalibr/enricher/transitivedependency/requirements" "github.com/google/osv-scalibr/extractor/filesystem" - "github.com/google/osv-scalibr/extractor/filesystem/language/java/pomxmlnet" scalibrfs "github.com/google/osv-scalibr/fs" "github.com/google/osv-scalibr/log" "github.com/google/osv-scalibr/plugin" pl "github.com/google/osv-scalibr/plugin/list" + "github.com/spdx/tools-golang/spdx/v2/common" + "google.golang.org/protobuf/encoding/prototext" ) // Array is a type to be passed to flag.Var that supports arrays passed as repeated flags, @@ -154,8 +150,6 @@ type Flags struct { StoreAbsolutePath bool WindowsAllDrives bool Offline bool - LocalRegistry string - DisableGoogleAuth bool } var supportedOutputFormats = []string{ @@ -553,25 +547,6 @@ func (f *Flags) pluginsToRun() ([]plugin.Plugin, *cpb.PluginConfig, error) { if err != nil { return nil, nil, err } - - // Apply plugin-specific config. - for _, p := range plugins { - if f.LocalRegistry != "" { - switch p.Name() { - case pomxmlnet.Name: - p.(*pomxmlnet.Extractor).MavenClient.SetLocalRegistry(f.LocalRegistry) - case requirements.Name: - if client, ok := p.(*requirements.Enricher).Client.(*resolution.PyPIRegistryClient); ok { - // The resolution client is the native PyPI registry client. - client.SetLocalRegistry(f.LocalRegistry) - } - } - } - if f.DisableGoogleAuth && p.Name() == pomxmlnet.Name { - p.(*pomxmlnet.Extractor).MavenClient.DisableGoogleAuth() - } - } - result = append(result, plugins...) } diff --git a/binary/proto/config.proto b/binary/proto/config.proto index 5673ac023..38e6e09ce 100644 --- a/binary/proto/config.proto +++ b/binary/proto/config.proto @@ -31,6 +31,12 @@ message PluginConfig { // The maximum file size the plugin will process. int64 max_file_size_bytes = 1; + // The local directory to store the downloaded manifests during dependency + // resolution. + string local_registry = 3; + // If true, do not try to create google.DefaultClient for Artifact Registry + // during dependency resolution. + bool disable_google_auth = 4; // Config values that only apply to a single plugin. repeated PluginSpecificConfig plugin_specific = 2; @@ -45,6 +51,8 @@ message PluginSpecificConfig { VDIConfig vdi = 5; VMDKConfig vmdk = 6; HashiCorpVaultValidatorConfig hashicorp_vault_validator = 7; + SDPInspectConfig sdp_inspect = 8; + POMXMLNetConfig pom_xml_net = 9; } } @@ -92,3 +100,14 @@ message HashiCorpVaultValidatorConfig { // https://developer.hashicorp.com/vault string vault_url = 1; } + +message SDPInspectConfig { + // The GCP project id to use for Sensitive Data Protection InspectContent API + // calls. + string project_id = 1; +} + +message POMXMLNetConfig { + // The URL of the upstream Maven registry. + string upstream_registry = 1; +} diff --git a/binary/proto/config_go_proto/config.pb.go b/binary/proto/config_go_proto/config.pb.go index 8276cc6d8..d09ef69c8 100644 --- a/binary/proto/config_go_proto/config.pb.go +++ b/binary/proto/config_go_proto/config.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc v3.21.1 // source: proto/config.proto package config_go_proto @@ -40,6 +40,12 @@ type PluginConfig struct { state protoimpl.MessageState `protogen:"open.v1"` // The maximum file size the plugin will process. MaxFileSizeBytes int64 `protobuf:"varint,1,opt,name=max_file_size_bytes,json=maxFileSizeBytes,proto3" json:"max_file_size_bytes,omitempty"` + // The local directory to store the downloaded manifests during dependency + // resolution. + LocalRegistry string `protobuf:"bytes,3,opt,name=local_registry,json=localRegistry,proto3" json:"local_registry,omitempty"` + // If true, do not try to create google.DefaultClient for Artifact Registry + // during dependency resolution. + DisableGoogleAuth bool `protobuf:"varint,4,opt,name=disable_google_auth,json=disableGoogleAuth,proto3" json:"disable_google_auth,omitempty"` // Config values that only apply to a single plugin. PluginSpecific []*PluginSpecificConfig `protobuf:"bytes,2,rep,name=plugin_specific,json=pluginSpecific,proto3" json:"plugin_specific,omitempty"` unknownFields protoimpl.UnknownFields @@ -83,6 +89,20 @@ func (x *PluginConfig) GetMaxFileSizeBytes() int64 { return 0 } +func (x *PluginConfig) GetLocalRegistry() string { + if x != nil { + return x.LocalRegistry + } + return "" +} + +func (x *PluginConfig) GetDisableGoogleAuth() bool { + if x != nil { + return x.DisableGoogleAuth + } + return false +} + func (x *PluginConfig) GetPluginSpecific() []*PluginSpecificConfig { if x != nil { return x.PluginSpecific @@ -101,6 +121,8 @@ type PluginSpecificConfig struct { // *PluginSpecificConfig_Vdi // *PluginSpecificConfig_Vmdk // *PluginSpecificConfig_HashicorpVaultValidator + // *PluginSpecificConfig_SdpInspect + // *PluginSpecificConfig_PomXmlNet Config isPluginSpecificConfig_Config `protobuf_oneof:"config"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -206,6 +228,24 @@ func (x *PluginSpecificConfig) GetHashicorpVaultValidator() *HashiCorpVaultValid return nil } +func (x *PluginSpecificConfig) GetSdpInspect() *SDPInspectConfig { + if x != nil { + if x, ok := x.Config.(*PluginSpecificConfig_SdpInspect); ok { + return x.SdpInspect + } + } + return nil +} + +func (x *PluginSpecificConfig) GetPomXmlNet() *POMXMLNetConfig { + if x != nil { + if x, ok := x.Config.(*PluginSpecificConfig_PomXmlNet); ok { + return x.PomXmlNet + } + } + return nil +} + type isPluginSpecificConfig_Config interface { isPluginSpecificConfig_Config() } @@ -238,6 +278,14 @@ type PluginSpecificConfig_HashicorpVaultValidator struct { HashicorpVaultValidator *HashiCorpVaultValidatorConfig `protobuf:"bytes,7,opt,name=hashicorp_vault_validator,json=hashicorpVaultValidator,proto3,oneof"` } +type PluginSpecificConfig_SdpInspect struct { + SdpInspect *SDPInspectConfig `protobuf:"bytes,8,opt,name=sdp_inspect,json=sdpInspect,proto3,oneof"` +} + +type PluginSpecificConfig_PomXmlNet struct { + PomXmlNet *POMXMLNetConfig `protobuf:"bytes,9,opt,name=pom_xml_net,json=pomXmlNet,proto3,oneof"` +} + func (*PluginSpecificConfig_GoBinary) isPluginSpecificConfig_Config() {} func (*PluginSpecificConfig_Govulncheck) isPluginSpecificConfig_Config() {} @@ -252,6 +300,10 @@ func (*PluginSpecificConfig_Vmdk) isPluginSpecificConfig_Config() {} func (*PluginSpecificConfig_HashicorpVaultValidator) isPluginSpecificConfig_Config() {} +func (*PluginSpecificConfig_SdpInspect) isPluginSpecificConfig_Config() {} + +func (*PluginSpecificConfig_PomXmlNet) isPluginSpecificConfig_Config() {} + type GoBinaryConfig struct { state protoimpl.MessageState `protogen:"open.v1"` // Enables extracting the module version from the Go binary content. @@ -577,14 +629,107 @@ func (x *HashiCorpVaultValidatorConfig) GetVaultUrl() string { return "" } +type SDPInspectConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The GCP project id to use for Sensitive Data Protection InspectContent API + // calls. + ProjectId string `protobuf:"bytes,1,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SDPInspectConfig) Reset() { + *x = SDPInspectConfig{} + mi := &file_proto_config_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SDPInspectConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SDPInspectConfig) ProtoMessage() {} + +func (x *SDPInspectConfig) ProtoReflect() protoreflect.Message { + mi := &file_proto_config_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SDPInspectConfig.ProtoReflect.Descriptor instead. +func (*SDPInspectConfig) Descriptor() ([]byte, []int) { + return file_proto_config_proto_rawDescGZIP(), []int{9} +} + +func (x *SDPInspectConfig) GetProjectId() string { + if x != nil { + return x.ProjectId + } + return "" +} + +type POMXMLNetConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The URL of the upstream Maven registry. + UpstreamRegistry string `protobuf:"bytes,1,opt,name=upstream_registry,json=upstreamRegistry,proto3" json:"upstream_registry,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *POMXMLNetConfig) Reset() { + *x = POMXMLNetConfig{} + mi := &file_proto_config_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *POMXMLNetConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*POMXMLNetConfig) ProtoMessage() {} + +func (x *POMXMLNetConfig) ProtoReflect() protoreflect.Message { + mi := &file_proto_config_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use POMXMLNetConfig.ProtoReflect.Descriptor instead. +func (*POMXMLNetConfig) Descriptor() ([]byte, []int) { + return file_proto_config_proto_rawDescGZIP(), []int{10} +} + +func (x *POMXMLNetConfig) GetUpstreamRegistry() string { + if x != nil { + return x.UpstreamRegistry + } + return "" +} + var File_proto_config_proto protoreflect.FileDescriptor const file_proto_config_proto_rawDesc = "" + "\n" + - "\x12proto/config.proto\x12\ascalibr\"\x85\x01\n" + + "\x12proto/config.proto\x12\ascalibr\"\xdc\x01\n" + "\fPluginConfig\x12-\n" + - "\x13max_file_size_bytes\x18\x01 \x01(\x03R\x10maxFileSizeBytes\x12F\n" + - "\x0fplugin_specific\x18\x02 \x03(\v2\x1d.scalibr.PluginSpecificConfigR\x0epluginSpecific\"\xad\x03\n" + + "\x13max_file_size_bytes\x18\x01 \x01(\x03R\x10maxFileSizeBytes\x12%\n" + + "\x0elocal_registry\x18\x03 \x01(\tR\rlocalRegistry\x12.\n" + + "\x13disable_google_auth\x18\x04 \x01(\bR\x11disableGoogleAuth\x12F\n" + + "\x0fplugin_specific\x18\x02 \x03(\v2\x1d.scalibr.PluginSpecificConfigR\x0epluginSpecific\"\xa7\x04\n" + "\x14PluginSpecificConfig\x126\n" + "\tgo_binary\x18\x01 \x01(\v2\x17.scalibr.GoBinaryConfigH\x00R\bgoBinary\x12>\n" + "\vgovulncheck\x18\x02 \x01(\v2\x1a.scalibr.GovulncheckConfigH\x00R\vgovulncheck\x122\n" + @@ -592,7 +737,10 @@ const file_proto_config_proto_rawDesc = "" + "\x03ova\x18\x04 \x01(\v2\x12.scalibr.OVAConfigH\x00R\x03ova\x12&\n" + "\x03vdi\x18\x05 \x01(\v2\x12.scalibr.VDIConfigH\x00R\x03vdi\x12)\n" + "\x04vmdk\x18\x06 \x01(\v2\x13.scalibr.VMDKConfigH\x00R\x04vmdk\x12d\n" + - "\x19hashicorp_vault_validator\x18\a \x01(\v2&.scalibr.HashiCorpVaultValidatorConfigH\x00R\x17hashicorpVaultValidatorB\b\n" + + "\x19hashicorp_vault_validator\x18\a \x01(\v2&.scalibr.HashiCorpVaultValidatorConfigH\x00R\x17hashicorpVaultValidator\x12<\n" + + "\vsdp_inspect\x18\b \x01(\v2\x19.scalibr.SDPInspectConfigH\x00R\n" + + "sdpInspect\x12:\n" + + "\vpom_xml_net\x18\t \x01(\v2\x18.scalibr.POMXMLNetConfigH\x00R\tpomXmlNetB\b\n" + "\x06config\"B\n" + "\x0eGoBinaryConfig\x120\n" + "\x14version_from_content\x18\x01 \x01(\bR\x12versionFromContent\"D\n" + @@ -608,7 +756,12 @@ const file_proto_config_proto_rawDesc = "" + "VMDKConfig\x12-\n" + "\x13max_file_size_bytes\x18\x01 \x01(\x03R\x10maxFileSizeBytes\"<\n" + "\x1dHashiCorpVaultValidatorConfig\x12\x1b\n" + - "\tvault_url\x18\x01 \x01(\tR\bvaultUrlBBB\x06ConfigP\x01Z6github.com/google/scalibr/binary/proto/config_go_protob\x06proto3" + "\tvault_url\x18\x01 \x01(\tR\bvaultUrl\"1\n" + + "\x10SDPInspectConfig\x12\x1d\n" + + "\n" + + "project_id\x18\x01 \x01(\tR\tprojectId\">\n" + + "\x0fPOMXMLNetConfig\x12+\n" + + "\x11upstream_registry\x18\x01 \x01(\tR\x10upstreamRegistryBBB\x06ConfigP\x01Z6github.com/google/scalibr/binary/proto/config_go_protob\x06proto3" var ( file_proto_config_proto_rawDescOnce sync.Once @@ -622,7 +775,7 @@ func file_proto_config_proto_rawDescGZIP() []byte { return file_proto_config_proto_rawDescData } -var file_proto_config_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_proto_config_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_proto_config_proto_goTypes = []any{ (*PluginConfig)(nil), // 0: scalibr.PluginConfig (*PluginSpecificConfig)(nil), // 1: scalibr.PluginSpecificConfig @@ -633,21 +786,25 @@ var file_proto_config_proto_goTypes = []any{ (*VDIConfig)(nil), // 6: scalibr.VDIConfig (*VMDKConfig)(nil), // 7: scalibr.VMDKConfig (*HashiCorpVaultValidatorConfig)(nil), // 8: scalibr.HashiCorpVaultValidatorConfig + (*SDPInspectConfig)(nil), // 9: scalibr.SDPInspectConfig + (*POMXMLNetConfig)(nil), // 10: scalibr.POMXMLNetConfig } var file_proto_config_proto_depIdxs = []int32{ - 1, // 0: scalibr.PluginConfig.plugin_specific:type_name -> scalibr.PluginSpecificConfig - 2, // 1: scalibr.PluginSpecificConfig.go_binary:type_name -> scalibr.GoBinaryConfig - 3, // 2: scalibr.PluginSpecificConfig.govulncheck:type_name -> scalibr.GovulncheckConfig - 4, // 3: scalibr.PluginSpecificConfig.archive:type_name -> scalibr.ArchiveConfig - 5, // 4: scalibr.PluginSpecificConfig.ova:type_name -> scalibr.OVAConfig - 6, // 5: scalibr.PluginSpecificConfig.vdi:type_name -> scalibr.VDIConfig - 7, // 6: scalibr.PluginSpecificConfig.vmdk:type_name -> scalibr.VMDKConfig - 8, // 7: scalibr.PluginSpecificConfig.hashicorp_vault_validator:type_name -> scalibr.HashiCorpVaultValidatorConfig - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 1, // 0: scalibr.PluginConfig.plugin_specific:type_name -> scalibr.PluginSpecificConfig + 2, // 1: scalibr.PluginSpecificConfig.go_binary:type_name -> scalibr.GoBinaryConfig + 3, // 2: scalibr.PluginSpecificConfig.govulncheck:type_name -> scalibr.GovulncheckConfig + 4, // 3: scalibr.PluginSpecificConfig.archive:type_name -> scalibr.ArchiveConfig + 5, // 4: scalibr.PluginSpecificConfig.ova:type_name -> scalibr.OVAConfig + 6, // 5: scalibr.PluginSpecificConfig.vdi:type_name -> scalibr.VDIConfig + 7, // 6: scalibr.PluginSpecificConfig.vmdk:type_name -> scalibr.VMDKConfig + 8, // 7: scalibr.PluginSpecificConfig.hashicorp_vault_validator:type_name -> scalibr.HashiCorpVaultValidatorConfig + 9, // 8: scalibr.PluginSpecificConfig.sdp_inspect:type_name -> scalibr.SDPInspectConfig + 10, // 9: scalibr.PluginSpecificConfig.pom_xml_net:type_name -> scalibr.POMXMLNetConfig + 10, // [10:10] is the sub-list for method output_type + 10, // [10:10] is the sub-list for method input_type + 10, // [10:10] is the sub-list for extension type_name + 10, // [10:10] is the sub-list for extension extendee + 0, // [0:10] is the sub-list for field type_name } func init() { file_proto_config_proto_init() } @@ -663,6 +820,8 @@ func file_proto_config_proto_init() { (*PluginSpecificConfig_Vdi)(nil), (*PluginSpecificConfig_Vmdk)(nil), (*PluginSpecificConfig_HashicorpVaultValidator)(nil), + (*PluginSpecificConfig_SdpInspect)(nil), + (*PluginSpecificConfig_PomXmlNet)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -670,7 +829,7 @@ func file_proto_config_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_config_proto_rawDesc), len(file_proto_config_proto_rawDesc)), NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/binary/scalibr/scalibr.go b/binary/scalibr/scalibr.go index 4cef69f14..0dd39f692 100644 --- a/binary/scalibr/scalibr.go +++ b/binary/scalibr/scalibr.go @@ -96,8 +96,6 @@ func parseFlags(args []string) (*cli.Flags, error) { filterByCapabilities := fs.Bool("filter-by-capabilities", true, "If set, plugins whose requirements (network access, OS, etc.) aren't satisfied by the scanning environment will be silently disabled instead of throwing a validation error.") windowsAllDrives := fs.Bool("windows-all-drives", false, "Scan all drives on Windows") offline := fs.Bool("offline", false, "Offline mode: Run only plugins that don't require network access") - localRegistry := fs.String("local-registry", "", "The local directory to store the downloaded manifests during dependency resolution.") - disableGoogleAuth := fs.Bool("disable-google-auth", false, "Disables the use of Google Application Default Credentials for authenticating with Google Artifact Registry.") if err := fs.Parse(args); err != nil { return nil, err @@ -138,8 +136,6 @@ func parseFlags(args []string) (*cli.Flags, error) { FilterByCapabilities: *filterByCapabilities, WindowsAllDrives: *windowsAllDrives, Offline: *offline, - LocalRegistry: *localRegistry, - DisableGoogleAuth: *disableGoogleAuth, } if err := cli.ValidateFlags(flags); err != nil { return nil, err diff --git a/enricher/enricherlist/list.go b/enricher/enricherlist/list.go index 7d05cc3f9..8c75f5e4c 100644 --- a/enricher/enricherlist/list.go +++ b/enricher/enricherlist/list.go @@ -137,7 +137,7 @@ var ( // TransitiveDependency enrichers. TransitiveDependency = InitMap{ - requirements.Name: {noCFG(requirements.NewDefault)}, + requirements.Name: {requirements.New}, } // PackageDeprecation enricher. diff --git a/enricher/transitivedependency/requirements/requirements.go b/enricher/transitivedependency/requirements/requirements.go index 6cd84b90e..814af8c4c 100644 --- a/enricher/transitivedependency/requirements/requirements.go +++ b/enricher/transitivedependency/requirements/requirements.go @@ -24,6 +24,7 @@ import ( "deps.dev/util/resolve" "deps.dev/util/resolve/dep" pypiresolve "deps.dev/util/resolve/pypi" + cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" "github.com/google/osv-scalibr/clients/resolution" "github.com/google/osv-scalibr/enricher" "github.com/google/osv-scalibr/extractor" @@ -66,19 +67,11 @@ func (Enricher) RequiredPlugins() []string { return []string{requirements.Name} } -// NewDefault returns a new enricher with the default configuration. -func NewDefault() enricher.Enricher { - return &Enricher{ - // Empty string indicates using default registry and no local registry. - Client: resolution.NewPyPIRegistryClient("", ""), - } -} - -// NewEnricher creates a new Enricher. -func NewEnricher(client resolve.Client) *Enricher { - return &Enricher{ - Client: client, - } +// New creates a new Enricher. +func New(cfg *cpb.PluginConfig) enricher.Enricher { + client := resolution.NewPyPIRegistryClient("", "") + client.SetLocalRegistry(cfg.LocalRegistry) + return &Enricher{Client: client} } // Enrich enriches the inventory in requirements.txt with transitive dependencies. diff --git a/enricher/transitivedependency/requirements/requirements_test.go b/enricher/transitivedependency/requirements/requirements_test.go index e3f7ac105..41155460b 100644 --- a/enricher/transitivedependency/requirements/requirements_test.go +++ b/enricher/transitivedependency/requirements/requirements_test.go @@ -19,6 +19,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" + cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" "github.com/google/osv-scalibr/clients/clienttest" "github.com/google/osv-scalibr/enricher" "github.com/google/osv-scalibr/enricher/transitivedependency/requirements" @@ -91,7 +92,8 @@ func TestEnricher_Enrich(t *testing.T) { } resolutionClient := clienttest.NewMockResolutionClient(t, "testdata/universe.yaml") - enricher := requirements.NewEnricher(resolutionClient) + enricher := requirements.New(&cpb.PluginConfig{}) + enricher.(*requirements.Enricher).Client = resolutionClient err := enricher.Enrich(t.Context(), &input, &inv) if err != nil { t.Fatalf("failed to enrich: %v", err) diff --git a/extractor/filesystem/language/java/pomxmlnet/pomxmlnet.go b/extractor/filesystem/language/java/pomxmlnet/pomxmlnet.go index d64a6c8f1..d43cca960 100644 --- a/extractor/filesystem/language/java/pomxmlnet/pomxmlnet.go +++ b/extractor/filesystem/language/java/pomxmlnet/pomxmlnet.go @@ -26,6 +26,7 @@ import ( "deps.dev/util/maven" "deps.dev/util/resolve" mavenresolve "deps.dev/util/resolve/maven" + cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" "github.com/google/osv-scalibr/clients/datasource" "github.com/google/osv-scalibr/clients/resolution" "github.com/google/osv-scalibr/extractor" @@ -44,47 +45,31 @@ const ( // Extractor extracts Maven packages with transitive dependency resolution. type Extractor struct { - depClient resolve.Client + DepClient resolve.Client MavenClient *datasource.MavenRegistryAPIClient } -// Config is the configuration for the pomxmlnet Extractor. -type Config struct { - *datasource.MavenRegistryAPIClient - - DependencyClient resolve.Client -} +// New makes a new pom.xml transitive extractor with the given config. +func New(cfg *cpb.PluginConfig) filesystem.Extractor { + upstreamRegistry := "" + specific := plugin.FindConfig(cfg, func(c *cpb.PluginSpecificConfig) *cpb.POMXMLNetConfig { return c.GetPomXmlNet() }) + if specific != nil { + upstreamRegistry = specific.UpstreamRegistry + } -// NewConfig returns the configuration given the URL of the Maven registry to fetch metadata. -func NewConfig(remote, local string, disableGoogleAuth bool) Config { // No need to check errors since we are using the default Maven Central URL. mavenClient, _ := datasource.NewMavenRegistryAPIClient(context.Background(), datasource.MavenRegistry{ - URL: remote, + URL: upstreamRegistry, ReleasesEnabled: true, - }, local, disableGoogleAuth) + }, cfg.LocalRegistry, cfg.DisableGoogleAuth) depClient := resolution.NewMavenRegistryClientWithAPI(mavenClient) - return Config{ - DependencyClient: depClient, - MavenRegistryAPIClient: mavenClient, - } -} - -// DefaultConfig returns the default configuration for the pomxmlnet extractor. -func DefaultConfig() Config { - return NewConfig("", "", false) -} -// New makes a new pom.xml transitive extractor with the given config. -func New(c Config) *Extractor { return &Extractor{ - depClient: c.DependencyClient, - MavenClient: c.MavenRegistryAPIClient, + DepClient: depClient, + MavenClient: mavenClient, } } -// NewDefault returns an extractor with the default config settings. -func NewDefault() filesystem.Extractor { return New(DefaultConfig()) } - // Name of the extractor. func (e Extractor) Name() string { return Name } @@ -156,14 +141,14 @@ func (e Extractor) Extract(ctx context.Context, input *filesystem.ScanInput) (in for i, reg := range registries { clientRegs[i] = reg } - if cl, ok := e.depClient.(resolution.ClientWithRegistries); ok { + if cl, ok := e.DepClient.(resolution.ClientWithRegistries); ok { if err := cl.AddRegistries(ctx, clientRegs); err != nil { return inventory.Inventory{}, err } } } - overrideClient := resolution.NewOverrideClient(e.depClient) + overrideClient := resolution.NewOverrideClient(e.DepClient) resolver := mavenresolve.NewResolver(overrideClient) // Resolve the dependencies. diff --git a/extractor/filesystem/language/java/pomxmlnet/pomxmlnet_test.go b/extractor/filesystem/language/java/pomxmlnet/pomxmlnet_test.go index 44a2575aa..01e80a610 100644 --- a/extractor/filesystem/language/java/pomxmlnet/pomxmlnet_test.go +++ b/extractor/filesystem/language/java/pomxmlnet/pomxmlnet_test.go @@ -19,6 +19,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + cpb "github.com/google/osv-scalibr/binary/proto/config_go_proto" "github.com/google/osv-scalibr/clients/clienttest" "github.com/google/osv-scalibr/clients/datasource" "github.com/google/osv-scalibr/extractor" @@ -339,10 +340,8 @@ func TestExtractor_Extract(t *testing.T) { for _, tt := range tests { t.Run(tt.Name, func(t *testing.T) { resolutionClient := clienttest.NewMockResolutionClient(t, "testdata/universe/basic-universe.yaml") - extr := pomxmlnet.New(pomxmlnet.Config{ - DependencyClient: resolutionClient, - MavenRegistryAPIClient: &datasource.MavenRegistryAPIClient{}, - }) + extr := pomxmlnet.New(&cpb.PluginConfig{}) + extr.(*pomxmlnet.Extractor).DepClient = resolutionClient scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) defer extracttest.CloseTestScanInput(t, scanInput) @@ -484,10 +483,9 @@ func TestExtractor_Extract_WithMockServer(t *testing.T) { } resolutionClient := clienttest.NewMockResolutionClient(t, "testdata/universe/basic-universe.yaml") - extr := pomxmlnet.New(pomxmlnet.Config{ - DependencyClient: resolutionClient, - MavenRegistryAPIClient: apiClient, - }) + extr := pomxmlnet.New(&cpb.PluginConfig{}) + extr.(*pomxmlnet.Extractor).DepClient = resolutionClient + extr.(*pomxmlnet.Extractor).MavenClient = apiClient scanInput := extracttest.GenerateScanInputMock(t, tt.InputConfig) defer extracttest.CloseTestScanInput(t, scanInput) diff --git a/extractor/filesystem/list/list.go b/extractor/filesystem/list/list.go index 451e6ea4b..25db3dacf 100644 --- a/extractor/filesystem/list/list.go +++ b/extractor/filesystem/list/list.go @@ -153,7 +153,7 @@ var ( gradleverificationmetadataxml.Name: {noCFG(gradleverificationmetadataxml.New)}, // pom.xml extraction for environments with and without network access. pomxml.Name: {noCFG(pomxml.New)}, - pomxmlnet.Name: {noCFG(pomxmlnet.NewDefault)}, + pomxmlnet.Name: {pomxmlnet.New}, } // JavaArtifact extractors for Java. JavaArtifact = InitMap{