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  }