github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/pluginmanager/plugin_manager_client.go (about)

     1  package pluginmanager
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  
     7  	"github.com/hashicorp/go-hclog"
     8  	"github.com/hashicorp/go-plugin"
     9  	"github.com/turbot/steampipe-plugin-sdk/v5/grpc"
    10  	"github.com/turbot/steampipe-plugin-sdk/v5/logging"
    11  	pb "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/proto"
    12  	pluginshared "github.com/turbot/steampipe/pkg/pluginmanager_service/grpc/shared"
    13  )
    14  
    15  // PluginManagerClient is the client used by steampipe to access the plugin manager
    16  type PluginManagerClient struct {
    17  	manager            pluginshared.PluginManager
    18  	pluginManagerState *State
    19  	rawClient          *plugin.Client
    20  }
    21  
    22  func NewPluginManagerClient(pluginManagerState *State) (*PluginManagerClient, error) {
    23  	res := &PluginManagerClient{
    24  		pluginManagerState: pluginManagerState,
    25  	}
    26  	err := res.attachToPluginManager()
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  
    31  	return res, nil
    32  }
    33  
    34  func (c *PluginManagerClient) attachToPluginManager() error {
    35  	// discard logging from the plugin client (plugin logs will still flow through)
    36  	loggOpts := &hclog.LoggerOptions{Name: "plugin", Output: io.Discard}
    37  	logger := logging.NewLogger(loggOpts)
    38  
    39  	// construct a client using the plugin manager reaattach config
    40  	c.rawClient = plugin.NewClient(&plugin.ClientConfig{
    41  		HandshakeConfig: pluginshared.Handshake,
    42  		Plugins:         pluginshared.PluginMap,
    43  		Reattach:        c.pluginManagerState.reattachConfig(),
    44  		AllowedProtocols: []plugin.Protocol{
    45  			plugin.ProtocolNetRPC, plugin.ProtocolGRPC},
    46  		Logger: logger,
    47  	})
    48  
    49  	// connect via RPC
    50  	rpcClient, err := c.rawClient.Client()
    51  	if err != nil {
    52  		log.Printf("[TRACE] failed to connect to plugin manager: %s", err.Error())
    53  		return err
    54  	}
    55  
    56  	// request the plugin
    57  	raw, err := rpcClient.Dispense(pluginshared.PluginName)
    58  	if err != nil {
    59  		log.Printf("[TRACE] failed to retreive to plugin manager from running plugin process: %s", err.Error())
    60  		return err
    61  	}
    62  
    63  	// cast to correct type
    64  	pluginManager := raw.(pluginshared.PluginManager)
    65  	c.manager = pluginManager
    66  
    67  	return nil
    68  }
    69  
    70  func (c *PluginManagerClient) Get(req *pb.GetRequest) (*pb.GetResponse, error) {
    71  	res, err := c.manager.Get(req)
    72  	if err != nil {
    73  		return nil, grpc.HandleGrpcError(err, "PluginManager", "Get")
    74  	}
    75  	return res, nil
    76  }
    77  
    78  func (c *PluginManagerClient) RefreshConnections(req *pb.RefreshConnectionsRequest) (*pb.RefreshConnectionsResponse, error) {
    79  	res, err := c.manager.RefreshConnections(req)
    80  	if err != nil {
    81  		return nil, grpc.HandleGrpcError(err, "PluginManager", "RefreshConnections")
    82  	}
    83  	return res, nil
    84  }
    85  
    86  func (c *PluginManagerClient) Shutdown(req *pb.ShutdownRequest) (*pb.ShutdownResponse, error) {
    87  	log.Printf("[DEBUG] PluginManagerClient.Shutdown start")
    88  	defer log.Printf("[DEBUG] PluginManagerClient.Shutdown done")
    89  
    90  	res, err := c.manager.Shutdown(req)
    91  	if err != nil {
    92  		return nil, grpc.HandleGrpcError(err, "PluginManager", "Get")
    93  	}
    94  	return res, nil
    95  }