github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/dashboard/dashboardexecute/dashboard_tree_run_impl.go (about) 1 package dashboardexecute 2 3 import ( 4 "context" 5 "github.com/turbot/steampipe/pkg/dashboard/dashboardevents" 6 "github.com/turbot/steampipe/pkg/dashboard/dashboardtypes" 7 "github.com/turbot/steampipe/pkg/error_helpers" 8 "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" 9 "log" 10 ) 11 12 type DashboardTreeRunImpl struct { 13 DashboardName string `json:"dashboard"` 14 Description string `json:"description,omitempty"` 15 Display string `cty:"display" hcl:"display" json:"display,omitempty"` 16 Documentation string `json:"documentation,omitempty"` 17 ErrorString string `json:"error,omitempty"` 18 Name string `json:"name"` 19 NodeType string `json:"panel_type"` 20 SourceDefinition string `json:"source_definition"` 21 Status dashboardtypes.RunStatus `json:"status"` 22 Tags map[string]string `json:"tags,omitempty"` 23 Title string `json:"title,omitempty"` 24 Type string `json:"display_type,omitempty"` 25 Width int `json:"width,omitempty"` 26 27 err error 28 parent dashboardtypes.DashboardParent 29 executionTree *DashboardExecutionTree 30 resource modconfig.DashboardLeafNode 31 // store the top level run which embeds this struct 32 // we need this for setStatus which serialises the run for the message payload 33 run dashboardtypes.DashboardTreeRun 34 } 35 36 func NewDashboardTreeRunImpl(resource modconfig.DashboardLeafNode, parent dashboardtypes.DashboardParent, run dashboardtypes.DashboardTreeRun, executionTree *DashboardExecutionTree) DashboardTreeRunImpl { 37 // NOTE: we MUST declare children inline - therefore we cannot share children between runs in the tree 38 // (if we supported the children property then we could reuse resources) 39 // so FOR NOW it is safe to use the container name directly as the run name 40 res := DashboardTreeRunImpl{ 41 Name: resource.Name(), 42 Title: resource.GetTitle(), 43 NodeType: resource.BlockType(), 44 Width: resource.GetWidth(), 45 Display: resource.GetDisplay(), 46 Description: resource.GetDescription(), 47 Documentation: resource.GetDocumentation(), 48 Type: resource.GetType(), 49 Tags: resource.GetTags(), 50 SourceDefinition: resource.GetMetadata().SourceDefinition, 51 52 // set to complete, optimistically 53 // if any children have SQL we will set this to DashboardRunReady instead 54 Status: dashboardtypes.RunComplete, 55 parent: parent, 56 executionTree: executionTree, 57 resource: resource, 58 run: run, 59 } 60 61 // TACTICAL if this run was created to create a snapshot output for a control run, 62 // there will be no execution tree 63 if executionTree != nil { 64 res.DashboardName = executionTree.dashboardName 65 } else { 66 // there is no execution tree - use the resource name as the dashboard name 67 res.DashboardName = resource.Name() 68 } 69 return res 70 } 71 72 // GetName implements DashboardTreeRun 73 func (r *DashboardTreeRunImpl) GetName() string { 74 return r.Name 75 } 76 77 // GetRunStatus implements DashboardTreeRun 78 func (r *DashboardTreeRunImpl) GetRunStatus() dashboardtypes.RunStatus { 79 return r.Status 80 } 81 82 // GetError implements DashboardTreeRun 83 func (r *DashboardTreeRunImpl) GetError() error { 84 return r.err 85 } 86 87 // RunComplete implements DashboardTreeRun 88 func (r *DashboardTreeRunImpl) RunComplete() bool { 89 return r.Status.IsFinished() 90 } 91 92 // GetInputsDependingOn implements DashboardTreeRun 93 // defaults to nothing 94 func (r *DashboardTreeRunImpl) GetInputsDependingOn(_ string) []string { return nil } 95 96 // GetParent implements DashboardTreeRun 97 func (r *DashboardTreeRunImpl) GetParent() dashboardtypes.DashboardParent { 98 return r.parent 99 } 100 101 // GetTitle implements DashboardTreeRun 102 func (r *DashboardTreeRunImpl) GetTitle() string { 103 return r.Title 104 } 105 106 // GetNodeType implements DashboardTreeRun 107 func (r *DashboardTreeRunImpl) GetNodeType() string { 108 return r.NodeType 109 } 110 111 // Initialise implements DashboardTreeRun 112 func (r *DashboardTreeRunImpl) Initialise(context.Context) { 113 panic("must be implemented by child struct") 114 } 115 116 // Execute implements DashboardTreeRun 117 func (r *DashboardTreeRunImpl) Execute(ctx context.Context) { 118 panic("must be implemented by child struct") 119 } 120 121 // AsTreeNode implements DashboardTreeRun 122 func (r *DashboardTreeRunImpl) AsTreeNode() *dashboardtypes.SnapshotTreeNode { 123 panic("must be implemented by child struct") 124 } 125 126 // GetResource implements DashboardTreeRun 127 func (r *DashboardTreeRunImpl) GetResource() modconfig.DashboardLeafNode { 128 return r.resource 129 } 130 131 // SetError implements DashboardTreeRun 132 func (r *DashboardTreeRunImpl) SetError(ctx context.Context, err error) { 133 log.Printf("[TRACE] %s SetError err %v", r.Name, err) 134 r.err = err 135 // error type does not serialise to JSON so copy into a string 136 r.ErrorString = err.Error() 137 // set status (this sends update event) 138 if error_helpers.IsContextCancelledError(err) { 139 r.setStatus(ctx, dashboardtypes.RunCanceled) 140 } else { 141 r.setStatus(ctx, dashboardtypes.RunError) 142 } 143 // tell parent we are done 144 r.notifyParentOfCompletion() 145 } 146 147 // SetComplete implements DashboardTreeRun 148 func (r *DashboardTreeRunImpl) SetComplete(ctx context.Context) { 149 // set status (this sends update event) 150 r.setStatus(ctx, dashboardtypes.RunComplete) 151 // tell parent we are done 152 r.notifyParentOfCompletion() 153 } 154 155 func (r *DashboardTreeRunImpl) setStatus(ctx context.Context, status dashboardtypes.RunStatus) { 156 r.Status = status 157 // notify our parent that our status has changed 158 r.parent.ChildStatusChanged(ctx) 159 160 // raise LeafNodeUpdated event 161 // TODO [node_reuse] do this a different way https://github.com/turbot/steampipe/issues/2919 162 // TACTICAL: pass the full run struct - 'r.run', rather than ourselves - so we serialize all properties 163 e, _ := dashboardevents.NewLeafNodeUpdate(r.run, r.executionTree.sessionId, r.executionTree.id) 164 r.executionTree.workspace.PublishDashboardEvent(ctx, e) 165 166 } 167 168 func (r *DashboardTreeRunImpl) notifyParentOfCompletion() { 169 r.parent.ChildCompleteChan() <- r 170 }