diff --git a/providers/os/resources/os.lr b/providers/os/resources/os.lr index 3d9a358421..d06e8af58a 100644 --- a/providers/os/resources/os.lr +++ b/providers/os/resources/os.lr @@ -51,6 +51,11 @@ platform.eol @defaults("date") { date time } +platform { + // Full advisory & vulnerability report + vulnerabilityReport() dict +} + // Returns all platform/package advisories platform.advisories { []audit.advisory diff --git a/providers/os/resources/os.lr.go b/providers/os/resources/os.lr.go index 635341ff7b..969402c0e7 100644 --- a/providers/os/resources/os.lr.go +++ b/providers/os/resources/os.lr.go @@ -34,6 +34,10 @@ func init() { Init: initPlatformEol, Create: createPlatformEol, }, + "platform": { + // to override args, implement: initPlatform(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createPlatform, + }, "platform.advisories": { // to override args, implement: initPlatformAdvisories(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) Create: createPlatformAdvisories, @@ -496,6 +500,9 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "platform.eol.date": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlPlatformEol).GetDate()).ToDataRes(types.Time) }, + "platform.vulnerabilityReport": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlPlatform).GetVulnerabilityReport()).ToDataRes(types.Dict) + }, "platform.advisories.cvss": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlPlatformAdvisories).GetCvss()).ToDataRes(types.Resource("audit.cvss")) }, @@ -1956,6 +1963,14 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlPlatformEol).Date, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) return }, + "platform.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlPlatform).__id, ok = v.Value.(string) + return + }, + "platform.vulnerabilityReport": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlPlatform).VulnerabilityReport, ok = plugin.RawToTValue[interface{}](v.Value, v.Error) + return + }, "platform.advisories.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlPlatformAdvisories).__id, ok = v.Value.(string) return @@ -4415,6 +4430,52 @@ func (c *mqlPlatformEol) GetDate() *plugin.TValue[*time.Time] { return &c.Date } +// mqlPlatform for the platform resource +type mqlPlatform struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlPlatformInternal it will be used here + VulnerabilityReport plugin.TValue[interface{}] +} + +// createPlatform creates a new instance of this resource +func createPlatform(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlPlatform{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("platform", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlPlatform) MqlName() string { + return "platform" +} + +func (c *mqlPlatform) MqlID() string { + return c.__id +} + +func (c *mqlPlatform) GetVulnerabilityReport() *plugin.TValue[interface{}] { + return plugin.GetOrCompute[interface{}](&c.VulnerabilityReport, func() (interface{}, error) { + return c.vulnerabilityReport() + }) +} + // mqlPlatformAdvisories for the platform.advisories resource type mqlPlatformAdvisories struct { MqlRuntime *plugin.Runtime diff --git a/providers/os/resources/os.lr.manifest.yaml b/providers/os/resources/os.lr.manifest.yaml index abcf1a2279..523cbe72d2 100644 --- a/providers/os/resources/os.lr.manifest.yaml +++ b/providers/os/resources/os.lr.manifest.yaml @@ -639,6 +639,10 @@ resources: file: {} params: {} min_mondoo_version: 5.15.0 + platform: + fields: + vulnerabilityReport: {} + min_mondoo_version: latest platform.advisories: fields: cvss: {} diff --git a/providers/os/resources/platform_advisories.go b/providers/os/resources/platform_advisories.go index 4c24e9bcce..1c165f1ec5 100644 --- a/providers/os/resources/platform_advisories.go +++ b/providers/os/resources/platform_advisories.go @@ -53,9 +53,8 @@ func newAdvisoryScannerHttpClient(mondooapi string, plugins []ranger.ClientPlugi return sa, nil } -// fetches the vulnerability report and returns the full report -func (p *mqlAsset) vulnerabilityReport() (interface{}, error) { - mcc := p.MqlRuntime.Upstream +func fetchVulnReport(runtime *plugin.Runtime) (interface{}, error) { + mcc := runtime.Upstream if mcc == nil || mcc.ApiEndpoint == "" { return nil, resources.MissingUpstreamError{} } @@ -67,13 +66,13 @@ func (p *mqlAsset) vulnerabilityReport() (interface{}, error) { return nil, err } - conn := p.MqlRuntime.Connection.(shared.Connection) + conn := runtime.Connection.(shared.Connection) apiPackages := []*mvd.Package{} kernelVersion := "" // collect pacakges if the platform supports gathering files if conn.Capabilities().Has(shared.Capability_File) { - obj, err := CreateResource(p.MqlRuntime, "packages", map[string]*llx.RawData{}) + obj, err := CreateResource(runtime, "packages", map[string]*llx.RawData{}) if err != nil { return nil, err } @@ -99,7 +98,7 @@ func (p *mqlAsset) vulnerabilityReport() (interface{}, error) { // determine the kernel version if possible (just needed for linux at this point) // therefore we ignore the error because its not important, worst case the user sees to many advisories - objKernel, err := CreateResource(p.MqlRuntime, "kernel", map[string]*llx.RawData{}) + objKernel, err := CreateResource(runtime, "kernel", map[string]*llx.RawData{}) if err == nil { kernelVersion = getKernelVersion(objKernel.(*mqlKernel)) } @@ -121,6 +120,15 @@ func (p *mqlAsset) vulnerabilityReport() (interface{}, error) { return convert.JsonToDict(report) } +func (p *mqlPlatform) vulnerabilityReport() (interface{}, error) { + return fetchVulnReport(p.MqlRuntime) +} + +// fetches the vulnerability report and returns the full report +func (p *mqlAsset) vulnerabilityReport() (interface{}, error) { + return fetchVulnReport(p.MqlRuntime) +} + func getAdvisoryReport(runtime *plugin.Runtime) (*mvd.VulnReport, error) { obj, err := CreateResource(runtime, "asset", map[string]*llx.RawData{}) if err != nil {