go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/yum.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package resources 5 6 import ( 7 "errors" 8 "fmt" 9 "regexp" 10 "strings" 11 12 "go.mondoo.com/cnquery/llx" 13 "go.mondoo.com/cnquery/providers-sdk/v1/plugin" 14 "go.mondoo.com/cnquery/providers/os/connection/shared" 15 "go.mondoo.com/cnquery/providers/os/resources/yum" 16 "go.mondoo.com/cnquery/types" 17 "go.mondoo.com/cnquery/utils/stringx" 18 ) 19 20 var supportedPlatforms = []string{"amazonlinux"} 21 22 func (y *mqlYum) id() (string, error) { 23 return "yum", nil 24 } 25 26 func (y *mqlYum) repos() ([]interface{}, error) { 27 conn := y.MqlRuntime.Connection.(shared.Connection) 28 platform := conn.Asset().Platform 29 30 if !platform.IsFamily("redhat") && !stringx.Contains(supportedPlatforms, platform.Name) { 31 return nil, errors.New("yum.repos is only supported on redhat-based platforms") 32 } 33 34 o, err := CreateResource(y.MqlRuntime, "command", map[string]*llx.RawData{ 35 "command": llx.StringData("yum -v repolist all"), 36 }) 37 cmd := o.(*mqlCommand) 38 if exit := cmd.GetExitcode(); exit.Data != 0 { 39 return nil, errors.New("could not retrieve yum repo list") 40 } 41 42 repos, err := yum.ParseRepos(strings.NewReader(cmd.Stdout.Data)) 43 if err != nil { 44 return nil, err 45 } 46 47 mqlRepos := make([]interface{}, len(repos)) 48 for i, repo := range repos { 49 f, err := CreateResource(y.MqlRuntime, "file", map[string]*llx.RawData{ 50 "path": llx.StringData(repo.Filename), 51 }) 52 if err != nil { 53 return nil, err 54 } 55 56 mqlRepo, err := CreateResource(y.MqlRuntime, "yum.repo", map[string]*llx.RawData{ 57 "id": llx.StringData(repo.Id), 58 "name": llx.StringData(repo.Name), 59 "status": llx.StringData(repo.Status), 60 "baseurl": llx.ArrayData(llx.TArr2Raw(repo.Baseurl), types.String), 61 "expire": llx.StringData(repo.Expire), 62 "filename": llx.StringData(repo.Filename), 63 "file": llx.ResourceData(f, "file"), 64 "revision": llx.StringData(repo.Revision), 65 "pkgs": llx.StringData(repo.Pkgs), 66 "size": llx.StringData(repo.Size), 67 "mirrors": llx.StringData(repo.Mirrors), 68 }) 69 if err != nil { 70 return nil, err 71 } 72 mqlRepos[i] = mqlRepo 73 } 74 75 return mqlRepos, nil 76 } 77 78 var rhel67release = regexp.MustCompile(`^[6|7].*$`) 79 80 func (y *mqlYum) vars() (map[string]interface{}, error) { 81 conn := y.MqlRuntime.Connection.(shared.Connection) 82 platform := conn.Asset().Platform 83 84 if !platform.IsFamily("redhat") && !stringx.Contains(supportedPlatforms, platform.Name) { 85 return nil, errors.New("yum.vars is only supported on redhat-based platforms") 86 } 87 88 // use dnf script as default 89 script := fmt.Sprintf(yum.DnfVarsCommand, yum.PythonRhel) 90 if !platform.IsFamily("redhat") { 91 // eg. amazon linux does not ship with /usr/libexec/platform-python 92 script = fmt.Sprintf(yum.DnfVarsCommand, yum.Python3) 93 } 94 95 // fallback for older versions like 6 and 7 version to use yum script 96 if rhel67release.MatchString(platform.Version) { 97 script = yum.Rhel6VarsCommand 98 } 99 100 o, err := CreateResource(y.MqlRuntime, "command", map[string]*llx.RawData{ 101 "command": llx.StringData(script), 102 }) 103 cmd := o.(*mqlCommand) 104 if exit := cmd.GetExitcode(); exit.Data != 0 { 105 return nil, errors.New("could not retrieve yum repo list") 106 } 107 108 vars, err := yum.ParseVariables(strings.NewReader(cmd.Stdout.Data)) 109 if err != nil { 110 return nil, err 111 } 112 113 res := map[string]interface{}{} 114 for k := range vars { 115 res[k] = vars[k] 116 } 117 118 return res, nil 119 } 120 121 func (y *mqlYumRepo) id() (string, error) { 122 return y.Id.Data, nil 123 } 124 125 func initYumRepo(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { 126 if len(args) > 2 { 127 return args, nil, nil 128 } 129 130 nameRaw := args["id"] 131 if nameRaw == nil { 132 return args, nil, nil 133 } 134 135 name, ok := nameRaw.Value.(string) 136 if !ok { 137 return args, nil, nil 138 } 139 140 o, err := CreateResource(runtime, "yum", map[string]*llx.RawData{}) 141 if err != nil { 142 return nil, nil, err 143 } 144 yumResource := o.(*mqlYum) 145 146 repos := yumResource.GetRepos() 147 if repos.Error != nil { 148 return nil, nil, repos.Error 149 } 150 151 for i := range repos.Data { 152 selected := repos.Data[i].(*mqlYumRepo) 153 if selected.Id.Data == name { 154 return nil, selected, nil 155 } 156 } 157 158 // if the repo cannot be found we return an error 159 return nil, nil, errors.New("could not find yum repo " + name) 160 } 161 162 func (y *mqlYumRepo) enabled() (bool, error) { 163 status := y.GetStatus() 164 if status.Error != nil { 165 return false, status.Error 166 } 167 168 return strings.ToLower(status.Data) == "enabled", nil 169 }