本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
插件 API 参考
Inspector-sbomgen Lua 插件的完整 API 参考。有关编写插件的指南,请参阅插件开发者指南。有关测试的信息,请参阅插件测试指南。
概述
运行时提供的所有函数均可通过全局sbomgen表(文件 I/O、正则表达式、日志记录、常量等)进行访问。此外,每个插件都定义了一小部分顶级全局函数(discover、、collectget_scanner_namesubscribe_to_event、等),sbomgen 在插件生命周期的定义时刻调用这些函数。这些记录在插件生命周期全局变量。
在*_test.lua文件中,sbomgen 还公开了一个testing全局变量,允许测试作者驱动发现→集合管道并做出断言。请参阅正在测试 API。
沙盒限制
插件在沙箱 Lua 虚拟机中运行,标准库访问受限。有以下 Lua 标准库模块可用:
| 模块 | 备注 |
|---|---|
base |
核心功能(print、type、tostring、tonumber、pairs、ipairs、pcall、、error、select、unpack、rawget、rawset、、等)。 dofile、loadfile、和已loadstring被移除。 |
string |
全字符串操作(string.matchstring.find、string.format、string.gsub、等) |
table |
全表操作(table.inserttable.remove、table.sort、table.concat、等) |
math |
完整的数学库(math.floormath.maxmath.min、、等) |
package |
require()可用,但仅限于插件自己的目录树中的模块。父目录遍历 () require("../shared") 已被阻止。 package.cpath并package.path被清除。 |
出于安全性和稳定性考虑,明确禁止使用以下标准库模块:
| 模块 | 原因 |
|---|---|
io |
直接文件系统访问已被阻止。所有文件操作都必须通过sbomgen.*函数,这些函数通过构件接口进行路由,以实现跨对象类型(目录、容器、卷等)的一致行为。 |
os |
系统级操作(os.execute、os.remove、os.renameos.getenv、等)被阻止,以防止插件修改主机系统。 |
debug |
阻止调试库是为了防止检查或修改 Lua VM 内部结构。 |
coroutine |
协程未加载。 |
这些模块不在虚拟机的许可名单中,也无法通过插件访问。
注意
重要:所有文件都 I/O 必须经过sbomgen.*函数(例如sbomgen.read_file、sbomgen.open_file、sbomgen.get_file_list)。使用io.open或任何直接访问文件系统都会引发运行时错误。sbomgenAPI 可确保插件与构件抽象层交互,无论是扫描目录、容器映像、档案还是卷,工件抽象层都能提供一致的行为。
插件生命周期全局变量
插件是一个名为 Lua 的文件init.lua,它定义了某些顶级全局函数。这些全局变量不在sbomgen桌面上——它们是插件定义的函数,供sbomgen调用。发现插件和集合插件的有效全局变量集不同。对于下面的每个函数,如果插件省略了该函数,则使用表格中显示的默认值。
发现插件
| 函数 | 阿里 | 必填 | 默认(省略时) | 描述 |
|---|---|---|---|---|
discover() |
0 | 是 | — | 返回此插件找到的文件。返回路径字符串的顺序表(单事件模式)或由事件名称字符串键控的表,其值为路径表(多事件模式)。 |
get_event_name() |
0 | 否 | "lua:{platform}/{category}/{ecosystem}" |
返回发布文件所依据的事件名称。在所有发现插件中必须是唯一的。 |
get_scanner_name() |
0 | 否 | 生态系统目录名称 | 返回扫描仪的显示名称。在所有发现插件中必须是唯一的。 |
get_scanner_description() |
0 | 否 | "Lua discovery plugin: {ecosystem}" |
返回人类可读的描述。 |
get_scanner_groups() |
0 | 否 | 源自类别目录(参见开发者指南) | 返回扫描仪组字符串表。使用sbomgen.groups.*常量。 |
get_localhost_scan_paths() |
0 | 否 | — | 返回扫描本地主机构件时要包含的 file/directory 路径表。仅在localhost扫描时咨询。 |
集合插件
| 函数 | 阿里 | 必填 | 默认(省略时) | 描述 |
|---|---|---|---|---|
collect(file_path) |
1 | 是 | — | 每个发布到已订阅事件的文件都调用一次。解析文件并通过发送调查结果。sbomgen.push_package()不返回任何内容。 |
subscribe_to_event() |
0 | 否 | "lua:{platform}/{category}/{ecosystem}" |
返回该收集器订阅的事件名称。应与相应的发现插件相匹配get_event_name()。 |
get_collector_name() |
0 | 否 | 生态系统目录名称 | 返回收藏家的显示名称。在所有集合插件中必须是唯一的。 |
get_collector_description() |
0 | 否 | ""(空) |
返回人类可读的描述。 |
文件 I/O
所有文件操作都必须通过 sbomgen.* API 进行。无法通过 Lua 的io库直接访问文件系统(请参阅沙盒限制)。sbomgen文件 I/O 函数通过工件接口进行路由,确保您的插件无论是扫描磁盘上的目录、容器映像、压缩存档还是已装入的卷,都能以相同的方式工作。
sbomgen.get_file_list()
以字符串表的形式返回构件中的所有文件路径。
-
返回:
{string, ...}— 绝对文件路径字符串表 -
性能:此函数将构件中的每个文件路径都作为 Lua 字符串复制到 Lua VM 中。对于大型工件(例如,包含30万多个文件的本地主机扫描),仅此一项就需要几秒钟。在 Lua 中迭代返回的表
string.match()会增加更多的开销——完整扫描可能需要 15 秒以上。工件中的文件越多,插件的速度就越慢。
注意
尽可能首选以下有针对性的替代方案:
| 函数 | 在... 时使用 |
|---|---|
sbomgen.find_files_by_name() |
你知道要匹配的确切文件名(例如,"requirements.txt","curl") |
sbomgen.find_files_by_name_icase() |
同上,但不区分大小写 |
sbomgen.find_files_by_suffix() |
你需要匹配路径后缀(例如,,"/pom.properties")"curlver.h" |
sbomgen.find_files_by_path_regex() |
你需要全路径正则表达式匹配 |
sbomgen.glob_find_files() |
你需要全局风格的基本名称匹配 |
这些函数在 Lua VM 之外执行匹配,仅返回匹配的路径,即使在 300K 文件工件上也能在 1 毫秒内完成。get_file_list()仅当您的匹配逻辑无法用上述任何一种表达时才使用。
-- AVOID in discovery plugins when possible: local files = sbomgen.get_file_list() for _, f in ipairs(files) do if string.match(f, "pattern$") then ... end end -- PREFER: local matches = sbomgen.find_files_by_name({"target-file.txt"})
sbomgen.read_file(path)
读取文件的全部内容并将其作为字符串返回。
-
退货:
string, err -
失败时:
nil, error_string
local content, err = sbomgen.read_file("/app/package.json") if err then sbomgen.log_error("read failed: " .. err) return end
sbomgen.open_file(path)
打开文件进行流式读取。返回一个 FileHandle 对象。对于不切实际地将全部内容加载到内存中的大型文件,请使用此选项。
-
退货:
FileHandle, err
local fh, err = sbomgen.open_file(path) if err then return end local line = fh:read_line() while line do -- process line line = fh:read_line() end fh:close()
sbomgen.glob_find_files(pattern)
返回与 filepath.Match Go glob 模式匹配的文件。该模式与基本文件名相匹配。
-
退货:
{string, ...}, err
local files, err = sbomgen.glob_find_files("*.txt")
sbomgen.get_file_list()与一起使用string.match可进行完整路径模式匹配。
sbomgen.find_files_by_name(names)
返回其基本名称(最后一个路径组件)与给定名称之一完全匹配的文件。迭代和比较发生在 Go 中,这使得迭代和比较比在 Lua sbomgen.get_file_list() 中迭代要快得多。
-
参数:
names— 字符串表(要匹配的基本名称) -
返回:
{string, ...}— 匹配的文件路径(无错误元组)
local curl_bins = sbomgen.find_files_by_name({"curl", "curl.exe"}) local headers = sbomgen.find_files_by_name({"curlver.h"})
sbomgen.find_files_by_name_icase(names)
返回基本名称与给定名称之一匹配的文件,忽略大小写。例如,"version"匹配VERSIONVersion、和version。比如find_files_by_name,匹配发生在 Lua 虚拟机之外。
-
参数:
names— 字符串表(要匹配的基本名称,不区分大小写) -
返回:
{string, ...}— 匹配的文件路径(无错误元组)
local version_files = sbomgen.find_files_by_name_icase({"version"}) local war_files = sbomgen.find_files_by_name_icase({"jenkins.war"})
sbomgen.find_files_by_suffix(suffixes)
返回其完整 (forward-slash-normalized) 路径以给定后缀之一结尾的文件。比如find_files_by_name,匹配发生在 Lua 虚拟机之外。
-
参数:
suffixes— 字符串表(要匹配的路径后缀) -
返回:
{string, ...}— 匹配的文件路径(无错误元组)
local pom_files = sbomgen.find_files_by_suffix({"/pom.properties"}) local release_headers = sbomgen.find_files_by_suffix({"ap_release.h", "opensslv.h"})
sbomgen.find_files_by_path_regex(patterns)
返回 forward-slash-normalized路径与任何给定 Go (RE2) 正则表达式模式匹配的文件。匹配发生在 Lua VM 之外,这使得在大文件列表上更有效率。
-
参数:
patterns— Go 正则表达式字符串表 -
返回:
{string, ...}— 匹配的文件路径(无错误元组) -
引发:如果任何模式无法编译,则会出现 Lua 错误
local configs = sbomgen.find_files_by_path_regex({"/etc/.*\\.conf$", "/opt/.*/config\\.json$"})
性能:find_files_by_*vs get_file_list
对于发现插件,最好使用find_files_by_namefind_files_by_suffix、或find_files_by_path_regex而不是get_file_list()在 Lua 中进行迭代。在包含 30 万个文件的本地主机扫描中,在 Lua 中迭代文件列表大约需要 15 string.match() 秒,而在 1 毫秒内find_files_by_name完成。不同之处在于,将每个文件路径作为字符串get_file_list()复制到 Lua VM 中,然后 Lua 解释每个路径的循环和模式匹配。这些find_files_by_*函数在 Lua VM 之外执行匹配并仅返回匹配的路径,从而避免了复制和每个路径的解释开销。
get_file_list()仅当您需要无法用基本名称、后缀或正则表达式匹配表示的自定义匹配逻辑时才使用。
sbomgen.read_dir(path)
列出目录中的条目。
-
退货:
{{name, is_dir}, ...}, err
local entries, err = sbomgen.read_dir("/app/node_modules") if err then return end for _, e in ipairs(entries) do if e.is_dir then sbomgen.log_debug("directory: " .. e.name) end end
sbomgen.file_stat(path)
返回有关文件的元数据。
-
退货:
{is_regular, is_dir, size}, err
local info, err = sbomgen.file_stat(path) if err then return end if info.is_regular and info.size > 0 then -- process file end
sbomgen.read_zip_entry(path, entry_path)
从 ZIP、JAR 或 WAR 存档中读取单个条目。
-
退货:
string, err
local manifest, err = sbomgen.read_zip_entry( "/app/lib/example.jar", "META-INF/MANIFEST.MF" )
sbomgen.search_binary(path, regex)
将文件解析为 ELF、PE 或 Mach-O 二进制文件,然后在默认 constant/variable 部分中搜索 Go 正则表达式匹配项。
-
返回:
string|nil, err— 匹配的字符串,如果不匹配则返回 nil
local version, err = sbomgen.search_binary(path, "Version:\\s+([\\d.]+)") if version then sbomgen.log_info("found version: " .. version) end
sbomgen.search_binary_all(path, regex [, n])
将文件解析为 ELF、PE 或 Mach-O 二进制文件,并返回默认部分中所有唯一的第一个捕获组匹配项。 constant/variable 通过n以限制结果。
-
返回:
{string, ...}|nil, err— 匹配字符串表,如果没有匹配项,则返回 nil
local versions, err = sbomgen.search_binary_all(path, "version[= ]+([\\d.]+)", 5) if versions then for _, v in ipairs(versions) do sbomgen.log_info("found: " .. v) end end
sbomgen.search_binary_raw(path, regex)
在整个二进制文件中搜索第一个正则表达式匹配项,而不限于特定部分。在基于节的搜索 (search_binary) 不足时使用,例如,当版本字符串位于非标准部分时。
-
返回:
string|nil, err— 匹配的字符串,如果不匹配则返回 nil
local version, err = sbomgen.search_binary_raw(path, "ProductVersion[\\x00\\s]+([\\d.]+)")
FileHandle 方法
FileHandle 对象由返回sbomgen.open_file()。
fh:read_line()
读取下一行(不含换行符)。nil在 EOF 时返回。
-
退货:
string|nil, err
fh:read(n)
读取最多n字节。nil在 EOF 时返回。
-
退货:
string|nil, err
fh:close()
关闭文件句柄。完成后请务必关闭手柄。
二进制实用程序
sbomgen.sha256(path)
返回文件内容的十六进制编码 SHA-256 哈希值。
-
退货:
string, err
local hash, err = sbomgen.sha256("/app/bin/server") if hash then sbomgen.log_info("SHA-256: " .. hash) end
sbomgen.contains_bytes(path, patterns)
检查文件是否包含每个给定的字节模式。按与输入模式相同的顺序返回布尔值表。
-
退货:
{bool, ...}, err
local results, err = sbomgen.contains_bytes(path, { "\xff Go buildinf:", -- Go build identifier "/rustc/", -- Rust build identifier }) if results then local is_go = results[1] local is_rust = results[2] end
sbomgen.get_pe_version_info(path)
从二进制文件中解析 Windows PE 版本资源。返回包含版本字段的表,或者nil, err如果该文件不是 PE 二进制文件或没有版本资源。
-
退货:
{product_version, file_version, string_table}, err
product_version和file_version字段来自 PE FixedFileInfo 结构,格式为"major.minor.build.revision"。该string_table字段是一个由区域代码键控的嵌套表(例如,"040904B0"对于美国英语 Unicode)。每个语言环境都映射到从 PE 中抽取的 name/value 对表StringFileInfo(ProductVersionProductNameFileDescription、、等)。PE 二进制文件可能会暴露一个或多个语言环境。
local info, err = sbomgen.get_pe_version_info(file_path) if err then return end -- Fixed version fields (always flat) local product_ver = info.product_version -- e.g. "25.1.0.0" local file_ver = info.file_version -- e.g. "25.1.0.0" -- String table — iterate locales, or address a known locale by key for locale, fields in pairs(info.string_table or {}) do sbomgen.log_info(string.format("%s ProductName=%s", locale, fields.ProductName or "")) end -- US English Unicode is the most common locale for PE files local us = (info.string_table or {})["040904B0"] if us then local display_ver = us.ProductVersion -- e.g. "25.01" local name = us.ProductName -- e.g. "7-Zip" end
sbomgen.parse_product_version(path)
便捷包装器,仅返回 PE 二进制文件中的产品版本字符串。 FixedFileInfo相当于打电话get_pe_version_info(path)和读书product_version。
-
退货:
string, err
local version, err = sbomgen.parse_product_version(file_path) if version then sbomgen.log_info("product version: " .. version) end
sbomgen.parse_file_version(path)
便捷包装器,仅返回 PE 二进制文件中的文件版本字符串。 FixedFileInfo相当于打电话get_pe_version_info(path)和读书file_version。
-
退货:
string, err
local version, err = sbomgen.parse_file_version(file_path) if version then sbomgen.log_info("file version: " .. version) end
Package 输出
sbomgen.push_package(pkg)
将软件包查找结果推送到 SBOM 中。仅在集合插件中可用。
该pkg表支持以下字段:
| 字段 | Type | 必填 | 描述 |
|---|---|---|---|
name |
字符串 | 是 | 软件包名称 |
version |
字符串 | 否 | 已解析的版本字符串 |
namespace |
字符串 | 否 | PURL 命名空间(例如,"curl","wordpress/plugin") |
purl_type |
字符串 | 是 | PURL 类型(例如、"pypi"、、"npm"、"cargo""deb"、"generic") |
component_type |
字符串 | 是 | CycloneDX 组件类型;使用sbomgen.component_types.*常量(例如)sbomgen.component_types.LIBRARY |
qualifiers |
表 | 否 | PURL 限定符作为键值对(出现在软件包 URL 中) |
properties |
表 | 否 | CycloneDX 组件属性作为键值对(参见)CycloneDX 属性 |
children |
表 | 否 | 嵌套子包,每个子包的形状都与pkg(递归验证必填字段) |
sbomgen.push_package({ name = "requests", version = "2.28.1", purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, qualifiers = { example_qualifier = "example_qualifier_value" }, properties = { -- Use your own namespace; amazon:inspector:* is reserved for Amazon Inspector. ["acme:example:extra_field"] = "example_value", }, })
CycloneDX 属性
CycloneDX 属性是附加到 SBOM 中组件的键值元数据。它们不同于 PURL 预选赛:
-
qualifiers— PURL 预选赛。它们成为软件包 URL 字符串的一部分(例如pkg:deb/debian/curl@7.88.1?arch=amd64)。一些 PURL 限定符对 Amazon Inspector 具有语义意义,会影响漏洞识别。请参阅什么是包裹 URL? 了解检查员的每种类型的惯例。 -
properties— CycloneDX 组件属性。它们显示在 SBOM 的components[].properties数组中,不会更改组件的标识方式。
保留的命名空间
CycloneDX 属性命名空间amazon:inspector:*系列是为 Amazon Inspector 保留的:
-
amazon:inspector:sbom_generator:*— 由 sbomgen 及其内置扫描仪使用。 -
amazon:inspector:sbom_scanner:*— 由 Amazon Inspector Scan API 使用。
插件定义的属性不得使用这些命名空间。写入保留的命名空间可能会与 Inspector 所依赖的值发生阴影或冲突,并且在漏洞识别过程中可能会错误地解释生成的 SBOM。有关保留密钥的完整列表,请参阅在 Amazon Inspector 中使用 CycloneDX 命名空间。
密钥命名规则
传递给的属性键sbomgen.push_package()的处理方式如下:
| 输入键 | SBOM 中生成的密钥 | 推荐用于自定义插件? |
|---|---|---|
包含:(例如,acme:my_plugin:field) |
逐字使用 | 是 — 将所有插件定义的属性放在你自己的命名空间中 |
否:(例如,field) |
自动添加前缀为 amazon:inspector:sbom_generator:field |
不是 — 这会写入保留的命名空间 |
请务必在您定义的属性键中至少包含一个冒号。使用您的组织或插件独有的命名空间(例如acme:python-pip:*):
properties = { -- Custom namespace — safe to use (recommended) ["acme:python-pip:manifest_path"] = file_path, ["acme:python-pip:pinned"] = "true", -- Fully-qualified key outside amazon:inspector:* — also fine ["my:custom:namespace:key"] = "value", -- No colon: avoid — ends up as "amazon:inspector:sbom_generator:custom_field" -- custom_field = "value", }
由 sbomgen 设置的属性
Sbomgen 可以将自己的属性附加到它发出的每个组件上。这些值来自保留的amazon:inspector:sbom_generator:*命名空间,不应由插件生成。观察到的运行时行为:
-
source_path总是由 sbomgen 添加的。 -
source_file_scanner并在启用source_package_collector--enable-debug-props时添加。
Amazon Inspector 用户指南:将 Cy cloneDX 命名空间与 Amazon Inspector 一起使用。
属性常量
内置的属性键常量可通过sbomgen.properties获得。下面的每个常量都解析为保留amazon:inspector:sbom_generator:*命名空间内的一个密钥。这些常量的存在是为了让 sbomgen 的内置扫描器发出一致的属性键。它们不是自定义插件的扩展点——在自定义插件中使用它们会写入保留的命名空间,而 Inspector 可以依赖这些值。见保留的命名空间上文。
例如acme:my_plugin:*,自定义插件作者应在自己的命名空间下定义属性,而不是重复使用这些常量。
| 常量 | 已解析值 |
|---|---|
sbomgen.properties.NAMESPACE |
amazon:inspector:sbom_generator: |
sbomgen.properties.VENDOR |
amazon:inspector:sbom_generator:vendor |
sbomgen.properties.FILE_SIZE_BYTES |
amazon:inspector:sbom_generator:file_size_bytes |
sbomgen.properties.KERNEL_COMPONENT |
amazon:inspector:sbom_generator:kernel_component |
sbomgen.properties.RUNNING_KERNEL |
amazon:inspector:sbom_generator:running_kernel |
sbomgen.properties.UNRESOLVED_VERSION |
amazon:inspector:sbom_generator:unresolved_version |
sbomgen.properties.TRANSITIVE_DEPENDENCY |
amazon:inspector:sbom_generator:experimental:transitive_dependency |
sbomgen.properties.GO_REPLACE_DIRECTIVE |
amazon:inspector:sbom_generator:replaced_by |
sbomgen.properties.DUPLICATE_PACKAGE |
amazon:inspector:sbom_generator:is_duplicate_package |
sbomgen.properties.DUPLICATE_PURL |
amazon:inspector:sbom_generator:duplicate_purl |
sbomgen.properties.DOCKERFILE_CHECK |
amazon:inspector:sbom_generator:dockerfile_finding |
sbomgen.properties.CERTIFICATE_FINDING |
amazon:inspector:sbom_generator:certificate_finding |
sbomgen.properties.CERTIFICATE_SUBJECT_NAME |
amazon:inspector:sbom_generator:certificate:subject_name |
sbomgen.properties.CERTIFICATE_ISSUER_NAME |
amazon:inspector:sbom_generator:certificate:issuer_name |
sbomgen.properties.CERTIFICATE_SIGNATURE_ALGORITHM |
amazon:inspector:sbom_generator:certificate:signature_algorithm |
sbomgen.properties.CERTIFICATE_NOT_VALID_BEFORE |
amazon:inspector:sbom_generator:certificate:not_valid_before |
sbomgen.properties.CERTIFICATE_NOT_VALID_AFTER |
amazon:inspector:sbom_generator:certificate:not_valid_after |
sbomgen.properties.WINDOWS_REGISTRY_KEY |
amazon:inspector:sbom_generator:registry_key |
sbomgen.properties.SUBSCRIPTION_ENABLED |
amazon:inspector:sbom_generator:subscription:enabled |
sbomgen.properties.SUBSCRIPTION_NAME |
amazon:inspector:sbom_generator:subscription:name |
sbomgen.properties.SUBSCRIPTION_LOCKED_VERSION |
amazon:inspector:sbom_generator:subscription:locked_version |
sbomgen.properties.OPENSSL_FULL_VERSION |
amazon:inspector:sbom_generator:openssl:full_version |
sbomgen.properties.HARDENED_IMAGE_VENDOR |
amazon:inspector:sbom_generator:hardened_image:vendor |
扫描仪组
发现插件必须通过声明其扫描器组get_scanner_groups()。群组对扫描仪进行分类,并允许用户有选择地启用或禁用类别。常量可通过以下方式sbomgen.groups获得:
| 常量 | 值 | 描述 |
|---|---|---|
sbomgen.groups.OS |
"os" |
操作系统包管理器(dpkg、rpm 等) |
sbomgen.groups.PROGRAMMING_LANGUAGE |
"programming-language-packages" |
语言包管理器(pip、npm、maven 等) |
sbomgen.groups.BINARY |
"binary" |
编译后的二进制分析(Go、Rust) |
sbomgen.groups.PACKAGE_COLLECTOR |
"pkg-scanner" |
一般包裹集合 |
sbomgen.groups.EXTRA_ECOSYSTEMS |
"extra-ecosystems" |
其他生态系统(curl、nginx 等) |
sbomgen.groups.CERTIFICATE |
"certificate" |
证书扫描 |
sbomgen.groups.CUSTOM |
"custom" |
自动添加到通过加载的所有自定义插件中 --plugin-dir |
sbomgen.groups.MACHINE_LEARNING |
"machine-learning" |
机器学习模型检测 |
示例:
function get_scanner_groups() return {sbomgen.groups.PROGRAMMING_LANGUAGE, sbomgen.groups.PACKAGE_COLLECTOR} end
组件类型常量
中的component_type字段push_package()必须是 CycloneDX 1.5 组件类型之一。常量可通过以下方式sbomgen.component_types获得:
| 常量 | 值 |
|---|---|
sbomgen.component_types.APPLICATION |
"application" |
sbomgen.component_types.FRAMEWORK |
"framework" |
sbomgen.component_types.LIBRARY |
"library" |
sbomgen.component_types.CONTAINER |
"container" |
sbomgen.component_types.PLATFORM |
"platform" |
sbomgen.component_types.OPERATING_SYSTEM |
"operating-system" |
sbomgen.component_types.DEVICE |
"device" |
sbomgen.component_types.DEVICE_DRIVER |
"device-driver" |
sbomgen.component_types.FIRMWARE |
"firmware" |
sbomgen.component_types.FILE |
"file" |
sbomgen.component_types.MACHINE_LEARNING_MODEL |
"machine-learning-model" |
sbomgen.component_types.DATA |
"data" |
示例:
sbomgen.push_package({ name = "requests", version = "2.28.1", purl_type = "pypi", component_type = sbomgen.component_types.LIBRARY, })
平台常量
用于比较sbomgen.get_platform()的常量。可通过sbomgen.platform以下方式获得:
| 常量 | 值 |
|---|---|
sbomgen.platform.LINUX |
"linux" |
sbomgen.platform.WINDOWS |
"windows" |
sbomgen.platform.DARWIN |
"darwin" |
示例:
if sbomgen.get_platform() == sbomgen.platform.WINDOWS then -- Windows-specific logic end
Artication
sbomgen.get_platform()
返回运行时平台字符串(例如"linux"、"windows"、"darwin")。
sbomgen.get_artifact_type()
返回正在扫描的工件的类型(例如"directory","archive")。
sbomgen.should_collect_licenses()
true如果用户通过启用了许可证收集,则返回--collect-licenses。
sbomgen.get_env_vars()
以{key, value}条目表的形式返回工件中的环境变量。
local env_vars = sbomgen.get_env_vars() for _, env in ipairs(env_vars) do if env.key == "NODE_ENV" then sbomgen.log_info("Node environment: " .. env.value) end end
sbomgen.get_system_drive()
从构件的环境中返回系统驱动器号(例如"C:")。读取SystemDrive环境变量,"C:"如果未设置,则默认为。这相当于 Lua。strutils.GetSystemDriverLetter()
local drive = sbomgen.get_system_drive() local program_files = drive .. "/Program Files/"
系统信息
这些函数返回有关工件操作系统和硬件的元数据。如果信息不可用(例如,扫描没有操作系统元数据的目录时),则值可能为空字符串。
| 函数 | 返回值 |
|---|---|
sbomgen.get_os_name() |
操作系统名称(例如"Ubuntu"、"Alpine Linux") |
sbomgen.get_os_version() |
操作系统版本(例如,"22.04","3.18") |
sbomgen.get_os_codename() |
操作系统代号(例如,,"jammy")"bookworm" |
sbomgen.get_os_id() |
操作系统标识符(例如"ubuntu","alpine") |
sbomgen.get_kernel_name() |
内核名称(例如"Linux") |
sbomgen.get_kernel_version() |
内核版本字符串 |
sbomgen.get_cpu_arch() |
CPU 架构(例如,"x86_64","aarch64") |
sbomgen.get_hostname() |
系统的主机名 |
正则表达式
Lua 的内置模式缺少交替 (|)、量词范围 ({n,}) 和前瞻等功能。为了缩小这一差距,sbomgen 直接暴露了 Go 的软件包。regexp这些函数使用 Go 正则表达式语法 (RE2),而不是 Lua 模式。
sbomgen.regex_find(str, pattern)
返回 Go 正则表达式模式的第一个匹配项,或者nil如果没有匹配则返回。
-
退货:
string|nil, err
local version = sbomgen.regex_find(content, "\\d+\\.\\d+\\.\\d+")
sbomgen.regex_match(str, pattern)
返回第一个匹配的捕获组。索引 1 为完整匹配,2+ 为捕获组。
-
退货:
{string, ...}|nil, err
local groups = sbomgen.regex_match(content, "(MySQL|MariaDB) (\\d+)\\.(\\d+)\\.(\\d+)") if groups then local db_type = groups[2] -- "MySQL" or "MariaDB" local major = groups[3] end
sbomgen.regex_find_all(str, pattern [, n])
返回所有不重叠的匹配项。通过n以限制结果(默认值:全部)。
-
退货:
{string, ...}|nil, err
local versions = sbomgen.regex_find_all(content, "\\d+\\.\\d+\\.\\d+")
sbomgen.regex_replace(str, pattern, replacement)
替换所有匹配项。替换字符串可以使用$1$2、等作为捕获组引用。
-
退货:
string, err
local cleaned = sbomgen.regex_replace(raw_version, "(1[6-9]\\d{8,}|buildkitsandbox.*)$", "")
何时使用正则表达式与 Lua 模式
使用 Lua 的内置 string.match /来string.find制作简单的模式 — 它们速度更快,不需要转义反斜杠。需要sbomgen.regex_*时使用:
-
交替:
(foo|bar) -
量词范围:
\d{8,} -
复杂的字符类无法在 Lua 模式中表达
结构化解析
Sbomgen 公开了用于将结构化文本格式直接解码为 Lua 表的轻量级助手。
sbomgen.json_decode(str)
将 JSON 字符串解析为 Lua 表。
-
退货:
table|nil, err
local doc, err = sbomgen.json_decode('{"name":"requests","version":"2.28.1"}') if err then return end sbomgen.log_info(doc.name)
sbomgen.xml_decode(str)
将 XML 字符串解析为 Lua 表。
-
退货:
table|nil, err
XML 值使用以下形状:
-
_name— 元素名称 -
_attr— 属性表(如果存在) -
_text— 修剪后的文本内容(如果存在) -
数字索引
1..n-子元素
local doc, err = sbomgen.xml_decode('<package id="Newtonsoft.Json" version="13.0.3" />') if err then return end sbomgen.log_info(doc._attr.id)
Windows 注册表
这些函数提供对 Windows 注册表的只读访问权限。在非 Windows 构件上,registry_open_key返回错误。注册表访问器在首次使用时会延迟初始化,并且支持实时 Windows API 访问(在 Windows 上进行本地主机扫描)和基于文件的 REGF 配置单元解析(容器/卷扫描)。
sbomgen.registry_open_key(path)
打开注册表项。返回必须用其关闭的密钥手柄registry_close。
-
退货:
key, err
local key, err = sbomgen.registry_open_key("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\7-Zip") if err then return end -- use key... sbomgen.registry_close(key)
sbomgen.registry_get_string(key, value_name)
从打开的注册表项中读取字符串值。
-
退货:
string, err
local version, err = sbomgen.registry_get_string(key, "DisplayVersion")
sbomgen.registry_get_integer(key, value_name)
从打开的注册表项中读取整数值。
-
退货:
number, err
sbomgen.registry_get_strings(key, value_name)
从打开的注册表项中读取多字符串 (REG_MULTI_SZ) 值。返回字符串表。
-
退货:
{string, ...}, err
local paths, err = sbomgen.registry_get_strings(key, "DependsOnService") if paths then for _, p in ipairs(paths) do sbomgen.log_info("depends on: " .. p) end end
sbomgen.registry_get_subkeys(key)
返回打开的注册表项下的所有子项名称。
-
退货:
{string, ...}, err
local subkeys, err = sbomgen.registry_get_subkeys(key) for _, name in ipairs(subkeys) do local subkey, err = sbomgen.registry_open_key(parent_path .. "\\" .. name) -- ... end
sbomgen.registry_close(key)
关闭注册表项句柄。垃圾回收器也会自动关闭密钥句柄,但建议明确关闭。
日志记录
日志消息将写入 sbomgen 的控制台输出中。插件发出的每条消息都会自动以插件的源标签和生态系统为前缀,例如:
[custom:python-pip] Parsing requirements.txt
log_info、log_warn,并log_error始终打印。 log_debug仅在使用调用 sbomgen 时才会打印。--verbose
| 函数 | 级别 | 默认情况下可见? |
|---|---|---|
sbomgen.log_debug(message) |
调试 | 否 — 需要 --verbose |
sbomgen.log_info(message) |
INFO | 是 |
sbomgen.log_warn(message) |
警告 | 是 |
sbomgen.log_error(message) |
ERROR | 是 |
string.format用于格式化消息:
sbomgen.log_info(string.format("found %d packages in %s", count, file_path))
调试函数
sbomgen.breakpoint(message)
打印message到 stderr 并阻止执行,直到用户按下 Enter。如果省略,message则打印一条默认消息。
将其用作粗略的调试器,方法是在插件的关键点放置断点,然后运行--verbose以查看周围的日志输出。
sbomgen.log_info("state: " .. some_variable) sbomgen.breakpoint("paused after state dump — press Enter to continue")
正在测试 API
全局testing表下的函数仅在加载的插件测试文件 (*_test.lua) 中可用inspector-sbomgen plugin test。它们在运行时在发现或集合插件中不可用。完整的 sbomgen.* API 也可以在测试文件中找到,但是需要构件的sbomgen.*函数(例如sbomgen.read_file())只有在扫描内部调用时才会产生有意义的结果。有关叙事指南,请参阅插件测试指南。
扫描功能
每个扫描函数都会创建一个给定类型的工件,针对它运行当前插件的 discovery→collection 管道,然后返回结果结果。path参数是相对于测试文件的目录进行解析的。
| 函数 | Artical 那种 |
|---|---|
testing.scan_directory(path) |
目录 |
testing.scan_archive(path) |
目录(的别名scan_directory) |
testing.scan_localhost(path) |
本地主机 |
testing.scan_binary(path) |
二元 |
testing.scan_volume(path) |
卷 |
testing.scan_container(path) |
Container |
所有六个都返回一个结果表,其形状如下所示。
结果形状
每个查找结果表仅投影下面列出的字段。特别是,namespace并且purl_type不是单独投影的——它们被合并到完整的purl字符串中。
local result = testing.scan_directory("_testdata/example") -- result.findings -- array of finding tables -- result.findings[i].name -- string -- result.findings[i].version -- string -- result.findings[i].component_type -- string -- result.findings[i].purl -- string (the full Package URL, or "" if none) -- result.findings[i].properties -- table<string, string> -- result.findings[i].children -- array of finding tables (same shape, recursive)
断言
| 函数 | 签名 | 描述 |
|---|---|---|
testing.assert_equals |
(expected: any, actual: any, message?: string) |
如果出现则失败tostring(expected) ~= tostring(actual)。 |
testing.assert_not_equals |
(expected: any, actual: any, message?: string) |
如果出现则失败tostring(expected) == tostring(actual)。 |
testing.assert_true |
(value: any, message?: string) |
如果value为false或则失败nil。 |
testing.assert_false |
(value: any, message?: string) |
如果不valuefalse是,则失败nil。 |
testing.assert_nil |
(value: any, message?: string) |
如果不value是,则失败nil。 |
testing.assert_not_nil |
(value: any, message?: string) |
如果value是则失败nil。 |
testing.assert_contains |
(haystack: string, needle: string, message?: string) |
如果haystack不包含needle(子字符串匹配),则失败。 |
testing.assert_matches |
(str: string, pattern: string, message?: string) |
如果与给定的 Go (RE2) 正则表达式str不匹配,则失败。 |
testing.assert_length |
(tbl: table, expected: integer, message?: string) |
如果#tbl不等于,则失败expected。 |
控制流
| 函数 | 签名 | 描述 |
|---|---|---|
testing.fail |
(message: string) |
使用给定消息立即使当前测试失败。 |
testing.skip |
(message: string) |
跳过当前测试。结果被报告为已跳过,而不是失败。 |
测试发现
文件匹配test_中名称以开头的任何全局 Lua 函数*_test.lua都被视为测试。测试文件必须位于正常{phase}/{platform}/{category}/{ecosystem}/深度旁边。init.lua夹具数据位于测试文件_testdata/旁边,运行器在搜索测试文件_testdata/时不会进入测试文件。
错误处理
可能失败的 API 函数返回两个值:value, err. 成功时,err是nil。失败时,第一个值为nil且err为错误字符串。
local content, err = sbomgen.read_file(path) if err then sbomgen.log_error("failed to read " .. path .. ": " .. err) return end -- content is safe to use here
如果插件引发未处理的 Lua 错误,sbomgen 会记录警告,然后继续处理下一个文件或插件。其他插件不受影响。