go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/testutils/mockprovider/mockprovider.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package mockprovider
     5  
     6  import (
     7  	"errors"
     8  	"strconv"
     9  	"strings"
    10  
    11  	"go.mondoo.com/cnquery/llx"
    12  	"go.mondoo.com/cnquery/providers-sdk/v1/plugin"
    13  	"go.mondoo.com/cnquery/providers-sdk/v1/testutils/mockprovider/resources"
    14  )
    15  
    16  var Config = plugin.Provider{
    17  	Name:       "mock",
    18  	ID:         "go.mondoo.com/cnquery/providers-sdk/v1/testutils/mockprovider",
    19  	Version:    "0.0.0",
    20  	Connectors: []plugin.Connector{},
    21  }
    22  
    23  type Service struct {
    24  	runtimes         map[uint32]*plugin.Runtime
    25  	lastConnectionID uint32
    26  }
    27  
    28  func Init() *Service {
    29  	return &Service{
    30  		runtimes: map[uint32]*plugin.Runtime{},
    31  	}
    32  }
    33  
    34  func (s *Service) ParseCLI(req *plugin.ParseCLIReq) (*plugin.ParseCLIRes, error) {
    35  	return nil, errors.New("core doesn't offer any connectors")
    36  }
    37  
    38  func (s *Service) Connect(req *plugin.ConnectReq, callback plugin.ProviderCallback) (*plugin.ConnectRes, error) {
    39  	if req == nil || req.Asset == nil {
    40  		return nil, errors.New("no connection data provided")
    41  	}
    42  
    43  	s.lastConnectionID++
    44  	connID := s.lastConnectionID
    45  	runtime := &plugin.Runtime{
    46  		Callback:     callback,
    47  		HasRecording: req.HasRecording,
    48  	}
    49  	s.runtimes[connID] = runtime
    50  
    51  	return &plugin.ConnectRes{
    52  		Id:   connID,
    53  		Name: "mockprovider",
    54  	}, nil
    55  }
    56  
    57  func (s *Service) MockConnect(req *plugin.ConnectReq, callback plugin.ProviderCallback) (*plugin.ConnectRes, error) {
    58  	// Should never happen: the mock provider should not be called with MockConnect.
    59  	// It is the only thing that should ever call MockConnect to other providers
    60  	// (outside of tests).
    61  	return nil, errors.New("the mock provider does not support the mock connect call, this is an internal error")
    62  }
    63  
    64  // Shutdown is automatically called when the shell closes.
    65  // It is not necessary to implement this method.
    66  // If you want to do some cleanup, you can do it here.
    67  func (s *Service) Shutdown(req *plugin.ShutdownReq) (*plugin.ShutdownRes, error) {
    68  	return &plugin.ShutdownRes{}, nil
    69  }
    70  
    71  func (s *Service) GetData(req *plugin.DataReq) (*plugin.DataRes, error) {
    72  	runtime, ok := s.runtimes[req.Connection]
    73  	if !ok {
    74  		return nil, errors.New("connection " + strconv.FormatUint(uint64(req.Connection), 10) + " not found")
    75  	}
    76  
    77  	args := plugin.PrimitiveArgsToRawDataArgs(req.Args, runtime)
    78  
    79  	if req.ResourceId == "" && req.Field == "" {
    80  		res, err := resources.CreateResource(runtime, req.Resource, args)
    81  		if err != nil {
    82  			return nil, err
    83  		}
    84  
    85  		rd := llx.ResourceData(res, req.Resource).Result()
    86  		return &plugin.DataRes{
    87  			Data: rd.Data,
    88  		}, nil
    89  	}
    90  
    91  	resource, ok := runtime.Resources.Get(req.Resource + "\x00" + req.ResourceId)
    92  	if !ok {
    93  		return nil, errors.New("resource '" + req.Resource + "' (id: " + req.ResourceId + ") doesn't exist")
    94  	}
    95  
    96  	return resources.GetData(resource, req.Field, args), nil
    97  }
    98  
    99  func (s *Service) StoreData(req *plugin.StoreReq) (*plugin.StoreRes, error) {
   100  	runtime, ok := s.runtimes[req.Connection]
   101  	if !ok {
   102  		return nil, errors.New("connection " + strconv.FormatUint(uint64(req.Connection), 10) + " not found")
   103  	}
   104  
   105  	var errs []string
   106  	for i := range req.Resources {
   107  		info := req.Resources[i]
   108  
   109  		args, err := plugin.ProtoArgsToRawDataArgs(info.Fields)
   110  		if err != nil {
   111  			errs = append(errs, "failed to add cached "+info.Name+" (id: "+info.Id+"), failed to parse arguments")
   112  			continue
   113  		}
   114  
   115  		resource, ok := runtime.Resources.Get(info.Name + "\x00" + info.Id)
   116  		if !ok {
   117  			resource, err = resources.CreateResource(runtime, info.Name, args)
   118  			if err != nil {
   119  				errs = append(errs, "failed to add cached "+info.Name+" (id: "+info.Id+"), creation failed: "+err.Error())
   120  				continue
   121  			}
   122  
   123  			runtime.Resources.Set(info.Name+"\x00"+info.Id, resource)
   124  		}
   125  
   126  		for k, v := range args {
   127  			if err := resources.SetData(resource, k, v); err != nil {
   128  				errs = append(errs, "failed to add cached "+info.Name+" (id: "+info.Id+"), field error: "+err.Error())
   129  			}
   130  		}
   131  	}
   132  
   133  	if len(errs) != 0 {
   134  		return nil, errors.New(strings.Join(errs, ", "))
   135  	}
   136  	return &plugin.StoreRes{}, nil
   137  }