github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/dashboard/dashboardexecute/snapshot.go (about)

     1  package dashboardexecute
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  
     8  	"github.com/turbot/steampipe/pkg/dashboard/dashboardevents"
     9  	"github.com/turbot/steampipe/pkg/dashboard/dashboardtypes"
    10  	"github.com/turbot/steampipe/pkg/initialisation"
    11  	"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
    12  )
    13  
    14  func GenerateSnapshot(ctx context.Context, target string, initData *initialisation.InitData, inputs map[string]any) (snapshot *dashboardtypes.SteampipeSnapshot, err error) {
    15  	w := initData.Workspace
    16  
    17  	parsedName, err := modconfig.ParseResourceName(target)
    18  	if err != nil {
    19  		return nil, err
    20  	}
    21  	// no session for manual execution
    22  	sessionId := ""
    23  	errorChannel := make(chan error)
    24  	resultChannel := make(chan *dashboardtypes.SteampipeSnapshot)
    25  	dashboardEventHandler := func(ctx context.Context, event dashboardevents.DashboardEvent) {
    26  		handleDashboardEvent(ctx, event, resultChannel, errorChannel)
    27  	}
    28  	w.RegisterDashboardEventHandler(ctx, dashboardEventHandler)
    29  	// clear event handlers again in case another snapshot will be generated in this run
    30  	defer w.UnregisterDashboardEventHandlers()
    31  
    32  	// all runtime dependencies must be resolved before execution (i.e. inputs must be passed in)
    33  	Executor.interactive = false
    34  	if err := Executor.ExecuteDashboard(ctx, sessionId, target, inputs, w, initData.Client); err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	select {
    39  	case err = <-errorChannel:
    40  		return nil, err
    41  	case snapshot = <-resultChannel:
    42  		// set the filename root of the snapshot
    43  		fileRootName, err := parsedName.ToFullNameWithMod(w.Mod.ShortName)
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  		snapshot.FileNameRoot = fileRootName
    48  		//  return the context error (if any) to ensure we respect cancellation
    49  		return snapshot, ctx.Err()
    50  	}
    51  }
    52  
    53  func handleDashboardEvent(_ context.Context, event dashboardevents.DashboardEvent, resultChannel chan *dashboardtypes.SteampipeSnapshot, errorChannel chan error) {
    54  	switch e := event.(type) {
    55  	case *dashboardevents.ExecutionError:
    56  		errorChannel <- e.Error
    57  	case *dashboardevents.ExecutionComplete:
    58  		log.Println("[TRACE] execution complete event", *e)
    59  		snap := ExecutionCompleteToSnapshot(e)
    60  		resultChannel <- snap
    61  	}
    62  }
    63  
    64  // ExecutionCompleteToSnapshot transforms the ExecutionComplete event into a SteampipeSnapshot
    65  func ExecutionCompleteToSnapshot(event *dashboardevents.ExecutionComplete) *dashboardtypes.SteampipeSnapshot {
    66  	return &dashboardtypes.SteampipeSnapshot{
    67  		SchemaVersion: fmt.Sprintf("%d", dashboardtypes.SteampipeSnapshotSchemaVersion),
    68  		Panels:        event.Panels,
    69  		Layout:        event.Root.AsTreeNode(),
    70  		Inputs:        event.Inputs,
    71  		Variables:     event.Variables,
    72  		SearchPath:    event.SearchPath,
    73  		StartTime:     event.StartTime,
    74  		EndTime:       event.EndTime,
    75  		Title:         event.Root.GetTitle(),
    76  	}
    77  }